diff options
Diffstat (limited to 'sc')
154 files changed, 4206 insertions, 3797 deletions
diff --git a/sc/inc/chart2uno.hxx b/sc/inc/chart2uno.hxx index 44737e711090..8ff1b0e9bd73 100644 --- a/sc/inc/chart2uno.hxx +++ b/sc/inc/chart2uno.hxx @@ -241,70 +241,6 @@ private: }; -// LabeledDataSequence ======================================================= - -class ScChart2LabeledDataSequence : public - ::cppu::WeakImplHelper4< - ::com::sun::star::chart2::data::XLabeledDataSequence, - ::com::sun::star::util::XCloneable, - ::com::sun::star::util::XModifyBroadcaster, - ::com::sun::star::lang::XServiceInfo >, - SfxListener -{ -public: - - explicit ScChart2LabeledDataSequence( ScDocument* pDoc ); - virtual ~ScChart2LabeledDataSequence(); - - // SfxListener ----------------------------------------------------------- - - virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); - - // XLabeledDataSequence -------------------------------------------------- - - virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > SAL_CALL getValues() - throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setValues( - const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >& xSequence ) - throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence > SAL_CALL getLabel() - throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setLabel( - const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSequence >& xSequence ) - throw (::com::sun::star::uno::RuntimeException); - - // XCloneable ------------------------------------------------------------ - - virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone() - throw (::com::sun::star::uno::RuntimeException); - - // XModifyBroadcaster ---------------------------------------------------- - - virtual void SAL_CALL addModifyListener( - const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) - throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeModifyListener( - const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) - throw (::com::sun::star::uno::RuntimeException); - - // XServiceInfo ---------------------------------------------------------- - - virtual ::rtl::OUString SAL_CALL getImplementationName() throw( - ::com::sun::star::uno::RuntimeException); - virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& - rServiceName) throw( ::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL - getSupportedServiceNames() throw( - ::com::sun::star::uno::RuntimeException); - -private: - ::com::sun::star::uno::Reference< - ::com::sun::star::chart2::data::XDataSequence > m_aData; - ::com::sun::star::uno::Reference< - ::com::sun::star::chart2::data::XDataSequence > m_aLabel; - ScDocument* m_pDocument; -}; - // DataSequence ============================================================== class ScChart2DataSequence : public diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 36569d4efefb..87c2f59d2d98 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -110,6 +110,7 @@ private: friend class ScDocument; // fuer FillInfo friend class ScDocumentIterator; friend class ScValueIterator; +friend class ScHorizontalValueIterator; friend class ScDBQueryDataIterator; friend class ScColumnIterator; friend class ScQueryCellIterator; diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index 27845bbc50cf..e2c863dace7d 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -361,6 +361,12 @@ public: static void CheckTabQuotes( String& aTabName, const formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO ); + /** Analyzes a string for a 'Doc'#Tab construct, or 'Do''c'#Tab etc.. + + @returns the position of the unquoted # hash mark in 'Doc'#Tab, or + STRING_NOTFOUND if none. */ + static xub_StrLen GetDocTabPos( const String& rString ); + static sal_Bool EnQuote( String& rStr ); sal_Unicode GetNativeAddressSymbol( Convention::SpecialSymbolType eType ) const; diff --git a/sc/inc/dbcolect.hxx b/sc/inc/dbcolect.hxx index 2398a142ee4e..32eeb2d65353 100644 --- a/sc/inc/dbcolect.hxx +++ b/sc/inc/dbcolect.hxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2011 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -44,7 +44,7 @@ class ScDocument; class ScDBData : public ScDataObject, public ScRefreshTimer { - +friend class ScDBCollection; private: // DBParam String aName; @@ -219,6 +219,7 @@ public: virtual sal_Bool IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const; ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const; ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; + ScDBData* GetFilterDBAtTable(SCTAB nTab) const; sal_Bool SearchName( const String& rName, sal_uInt16& rIndex ) const; diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx index e61d1f0281c8..15be21b697b8 100644 --- a/sc/inc/dociter.hxx +++ b/sc/inc/dociter.hxx @@ -423,6 +423,7 @@ private: SCTAB nTab; SCCOL nStartCol; SCCOL nEndCol; + SCROW nStartRow; SCROW nEndRow; SCROW* pNextRows; SCSIZE* pNextIndices; @@ -437,12 +438,47 @@ public: ScBaseCell* GetNext( SCCOL& rCol, SCROW& rRow ); sal_Bool ReturnNext( SCCOL& rCol, SCROW& rRow ); + /// Set a(nother) sheet and (re)init. + void SetTab( SCTAB nTab ); private: void Advance(); }; +/** Row-wise value iterator. */ +class ScHorizontalValueIterator +{ +private: + ScDocument *pDoc; + const ScAttrArray *pAttrArray; + ScHorizontalCellIterator *pCellIter; + sal_uLong nNumFormat; // for CalcAsShown + sal_uLong nNumFmtIndex; + SCTAB nEndTab; + SCCOL nCurCol; + SCROW nCurRow; + SCTAB nCurTab; + SCROW nAttrEndRow; + short nNumFmtType; + bool bNumValid; + bool bSubTotal; + bool bCalcAsShown; + bool bTextAsZero; + +public: + + ScHorizontalValueIterator( ScDocument* pDocument, + const ScRange& rRange, + bool bSTotal = false, + bool bTextAsZero = false ); + ~ScHorizontalValueIterator(); + void GetCurNumFmtInfo( short& nType, sal_uLong& nIndex ); + /// Does NOT reset rValue if no value found! + bool GetNext( double& rValue, sal_uInt16& rErr ); +}; + + // // gibt alle Bereiche mit nicht-Default-Formatierung zurueck (horizontal) // diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 9a83a49b8c5e..ecbd73e6cd4e 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2011 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -49,8 +49,7 @@ // Wang Xu Ming -- 2009-8-17 // DataPilot Migration - Cache&&Performance #include <list> -#include "dpobject.hxx" -#include "dptabdat.hxx" +class ScDPTableDataCache; // End Comments class KeyEvent; @@ -120,6 +119,7 @@ class ScViewOptions; class ScStrCollection; class TypedScStrCollection; class ScChangeTrack; +class ScEditEngineDefaulter; class ScFieldEditEngine; class ScNoteEditEngine; struct ScConsolidateParam; @@ -241,6 +241,7 @@ class ScDocument { friend class ScDocumentIterator; friend class ScValueIterator; +friend class ScHorizontalValueIterator; friend class ScDBQueryDataIterator; friend class ScCellIterator; friend class ScQueryCellIterator; @@ -273,7 +274,6 @@ private: ScDPCollection* pDPCollection; // Wang Xu Ming -- 2009-8-17 // DataPilot Migration - Cache&&Performance - std::list<ScDPObject> m_listDPObjectsInClip; std::list<ScDPTableDataCache*> m_listDPObjectsCaches; // End Comments ScChartCollection* pChartCollection; @@ -505,7 +505,7 @@ public: ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly = sal_False) const; ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; - + ScDBData* GetFilterDBAtTable(SCTAB nTab) const; //UNUSED2008-05 ScRangeData* GetRangeAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, //UNUSED2008-05 sal_Bool bStartOnly = sal_False) const; SC_DLLPUBLIC ScRangeData* GetRangeAtBlock( const ScRange& rBlock, String* pName=NULL ) const; @@ -790,6 +790,7 @@ public: SC_DLLPUBLIC void GetString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString ); SC_DLLPUBLIC void GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString ); + sal_uInt16 GetStringForFormula( const ScAddress& rPos, rtl::OUString& rString ); SC_DLLPUBLIC double GetValue( const ScAddress& ); SC_DLLPUBLIC void GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, double& rValue ); SC_DLLPUBLIC double RoundValueAsShown( double fVal, sal_uLong nFormat ); @@ -924,10 +925,10 @@ public: selection, but the bounds of the sheet's data area instead. - @returns sal_True if the area passed intersected the data - area, sal_False if not, in which case the values + @returns True if the area passed intersected the data + area, false if not, in which case the values obtained may be out of bounds, not in order or - unmodified. sal_True does not mean that there + unmodified. True does not mean that there actually is any data within the selection. */ bool ShrinkToDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow ) const; @@ -935,9 +936,9 @@ public: /** Shrink a range to only include used data area. @param o_bShrunk - Out parameter, sal_True if area was shrunk, sal_False if not. + Out parameter, True if area was shrunk, false if not. - @returns sal_True if there is any data, sal_False if not. + @returns True if there is any data, fakse if not. */ bool ShrinkToUsedDataArea( bool& o_bShrunk, SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, @@ -1596,6 +1597,8 @@ public: sal_Bool IsValidAsianKerning() const; void SetAsianKerning(sal_Bool bNew); + void ApplyAsianEditSettings(ScEditEngineDefaulter& rEngine); + sal_uInt8 GetEditTextDirection(SCTAB nTab) const; // EEHorizontalTextDirection values SC_DLLPUBLIC ScLkUpdMode GetLinkMode() const { return eLinkMode ;} @@ -1790,7 +1793,6 @@ public: SC_DLLPUBLIC SfxItemPool* GetEnginePool() const; SC_DLLPUBLIC ScFieldEditEngine& GetEditEngine(); SC_DLLPUBLIC ScNoteEditEngine& GetNoteEngine(); -//UNUSED2009-05 SfxItemPool& GetNoteItemPool(); ScRefreshTimerControl* GetRefreshTimerControl() const { return pRefreshTimerControl; } diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index e152b4a88f97..f213806762d8 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -129,7 +129,7 @@ public: ScDocument* GetDocument() const; SfxObjectShell* GetEmbeddedObject() const; - void UpdateAllRowHeights( const ScMarkData* pTabMark = NULL ); + void UpdateAllRowHeights( const ScMarkData* pTabMark = NULL, bool bCalcOutputFactor = false ); void BeforeXMLLoading(); void AfterXMLLoading(sal_Bool bRet); diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index e69f8e8c3a3f..5890ca847c08 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -106,7 +106,6 @@ private: ScDPOutput* pOutput; sal_Bool bSettingsChanged; sal_Bool bAlive; // sal_False if only used to hold settings - sal_uInt16 mnAutoFormatIndex; sal_Bool bAllowMove; long nHeaderRows; // page fields plus filter button bool mbHeaderLayout; // sal_True : grid, sal_False : standard @@ -117,6 +116,7 @@ private: SC_DLLPRIVATE void CreateOutput(); sal_Bool bRefresh; long mnCacheId; + bool mbCreatingTableData; public: // Wang Xu Ming -- 2009-8-17 @@ -150,13 +150,10 @@ public: void SetOutRange(const ScRange& rRange); const ScRange& GetOutRange() const { return aOutRange; } - void SetAutoFormatIndex (const sal_uInt16 nIndex); - sal_uInt16 GetAutoFormatIndex() const; - void SetHeaderLayout(bool bUseGrid); bool GetHeaderLayout() const; - void SetSheetDesc(const ScSheetSourceDesc& rDesc); + void SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate = false); void SetImportDesc(const ScImportSourceDesc& rDesc); void SetServiceData(const ScDPServiceDesc& rDesc); diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index 8c4babc77da3..b5c36e9d2f72 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -46,6 +46,7 @@ namespace com { namespace sun { namespace star { namespace sheet { class ScDPDimensionSaveData; class ScDPTableData; +class ScDPObject; // -------------------------------------------------------------------- // @@ -69,16 +70,16 @@ public: sal_Bool operator== ( const ScDPSaveMember& r ) const; const String& GetName() const { return aName; } - sal_Bool HasIsVisible() const; - SC_DLLPUBLIC void SetIsVisible(sal_Bool bSet); - sal_Bool GetIsVisible() const { return sal_Bool(nVisibleMode); } - sal_Bool HasShowDetails() const; - SC_DLLPUBLIC void SetShowDetails(sal_Bool bSet); - sal_Bool GetShowDetails() const { return sal_Bool(nShowDetailsMode); } + SC_DLLPUBLIC sal_Bool HasIsVisible() const; + SC_DLLPUBLIC void SetIsVisible(sal_Bool bSet); + sal_Bool GetIsVisible() const { return sal_Bool(nVisibleMode); } + SC_DLLPUBLIC sal_Bool HasShowDetails() const; + SC_DLLPUBLIC void SetShowDetails(sal_Bool bSet); + sal_Bool GetShowDetails() const { return sal_Bool(nShowDetailsMode); } void SetName( const String& rNew ); // used if the source member was renamed (groups) - SC_DLLPUBLIC void SetLayoutName( const ::rtl::OUString& rName ); + SC_DLLPUBLIC void SetLayoutName( const ::rtl::OUString& rName ); SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const; void RemoveLayoutName(); @@ -272,6 +273,7 @@ public: SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied void BuildAllDimensionMembers(ScDPTableData* pData); + void BuildAllDimensionMembersFromSource(ScDPObject* pDPObj); /** * Check whether a dimension has one or more invisible members. diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index 818920885493..3e78232db55a 100644 --- a/sc/inc/externalrefmgr.hxx +++ b/sc/inc/externalrefmgr.hxx @@ -257,8 +257,6 @@ public: void getAllTableNames(sal_uInt16 nFileId, ::std::vector<String>& rTabNames) const; SCsTAB getTabSpan( sal_uInt16 nFileId, const String& rStartTabName, const String& rEndTabName ) const; void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const; - bool hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const; - size_t getCacheTableCount(sal_uInt16 nFileId) const; /** * Set all tables of a document as referenced, used only during @@ -508,8 +506,6 @@ public: */ void getAllCachedNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const; - bool hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const; - size_t getCacheTableCount(sal_uInt16 nFileId) const; sal_uInt16 getExternalFileCount() const; /** @@ -646,6 +642,11 @@ public: void resetSrcFileData(const String& rBaseFileUrl); /** + * Replace the original URL wirh the real URL that was generated from the relative URL. + */ + void updateAbsAfterLoad(); + + /** * Stop tracking a specific formula cell. * * @param pCell pointer to cell that formerly contained external diff --git a/sc/inc/notesuno.hxx b/sc/inc/notesuno.hxx index a1648132f8e1..c7e60072698b 100644 --- a/sc/inc/notesuno.hxx +++ b/sc/inc/notesuno.hxx @@ -28,18 +28,14 @@ #ifndef SC_NOTESUNO_HXX #define SC_NOTESUNO_HXX -#include "address.hxx" -#include <svl/lstner.hxx> #include <com/sun/star/sheet/XSheetAnnotation.hpp> #include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/container/XChild.hpp> #include <com/sun/star/text/XSimpleText.hpp> -#include <com/sun/star/text/XTextRangeMover.hpp> -#include <com/sun/star/drawing/XShape.hpp> #include <cppuhelper/implbase5.hxx> -#include <cppuhelper/implbase10.hxx> - +#include <svl/lstner.hxx> +#include "address.hxx" class ScDocShell; class SvxUnoText; @@ -129,193 +125,4 @@ private: SvxUnoText* pUnoText; }; -class ScAnnotationShapeObj : public cppu::WeakImplHelper10< - com::sun::star::lang::XComponent, - com::sun::star::container::XChild, - com::sun::star::text::XText, - com::sun::star::container::XEnumerationAccess, - com::sun::star::text::XTextRangeMover, - com::sun::star::drawing::XShape, - com::sun::star::beans::XPropertySet, - com::sun::star::beans::XMultiPropertySet, - com::sun::star::beans::XPropertyState, - com::sun::star::lang::XServiceInfo >, - public SfxListener -{ -private: - ScDocShell* pDocShell; - ScAddress aCellPos; - SvxUnoText* pUnoText; - com::sun::star::uno::Reference < com::sun::star::drawing::XShape > xShape; - -private: - SvxUnoText& GetUnoText(); - com::sun::star::uno::Reference < com::sun::star::drawing::XShape > GetXShape(); - -public: - ScAnnotationShapeObj(ScDocShell* pDocSh, const ScAddress& rPos); - virtual ~ScAnnotationShapeObj(); - - virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); - - // XChild - virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL - getParent() throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< - ::com::sun::star::uno::XInterface >& Parent ) - throw(::com::sun::star::lang::NoSupportException, - ::com::sun::star::uno::RuntimeException); - - // XElementAccess - virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException); - - // XEnumerationAccess - virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL - createEnumeration( ) throw (::com::sun::star::uno::RuntimeException); - - // XTextRangeMover - virtual void SAL_CALL moveTextRange( const ::com::sun::star::uno::Reference< - ::com::sun::star::text::XTextRange >& xRange, - ::sal_Int16 nParagraphs ) - throw (::com::sun::star::uno::RuntimeException); - - // XText - virtual void SAL_CALL insertTextContent( const ::com::sun::star::uno::Reference< - ::com::sun::star::text::XTextRange >& xRange, - const ::com::sun::star::uno::Reference< - ::com::sun::star::text::XTextContent >& xContent, - ::sal_Bool bAbsorb ) - throw (::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeTextContent( const ::com::sun::star::uno::Reference< - ::com::sun::star::text::XTextContent >& xContent ) - throw (::com::sun::star::container::NoSuchElementException, - ::com::sun::star::uno::RuntimeException); - - // XSimpleText - virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextCursor > SAL_CALL - createTextCursor() throw(::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextCursor > SAL_CALL - createTextCursorByRange( const ::com::sun::star::uno::Reference< - ::com::sun::star::text::XTextRange >& aTextPosition ) - throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL insertString( const ::com::sun::star::uno::Reference< - ::com::sun::star::text::XTextRange >& xRange, - const ::rtl::OUString& aString, sal_Bool bAbsorb ) - throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL insertControlCharacter( const ::com::sun::star::uno::Reference< - ::com::sun::star::text::XTextRange >& xRange, - sal_Int16 nControlCharacter, sal_Bool bAbsorb ) - throw(::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::uno::RuntimeException); - - // XTextRange - virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > SAL_CALL - getText() throw(::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL - getStart() throw(::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL - getEnd() throw(::com::sun::star::uno::RuntimeException); - virtual ::rtl::OUString SAL_CALL getString() throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setString( const ::rtl::OUString& aString ) - throw(::com::sun::star::uno::RuntimeException); - - // XShapeDescriptor - virtual ::rtl::OUString SAL_CALL getShapeType( ) throw (::com::sun::star::uno::RuntimeException); - - // XShape - virtual ::com::sun::star::awt::Point SAL_CALL getPosition( ) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setPosition( const ::com::sun::star::awt::Point& aPosition ) throw (::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setSize( const ::com::sun::star::awt::Size& aSize ) - throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException); - - // XPropertyState - virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( const ::rtl::OUString& PropertyName ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > SAL_CALL getPropertyStates( - const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyName ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setPropertyToDefault( const ::rtl::OUString& PropertyName ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault( const ::rtl::OUString& aPropertyName ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); - - // XPropertySet - virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) - throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::beans::PropertyVetoException, - ::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::lang::WrappedTargetException, - ::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::lang::WrappedTargetException, - ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, - const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::lang::WrappedTargetException, - ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, - const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::lang::WrappedTargetException, - ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, - const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::lang::WrappedTargetException, - ::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, - const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::lang::WrappedTargetException, - ::com::sun::star::uno::RuntimeException); - - // XMultiPropertySet - virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, - const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aValues ) - throw (::com::sun::star::beans::PropertyVetoException, - ::com::sun::star::lang::IllegalArgumentException, - ::com::sun::star::lang::WrappedTargetException, - ::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > SAL_CALL getPropertyValues( - const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ) - throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL addPropertiesChangeListener( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, - const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) - throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removePropertiesChangeListener( const ::com::sun::star::uno::Reference< - ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) - throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL firePropertiesChangeEvent( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, - const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener ) - throw (::com::sun::star::uno::RuntimeException); - - // XComponent - virtual void SAL_CALL dispose( ) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) - throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) - throw (::com::sun::star::uno::RuntimeException); - - // XServiceInfo - virtual ::rtl::OUString SAL_CALL getImplementationName() - throw(::com::sun::star::uno::RuntimeException); - virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) - throw(::com::sun::star::uno::RuntimeException); - virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() - throw(::com::sun::star::uno::RuntimeException); -}; - - #endif - diff --git a/sc/inc/shapeuno.hxx b/sc/inc/shapeuno.hxx index 74ae321bd409..87eb82a3d185 100644 --- a/sc/inc/shapeuno.hxx +++ b/sc/inc/shapeuno.hxx @@ -36,6 +36,7 @@ #include <com/sun/star/lang/XTypeProvider.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/document/XEventsSupplier.hpp> +#include <com/sun/star/container/XChild.hpp> #include <cppuhelper/implbase5.hxx> #include <cppuhelper/implbase1.hxx> @@ -66,8 +67,11 @@ typedef ::cppu::WeakImplHelper5 < ::com::sun::star::beans::XPropertySet > ScShapeObj_Base; typedef ::cppu::ImplHelper1 < ::com::sun::star::text::XText > ScShapeObj_TextBase; +typedef ::cppu::ImplHelper1 < ::com::sun::star::container::XChild + > ScShapeObj_ChildBase; class ScShapeObj :public ScShapeObj_Base ,public ScShapeObj_TextBase + ,public ScShapeObj_ChildBase { private: ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation > mxShapeAgg; @@ -76,7 +80,8 @@ private: ::com::sun::star::beans::XPropertyState* pShapePropertyState; ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > mxPropSetInfo; com::sun::star::uno::Sequence< sal_Int8 >* pImplementationId; - sal_Bool bIsTextShape; + bool bIsTextShape; + bool bIsNoteCaption; bool bInitializedNotifier; SdrObject* GetSdrObject() const throw(); @@ -219,6 +224,12 @@ public: virtual void SAL_CALL setString( const ::rtl::OUString& aString ) throw(::com::sun::star::uno::RuntimeException); + // XChild + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getParent() + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xParent ) + throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + // XTypeProvider virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 524919da5e39..5ac110373257 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2011 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -196,6 +196,7 @@ private: friend class ScDocument; // fuer FillInfo friend class ScDocumentIterator; friend class ScValueIterator; +friend class ScHorizontalValueIterator; friend class ScDBQueryDataIterator; friend class ScCellIterator; friend class ScQueryCellIterator; @@ -683,6 +684,7 @@ public: /// @return the index of the last changed row (flags and row height, auto pagebreak is ignored). SCROW GetLastChangedRow() const; + sal_Bool IsDataFiltered() const; sal_uInt8 GetColFlags( SCCOL nCol ) const; sal_uInt8 GetRowFlags( SCROW nRow ) const; diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx index 13a8038a4109..28cefeec8554 100644 --- a/sc/inc/token.hxx +++ b/sc/inc/token.hxx @@ -198,14 +198,14 @@ public: ScExternalSingleRefToken( const ScExternalSingleRefToken& r ); virtual ~ScExternalSingleRefToken(); - virtual sal_uInt16 GetIndex() const; + virtual sal_uInt16 GetIndex() const; virtual const String& GetString() const; virtual const ScSingleRefData& GetSingleRef() const; - virtual ScSingleRefData& GetSingleRef(); - virtual void CalcAbsIfRel( const ScAddress& ); - virtual void CalcRelFromAbs( const ScAddress& ); + virtual ScSingleRefData& GetSingleRef(); + virtual void CalcAbsIfRel( const ScAddress& ); + virtual void CalcRelFromAbs( const ScAddress& ); virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; - virtual FormulaToken* Clone() const { return new ScExternalSingleRefToken(*this); } + virtual FormulaToken* Clone() const { return new ScExternalSingleRefToken(*this); } }; @@ -220,20 +220,21 @@ private: public: ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& r ); ScExternalDoubleRefToken( const ScExternalDoubleRefToken& r ); + explicit ScExternalDoubleRefToken( const ScExternalSingleRefToken& r ); virtual ~ScExternalDoubleRefToken(); - virtual sal_uInt16 GetIndex() const; - virtual const String& GetString() const; - virtual const ScSingleRefData& GetSingleRef() const; - virtual ScSingleRefData& GetSingleRef(); - virtual const ScSingleRefData& GetSingleRef2() const; - virtual ScSingleRefData& GetSingleRef2(); - virtual const ScComplexRefData& GetDoubleRef() const; - virtual ScComplexRefData& GetDoubleRef(); - virtual void CalcAbsIfRel( const ScAddress& ); - virtual void CalcRelFromAbs( const ScAddress& ); + virtual sal_uInt16 GetIndex() const; + virtual const String& GetString() const; + virtual const ScSingleRefData& GetSingleRef() const; + virtual ScSingleRefData& GetSingleRef(); + virtual const ScSingleRefData& GetSingleRef2() const; + virtual ScSingleRefData& GetSingleRef2(); + virtual const ScComplexRefData& GetDoubleRef() const; + virtual ScComplexRefData& GetDoubleRef(); + virtual void CalcAbsIfRel( const ScAddress& ); + virtual void CalcRelFromAbs( const ScAddress& ); virtual sal_Bool operator==( const formula::FormulaToken& rToken ) const; - virtual FormulaToken* Clone() const { return new ScExternalDoubleRefToken(*this); } + virtual FormulaToken* Clone() const { return new ScExternalDoubleRefToken(*this); } }; diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index 1e42ce5fb1dc..0deaeb0ccaf1 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -2795,10 +2795,10 @@ SfxVoidItem ValidityReference SID_VALIDITY_REFERENCE Synchron; /* config: */ - AccelConfig = TRUE, - MenuConfig = TRUE, + AccelConfig = FALSE, + MenuConfig = FALSE, StatusBarConfig = FALSE, - ToolBoxConfig = TRUE, + ToolBoxConfig = FALSE, GroupId = GID_OPTIONS; ] //-->Added by PengYunQuan for Validity Cell Range Picker @@ -5390,7 +5390,7 @@ SfxUInt16Item RowHeight FID_ROW_HEIGHT //-------------------------------------------------------------------------- SfxVoidItem SbaImport SID_SBA_IMPORT -(SfxStringItem Query SID_SBA_IMPORT,SfxStringItem Target FN_PARAM_1) +(SfxUsrAnyItem Query SID_SBA_IMPORT,SfxStringItem Target FN_PARAM_1) [ /* flags: */ AutoUpdate = FALSE, diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx index e4631dde2d9a..23b9934564b9 100644 --- a/sc/source/core/data/cell2.cxx +++ b/sc/source/core/data/cell2.cxx @@ -990,6 +990,10 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode, pUndoDoc->PutCell( aUndoPos, pFCell ); } } + // #i116833# If the formula is changed, always invalidate the stream (even if the result is the same). + // If the formula is moved, the change is recognized separately. + if (bValChanged && pDocument->IsStreamValid(aPos.Tab())) + pDocument->SetStreamValid(aPos.Tab(), sal_False); bValChanged = sal_False; if ( pRangeData ) { // Replace shared formula with own formula diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 0cffd3bef163..db48b58a169a 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -244,9 +244,16 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, else bBreak = ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue(); - if (pCell->HasValueData()) - // Cell has a value. Disable line break. - bBreak = false; + SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); + sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet ); + // #i111387# #o11817313# disable automatic line breaks only for "General" number format + if ( bBreak && pCell->HasValueData() && ( nFormat % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 ) + { + // also take formula result type into account for number format + if ( pCell->GetCellType() != CELLTYPE_FORMULA || + ( static_cast<ScFormulaCell*>(pCell)->GetStandardFormat(*pFormatter, nFormat) % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 ) + bBreak = false; + } // get other attributes from pattern and conditional formatting @@ -332,8 +339,6 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, { String aValStr; Color* pColor; - SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); - sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet ); ScCellFormat::GetString( pCell, nFormat, aValStr, &pColor, *pFormatter, sal_True, rOptions.bFormula, ftCheck ); @@ -427,12 +432,17 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, ScFieldEditEngine* pEngine = pDocument->CreateFieldEditEngine(); pEngine->SetUpdateMode( sal_False ); + sal_Bool bTextWysiwyg = ( pDev->GetOutDevType() == OUTDEV_PRINTER ); + sal_uInt32 nCtrl = pEngine->GetControlWord(); + if ( bTextWysiwyg ) + nCtrl |= EE_CNTRL_FORMAT100; + else + nCtrl &= ~EE_CNTRL_FORMAT100; + pEngine->SetControlWord( nCtrl ); MapMode aOld = pDev->GetMapMode(); pDev->SetMapMode( aHMMMode ); pEngine->SetRefDevice( pDev ); - pEngine->SetForbiddenCharsTable( pDocument->GetForbiddenCharacters() ); - pEngine->SetAsianCompressionMode( pDocument->GetAsianCompression() ); - pEngine->SetKernAsianPunctuation( pDocument->GetAsianKerning() ); + pDocument->ApplyAsianEditSettings( *pEngine ); SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() ); pPattern->FillEditItemSet( pSet, pCondSet ); @@ -451,7 +461,6 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, else if (bBreak) { double fWidthFactor = nPPTX; - sal_Bool bTextWysiwyg = ( pDev->GetOutDevType() == OUTDEV_PRINTER ); if ( bTextWysiwyg ) { // #95593# if text is formatted for printer, don't use PixelToLogic, @@ -493,8 +502,6 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, else { Color* pColor; - SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); - sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet ); String aString; ScCellFormat::GetString( pCell, nFormat, aString, &pColor, *pFormatter, @@ -564,6 +571,17 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, { nValue = pDev->LogicToPixel(Size( 0, pEngine->GetTextHeight() ), aHMMMode).Height(); + + // With non-100% zoom and several lines or paragraphs, don't shrink below the result with FORMAT100 set + if ( !bTextWysiwyg && ( rZoomY.GetNumerator() != 1 || rZoomY.GetDenominator() != 1 ) && + ( pEngine->GetParagraphCount() > 1 || ( bBreak && pEngine->GetLineCount(0) > 1 ) ) ) + { + pEngine->SetControlWord( nCtrl | EE_CNTRL_FORMAT100 ); + pEngine->QuickFormatDoc( sal_True ); + long nSecondValue = pDev->LogicToPixel(Size( 0, pEngine->GetTextHeight() ), aHMMMode).Height(); + if ( nSecondValue > nValue ) + nValue = nSecondValue; + } } if ( nValue && bAddMargin ) @@ -1042,9 +1060,7 @@ void ScColumn::RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow ) pEngine = new ScFieldEditEngine( pDocument->GetEditPool() ); // EE_CNTRL_ONLINESPELLING falls schon Fehler drin sind pEngine->SetControlWord( pEngine->GetControlWord() | EE_CNTRL_ONLINESPELLING ); - pEngine->SetForbiddenCharsTable( pDocument->GetForbiddenCharacters() ); - pEngine->SetAsianCompressionMode( pDocument->GetAsianCompression() ); - pEngine->SetKernAsianPunctuation( pDocument->GetAsianKerning() ); + pDocument->ApplyAsianEditSettings( *pEngine ); } pEngine->SetText( *pData ); sal_uInt16 nParCount = pEngine->GetParagraphCount(); diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index 0e30a2750dbb..2db9bd61bcfd 100755 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -541,7 +541,8 @@ SCSIZE ScDBQueryDataIterator::SearchColEntryIndex(ScDocument& rDoc, SCTAB nTab, ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(const ScDBQueryDataIterator* pParent, ScDBQueryParamInternal* pParam, ScDocument* pDoc) : DataAccess(pParent), mpParam(pParam), - mpDoc(pDoc) + mpDoc(pDoc), + bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() ) { nCol = mpParam->mnField; nRow = mpParam->nRow1; @@ -1673,22 +1674,38 @@ ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTab( nTable ), nStartCol( nCol1 ), nEndCol( nCol2 ), + nStartRow( nRow1 ), nEndRow( nRow2 ), nCol( nCol1 ), nRow( nRow1 ), bMore( sal_True ) { - SCCOL i; - SCSIZE nIndex; pNextRows = new SCROW[ nCol2-nCol1+1 ]; pNextIndices = new SCSIZE[ nCol2-nCol1+1 ]; - for (i=nStartCol; i<=nEndCol; i++) + SetTab( nTab ); +} + +ScHorizontalCellIterator::~ScHorizontalCellIterator() +{ + delete [] pNextRows; + delete [] pNextIndices; +} + +void ScHorizontalCellIterator::SetTab( SCTAB nTabP ) +{ + nTab = nTabP; + nRow = nStartRow; + nCol = nStartCol; + bMore = sal_True; + + for (SCCOL i=nStartCol; i<=nEndCol; i++) { ScColumn* pCol = &pDoc->pTab[nTab]->aCol[i]; - pCol->Search( nRow1, nIndex ); + SCSIZE nIndex; + pCol->Search( nStartRow, nIndex ); if ( nIndex < pCol->nCount ) { pNextRows[i-nStartCol] = pCol->pItems[nIndex].nRow; @@ -1701,16 +1718,10 @@ ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB } } - if (pNextRows[0] != nRow1) + if (pNextRows[0] != nStartRow) Advance(); } -ScHorizontalCellIterator::~ScHorizontalCellIterator() -{ - delete [] pNextRows; - delete [] pNextIndices; -} - ScBaseCell* ScHorizontalCellIterator::GetNext( SCCOL& rCol, SCROW& rRow ) { if ( bMore ) @@ -1780,6 +1791,156 @@ void ScHorizontalCellIterator::Advance() bMore = sal_False; } +//------------------------------------------------------------------------ + +ScHorizontalValueIterator::ScHorizontalValueIterator( ScDocument* pDocument, + const ScRange& rRange, bool bSTotal, bool bTextZero ) : + pDoc( pDocument ), + nNumFmtIndex(0), + nEndTab( rRange.aEnd.Tab() ), + nNumFmtType( NUMBERFORMAT_UNDEFINED ), + bNumValid( false ), + bSubTotal( bSTotal ), + bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ), + bTextAsZero( bTextZero ) +{ + SCCOL nStartCol = rRange.aStart.Col(); + SCROW nStartRow = rRange.aStart.Row(); + SCTAB nStartTab = rRange.aStart.Tab(); + SCCOL nEndCol = rRange.aEnd.Col(); + SCROW nEndRow = rRange.aEnd.Row(); + PutInOrder( nStartCol, nEndCol); + PutInOrder( nStartRow, nEndRow); + PutInOrder( nStartTab, nEndTab ); + + if (!ValidCol(nStartCol)) nStartCol = MAXCOL; + if (!ValidCol(nEndCol)) nEndCol = MAXCOL; + if (!ValidRow(nStartRow)) nStartRow = MAXROW; + if (!ValidRow(nEndRow)) nEndRow = MAXROW; + if (!ValidTab(nStartTab)) nStartTab = MAXTAB; + if (!ValidTab(nEndTab)) nEndTab = MAXTAB; + + nCurCol = nStartCol; + nCurRow = nStartRow; + nCurTab = nStartTab; + + nNumFormat = 0; // will be initialized in GetNumberFormat() + pAttrArray = 0; + nAttrEndRow = 0; + + pCellIter = new ScHorizontalCellIterator( pDoc, nStartTab, nStartCol, + nStartRow, nEndCol, nEndRow ); +} + +ScHorizontalValueIterator::~ScHorizontalValueIterator() +{ + delete pCellIter; +} + +bool ScHorizontalValueIterator::GetNext( double& rValue, sal_uInt16& rErr ) +{ + bool bFound = false; + while ( !bFound ) + { + ScBaseCell* pCell = pCellIter->GetNext( nCurCol, nCurRow ); + while ( !pCell ) + { + if ( nCurTab < nEndTab ) + { + pCellIter->SetTab( ++nCurTab); + pCell = pCellIter->GetNext( nCurCol, nCurRow ); + } + else + return false; + } + if ( !bSubTotal || !pDoc->pTab[nCurTab]->RowFiltered( nCurRow ) ) + { + switch (pCell->GetCellType()) + { + case CELLTYPE_VALUE: + { + bNumValid = false; + rValue = ((ScValueCell*)pCell)->GetValue(); + rErr = 0; + if ( bCalcAsShown ) + { + ScColumn* pCol = &pDoc->pTab[nCurTab]->aCol[nCurCol]; + lcl_IterGetNumberFormat( nNumFormat, pAttrArray, + nAttrEndRow, pCol->pAttrArray, nCurRow, pDoc ); + rValue = pDoc->RoundValueAsShown( rValue, nNumFormat ); + } + bFound = true; + } + break; + case CELLTYPE_FORMULA: + { + if (!bSubTotal || !((ScFormulaCell*)pCell)->IsSubTotal()) + { + rErr = ((ScFormulaCell*)pCell)->GetErrCode(); + if ( rErr || ((ScFormulaCell*)pCell)->IsValue() ) + { + rValue = ((ScFormulaCell*)pCell)->GetValue(); + bNumValid = false; + bFound = true; + } + else if ( bTextAsZero ) + { + rValue = 0.0; + bNumValid = false; + bFound = true; + } + } + } + break; + case CELLTYPE_STRING : + case CELLTYPE_EDIT : + { + if ( bTextAsZero ) + { + rErr = 0; + rValue = 0.0; + nNumFmtType = NUMBERFORMAT_NUMBER; + nNumFmtIndex = 0; + bNumValid = true; + bFound = true; + } + } + break; + default: + ; // nothing + } + } + } + return bFound; +} + +void ScHorizontalValueIterator::GetCurNumFmtInfo( short& nType, sal_uLong& nIndex ) +{ + if (!bNumValid) + { + const ScColumn* pCol = &(pDoc->pTab[nCurTab])->aCol[nCurCol]; + nNumFmtIndex = pCol->GetNumberFormat( nCurRow ); + if ( (nNumFmtIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0 ) + { + const ScBaseCell* pCell; + SCSIZE nCurIndex; + if ( pCol->Search( nCurRow, nCurIndex ) ) + pCell = pCol->pItems[nCurIndex].pCell; + else + pCell = NULL; + if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA ) + ((const ScFormulaCell*)pCell)->GetFormatInfo( nNumFmtType, nNumFmtIndex ); + else + nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex ); + } + else + nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex ); + bNumValid = true; + } + nType = nNumFmtType; + nIndex = nNumFmtIndex; +} + //------------------------------------------------------------------------------- ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable, diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 22155543ee81..e0242ab90305 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -447,7 +447,12 @@ ScDocument::~ScDocument() delete pChangeViewSettings; // und weg damit delete pVirtualDevice_100th_mm; - delete pDPCollection; + if (pDPCollection) + { + pDPCollection->FreeAll(); + RemoveUnusedDPObjectCaches(); + delete pDPCollection; + } // delete the EditEngine before destroying the xPoolHelper delete pCacheFieldEditEngine; @@ -531,7 +536,7 @@ ScFieldEditEngine& ScDocument::GetEditEngine() pEditEngine->SetUpdateMode( sal_False ); pEditEngine->EnableUndo( sal_False ); pEditEngine->SetRefMapMode( MAP_100TH_MM ); - pEditEngine->SetForbiddenCharsTable( xForbiddenCharacters ); + ApplyAsianEditSettings( *pEditEngine ); } return *pEditEngine; } @@ -544,22 +549,15 @@ ScNoteEditEngine& ScDocument::GetNoteEngine() pNoteEngine->SetUpdateMode( sal_False ); pNoteEngine->EnableUndo( sal_False ); pNoteEngine->SetRefMapMode( MAP_100TH_MM ); - pNoteEngine->SetForbiddenCharsTable( xForbiddenCharacters ); - const SfxItemSet& rItemSet = GetDefPattern()->GetItemSet(); - SfxItemSet* pEEItemSet = new SfxItemSet( pNoteEngine->GetEmptyItemSet() ); - ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet ); - pNoteEngine->SetDefaults( pEEItemSet ); // edit engine takes ownership + ApplyAsianEditSettings( *pNoteEngine ); + const SfxItemSet& rItemSet = GetDefPattern()->GetItemSet(); + SfxItemSet* pEEItemSet = new SfxItemSet( pNoteEngine->GetEmptyItemSet() ); + ScPatternAttr::FillToEditItemSet( *pEEItemSet, rItemSet ); + pNoteEngine->SetDefaults( pEEItemSet ); // edit engine takes ownership } return *pNoteEngine; } -//UNUSED2009-05 SfxItemPool& ScDocument::GetNoteItemPool() -//UNUSED2009-05 { -//UNUSED2009-05 if ( !pNoteItemPool ) -//UNUSED2009-05 pNoteItemPool = new SfxItemPool(SdrObject::GetGlobalDrawObjectItemPool()); -//UNUSED2009-05 return *pNoteItemPool; -//UNUSED2009-05 } - void ScDocument::ResetClip( ScDocument* pSourceDoc, const ScMarkData* pMarks ) { if (bIsClip) diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index e249d7f3bf47..3f8742ee1d56 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2011 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -197,6 +197,14 @@ ScDBData* ScDocument::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nC return NULL; } +ScDBData* ScDocument::GetFilterDBAtTable(SCTAB nTab) const +{ + if (pDBCollection) + return pDBCollection->GetFilterDBAtTable(nTab); + else + return NULL; +} + ScDPCollection* ScDocument::GetDPCollection() { if (!pDPCollection) @@ -1359,6 +1367,20 @@ sal_Bool ScDocument::GetFilterEntries( SCCOL nEndCol; SCROW nEndRow; pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow ); + + //Add for i85305 + SCCOL nTmpStartCol = nCol; + SCROW nTmpStartRow = nRow; + SCCOL nTmpEndCol = nCol; + SCROW nTmpEndRow = nRow; + GetDataArea( nTab, nTmpStartCol, nTmpStartRow, nTmpEndCol, nTmpEndRow, sal_False, false); + if (nTmpEndRow > nEndRow) + { + nEndRow = nTmpEndRow; + pDBData->SetArea(nAreaTab, nStartCol,nStartRow, nEndCol,nEndRow); + } + //End of i85305 + if (pDBData->HasHeader()) ++nStartRow; @@ -2098,7 +2120,7 @@ void ScDocument::RemoveDPObjectCache( long nID ) void ScDocument::RemoveUnusedDPObjectCaches() { - for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); ) { long nID = (*iter)->GetId(); sal_uInt16 nCount = GetDPCollection()->GetCount(); @@ -2111,10 +2133,11 @@ void ScDocument::RemoveUnusedDPObjectCaches() if ( i == nCount ) { ScDPTableDataCache* pCache = *iter; - m_listDPObjectsCaches.erase( iter ); + iter = m_listDPObjectsCaches.erase( iter ); delete pCache; continue; } + ++iter; } } diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx index 385939738d81..819dbba3ecc8 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -60,6 +60,8 @@ #include <vcl/virdev.hxx> #include <vcl/msgbox.hxx> +#include <com/sun/star/i18n/TransliterationModulesExtra.hpp> + #include "inputopt.hxx" #include "global.hxx" #include "table.hxx" @@ -1489,57 +1491,6 @@ SfxBindings* ScDocument::GetViewBindings() //------------------------------------------------------------------------ -void lcl_TransliterateEditEngine( ScEditEngineDefaulter& rEngine, - utl::TransliterationWrapper& rTranslitarationWrapper, - sal_Bool bConsiderLanguage, ScDocument* pDoc ) -{ - //! should use TransliterateText method of EditEngine instead, when available! - - sal_uInt16 nLanguage = LANGUAGE_SYSTEM; - - sal_uInt16 nParCount = rEngine.GetParagraphCount(); - for (sal_uInt16 nPar=0; nPar<nParCount; nPar++) - { - SvUShorts aPortions; - rEngine.GetPortions( (sal_uInt16)nPar, aPortions ); - - for ( sal_uInt16 nPos = aPortions.Count(); nPos; ) - { - --nPos; - sal_uInt16 nEnd = aPortions.GetObject( nPos ); - sal_uInt16 nStart = nPos ? aPortions.GetObject( nPos - 1 ) : 0; - - ESelection aSel( nPar, nStart, nPar, nEnd ); - String aOldStr = rEngine.GetText( aSel ); - SfxItemSet aAttr = rEngine.GetAttribs( aSel ); - - if ( aAttr.GetItemState( EE_FEATURE_FIELD ) != SFX_ITEM_ON ) // fields are not touched - { - if ( bConsiderLanguage ) - { - sal_uInt8 nScript = pDoc->GetStringScriptType( aOldStr ); - sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? EE_CHAR_LANGUAGE_CJK : - ( ( nScript == SCRIPTTYPE_COMPLEX ) ? EE_CHAR_LANGUAGE_CTL : - EE_CHAR_LANGUAGE ); - nLanguage = ((const SvxLanguageItem&)aAttr.Get(nWhich)).GetValue(); - } - - com::sun::star::uno::Sequence<sal_Int32> aOffsets; - String aNewStr = rTranslitarationWrapper.transliterate( aOldStr, nLanguage, 0, aOldStr.Len(), &aOffsets ); - - if ( aNewStr != aOldStr ) - { - // replace string, keep attributes - - rEngine.QuickInsertText( aNewStr, aSel ); - aSel.nEndPos = aSel.nStartPos + aNewStr.Len(); - rEngine.QuickSetAttribs( aAttr, aSel ); - } - } - } - } -} - void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nType ) { DBG_ASSERT( rMultiMark.IsMultiMarked(), "TransliterateText: no selection" ); @@ -1566,28 +1517,13 @@ void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nTyp const ScBaseCell* pCell = GetCell( ScAddress( nCol, nRow, nTab ) ); CellType eType = pCell ? pCell->GetCellType() : CELLTYPE_NONE; - if ( eType == CELLTYPE_STRING ) - { - String aOldStr; - ((const ScStringCell*)pCell)->GetString(aOldStr); - xub_StrLen nOldLen = aOldStr.Len(); + // #i115128# TITLE_CASE/SENTENCE_CASE need the extra handling in EditEngine (loop over words/sentences). + // Still use TransliterationWrapper directly for text cells with other transliteration types, + // for performance reasons. - if ( bConsiderLanguage ) - { - sal_uInt8 nScript = GetStringScriptType( aOldStr ); //! cell script type? - sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE : - ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE : - ATTR_FONT_LANGUAGE ); - nLanguage = ((const SvxLanguageItem*)GetAttr( nCol, nRow, nTab, nWhich ))->GetValue(); - } - - com::sun::star::uno::Sequence<sal_Int32> aOffsets; - String aNewStr = aTranslitarationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets ); - - if ( aNewStr != aOldStr ) - PutCell( nCol, nRow, nTab, new ScStringCell( aNewStr ) ); - } - else if ( eType == CELLTYPE_EDIT ) + if ( eType == CELLTYPE_EDIT || + ( eType == CELLTYPE_STRING && ( nType == com::sun::star::i18n::TransliterationModulesExtra::SENTENCE_CASE || + nType == com::sun::star::i18n::TransliterationModulesExtra::TITLE_CASE ) ) ) { if (!pEngine) pEngine = new ScFieldEditEngine( GetEnginePool(), GetEditPool() ); @@ -1598,12 +1534,22 @@ void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nTyp pPattern->FillEditItemSet( pDefaults ); pEngine->SetDefaults( pDefaults, sal_True ); - const EditTextObject* pData = ((const ScEditCell*)pCell)->GetData(); - pEngine->SetText( *pData ); - + if ( eType == CELLTYPE_STRING ) + pEngine->SetText( static_cast<const ScStringCell*>(pCell)->GetString() ); + else + { + const EditTextObject* pData = static_cast<const ScEditCell*>(pCell)->GetData(); + pEngine->SetText( *pData ); + } pEngine->ClearModifyFlag(); - lcl_TransliterateEditEngine( *pEngine, aTranslitarationWrapper, bConsiderLanguage, this ); + sal_uInt16 nLastPar = pEngine->GetParagraphCount(); + if (nLastPar) + --nLastPar; + xub_StrLen nTxtLen = pEngine->GetTextLen(nLastPar); + ESelection aSelAll( 0, 0, nLastPar, nTxtLen ); + + pEngine->TransliterateText( aSelAll, nType ); if ( pEngine->IsModified() ) { @@ -1626,6 +1572,27 @@ void ScDocument::TransliterateText( const ScMarkData& rMultiMark, sal_Int32 nTyp } } } + else if ( eType == CELLTYPE_STRING ) + { + String aOldStr; + ((const ScStringCell*)pCell)->GetString(aOldStr); + xub_StrLen nOldLen = aOldStr.Len(); + + if ( bConsiderLanguage ) + { + sal_uInt8 nScript = GetStringScriptType( aOldStr ); //! cell script type? + sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE : + ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE : + ATTR_FONT_LANGUAGE ); + nLanguage = ((const SvxLanguageItem*)GetAttr( nCol, nRow, nTab, nWhich ))->GetValue(); + } + + com::sun::star::uno::Sequence<sal_Int32> aOffsets; + String aNewStr = aTranslitarationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets ); + + if ( aNewStr != aOldStr ) + PutCell( nCol, nRow, nTab, new ScStringCell( aNewStr ) ); + } bFound = GetNextMarkedCell( nCol, nRow, nTab, rMultiMark ); } diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx index 93ca7eefe82c..9ad38c171489 100755 --- a/sc/source/core/data/documen9.cxx +++ b/sc/source/core/data/documen9.cxx @@ -111,17 +111,21 @@ void ScDocument::TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDes SdrObject* pOldObject = aIter.Next(); while (pOldObject) { - // #116235# - SdrObject* pNewObject = pOldObject->Clone(); - // SdrObject* pNewObject = pOldObject->Clone( pNewPage, pDrawLayer ); - pNewObject->SetModel(pDrawLayer); - pNewObject->SetPage(pNewPage); + // #i112034# do not copy internal objects (detective) and note captions + if ( pOldObject->GetLayer() != SC_LAYER_INTERN && !ScDrawLayer::IsNoteCaption( pOldObject ) ) + { + // #116235# + SdrObject* pNewObject = pOldObject->Clone(); + // SdrObject* pNewObject = pOldObject->Clone( pNewPage, pDrawLayer ); + pNewObject->SetModel(pDrawLayer); + pNewObject->SetPage(pNewPage); - pNewObject->NbcMove(Size(0,0)); - pNewPage->InsertObject( pNewObject ); + pNewObject->NbcMove(Size(0,0)); + pNewPage->InsertObject( pNewObject ); - if (pDrawLayer->IsRecording()) - pDrawLayer->AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); + if (pDrawLayer->IsRecording()) + pDrawLayer->AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); + } pOldObject = aIter.Next(); } @@ -819,3 +823,10 @@ void ScDocument::SetAsianKerning(sal_Bool bNew) pDrawLayer->SetKernAsianPunctuation( (sal_Bool)nAsianKerning ); } +void ScDocument::ApplyAsianEditSettings( ScEditEngineDefaulter& rEngine ) +{ + rEngine.SetForbiddenCharsTable( xForbiddenCharacters ); + rEngine.SetAsianCompressionMode( GetAsianCompression() ); + rEngine.SetKernAsianPunctuation( GetAsianKerning() ); +} + diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 714467d8e5eb..68cbef5e8e94 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -2696,6 +2696,60 @@ void ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rSt } +sal_uInt16 ScDocument::GetStringForFormula( const ScAddress& rPos, rtl::OUString& rString ) +{ + // Used in formulas (add-in parameters etc), so it must use the same semantics as + // ScInterpreter::GetCellString: always format values as numbers. + // The return value is the error code. + + sal_uInt16 nErr = 0; + String aStr; + ScBaseCell* pCell = GetCell( rPos ); + if (pCell) + { + SvNumberFormatter* pFormatter = GetFormatTable(); + switch (pCell->GetCellType()) + { + case CELLTYPE_STRING: + static_cast<ScStringCell*>(pCell)->GetString(aStr); + break; + case CELLTYPE_EDIT: + static_cast<ScEditCell*>(pCell)->GetString(aStr); + break; + case CELLTYPE_FORMULA: + { + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); + nErr = pFCell->GetErrCode(); + if (pFCell->IsValue()) + { + double fVal = pFCell->GetValue(); + sal_uInt32 nIndex = pFormatter->GetStandardFormat( + NUMBERFORMAT_NUMBER, + ScGlobal::eLnge); + pFormatter->GetInputLineString(fVal, nIndex, aStr); + } + else + pFCell->GetString(aStr); + } + break; + case CELLTYPE_VALUE: + { + double fVal = static_cast<ScValueCell*>(pCell)->GetValue(); + sal_uInt32 nIndex = pFormatter->GetStandardFormat( + NUMBERFORMAT_NUMBER, + ScGlobal::eLnge); + pFormatter->GetInputLineString(fVal, nIndex, aStr); + } + break; + default: + ; + } + } + rString = aStr; + return nErr; +} + + void ScDocument::GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, double& rValue ) { if ( VALIDTAB(nTab) && pTab[nTab] ) diff --git a/sc/source/core/data/dpglobal.cxx b/sc/source/core/data/dpglobal.cxx index 61161f333cd3..b5527a5ab0f7 100644 --- a/sc/source/core/data/dpglobal.cxx +++ b/sc/source/core/data/dpglobal.cxx @@ -33,6 +33,7 @@ #include "precompiled_sc.hxx" #include "dpglobal.hxx" +#include "dpobject.hxx" #include "document.hxx" #include <stdio.h> diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index ad1932303da0..431b86d328a0 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -171,12 +171,12 @@ ScDPObject::ScDPObject( ScDocument* pD ) : pOutput( NULL ), bSettingsChanged( sal_False ), bAlive( sal_False ), - mnAutoFormatIndex( 65535 ), bAllowMove( sal_False ), nHeaderRows( 0 ), mbHeaderLayout(false), bRefresh( sal_False ), // Wang Xu Ming - DataPilot migration - mnCacheId( -1) // Wang Xu Ming - DataPilot migration + mnCacheId( -1 ), // Wang Xu Ming - DataPilot migration + mbCreatingTableData( false ) { } @@ -194,12 +194,12 @@ ScDPObject::ScDPObject(const ScDPObject& r) : pOutput( NULL ), bSettingsChanged( sal_False ), bAlive( sal_False ), - mnAutoFormatIndex( r.mnAutoFormatIndex ), bAllowMove( sal_False ), nHeaderRows( r.nHeaderRows ), mbHeaderLayout( r.mbHeaderLayout ), bRefresh( r.bRefresh ), // Wang Xu Ming - DataPilot migration - mnCacheId ( r.mnCacheId ) // Wang Xu Ming - DataPilot migration + mnCacheId ( r.mnCacheId ), // Wang Xu Ming - DataPilot migration + mbCreatingTableData( false ) { if (r.pSaveData) pSaveData = new ScDPSaveData(*r.pSaveData); @@ -256,16 +256,6 @@ void ScDPObject::SetSaveData(const ScDPSaveData& rData) InvalidateData(); // re-init source from SaveData } -void ScDPObject::SetAutoFormatIndex(const sal_uInt16 nIndex) -{ - mnAutoFormatIndex = nIndex; -} - -sal_uInt16 ScDPObject::GetAutoFormatIndex() const -{ - return mnAutoFormatIndex; -} - void ScDPObject::SetHeaderLayout (bool bUseGrid) { mbHeaderLayout = bUseGrid; @@ -284,7 +274,7 @@ void ScDPObject::SetOutRange(const ScRange& rRange) pOutput->SetPosition( rRange.aStart ); } -void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc) +void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate) { if ( pSheetDesc && rDesc == *pSheetDesc ) return; // nothing to do @@ -292,7 +282,7 @@ void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc) DELETEZ( pImpDesc ); DELETEZ( pServDesc ); - delete pImpDesc; + delete pSheetDesc; pSheetDesc = new ScSheetSourceDesc(rDesc); // make valid QueryParam @@ -304,6 +294,8 @@ void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc) pSheetDesc->aQueryParam.bHasHeader = sal_True; InvalidateSource(); // new source must be created + if (!bFromRefUpdate) + SetCacheId( -1 ); // #i116504# don't use the same cache ID for a different range (except reference update) } void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc) @@ -318,6 +310,7 @@ void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc) pImpDesc = new ScImportSourceDesc(rDesc); InvalidateSource(); // new source must be created + SetCacheId( -1 ); } void ScDPObject::SetServiceData(const ScDPServiceDesc& rDesc) @@ -428,8 +421,12 @@ void ScDPObject::CreateOutput() ScDPTableData* ScDPObject::GetTableData() { - if (!mpTableData) + if (!mpTableData && !mbCreatingTableData) { + // #i117239# While filling the cache, mpTableData is still null. + // Prevent nested calls from GetPivotData and similar functions. + mbCreatingTableData = true; + shared_ptr<ScDPTableData> pData; if ( pImpDesc ) { @@ -465,6 +462,8 @@ ScDPTableData* ScDPObject::GetTableData() // End Comments mpTableData = pData; // after SetCacheId + + mbCreatingTableData = false; } return mpTableData.get(); @@ -494,16 +493,19 @@ void ScDPObject::CreateObjects() DBG_ASSERT( !pServDesc, "DPSource could not be created" ); ScDPTableData* pData = GetTableData(); - ScDPSource* pSource = new ScDPSource( pData ); - xSource = pSource; - - if ( pSaveData && bRefresh ) + if ( pData ) // nested GetTableData calls may return NULL { - pSaveData->Refresh( xSource ); - bRefresh = sal_False; + ScDPSource* pSource = new ScDPSource( pData ); + xSource = pSource; + + if ( pSaveData && bRefresh ) + { + pSaveData->Refresh( xSource ); + bRefresh = sal_False; + } } } - if (pSaveData ) + if ( xSource.is() && pSaveData ) pSaveData->WriteToSource( xSource ); } else if (bSettingsChanged) @@ -642,9 +644,12 @@ void ScDPObject::BuildAllDimensionMembers() return; // #i111857# don't always create empty mpTableData for external service. - // Ideally, xSource should be used instead of mpTableData. + // #163781# Initialize all members from xSource instead. if (pServDesc) + { + pSaveData->BuildAllDimensionMembersFromSource( this ); return; + } pSaveData->BuildAllDimensionMembers(GetTableData()); } @@ -751,7 +756,7 @@ void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode, if (aNewDesc.aQueryParam.GetEntry(i).bDoQuery) aNewDesc.aQueryParam.GetEntry(i).nField += nDiffX; - SetSheetDesc( aNewDesc ); // allocates new pSheetDesc + SetSheetDesc( aNewDesc, true ); // allocates new pSheetDesc } } } @@ -779,7 +784,7 @@ void ScDPObject::WriteRefsTo( ScDPObject& r ) const { r.SetOutRange( aOutRange ); if ( pSheetDesc ) - r.SetSheetDesc( *pSheetDesc ); + r.SetSheetDesc( *pSheetDesc, true ); } void ScDPObject::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData) @@ -1055,6 +1060,11 @@ void ScDPObject::GetHeaderPositionData(const ScAddress& rPos, DataPilotTableHead sal_Bool ScDPObject::GetPivotData( ScDPGetPivotDataField& rTarget, const std::vector< ScDPGetPivotDataField >& rFilters ) { + // #i117239# Exit with an error if called from creating the cache for this object + // (don't create an empty pOutput object) + if (mbCreatingTableData) + return sal_False; + CreateOutput(); // create xSource and pOutput if not already done return pOutput->GetPivotData( rTarget, rFilters ); diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index 100db65df4b7..24df9f90b31f 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -34,6 +34,7 @@ #include "dpsave.hxx" #include "dpdimsave.hxx" +#include "dpobject.hxx" // GetMemberNames used in BuildAllDimensionMembersFromSource #include "miscuno.hxx" #include "scerrors.hxx" #include "unonames.hxx" @@ -874,6 +875,7 @@ ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName) } ScDPSaveDimension* pNew = new ScDPSaveDimension( rName, sal_False ); aDimList.Insert( pNew, LIST_APPEND ); + mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList return pNew; } @@ -900,6 +902,7 @@ ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const String& rName) } ScDPSaveDimension* pNew = new ScDPSaveDimension( rName, sal_False ); aDimList.Insert( pNew, LIST_APPEND ); + mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList return pNew; } @@ -911,6 +914,7 @@ ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension() ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), sal_True ); aDimList.Insert( pNew, LIST_APPEND ); + mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList return pNew; } @@ -935,6 +939,7 @@ ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName) ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld ); pNew->SetDupFlag( sal_True ); aDimList.Insert( pNew, LIST_APPEND ); + mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList return pNew; } @@ -958,6 +963,7 @@ ScDPSaveDimension& ScDPSaveData::DuplicateDimension( const ScDPSaveDimension& rD ScDPSaveDimension* pNew = new ScDPSaveDimension( rDim ); pNew->SetDupFlag( sal_True ); aDimList.Insert( pNew, LIST_APPEND ); + mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList return *pNew; } @@ -1275,6 +1281,63 @@ void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData) mbDimensionMembersBuilt = true; } +void ScDPSaveData::BuildAllDimensionMembersFromSource( ScDPObject* pDPObj ) +{ + // Initialize all members like BuildAllDimensionMembers, but access only the DataPilotSource, not the table data. + // This could also replace BuildAllDimensionMembers, but the performance implications still have to be checked. + // ScDPObject is used for the helper method GetMemberNames. + + if (mbDimensionMembersBuilt) + return; + + uno::Reference<sheet::XDimensionsSupplier> xSource = pDPObj->GetSource(); + uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions(); + // GetMemberNames uses the dimension index from getElementNames + uno::Sequence<OUString> aDimNames = xDimsName->getElementNames(); + + // First, build a dimension name-to-index map. + typedef hash_map<OUString, long, ::rtl::OUStringHash> NameIndexMap; + NameIndexMap aMap; + long nColCount = aDimNames.getLength(); + for (long i = 0; i < nColCount; ++i) + aMap.insert( NameIndexMap::value_type(aDimNames[i], i) ); + + NameIndexMap::const_iterator itrEnd = aMap.end(); + + sal_uInt32 n = aDimList.Count(); + for (sal_uInt32 i = 0; i < n; ++i) + { + ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i)); + const String& rDimName = pDim->GetName(); + if (!rDimName.Len()) + // empty dimension name. It must be data layout. + continue; + + NameIndexMap::const_iterator itr = aMap.find(rDimName); + if (itr == itrEnd) + // dimension name not in the data. This should never happen! + continue; + + long nDimIndex = itr->second; + uno::Sequence<OUString> aMemberNames; + pDPObj->GetMemberNames( nDimIndex, aMemberNames ); + sal_Int32 nMemberCount = aMemberNames.getLength(); + for (sal_Int32 j = 0; j < nMemberCount; ++j) + { + String aMemName = aMemberNames[j]; + if (pDim->GetExistingMemberByName(aMemName)) + // this member instance already exists. nothing to do. + continue; + + auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName)); + pNewMember->SetIsVisible(true); + pDim->AddMember(pNewMember.release()); + } + } + + mbDimensionMembersBuilt = true; +} + bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const { ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName); diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx index f0e060e8cc7d..977be2e182a9 100644 --- a/sc/source/core/data/dpsdbtab.cxx +++ b/sc/source/core/data/dpsdbtab.cxx @@ -214,7 +214,7 @@ ScDatabaseDPData::ScDatabaseDPData( ScDocument* pDoc, const ScImportSourceDesc& rImport, long nCacheId /*=-1 */ ) : ScDPTableData(pDoc, rImport.GetCacheId( pDoc, nCacheId) ), - aCacheTable( pDoc, rImport.GetCacheId( pDoc, nCacheId)) + aCacheTable( pDoc, GetCacheId() ) // base class ID is initialized with the GetCacheId call above { } diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx index 33ce84cc94c2..6c376209e035 100644 --- a/sc/source/core/data/dpshttab.cxx +++ b/sc/source/core/data/dpshttab.cxx @@ -67,7 +67,7 @@ ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc , l pSpecial(NULL), bIgnoreEmptyRows( sal_False ), bRepeatIfEmpty(sal_False), - aCacheTable( pD, rDesc.GetCacheId( pD, nCacheId)) + aCacheTable( pD, GetCacheId() ) // base class ID is initialized with the GetCacheId call above { SCSIZE nEntryCount( aQuery.GetEntryCount()); pSpecial = new sal_Bool[nEntryCount]; @@ -291,12 +291,10 @@ sal_uLong ScSheetSourceDesc::CheckValidate( ScDocument* pDoc ) const ScRange aSrcRange( aSourceRange); if ( !pDoc ) return STR_ERR_DATAPILOTSOURCE; - for(sal_uInt16 i= aSrcRange.aStart.Col();i <= aSrcRange.aEnd.Col();i++) - { - if ( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), - i, aSrcRange.aStart.Row(),i, aSrcRange.aStart.Row())) - return STR_PIVOT_FIRSTROWEMPTYERR; - } + + // #i116457# Empty column titles were allowed before 3.3, and might be useful for hidden columns with annotations. + // Be compatible with 3.2: Allow empty titles, create columns with empty names, hide them in the dialogs. + if( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), aSrcRange.aStart.Col(), aSrcRange.aStart.Row()+1, aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row() ) ) { return STR_PIVOT_ONLYONEROWERR; diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx index f2cc8d2c1e5c..4a80f742769b 100644 --- a/sc/source/core/data/dptablecache.cxx +++ b/sc/source/core/data/dptablecache.cxx @@ -32,6 +32,7 @@ #include "precompiled_sc.hxx" // INCLUDE --------------------------------------------------------------- #include "dptablecache.hxx" +#include "dptabdat.hxx" #include "document.hxx" #include "cell.hxx" #include "globstr.hrc" @@ -209,13 +210,13 @@ ScDPItemData::ScDPItemData( ScDocument* pDoc, SCROW nRow, sal_uInt16 nCol, sal_u else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) ) { double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab)); + nNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ); sal_uLong nFormat = NUMBERFORMAT_NUMBER; if ( pFormatter ) - nFormat = pFormatter->GetType( pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ) ); + nFormat = pFormatter->GetType( nNumFormat ); aString = aDocStr; fValue = fVal; mbFlag |= MK_VAL|MK_DATA; - nNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ); lcl_isDate( nFormat ) ? ( mbFlag |= MK_DATE ) : (mbFlag &= ~MK_DATE); } else if ( pDoc->HasData( nCol,nRow, nDocTab ) ) @@ -937,23 +938,28 @@ void ScDPTableDataCache::AddLabel(ScDPItemData *pData) //reset name if needed String strNewName = pData->aString; - sal_Bool bFound = sal_False; - long nIndex = 1; - do + + // #i116457# don't modify empty column titles + if ( strNewName.Len() ) { - for ( long i= mrLabelNames.size()-1; i>=0; i-- ) + sal_Bool bFound = sal_False; + long nIndex = 1; + do { - if( mrLabelNames[i]->aString == strNewName ) + for ( long i= mrLabelNames.size()-1; i>=0; i-- ) { - strNewName = pData->aString; - strNewName += String::CreateFromInt32( nIndex ); - nIndex ++ ; - bFound = sal_True; + if( mrLabelNames[i]->aString == strNewName ) + { + strNewName = pData->aString; + strNewName += String::CreateFromInt32( nIndex ); + nIndex ++ ; + bFound = sal_True; + } } + bFound = !bFound; } - bFound = !bFound; + while ( !bFound ); } - while ( !bFound ); pData->aString = strNewName; mrLabelNames.push_back( pData ); @@ -1020,10 +1026,15 @@ sal_uLong ScDPTableDataCache::GetNumberFormat( long nDim ) const { if ( nDim >= mnColumnCount ) return 0; - if ( mpTableDataValues[nDim].size()==0 ) - return 0; - else - return mpTableDataValues[nDim][0]->nNumFormat; + + // #i113411# take the number format from the first value entry + size_t nSize = mpTableDataValues[nDim].size(); + size_t nPos = 0; + while ( nPos < nSize && mpTableDataValues[nDim][nPos]->GetType() != SC_VALTYPE_VALUE ) + ++nPos; + if ( nPos < nSize ) + return mpTableDataValues[nDim][nPos]->nNumFormat; + return 0; } sal_Bool ScDPTableDataCache::IsDateDimension( long nDim ) const diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index e3b75436f72c..c3f8edbbc265 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -430,16 +430,20 @@ void ScDrawLayer::ScCopyPage( sal_uInt16 nOldPos, sal_uInt16 nNewPos, sal_Bool b SdrObject* pOldObject = aIter.Next(); while (pOldObject) { - // #116235# - SdrObject* pNewObject = pOldObject->Clone(); - //SdrObject* pNewObject = pOldObject->Clone( pNewPage, this ); - pNewObject->SetModel(this); - pNewObject->SetPage(pNewPage); - - pNewObject->NbcMove(Size(0,0)); - pNewPage->InsertObject( pNewObject ); - if (bRecording) - AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); + // #i112034# do not copy internal objects (detective) and note captions + if ( pOldObject->GetLayer() != SC_LAYER_INTERN && !IsNoteCaption( pOldObject ) ) + { + // #116235# + SdrObject* pNewObject = pOldObject->Clone(); + //SdrObject* pNewObject = pOldObject->Clone( pNewPage, this ); + pNewObject->SetModel(this); + pNewObject->SetPage(pNewPage); + + pNewObject->NbcMove(Size(0,0)); + pNewPage->InsertObject( pNewObject ); + if (bRecording) + AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); + } pOldObject = aIter.Next(); } @@ -767,7 +771,8 @@ sal_Bool ScDrawLayer::GetPrintArea( ScRange& rRange, sal_Bool bSetHor, sal_Bool bFit = sal_False; if ( !bSetVer && ( aObjRect.Bottom() < nStartY || aObjRect.Top() > nEndY ) ) bFit = sal_False; - if ( bFit ) + // #i104716# don't include hidden note objects + if ( bFit && pObject->GetLayer() != SC_LAYER_HIDDEN ) { if (bSetHor) { diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx index 0db09d4d50d9..27aed0447a7a 100644 --- a/sc/source/core/data/global.cxx +++ b/sc/source/core/data/global.cxx @@ -284,6 +284,7 @@ void ScGlobal::SetSearchItem( const SvxSearchItem& rNew ) pSearchItem = (SvxSearchItem*)rNew.Clone(); pSearchItem->SetWhich( SID_SEARCH_ITEM ); + pSearchItem->SetAppFlag( SVX_SEARCHAPP_CALC ); } void ScGlobal::ClearAutoFormat() diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 3b10e51355e8..83c5412d08c3 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2011 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -59,6 +59,7 @@ #include "sheetevents.hxx" #include "globstr.hrc" #include "segmenttree.hxx" +#include "dbcolect.hxx" #include <math.h> @@ -2487,8 +2488,22 @@ sal_uLong ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fS { if (nLastRow > nEndRow) nLastRow = nEndRow; - sal_uInt32 nThisHeight = mpRowHeights->getSumValue(nRow, nLastRow); - nHeight += static_cast<sal_uLong>(nThisHeight * fScale); + + // #i117315# can't use getSumValue, because individual values must be rounded + while (nRow <= nLastRow) + { + ScFlatUInt16RowSegments::RangeData aData; + if (!mpRowHeights->getRangeData(nRow, aData)) + return nHeight; // shouldn't happen + + SCROW nSegmentEnd = std::min( nLastRow, aData.mnRow2 ); + + // round-down a single height value, multiply resulting (pixel) values + sal_uLong nOneHeight = static_cast<sal_uLong>( aData.mnValue * fScale ); + nHeight += nOneHeight * ( nSegmentEnd + 1 - nRow ); + + nRow = nSegmentEnd + 1; + } } nRow = nLastRow + 1; } @@ -2772,6 +2787,19 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow) DecRecalcLevel(); } +sal_Bool ScTable::IsDataFiltered() const +{ + sal_Bool bAnyQuery = sal_False; + ScDBData* pDBData = pDocument->GetFilterDBAtTable(nTab); + if ( pDBData ) + { + ScQueryParam aParam; + pDBData->GetQueryParam( aParam ); + if ( aParam.GetEntry(0).bDoQuery ) + bAnyQuery = sal_True; + } + return bAnyQuery; +} void ScTable::SetColFlags( SCCOL nCol, sal_uInt8 nNewFlags ) { diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index 5c7c872f6c64..ba68fa53b13f 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2011 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -78,6 +78,7 @@ #include "rangenam.hxx" #include "docpool.hxx" #include "progress.hxx" +#include "segmenttree.hxx" #include <math.h> @@ -198,7 +199,7 @@ void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, rMinDigits = 0; rListData = NULL; rCmd = FILL_SIMPLE; - if ( nScFillModeMouseModifier & KEY_MOD1 ) + if (( nScFillModeMouseModifier & KEY_MOD1 )||IsDataFiltered()) //i89232 return ; // Ctrl-Taste: Copy SCCOL nAddX; @@ -567,11 +568,14 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uLong nIMin = nIStart; sal_uLong nIMax = nIEnd; PutInOrder(nIMin,nIMax); - if (bVertical) - DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), IDF_AUTOFILL); - else - DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, IDF_AUTOFILL); - + sal_Bool bHasFiltered = IsDataFiltered(); + if (!bHasFiltered) //modify for i89232 + { + if (bVertical) + DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), IDF_AUTOFILL); + else + DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, IDF_AUTOFILL); + } sal_uLong nProgress = rProgress.GetState(); // @@ -617,7 +621,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, pNewPattern = NULL; } - if ( bVertical && nISrcStart == nISrcEnd ) + if ( bVertical && nISrcStart == nISrcEnd && !bHasFiltered ) { // Attribute komplett am Stueck setzen if (pNewPattern || pSrcPattern != pDocument->GetDefPattern()) @@ -635,37 +639,44 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, break; // Schleife abbrechen } - if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) ) + if ( !RowFiltered(nRow) ) { - // Vorlage auch uebernehmen - //! am AttrArray mit ApplyPattern zusammenfassen ?? - if ( pStyleSheet ) - aCol[nCol].ApplyStyle( static_cast<SCROW>(nRow), *pStyleSheet ); + if ( bHasFiltered ) + DeleteArea(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), + static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), IDF_AUTOFILL); - // ApplyPattern statt SetPattern um alte MergeFlags stehenzulassen - if ( pNewPattern ) - aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pNewPattern ); - else - aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pSrcPattern ); - } + if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) ) + { + // Vorlage auch uebernehmen + //! am AttrArray mit ApplyPattern zusammenfassen ?? + if ( pStyleSheet ) + aCol[nCol].ApplyStyle( static_cast<SCROW>(nRow), *pStyleSheet ); - if (nAtSrc==nISrcEnd) - { - if ( nAtSrc != nISrcStart ) - { // mehr als eine Source-Zelle - nAtSrc = nISrcStart; + // ApplyPattern statt SetPattern um alte MergeFlags stehenzulassen + if ( pNewPattern ) + aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pNewPattern ); + else + aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pSrcPattern ); + } + + if (nAtSrc==nISrcEnd) + { + if ( nAtSrc != nISrcStart ) + { // mehr als eine Source-Zelle + nAtSrc = nISrcStart; + bGetPattern = sal_True; + } + } + else if (bPositive) + { + ++nAtSrc; + bGetPattern = sal_True; + } + else + { + --nAtSrc; bGetPattern = sal_True; } - } - else if (bPositive) - { - ++nAtSrc; - bGetPattern = sal_True; - } - else - { - --nAtSrc; - bGetPattern = sal_True; } if (rInner == nIEnd) break; @@ -733,7 +744,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, { sal_uLong nSource = nISrcStart; double nDelta; - if ( nScFillModeMouseModifier & KEY_MOD1 ) + if (( nScFillModeMouseModifier & KEY_MOD1 )||bHasFiltered) //i89232 nDelta = 0.0; else if ( bPositive ) nDelta = 1.0; @@ -750,6 +761,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScBaseCell* pSrcCell = NULL; CellType eCellType = CELLTYPE_NONE; sal_Bool bIsOrdinalSuffix = sal_False; + sal_Bool bRowFiltered = sal_False; //i89232 rInner = nIStart; while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes @@ -775,7 +787,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ((ScStringCell*)pSrcCell)->GetString( aValue ); else ((ScEditCell*)pSrcCell)->GetString( aValue ); - if ( !(nScFillModeMouseModifier & KEY_MOD1) ) + if ( !(nScFillModeMouseModifier & KEY_MOD1) && !bHasFiltered) //i89232 { nCellDigits = 0; // look at each source cell individually nHeadNoneTail = lcl_DecompValueString( @@ -794,92 +806,101 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, else eCellType = CELLTYPE_NONE; } - switch (eCellType) + + //Modify for i89232 + bRowFiltered = mpFilteredRows->getValue(nRow); + + if (!bRowFiltered) { - case CELLTYPE_VALUE: - aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScValueCell(nVal + nDelta)); - break; - case CELLTYPE_STRING: - case CELLTYPE_EDIT: - if ( nHeadNoneTail ) - { - // #i48009# with the "nStringValue+(long)nDelta" expression within the - // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3), - // so nNextValue is now calculated ahead. - sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta; + //End of i89232 - String aStr; - if ( nHeadNoneTail < 0 ) + switch (eCellType) + { + case CELLTYPE_VALUE: + aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScValueCell(nVal + nDelta)); + break; + case CELLTYPE_STRING: + case CELLTYPE_EDIT: + if ( nHeadNoneTail ) { - aCol[nCol].Insert( static_cast<SCROW>(nRow), - lcl_getSuffixCell( pDocument, - nNextValue, nCellDigits, aValue, - eCellType, bIsOrdinalSuffix)); + // #i48009# with the "nStringValue+(long)nDelta" expression within the + // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3), + // so nNextValue is now calculated ahead. + sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta; + + String aStr; + if ( nHeadNoneTail < 0 ) + { + aCol[nCol].Insert( static_cast<SCROW>(nRow), + lcl_getSuffixCell( pDocument, + nNextValue, nCellDigits, aValue, + eCellType, bIsOrdinalSuffix)); + } + else + { + aStr = aValue; + aStr += lcl_ValueString( nNextValue, nCellDigits ); + aCol[nCol].Insert( static_cast<SCROW>(nRow), + new ScStringCell( aStr)); + } } else { - aStr = aValue; - aStr += lcl_ValueString( nNextValue, nCellDigits ); - aCol[nCol].Insert( static_cast<SCROW>(nRow), - new ScStringCell( aStr)); - } - } - else - { - ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab ); - switch ( eCellType ) - { - case CELLTYPE_STRING: - case CELLTYPE_EDIT: - aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) ); - break; - default: + ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab ); + switch ( eCellType ) { - // added to avoid warnings + case CELLTYPE_STRING: + case CELLTYPE_EDIT: + aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) ); + break; + default: + { + // added to avoid warnings + } } } + break; + case CELLTYPE_FORMULA : + FillFormula( nFormulaCounter, bFirst, + (ScFormulaCell*) pSrcCell, + static_cast<SCCOL>(nCol), + static_cast<SCROW>(nRow), (rInner == nIEnd) ); + if (nFormulaCounter - nActFormCnt > nMaxFormCnt) + nMaxFormCnt = nFormulaCounter - nActFormCnt; + break; + default: + { + // added to avoid warnings } - break; - case CELLTYPE_FORMULA : - FillFormula( nFormulaCounter, bFirst, - (ScFormulaCell*) pSrcCell, - static_cast<SCCOL>(nCol), - static_cast<SCROW>(nRow), (rInner == nIEnd) ); - if (nFormulaCounter - nActFormCnt > nMaxFormCnt) - nMaxFormCnt = nFormulaCounter - nActFormCnt; - break; - default: - { - // added to avoid warnings } - } - if (nSource==nISrcEnd) - { - if ( nSource != nISrcStart ) - { // mehr als eine Source-Zelle - nSource = nISrcStart; + if (nSource==nISrcEnd) + { + if ( nSource != nISrcStart ) + { // mehr als eine Source-Zelle + nSource = nISrcStart; + bGetCell = sal_True; + } + if ( !(nScFillModeMouseModifier & KEY_MOD1) && !bHasFiltered ) //i89232 + { + if ( bPositive ) + nDelta += 1.0; + else + nDelta -= 1.0; + } + nFormulaCounter = nActFormCnt; + bFirst = sal_False; + } + else if (bPositive) + { + ++nSource; bGetCell = sal_True; } - if ( !(nScFillModeMouseModifier & KEY_MOD1) ) + else { - if ( bPositive ) - nDelta += 1.0; - else - nDelta -= 1.0; + --nSource; + bGetCell = sal_True; } - nFormulaCounter = nActFormCnt; - bFirst = sal_False; - } - else if (bPositive) - { - ++nSource; - bGetCell = sal_True; - } - else - { - --nSource; - bGetCell = sal_True; } // Progress in der inneren Schleife nur bei teuren Zellen, @@ -978,6 +999,30 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n } else if ( eFillCmd == FILL_SIMPLE ) // Auffuellen mit Muster { + //Add for i89232 + if ((eFillDir == FILL_TO_BOTTOM)||(eFillDir == FILL_TO_TOP)) + { + long nBegin = 0; + long nEnd = 0; + if (nEndY > nRow1) + { + nBegin = nRow2+1; + nEnd = nEndY; + } + else + { + nBegin = nEndY; + nEnd = nRow1 -1; + } + long nNonFiltered = CountNonFilteredRows(nBegin, nEnd); + long nFiltered = nEnd + 1 - nBegin - nNonFiltered; + if (nIndex >0) + nIndex = nIndex - nFiltered; + else + nIndex = nIndex + nFiltered; + } + //End of i89232 + long nPosIndex = nIndex; while ( nPosIndex < 0 ) nPosIndex += nSrcCount; @@ -1008,7 +1053,7 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n ((ScStringCell*)pCell)->GetString( aValue ); else ((ScEditCell*)pCell)->GetString( aValue ); - if ( !(nScFillModeMouseModifier & KEY_MOD1) ) + if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered() ) //i89232 { sal_Int32 nVal; sal_uInt16 nCellDigits = 0; // look at each source cell individually @@ -1029,7 +1074,7 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n { // dabei kann's keinen Ueberlauf geben... double nVal = ((ScValueCell*)pCell)->GetValue(); - if ( !(nScFillModeMouseModifier & KEY_MOD1) ) + if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered() ) //i89232 nVal += (double) nDelta; Color* pColor; diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx index 0548e3ce0abd..a8189b8bb260 100644 --- a/sc/source/core/data/table5.cxx +++ b/sc/source/core/data/table5.cxx @@ -308,7 +308,7 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) if (nEndRow+2 <= MAXROW) RemoveRowPageBreaks(nEndRow+2, MAXROW); } - mbPageBreaksValid = true; + mbPageBreaksValid = !pUserArea; // #i116881# the valid flag can only apply to the "no user area" case } void ScTable::RemoveManualBreaks() diff --git a/sc/source/core/inc/doubleref.hxx b/sc/source/core/inc/doubleref.hxx index 10221d942c9c..52f437e327f5 100644 --- a/sc/source/core/inc/doubleref.hxx +++ b/sc/source/core/inc/doubleref.hxx @@ -140,9 +140,6 @@ public: virtual bool isRangeEqual(const ScRange& rRange) const; private: - sal_uInt16 getCellString(::rtl::OUString& rStr, ScBaseCell* pCell) const; - -private: ScRange maRange; }; diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 926c44c06317..0adef9f88348 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -411,6 +411,10 @@ void ScArcSinHyp(); void ScArcCosHyp(); void ScArcTanHyp(); void ScArcCotHyp(); +void ScCosecant(); +void ScSecant(); +void ScCosecantHyp(); +void ScSecantHyp(); void ScExp(); void ScLn(); void ScLog10(); @@ -639,7 +643,6 @@ void ScLCM(); void ScMatValue(); void MEMat(ScMatrix* mM, SCSIZE n); -void MFastMult(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR, SCSIZE n, SCSIZE m, SCSIZE l); void ScMatDet(); void ScMatInv(); void ScMatMult(); @@ -652,13 +655,6 @@ void ScSumX2MY2(); void ScSumX2DY2(); void ScSumXMY2(); void ScGrowth(); -// multiple Regression: Varianzen der Koeffizienten -sal_Bool RGetVariances( ScMatrix* pV, ScMatrix* pX, SCSIZE nC, SCSIZE nR, - sal_Bool bSwapColRow, sal_Bool bZeroConstant ); -void Calculate(ScMatrixRef& pResMat,ScMatrixRef& pE,ScMatrixRef& pQ,ScMatrixRef& pV,ScMatrixRef& pMatX,sal_Bool bConstant,SCSIZE N,SCSIZE M,sal_uInt8 nCase); -ScMatrixRef Calculate2(const sal_Bool bConstant,const SCSIZE M ,const SCSIZE N,ScMatrixRef& pMatX,ScMatrixRef& pMatY,sal_uInt8 nCase); -bool Calculate3(const SCSIZE M ,ScMatrixRef& pQ); -bool Calculate4(sal_Bool _bExp,ScMatrixRef& pResMat,ScMatrixRef& pQ,sal_Bool bConstant,SCSIZE N,SCSIZE M); bool CalculateSkew(double& fSum,double& fCount,double& vSum,std::vector<double>& values); void CalculateSlopeIntercept(sal_Bool bSlope); void CalculateSmallLarge(sal_Bool bSmall); @@ -670,12 +666,11 @@ bool CalculateTest( sal_Bool _bTemplin void CalculateLookup(sal_Bool HLookup); bool FillEntry(ScQueryEntry& rEntry); void CalculateAddSub(sal_Bool _bSub); -void CalculateTrendGrowth(sal_Bool _bGrowth); -void CalulateRGPRKP(sal_Bool _bRKP); +void CalculateTrendGrowth(bool _bGrowth); +void CalulateRGPRKP(bool _bRKP); void CalculateSumX2MY2SumX2DY2(sal_Bool _bSumX2DY2); void CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR); -bool CheckMatrix(sal_Bool _bLOG,sal_Bool _bTrendGrowth,sal_uInt8& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY); - +bool CheckMatrix(bool _bLOG,sal_uInt8& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY); void ScRGP(); void ScRKP(); void ScForecast(); @@ -701,6 +696,7 @@ double GetGamma(double x); double GetLogGamma(double x); double GetBeta(double fAlpha, double fBeta); double GetLogBeta(double fAlpha, double fBeta); +double GetBinomDistPMF(double x, double n, double p); //probability mass function void ScLogGamma(); void ScGamma(); void ScPhi(); diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx index 26a194b731ef..e24a4ff4158e 100644 --- a/sc/source/core/tool/address.cxx +++ b/sc/source/core/tool/address.cxx @@ -1648,8 +1648,8 @@ void ScAddress::Format( String& r, sal_uInt16 nFlags, ScDocument* pDoc, // External Reference, same as in ScCompiler::MakeTabStr() if( aTabName.GetChar(0) == '\'' ) { // "'Doc'#Tab" - xub_StrLen nPos = ScGlobal::FindUnquoted( aTabName, SC_COMPILER_FILE_TAB_SEP); - if (nPos != STRING_NOTFOUND && nPos > 0 && aTabName.GetChar(nPos-1) == '\'') + xub_StrLen nPos = ScCompiler::GetDocTabPos( aTabName); + if (nPos != STRING_NOTFOUND) { aDocName = aTabName.Copy( 0, nPos + 1 ); aTabName.Erase( 0, nPos + 1 ); @@ -1731,8 +1731,8 @@ lcl_Split_DocTab( const ScDocument* pDoc, SCTAB nTab, // External reference, same as in ScCompiler::MakeTabStr() if ( rTabName.GetChar(0) == '\'' ) { // "'Doc'#Tab" - xub_StrLen nPos = ScGlobal::FindUnquoted( rTabName, SC_COMPILER_FILE_TAB_SEP); - if (nPos != STRING_NOTFOUND && nPos > 0 && rTabName.GetChar(nPos-1) == '\'') + xub_StrLen nPos = ScCompiler::GetDocTabPos( rTabName); + if (nPos != STRING_NOTFOUND) { rDocName = rTabName.Copy( 0, nPos + 1 ); rTabName.Erase( 0, nPos + 1 ); diff --git a/sc/source/core/tool/charthelper.cxx b/sc/source/core/tool/charthelper.cxx index a2db16dff690..64b2a7776bb5 100644 --- a/sc/source/core/tool/charthelper.cxx +++ b/sc/source/core/tool/charthelper.cxx @@ -309,6 +309,7 @@ void ScChartHelper::AddRangesIfProtectedChart( ScRangeListVector& rRangesVector, if ( xEmbeddedObj.is() ) { bool bDisableDataTableDialog = false; + sal_Int32 nOldState = xEmbeddedObj->getCurrentState(); svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj ); uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY ); if ( xProps.is() && @@ -333,6 +334,10 @@ void ScChartHelper::AddRangesIfProtectedChart( ScRangeListVector& rRangesVector, } } } + if ( xEmbeddedObj->getCurrentState() != nOldState ) + { + xEmbeddedObj->changeState( nOldState ); + } } } } diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 3dd25801532f..31964eff34be 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -855,18 +855,14 @@ struct ConventionOOO_A1 : public Convention_A1 aString = ScGlobal::GetRscString(STR_NO_REF_TABLE); else { - if ( aString.GetChar(0) == '\'' ) - { // "'Doc'#Tab" - xub_StrLen nPos = ScGlobal::FindUnquoted( aString, SC_COMPILER_FILE_TAB_SEP); - if (nPos != STRING_NOTFOUND && nPos > 0 && aString.GetChar(nPos-1) == '\'') - { - aDoc = aString.Copy( 0, nPos + 1 ); - aString.Erase( 0, nPos + 1 ); - aDoc = INetURLObject::decode( aDoc, INET_HEX_ESCAPE, + // "'Doc'#Tab" + xub_StrLen nPos = ScCompiler::GetDocTabPos( aString); + if (nPos != STRING_NOTFOUND) + { + aDoc = aString.Copy( 0, nPos + 1 ); + aString.Erase( 0, nPos + 1 ); + aDoc = INetURLObject::decode( aDoc, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS ); - } - else - aDoc.Erase(); } else aDoc.Erase(); @@ -1203,18 +1199,15 @@ struct ConventionXL } // Cheesy hack to unparse the OOO style "'Doc'#Tab" - if ( rTabName.GetChar(0) == '\'' ) + xub_StrLen nPos = ScCompiler::GetDocTabPos( rTabName); + if (nPos != STRING_NOTFOUND) { - xub_StrLen nPos = ScGlobal::FindUnquoted( rTabName, SC_COMPILER_FILE_TAB_SEP); - if (nPos != STRING_NOTFOUND && nPos > 0 && rTabName.GetChar(nPos-1) == '\'') - { - rDocName = rTabName.Copy( 0, nPos ); - // TODO : More research into how XL escapes the doc path - rDocName = INetURLObject::decode( rDocName, INET_HEX_ESCAPE, + rDocName = rTabName.Copy( 0, nPos ); + // TODO : More research into how XL escapes the doc path + rDocName = INetURLObject::decode( rDocName, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS ); - rTabName.Erase( 0, nPos + 1 ); - bHasDoc = true; - } + rTabName.Erase( 0, nPos + 1 ); + bHasDoc = true; } // XL uses the same sheet name quoting conventions in both modes @@ -1872,6 +1865,18 @@ void ScCompiler::CheckTabQuotes( String& rString, } } + +xub_StrLen ScCompiler::GetDocTabPos( const String& rString ) +{ + if (rString.GetChar(0) != '\'') + return STRING_NOTFOUND; + xub_StrLen nPos = ScGlobal::FindUnquoted( rString, SC_COMPILER_FILE_TAB_SEP); + // it must be 'Doc'# + if (nPos != STRING_NOTFOUND && rString.GetChar(nPos-1) != '\'') + nPos = STRING_NOTFOUND; + return nPos; +} + //--------------------------------------------------------------------------- void ScCompiler::SetRefConvention( FormulaGrammar::AddressConvention eConv ) diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx index 800716bef3b6..baf2c3de8c2a 100644 --- a/sc/source/core/tool/dbcolect.cxx +++ b/sc/source/core/tool/dbcolect.cxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2011 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -753,6 +753,27 @@ ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCO return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden } +ScDBData* ScDBCollection::GetFilterDBAtTable(SCTAB nTab) const +{ + ScDBData* pDataEmpty = NULL; + if (pItems) + { + for (sal_uInt16 i = 0; i < nCount; i++) + { + ScDBData* pDBTemp = (ScDBData*)pItems[i]; + if ( pDBTemp->nTable == nTab ) + { + sal_Bool bFilter = pDBTemp->HasAutoFilter() || pDBTemp->HasQueryParam(); + + if ( bFilter ) + return pDBTemp; + } + } + } + + return pDataEmpty; +} + sal_Bool ScDBCollection::SearchName( const String& rName, sal_uInt16& rIndex ) const { ScDBData aDataObj( rName, 0,0,0,0,0 ); diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx index 7af5a17125ee..b0908218e8ce 100644 --- a/sc/source/core/tool/doubleref.cxx +++ b/sc/source/core/tool/doubleref.cxx @@ -334,6 +334,7 @@ OUString ScDBInternalRange::getString(SCCOL nCol, SCROW nRow) const const ScAddress& s = maRange.aStart; // #i109200# this is used in formula calculation, use GetInputString, not GetString // (consistent with ScDBInternalRange::getCellString) + // GetStringForFormula is not used here, to allow querying for date values. getDoc()->GetInputString(s.Col() + nCol, s.Row() + nRow, maRange.aStart.Tab(), aStr); return aStr; } @@ -358,54 +359,6 @@ SCCOL ScDBInternalRange::findFieldColumn(SCCOL nIndex) const return Min(nDBCol2, static_cast<SCCOL>(nDBCol1 + nIndex - 1)); } -sal_uInt16 ScDBInternalRange::getCellString(OUString& rStr, ScBaseCell* pCell) const -{ - sal_uInt16 nErr = 0; - String aStr; - if (pCell) - { - SvNumberFormatter* pFormatter = getDoc()->GetFormatTable(); - switch (pCell->GetCellType()) - { - case CELLTYPE_STRING: - ((ScStringCell*) pCell)->GetString(aStr); - break; - case CELLTYPE_EDIT: - ((ScEditCell*) pCell)->GetString(aStr); - break; - case CELLTYPE_FORMULA: - { - ScFormulaCell* pFCell = (ScFormulaCell*) pCell; - nErr = pFCell->GetErrCode(); - if (pFCell->IsValue()) - { - double fVal = pFCell->GetValue(); - sal_uLong nIndex = pFormatter->GetStandardFormat( - NUMBERFORMAT_NUMBER, - ScGlobal::eLnge); - pFormatter->GetInputLineString(fVal, nIndex, aStr); - } - else - pFCell->GetString(aStr); - } - break; - case CELLTYPE_VALUE: - { - double fVal = ((ScValueCell*) pCell)->GetValue(); - sal_uLong nIndex = pFormatter->GetStandardFormat( - NUMBERFORMAT_NUMBER, - ScGlobal::eLnge); - pFormatter->GetInputLineString(fVal, nIndex, aStr); - } - break; - default: - ; - } - } - rStr = aStr; - return nErr; -} - SCCOL ScDBInternalRange::findFieldColumn(const OUString& rStr, sal_uInt16* pErr) const { const ScAddress& s = maRange.aStart; @@ -426,8 +379,7 @@ SCCOL ScDBInternalRange::findFieldColumn(const OUString& rStr, sal_uInt16* pErr) ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 ); while (!bFound && (aLook.Col() <= nDBCol2)) { - ScBaseCell* pCell = getDoc()->GetCell( aLook ); - sal_uInt16 nErr = getCellString( aCellStr, pCell ); + sal_uInt16 nErr = getDoc()->GetStringForFormula( aLook, aCellStr ); if (pErr) *pErr = nErr; lcl_toUpper(aCellStr); diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 23c13331db26..c507c3970bb1 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -653,6 +653,7 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOp if ( !rComp.bEmpty[1] && rComp.bVal[1] && !::rtl::math::isFinite( rComp.nVal[1])) return rComp.nVal[1]; + size_t nStringQuery = 0; // 0:=no, 1:=0, 2:=1 double fRes = 0; if ( rComp.bEmpty[ 0 ] ) { @@ -709,16 +710,22 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOp } } else - fRes = -1; // number is less than string + { + fRes = -1; // number is less than string + nStringQuery = 2; // 1+1 + } } else if( rComp.bVal[ 1 ] ) - fRes = 1; // number is less than string + { + fRes = 1; // string is greater than number + nStringQuery = 1; // 0+1 + } else { // Both strings. if (pOptions) { - // All similar to Sctable::ValidQuery(), *rComp.pVal[1] actually + // All similar to ScTable::ValidQuery(), *rComp.pVal[1] actually // is/must be identical to *rEntry.pStr, which is essential for // regex to work through GetSearchTextPtr(). ScQueryEntry& rEntry = pOptions->aQueryEntry; @@ -768,6 +775,20 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOp fRes = (double) ScGlobal::GetCaseCollator()->compareString( *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] ); } + if (nStringQuery && pOptions) + { + const ScQueryEntry& rEntry = pOptions->aQueryEntry; + if (!rEntry.bQueryByString && rEntry.pStr->Len() && + (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)) + { + // As in ScTable::ValidQuery() match a numeric string for a + // number query that originated from a string, e.g. in SUMIF + // and COUNTIF. Transliteration is not needed here. + bool bEqual = rComp.pVal[nStringQuery-1]->Equals( *rEntry.pStr); + // match => fRes=0, else fRes=1 + fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual; + } + } return fRes; } @@ -1579,6 +1600,30 @@ void ScInterpreter::ScArcCotHyp() PushDouble(0.5 * log((nVal + 1.0) / (nVal - 1.0))); } +void ScInterpreter::ScCosecant() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "regina", "ScInterpreter::ScCosecant" ); + PushDouble(1.0 / ::rtl::math::sin(GetDouble())); +} + +void ScInterpreter::ScSecant() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "regina", "ScInterpreter::ScSecant" ); + PushDouble(1.0 / ::rtl::math::cos(GetDouble())); +} + +void ScInterpreter::ScCosecantHyp() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "regina", "ScInterpreter::ScCosecantHyp" ); + PushDouble(1.0 / sinh(GetDouble())); +} + +void ScInterpreter::ScSecantHyp() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "regina", "ScInterpreter::ScSecantHyp" ); + PushDouble(1.0 / cosh(GetDouble())); +} + void ScInterpreter::ScExp() { @@ -6199,7 +6244,7 @@ void ScInterpreter::ScDBVarP() } -ScTokenArray* lcl_CreateExternalRefTokenArray( const ScAddress& rPos, ScDocument* pDoc, +FormulaSubroutineToken* lcl_CreateExternalRefSubroutine( const ScAddress& rPos, ScDocument* pDoc, const ScAddress::ExternalInfo& rExtInfo, const ScRefAddress& rRefAd1, const ScRefAddress* pRefAd2 ) { @@ -6241,7 +6286,7 @@ ScTokenArray* lcl_CreateExternalRefTokenArray( const ScAddress& rPos, ScDocument rExtInfo.maTabName, nSheets); ScCompiler aComp( pDoc, rPos, *pTokenArray); aComp.CompileTokenArray(); - return pTokenArray; + return new FormulaSubroutineToken( pTokenArray); } @@ -6270,15 +6315,10 @@ void ScInterpreter::ScIndirect() { if (aExtInfo.mbExternal) { - /* TODO: future versions should implement a proper subroutine - * token. This procedure here is a minimally invasive fix for - * #i101645# in OOo3.1.1 */ - // Push a subroutine on the instruction code stack that - // resolves the external reference as the next instruction. - aCode.Push( lcl_CreateExternalRefTokenArray( aPos, pDok, + // Push a subroutine that resolves the external reference as + // the next instruction. + PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok, aExtInfo, aRefAd, &aRefAd2)); - // Signal subroutine call to interpreter. - PushTempToken( new FormulaUnknownToken( ocCall)); } else PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(), @@ -6290,15 +6330,10 @@ void ScInterpreter::ScIndirect() { if (aExtInfo.mbExternal) { - /* TODO: future versions should implement a proper subroutine - * token. This procedure here is a minimally invasive fix for - * #i101645# in OOo3.1.1 */ - // Push a subroutine on the instruction code stack that - // resolves the external reference as the next instruction. - aCode.Push( lcl_CreateExternalRefTokenArray( aPos, pDok, + // Push a subroutine that resolves the external reference as + // the next instruction. + PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok, aExtInfo, aRefAd, NULL)); - // Signal subroutine call to interpreter. - PushTempToken( new FormulaUnknownToken( ocCall)); } else PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() ); @@ -6417,9 +6452,27 @@ void ScInterpreter::ScAddressFunc() const ScAddress aAdr( nCol, nRow, 0); aAdr.Format( aRefStr, nFlags, pDok, aDetails ); - if( nParamCount >= 5 ) + if( nParamCount >= 5 && sTabStr.Len() ) { - ScCompiler::CheckTabQuotes( sTabStr, eConv); + String aDoc; + if (eConv == FormulaGrammar::CONV_OOO) + { + // Isolate Tab from 'Doc'#Tab + xub_StrLen nPos = ScCompiler::GetDocTabPos( sTabStr); + if (nPos != STRING_NOTFOUND) + { + if (sTabStr.GetChar(nPos+1) == '$') + ++nPos; // also split 'Doc'#$Tab + aDoc = sTabStr.Copy( 0, nPos+1); + sTabStr.Erase( 0, nPos+1); + } + } + /* TODO: yet unsupported external reference in CONV_XL_R1C1 syntax may + * need some extra handling to isolate Tab from Doc. */ + if (sTabStr.GetChar(0) != '\'' || sTabStr.GetChar(sTabStr.Len()-1) != '\'') + ScCompiler::CheckTabQuotes( sTabStr, eConv); + if (aDoc.Len()) + sTabStr.Insert( aDoc, 0); sTabStr += static_cast<sal_Unicode>(eConv == FormulaGrammar::CONV_XL_R1C1 ? '!' : '.'); sTabStr += aRefStr; PushString( sTabStr ); @@ -6429,6 +6482,24 @@ void ScInterpreter::ScAddressFunc() } +FormulaSubroutineToken* lcl_CreateExternalRefSubroutine( const ScAddress& rPos, + ScDocument* pDoc, const FormulaTokenRef& xExtRef ) +{ + // The exact usage (which cell range) of the external table can't be + // detected during the store-to-file cycle, mark it as permanently + // referenced so it gets stored even if not directly referenced anywhere. + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + pRefMgr->setCacheTableReferencedPermanently( + static_cast<const ScToken*>(xExtRef.get())->GetIndex(), + static_cast<const ScToken*>(xExtRef.get())->GetString(), 1); + ScTokenArray* pTokenArray = new ScTokenArray; + pTokenArray->AddToken( *xExtRef); + ScCompiler aComp( pDoc, rPos, *pTokenArray); + aComp.CompileTokenArray(); + return new FormulaSubroutineToken( pTokenArray); +} + + void ScInterpreter::ScOffset() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOffset" ); @@ -6453,54 +6524,129 @@ void ScInterpreter::ScOffset() PushIllegalArgument(); return; } - if (GetStackType() == svSingleRef) - { - PopSingleRef(nCol1, nRow1, nTab1); - if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0)) - { - nCol1 = (SCCOL)((long) nCol1 + nColPlus); - nRow1 = (SCROW)((long) nRow1 + nRowPlus); - if (!ValidCol(nCol1) || !ValidRow(nRow1)) - PushIllegalArgument(); - else - PushSingleRef(nCol1, nRow1, nTab1); - } - else - { - if (nColNew < 0) - nColNew = 1; - if (nRowNew < 0) - nRowNew = 1; - nCol1 = (SCCOL)((long)nCol1+nColPlus); // ! nCol1 wird veraendert! - nRow1 = (SCROW)((long)nRow1+nRowPlus); - nCol2 = (SCCOL)((long)nCol1+nColNew-1); - nRow2 = (SCROW)((long)nRow1+nRowNew-1); - if (!ValidCol(nCol1) || !ValidRow(nRow1) || - !ValidCol(nCol2) || !ValidRow(nRow2)) - PushIllegalArgument(); - else - PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); - } - } - else if (GetStackType() == svDoubleRef) + FormulaTokenRef xExtRef; + switch (GetStackType()) { - PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); - if (nColNew < 0) - nColNew = nCol2 - nCol1 + 1; - if (nRowNew < 0) - nRowNew = nRow2 - nRow1 + 1; - nCol1 = (SCCOL)((long)nCol1+nColPlus); - nRow1 = (SCROW)((long)nRow1+nRowPlus); - nCol2 = (SCCOL)((long)nCol1+nColNew-1); - nRow2 = (SCROW)((long)nRow1+nRowNew-1); - if (!ValidCol(nCol1) || !ValidRow(nRow1) || - !ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2) - PushIllegalArgument(); - else - PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); + case svExternalSingleRef: + xExtRef = PopToken()->Clone(); + // fallthru + case svSingleRef: + { + if (xExtRef) + { + ScSingleRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetSingleRef(); + rData.CalcAbsIfRel( aPos); + nCol1 = rData.nCol; + nRow1 = rData.nRow; + nTab1 = rData.nTab; + } + else + PopSingleRef( nCol1, nRow1, nTab1); + if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0)) + { + nCol1 = (SCCOL)((long) nCol1 + nColPlus); + nRow1 = (SCROW)((long) nRow1 + nRowPlus); + if (!ValidCol(nCol1) || !ValidRow(nRow1)) + PushIllegalArgument(); + else if (xExtRef) + { + ScSingleRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetSingleRef(); + rData.nCol = nCol1; + rData.nRow = nRow1; + rData.nTab = nTab1; + rData.CalcRelFromAbs( aPos); + // Push a subroutine that resolves the external + // reference as the next instruction. + PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok, xExtRef)); + } + else + PushSingleRef(nCol1, nRow1, nTab1); + } + else + { + if (nColNew < 0) + nColNew = 1; + if (nRowNew < 0) + nRowNew = 1; + nCol1 = (SCCOL)((long)nCol1+nColPlus); // ! nCol1 is modified + nRow1 = (SCROW)((long)nRow1+nRowPlus); + nCol2 = (SCCOL)((long)nCol1+nColNew-1); + nRow2 = (SCROW)((long)nRow1+nRowNew-1); + if (!ValidCol(nCol1) || !ValidRow(nRow1) || + !ValidCol(nCol2) || !ValidRow(nRow2)) + PushIllegalArgument(); + else if (xExtRef) + { + // Convert SingleRef to DoubleRef. + xExtRef = new ScExternalDoubleRefToken( + *static_cast<const ScExternalSingleRefToken*>(xExtRef.get())); + ScComplexRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetDoubleRef(); + rData.Ref1.nCol = nCol1; + rData.Ref1.nRow = nRow1; + rData.Ref1.nTab = nTab1; + rData.Ref2.nCol = nCol2; + rData.Ref2.nRow = nRow2; + rData.Ref2.nTab = nTab1; + rData.CalcRelFromAbs( aPos); + // Push a subroutine that resolves the external + // reference as the next instruction. + PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok, xExtRef)); + } + else + PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); + } + } + break; + case svExternalDoubleRef: + xExtRef = PopToken()->Clone(); + // fallthru + case svDoubleRef: + { + if (xExtRef) + { + ScComplexRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetDoubleRef(); + rData.CalcAbsIfRel( aPos); + nCol1 = rData.Ref1.nCol; + nRow1 = rData.Ref1.nRow; + nTab1 = rData.Ref1.nTab; + nCol2 = rData.Ref2.nCol; + nRow2 = rData.Ref2.nRow; + nTab2 = rData.Ref2.nTab; + } + else + PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (nColNew < 0) + nColNew = nCol2 - nCol1 + 1; + if (nRowNew < 0) + nRowNew = nRow2 - nRow1 + 1; + nCol1 = (SCCOL)((long)nCol1+nColPlus); + nRow1 = (SCROW)((long)nRow1+nRowPlus); + nCol2 = (SCCOL)((long)nCol1+nColNew-1); + nRow2 = (SCROW)((long)nRow1+nRowNew-1); + if (!ValidCol(nCol1) || !ValidRow(nRow1) || + !ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2) + PushIllegalArgument(); + else if (xExtRef) + { + ScComplexRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetDoubleRef(); + rData.Ref1.nCol = nCol1; + rData.Ref1.nRow = nRow1; + rData.Ref1.nTab = nTab1; + rData.Ref2.nCol = nCol2; + rData.Ref2.nRow = nRow2; + rData.Ref2.nTab = nTab1; + rData.CalcRelFromAbs( aPos); + // Push a subroutine that resolves the external + // reference as the next instruction. + PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok, xExtRef)); + } + else + PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1); + } + break; + default: + PushIllegalParameter(); } - else - PushIllegalParameter(); } } diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index c13cb5c924c4..d439d63b035f 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -297,7 +297,11 @@ void ScInterpreter::ScGetTime() double nSec = GetDouble(); double nMin = GetDouble(); double nHour = GetDouble(); - PushDouble( ( (nHour * 3600) + (nMin * 60) + nSec ) / D_TIMEFACTOR ); + double fTime = fmod( (nHour * 3600) + (nMin * 60) + nSec, D_TIMEFACTOR) / D_TIMEFACTOR; + if (fTime < 0) + PushIllegalArgument(); + else + PushDouble( fTime); } } @@ -650,8 +654,15 @@ void ScInterpreter::ScNPV() break; case svSingleRef : { - nVal += (GetDouble() / pow(1.0 + nZins, (double)nCount)); - nCount++; + ScAddress aAdr; + PopSingleRef( aAdr ); + ScBaseCell* pCell = GetCell( aAdr ); + if (!HasCellEmptyData(pCell) && HasCellValueData(pCell)) + { + double nCellVal = GetCellValue( aAdr, pCell ); + nVal += (nCellVal / pow(1.0 + nZins, (double)nCount)); + nCount++; + } } break; case svDoubleRef : @@ -660,18 +671,14 @@ void ScInterpreter::ScNPV() sal_uInt16 nErr = 0; double nCellVal; PopDoubleRef( aRange, nParamCount, nRefInList); - ScValueIterator aValIter(pDok, aRange, glSubTotal); - if (aValIter.GetFirst(nCellVal, nErr)) + ScHorizontalValueIterator aValIter( pDok, aRange, glSubTotal); + while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) { nVal += (nCellVal / pow(1.0 + nZins, (double)nCount)); nCount++; - while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) - { - nVal += (nCellVal / pow(1.0 + nZins, (double)nCount)); - nCount++; - } - SetError(nErr); } + if ( nErr != 0 ) + SetError(nErr); } break; default : SetError(errIllegalParameter); break; @@ -1122,24 +1129,23 @@ void ScInterpreter::ScLIA() } } -double ScInterpreter::ScGetRmz(double fZins, double fZzr, double fBw, - double fZw, double fF) +double ScInterpreter::ScGetRmz(double fRate, double fNper, double fPv, + double fFv, double fPaytype) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGetRmz" ); - double fRmz; - if (fZins == 0.0) - fRmz = (fBw + fZw) / fZzr; + double fPayment; + if (fRate == 0.0) + fPayment = (fPv + fFv) / fNper; else { - double fTerm = pow(1.0 + fZins, fZzr); - if (fF > 0.0) - fRmz = (fZw * fZins / (fTerm - 1.0) - + fBw * fZins / (1.0 - 1.0 / fTerm)) / (1.0+fZins); - else - fRmz = fZw * fZins / (fTerm - 1.0) - + fBw * fZins / (1.0 - 1.0 / fTerm); + if (fPaytype > 0.0) // payment in advance + fPayment = (fFv + fPv * exp( fNper * ::rtl::math::log1p(fRate) ) ) * fRate / + (::rtl::math::expm1( (fNper + 1) * ::rtl::math::log1p(fRate) ) - fRate); + else // payment in arrear + fPayment = (fFv + fPv * exp(fNper * ::rtl::math::log1p(fRate) ) ) * fRate / + ::rtl::math::expm1( fNper * ::rtl::math::log1p(fRate) ); } - return -fRmz; + return -fPayment; } void ScInterpreter::ScRMZ() diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx index dfcce4c06c3f..ef1a18b65def 100644 --- a/sc/source/core/tool/interpr3.cxx +++ b/sc/source/core/tool/interpr3.cxx @@ -949,17 +949,18 @@ double ScInterpreter::GetBetaDistPDF(double fX, double fA, double fB) const double fLogDblMin = log( ::std::numeric_limits<double>::min()); double fLogY = (fX < 0.1) ? ::rtl::math::log1p(-fX) : log(0.5-fX+0.5); double fLogX = log(fX); - double fAm1 = fA-1.0; - double fBm1 = fB-1.0; + double fAm1LogX = (fA-1.0) * fLogX; + double fBm1LogY = (fB-1.0) * fLogY; double fLogBeta = GetLogBeta(fA,fB); // check whether parts over- or underflow - if ( fAm1 * fLogX < fLogDblMax && fAm1 * fLogX > fLogDblMin - && fBm1 * fLogY < fLogDblMax && fBm1* fLogY > fLogDblMin - && fLogBeta < fLogDblMax && fLogBeta > fLogDblMin ) + if ( fAm1LogX < fLogDblMax && fAm1LogX > fLogDblMin + && fBm1LogY < fLogDblMax && fBm1LogY > fLogDblMin + && fLogBeta < fLogDblMax && fLogBeta > fLogDblMin + && fAm1LogX + fBm1LogY < fLogDblMax && fAm1LogX + fBm1LogY > fLogDblMin) return pow(fX,fA-1.0) * pow(0.5-fX+0.5,fB-1.0) / GetBeta(fA,fB); else // need logarithm; // might overflow as a whole, but seldom, not worth to pre-detect it - return exp((fA-1.0)*fLogX + (fB-1.0)* fLogY - fLogBeta); + return exp( fAm1LogX + fBm1LogY - fLogBeta); } @@ -1226,121 +1227,106 @@ void ScInterpreter::ScVariationen2() } } -void ScInterpreter::ScB() -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScB" ); - sal_uInt8 nParamCount = GetByte(); - if ( !MustHaveParamCount( nParamCount, 3, 4 ) ) - return ; - if (nParamCount == 3) - { - double x = ::rtl::math::approxFloor(GetDouble()); - double p = GetDouble(); - double n = ::rtl::math::approxFloor(GetDouble()); - if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0) - PushIllegalArgument(); - else + +double ScInterpreter::GetBinomDistPMF(double x, double n, double p) +// used in ScB and ScBinomDist +// preconditions: 0.0 <= x <= n, 0.0 < p < 1.0; x,n integral although double { - double q = 1.0 - p; + double q = (0.5 - p) + 0.5; double fFactor = pow(q, n); - if (fFactor == 0.0) + if (fFactor <=::std::numeric_limits<double>::min()) { fFactor = pow(p, n); - if (fFactor == 0.0) - PushNoValue(); + if (fFactor <= ::std::numeric_limits<double>::min()) + return GetBetaDistPDF(p, x+1.0, n-x+1.0)/(n+1.0); else { - sal_uLong max = (sal_uLong) (n - x); - for (sal_uLong i = 0; i < max && fFactor > 0.0; i++) + sal_uInt32 max = static_cast<sal_uInt32>(n - x); + for (sal_uInt32 i = 0; i < max && fFactor > 0.0; i++) fFactor *= (n-i)/(i+1)*q/p; - PushDouble(fFactor); + return fFactor; } } else { - sal_uLong max = (sal_uLong) x; - for (sal_uLong i = 0; i < max && fFactor > 0.0; i++) + sal_uInt32 max = static_cast<sal_uInt32>(x); + for (sal_uInt32 i = 0; i < max && fFactor > 0.0; i++) fFactor *= (n-i)/(i+1)*p/q; - PushDouble(fFactor); - } + return fFactor; } } - else if (nParamCount == 4) - { - double xe = GetDouble(); - double xs = GetDouble(); - double p = GetDouble(); - double n = GetDouble(); -// alter Stand 300-SC -// if ((xs < n) && (xe < n) && (p < 1.0)) -// { -// double Varianz = sqrt(n * p * (1.0 - p)); -// xs = fabs(xs - (n * p /* / 2.0 STE */ )); -// xe = fabs(xe - (n * p /* / 2.0 STE */ )); -//// STE double nVal = gauss((xs + 0.5) / Varianz) + gauss((xe + 0.5) / Varianz); -// double nVal = fabs(gauss(xs / Varianz) - gauss(xe / Varianz)); -// PushDouble(nVal); -// } - bool bIsValidX = ( 0.0 <= xs && xs <= xe && xe <= n); - if ( bIsValidX && 0.0 < p && p < 1.0 ) - { - double q = 1.0 - p; - double fFactor = pow(q, n); - if (fFactor == 0.0) - { - fFactor = pow(p, n); - if (fFactor == 0.0) - PushNoValue(); - else + +double lcl_GetBinomDistRange(double n, double xs,double xe, + double fFactor /* q^n */, double p, double q) +//preconditions: 0.0 <= xs < xe <= n; xs,xe,n integral although double { - double fSum = 0.0; - sal_uLong max; - if (xe < (sal_uLong) n) - max = (sal_uLong) (n-xe)-1; - else - max = 0; - sal_uLong i; - for (i = 0; i < max && fFactor > 0.0; i++) - fFactor *= (n-i)/(i+1)*q/p; - if (xs < (sal_uLong) n) - max = (sal_uLong) (n-xs); - else - fSum = fFactor; - for (; i < max && fFactor > 0.0; i++) + sal_uInt32 i; + double fSum; + // skip summands index 0 to xs-1, start sum with index xs + sal_uInt32 nXs = static_cast<sal_uInt32>( xs ); + for (i = 1; i <= nXs && fFactor > 0.0; i++) + fFactor *= (n-i+1)/i * p/q; + fSum = fFactor; // Summand xs + sal_uInt32 nXe = static_cast<sal_uInt32>(xe); + for (i = nXs+1; i <= nXe && fFactor > 0.0; i++) { - fFactor *= (n-i)/(i+1)*q/p; + fFactor *= (n-i+1)/i * p/q; fSum += fFactor; } - PushDouble(fSum); + return (fSum>1.0) ? 1.0 : fSum; } + +void ScInterpreter::ScB() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScB" ); + sal_uInt8 nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 3, 4 ) ) + return ; + if (nParamCount == 3) // mass function + { + double x = ::rtl::math::approxFloor(GetDouble()); + double p = GetDouble(); + double n = ::rtl::math::approxFloor(GetDouble()); + if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0) + PushIllegalArgument(); + else + if (p == 0.0) + PushDouble( (x == 0.0) ? 1.0 : 0.0 ); + else + if ( p == 1.0) + PushDouble( (x == n) ? 1.0 : 0.0); + else + PushDouble(GetBinomDistPMF(x,n,p)); } else + { // nParamCount == 4 + double xe = ::rtl::math::approxFloor(GetDouble()); + double xs = ::rtl::math::approxFloor(GetDouble()); + double p = GetDouble(); + double n = ::rtl::math::approxFloor(GetDouble()); + double q = (0.5 - p) + 0.5; + bool bIsValidX = ( 0.0 <= xs && xs <= xe && xe <= n); + if ( bIsValidX && 0.0 < p && p < 1.0) { - sal_uLong max; - double fSum; - if ( (sal_uLong) xs == 0) + if (xs == xe) // mass function + PushDouble(GetBinomDistPMF(xs,n,p)); + else { - fSum = fFactor; - max = 0; - } + double fFactor = pow(q, n); + if (fFactor > ::std::numeric_limits<double>::min()) + PushDouble(lcl_GetBinomDistRange(n,xs,xe,fFactor,p,q)); else { - max = (sal_uLong) xs-1; - fSum = 0.0; + fFactor = pow(p, n); + if (fFactor > ::std::numeric_limits<double>::min()) + { + // sum from j=xs to xe {(n choose j) * p^j * q^(n-j)} + // = sum from i = n-xe to n-xs { (n choose i) * q^i * p^(n-i)} + PushDouble(lcl_GetBinomDistRange(n,n-xe,n-xs,fFactor,q,p)); } - sal_uLong i; - for (i = 0; i < max && fFactor > 0.0; i++) - fFactor *= (n-i)/(i+1)*p/q; - if ((sal_uLong)xe == 0) // beide 0 - fSum = fFactor; else - max = (sal_uLong) xe; - for (; i < max && fFactor > 0.0; i++) - { - fFactor *= (n-i)/(i+1)*p/q; - fSum += fFactor; + PushDouble(GetBetaDist(q,n-xe,xe+1.0)-GetBetaDist(q,n-xs+1,xs) ); } - PushDouble(fSum); } } else @@ -1365,77 +1351,63 @@ void ScInterpreter::ScBinomDist() RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBinomDist" ); if ( MustHaveParamCount( GetByte(), 4 ) ) { - double kum = GetDouble(); // 0 oder 1 - double p = GetDouble(); // p - double n = ::rtl::math::approxFloor(GetDouble()); // n - double x = ::rtl::math::approxFloor(GetDouble()); // x - double fFactor, q, fSum; + bool bIsCum = GetBool(); // false=mass function; true=cumulative + double p = GetDouble(); + double n = ::rtl::math::approxFloor(GetDouble()); + double x = ::rtl::math::approxFloor(GetDouble()); + double q = (0.5 - p) + 0.5; // get one bit more for p near 1.0 + double fFactor, fSum; if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0) - PushIllegalArgument(); - else if (kum == 0.0) // Dichte { - q = 1.0 - p; - fFactor = pow(q, n); - if (fFactor == 0.0) - { - fFactor = pow(p, n); - if (fFactor == 0.0) - PushNoValue(); - else - { - sal_uLong max = (sal_uLong) (n - x); - for (sal_uLong i = 0; i < max && fFactor > 0.0; i++) - fFactor *= (n-i)/(i+1)*q/p; - PushDouble(fFactor); - } + PushIllegalArgument(); + return; } - else + if ( p == 0.0) { - sal_uLong max = (sal_uLong) x; - for (sal_uLong i = 0; i < max && fFactor > 0.0; i++) - fFactor *= (n-i)/(i+1)*p/q; - PushDouble(fFactor); + PushDouble( (x==0.0 || bIsCum) ? 1.0 : 0.0 ); + return; } + if ( p == 1.0) + { + PushDouble( (x==n) ? 1.0 : 0.0); + return; } - else // Verteilung + if (!bIsCum) + PushDouble( GetBinomDistPMF(x,n,p)); + else { - if (n == x) + if (x == n) PushDouble(1.0); else { - q = 1.0 - p; fFactor = pow(q, n); - if (fFactor == 0.0) + if (x == 0.0) + PushDouble(fFactor); + else + if (fFactor <= ::std::numeric_limits<double>::min()) { fFactor = pow(p, n); - if (fFactor == 0.0) - PushNoValue(); + if (fFactor <= ::std::numeric_limits<double>::min()) + PushDouble(GetBetaDist(q,n-x,x+1.0)); else { + if (fFactor > fMachEps) + { fSum = 1.0 - fFactor; - sal_uLong max = (sal_uLong) (n - x) - 1; - for (sal_uLong i = 0; i < max && fFactor > 0.0; i++) + sal_uInt32 max = static_cast<sal_uInt32> (n - x) - 1; + for (sal_uInt32 i = 0; i < max && fFactor > 0.0; i++) { fFactor *= (n-i)/(i+1)*q/p; fSum -= fFactor; } - if (fSum < 0.0) - PushDouble(0.0); - else - PushDouble(fSum); - } + PushDouble( (fSum < 0.0) ? 0.0 : fSum ); } else - { - fSum = fFactor; - sal_uLong max = (sal_uLong) x; - for (sal_uLong i = 0; i < max && fFactor > 0.0; i++) - { - fFactor *= (n-i)/(i+1)*p/q; - fSum += fFactor; + PushDouble(lcl_GetBinomDistRange(n,n-x,n,fFactor,q,p)); } - PushDouble(fSum); } + else + PushDouble( lcl_GetBinomDistRange(n,0.0,x,fFactor,p,q)) ; } } } diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 7a4ac7ecdac8..439e0375a8b9 100755 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -1445,7 +1445,7 @@ bool ScInterpreter::ConvertMatrixParameters() for ( sal_uInt16 i=1; i <= nParams && i <= sp; ++i ) { FormulaToken* p = pStack[ sp - i ]; - if ( p->GetOpCode() != ocPush ) + if ( p->GetOpCode() != ocPush && p->GetOpCode() != ocMissing ) { DBG_ERRORFILE( "ConvertMatrixParameters: not a push"); } @@ -3181,6 +3181,14 @@ void ScInterpreter::ScColRowNameAuto() void ScInterpreter::ScExternalRef() { + const FormulaToken* pNextOp = aCode.PeekNextOperator(); + if (pNextOp && pNextOp->GetOpCode() == ocOffset) + { + // Handled by OFFSET function. + PushTempToken( *pCur); + return; + } + ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager(); const String* pFile = pRefMgr->getExternalFileName(pCur->GetIndex()); if (!pFile) @@ -3324,6 +3332,21 @@ void ScInterpreter::GlobalExit() // static } +// A ::std::vector<FormulaTokenRef> is not possible, a push_back() attempts to +// use a FormulaToken(const FormulaTokenRef&) ctor. Reinvent wheel.. +struct FormulaTokenRefPtr +{ + FormulaToken* mp; + FormulaTokenRefPtr() : mp(0) {} + FormulaTokenRefPtr( FormulaToken* p ) : mp(p) { if (mp) mp->IncRef(); } + FormulaTokenRefPtr( const FormulaTokenRefPtr & r ) : mp(r.mp) { if (mp) mp->IncRef(); } + ~FormulaTokenRefPtr() { if (mp) mp->DecRef(); } + FormulaTokenRefPtr& operator=( const FormulaTokenRefPtr & r ) + { if (r.mp) r.mp->IncRef(); if (mp) mp->DecRef(); mp = r.mp; return *this; } +}; +typedef ::std::vector< FormulaTokenRefPtr > FormulaTokenDtor; + + StackVar ScInterpreter::Interpret() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Interpret" ); @@ -3342,6 +3365,7 @@ StackVar ScInterpreter::Interpret() pJumpMatrix = NULL; glSubTotal = sal_False; ScTokenMatrixMap::const_iterator aTokenMatrixMapIter; + ::boost::scoped_ptr< FormulaTokenDtor > pTokenDtor; // Once upon a time we used to have FP exceptions on, and there was a // Windows printer driver that kept switching off exceptions, so we had to @@ -3459,6 +3483,10 @@ StackVar ScInterpreter::Interpret() case ocArcCosHyp : ScArcCosHyp(); break; case ocArcTanHyp : ScArcTanHyp(); break; case ocArcCotHyp : ScArcCotHyp(); break; + case ocCosecant : ScCosecant(); break; + case ocSecant : ScSecant(); break; + case ocCosecantHyp : ScCosecantHyp(); break; + case ocSecantHyp : ScSecantHyp(); break; case ocExp : ScExp(); break; case ocLn : ScLn(); break; case ocLog10 : ScLog10(); break; @@ -3720,13 +3748,27 @@ StackVar ScInterpreter::Interpret() default : PushError( errUnknownOpCode); break; } - // If the function signalled that it pushed a subroutine on the - // instruction code stack instead of a result, continue with + // If the function pushed a subroutine as result, continue with // execution of the subroutine. - if (sp > nStackBase && pStack[sp-1]->GetOpCode() == ocCall) + if (sp > nStackBase && pStack[sp-1]->GetOpCode() == ocCall && pStack[sp-1]->GetType() == svSubroutine) { - Pop(); - continue; // while( ( pCur = aCode.Next() ) != NULL ... + FormulaTokenRef xTok = PopToken(); + const FormulaSubroutineToken* pSub = dynamic_cast<FormulaSubroutineToken*>(xTok.get()); + if (pSub) + { + // Remember token for late destruction. + if (!pTokenDtor) + pTokenDtor.reset( new FormulaTokenDtor); + pTokenDtor->push_back( FormulaTokenDtor::value_type( xTok)); + // Continue with execution of subroutine. + aCode.Push( pSub->GetTokenArray()); + continue; // while( ( pCur = aCode.Next() ) != NULL ... + } + else + { + DBG_ERRORFILE( "ScInterpreter::Interpret: ocCall svSubroutine, but no FormulaSubroutineToken?!?"); + PushError( errNoCode); + } } // Remember result matrix in case it could be reused. diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index cf22b23e69ef..cf6757556ed2 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -656,25 +656,6 @@ void ScInterpreter::MEMat(ScMatrix* mM, SCSIZE n) mM->PutDouble(1.0, i, i); } -void ScInterpreter::MFastMult(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR, - SCSIZE n, SCSIZE m, SCSIZE l) - // Multipliziert n x m Mat a mit m x l Mat b nach Mat r -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MFastMult" ); - double sum; - for (SCSIZE i = 0; i < n; i++) - { - for (SCSIZE j = 0; j < l; j++) - { - sum = 0.0; - for (SCSIZE k = 0; k < m; k++) - sum += pA->GetDouble(i,k)*pB->GetDouble(k,j); - pR->PutDouble(sum, i, j); - } - } -} - - /* Matrix LUP decomposition according to the pseudocode of "Introduction to * Algorithms" by Cormen, Leiserson, Rivest, Stein. * @@ -779,6 +760,13 @@ static int lcl_LUP_decompose( ScMatrix* mA, const SCSIZE n, fprintf( stderr, "%5u ", (unsigned)P[j]); fprintf( stderr, "\n%s\n", ""); #endif + + bool bSingular=false; + for (SCSIZE i=0; i < n && !bSingular; i++) + bSingular = (mA->GetDouble(i,i) == 0.0); + if (bSingular) + nSign = 0; + return nSign; } @@ -946,7 +934,7 @@ void ScInterpreter::ScMatInv() if (xR) { ScMatrix* pR = xR; - MFastMult( pMat, pY, pR, nR, nR, nR); + lcl_MFastMult( pMat, pY, pR, nR, nR, nR); #if OSL_DEBUG_LEVEL > 1 fprintf( stderr, "\n%s\n", "ScMatInv(): mult-identity"); #endif @@ -1852,212 +1840,397 @@ void ScInterpreter::ScFrequency() PushMatrix(pResMat); } -sal_Bool ScInterpreter::RGetVariances( ScMatrix* pV, ScMatrix* pX, - SCSIZE nC, SCSIZE nR, sal_Bool bSwapColRow, sal_Bool bZeroConstant ) -{ // multiple Regression: Varianzen der Koeffizienten - // bSwapColRow==sal_True : Koeffizienten in Zeilen statt Spalten angeordnet - SCSIZE i, j, k; +// ----------------------------------------------------------------------------- +// Helper methods for LINEST/LOGEST and TREND/GROWTH +// All matrices must already exist and have the needed size, no control tests +// done. Those methodes, which names start with lcl_T, are adapted to case 3, +// where Y (=observed values) is given as row. +// Remember, ScMatrix matrices are zero based, index access (column,row). +// ----------------------------------------------------------------------------- + +// Multiply n x m Mat A with m x l Mat B to n x l Mat R +void lcl_MFastMult( ScMatrixRef pA, ScMatrixRef pB, ScMatrixRef pR, SCSIZE n, SCSIZE m, SCSIZE l ) +{ double sum; - ScMatrixRef pC = GetNewMat(nC, nC); - if ( !pC ) - return sal_False; - // X transformiert mit X multipziert, X'X Matrix - if ( !bZeroConstant ) - { // in der X-Designmatrix existiert ein gedachtes X0j==1 - if ( bSwapColRow ) - { - for ( i=0; i<nC; i++ ) - { - for ( j=0; j<nC; j++ ) - { - sum = 0.0; - for ( k=0; k<nR; k++ ) - { - sum += (j==0 ? 1 : pX->GetDouble(k,j-1)) - * (i==0 ? 1 : pX->GetDouble(k,i-1)); - } - pC->PutDouble(sum, i, j); - } - } - } - else - { - for ( i=0; i<nC; i++ ) - { - for ( j=0; j<nC; j++ ) - { - sum = 0.0; - for ( k=0; k<nR; k++ ) - { - sum += (j==0 ? 1 : pX->GetDouble(j-1,k)) - * (i==0 ? 1 : pX->GetDouble(i-1,k)); - } - pC->PutDouble(sum, i, j); - } - } + for (SCSIZE row = 0; row < n; row++) + { + for (SCSIZE col = 0; col < l; col++) + { // result element(col, row) =sum[ (row of A) * (column of B)] + sum = 0.0; + for (SCSIZE k = 0; k < m; k++) + sum += pA->GetDouble(k,row) * pB->GetDouble(col,k); + pR->PutDouble(sum, col, row); } } +} + +// <A;B> over all elements; uses the matrices as vectors of length M +double lcl_GetSumProduct( ScMatrixRef pMatA, ScMatrixRef pMatB, SCSIZE nM ) +{ + double fSum = 0.0; + for (SCSIZE i=0; i<nM; i++) + fSum += pMatA->GetDouble(i) * pMatB->GetDouble(i); + return fSum; +} + +// Special version for use within QR decomposition. +// Euclidean norm of column index C starting in row index R; +// matrix A has count N rows. +double lcl_GetColumnEuclideanNorm( ScMatrixRef pMatA, SCSIZE nC, SCSIZE nR, SCSIZE nN ) +{ + double fNorm = 0.0; + for (SCSIZE row=nR; row<nN; row++) + fNorm += (pMatA->GetDouble(nC,row)) * (pMatA->GetDouble(nC,row)); + return sqrt(fNorm); +} + +// Euclidean norm of row index R starting in column index C; +// matrix A has count N columns. +double lcl_TGetColumnEuclideanNorm( ScMatrixRef pMatA, SCSIZE nR, SCSIZE nC, SCSIZE nN ) +{ + double fNorm = 0.0; + for (SCSIZE col=nC; col<nN; col++) + fNorm += (pMatA->GetDouble(col,nR)) * (pMatA->GetDouble(col,nR)); + return sqrt(fNorm); + } + +// Special version for use within QR decomposition. +// Maximum norm of column index C starting in row index R; +// matrix A has count N rows. +double lcl_GetColumnMaximumNorm( ScMatrixRef pMatA, SCSIZE nC, SCSIZE nR, SCSIZE nN ) +{ + double fNorm = 0.0; + for (SCSIZE row=nR; row<nN; row++) + if (fNorm < fabs(pMatA->GetDouble(nC,row))) + fNorm = fabs(pMatA->GetDouble(nC,row)); + return fNorm; +} + +// Maximum norm of row index R starting in col index C; +// matrix A has count N columns. +double lcl_TGetColumnMaximumNorm( ScMatrixRef pMatA, SCSIZE nR, SCSIZE nC, SCSIZE nN ) +{ + double fNorm = 0.0; + for (SCSIZE col=nC; col<nN; col++) + if (fNorm < fabs(pMatA->GetDouble(col,nR))) + fNorm = fabs(pMatA->GetDouble(col,nR)); + return fNorm; +} + +// Special version for use within QR decomposition. +// <A(Ca);B(Cb)> starting in row index R; +// Ca and Cb are indices of columns, matrices A and B have count N rows. +double lcl_GetColumnSumProduct( ScMatrixRef pMatA, SCSIZE nCa, ScMatrixRef pMatB, + SCSIZE nCb, SCSIZE nR, SCSIZE nN ) +{ + double fResult = 0.0; + for (SCSIZE row=nR; row<nN; row++) + fResult += pMatA->GetDouble(nCa,row) * pMatB->GetDouble(nCb,row); + return fResult; +} + +// <A(Ra);B(Rb)> starting in column index C; +// Ra and Rb are indices of rows, matrices A and B have count N columns. +double lcl_TGetColumnSumProduct( ScMatrixRef pMatA, SCSIZE nRa, + ScMatrixRef pMatB, SCSIZE nRb, SCSIZE nC, SCSIZE nN ) +{ + double fResult = 0.0; + for (SCSIZE col=nC; col<nN; col++) + fResult += pMatA->GetDouble(col,nRa) * pMatB->GetDouble(col,nRb); + return fResult; +} + +double lcl_GetSign(double fValue) +{ + if (fValue < 0.0) + return -1.0; + else if (fValue > 0.0) + return 1.0; else - { - if ( bSwapColRow ) + return 0.0; +} + +/* Calculates a QR decomposition with Householder reflection. + * For each NxK matrix A exists a decomposition A=Q*R with an orthogonal + * NxN matrix Q and a NxK matrix R. + * Q=H1*H2*...*Hk with Householder matrices H. Such a householder matrix can + * be build from a vector u by H=I-(2/u'u)*(u u'). This vectors u are returned + * in the columns of matrix A, overwriting the old content. + * The matrix R has a quadric upper part KxK with values in the upper right + * triangle and zeros in all other elements. Here the diagonal elements of R + * are stored in the vector R and the other upper right elements in the upper + * right of the matrix A. + * The function returns false, if calculation breaks. But because of round-off + * errors singularity is often not detected. + */ +bool lcl_CalculateQRdecomposition(ScMatrixRef pMatA, + ::std::vector< double>& pVecR, SCSIZE nK, SCSIZE nN) +{ + double fScale ; + double fEuclid ; + double fFactor ; + double fSignum ; + double fSum ; + // ScMatrix matrices are zero based, index access (column,row) + for (SCSIZE col = 0; col <nK; col++) + { + // calculate vector u of the householder transformation + fScale = lcl_GetColumnMaximumNorm(pMatA, col, col, nN); + if (fScale == 0.0) + // A is singular + return false; + + for (SCSIZE row = col; row <nN; row++) + pMatA->PutDouble( pMatA->GetDouble(col,row)/fScale, col, row); + + fEuclid = lcl_GetColumnEuclideanNorm(pMatA, col, col, nN); + fFactor = 1.0/fEuclid/(fEuclid + fabs(pMatA->GetDouble(col,col))); + fSignum = lcl_GetSign(pMatA->GetDouble(col,col)); + pMatA->PutDouble( pMatA->GetDouble(col,col) + fSignum*fEuclid, col,col); + pVecR[col] = -fSignum * fScale * fEuclid; + + // apply Householder transformation to A + for (SCSIZE c=col+1; c<nK; c++) { - for ( i=0; i<nC; i++ ) - { - for ( j=0; j<nC; j++ ) - { - sum = 0.0; - for ( k=0; k<nR; k++ ) - { - sum += pX->GetDouble(k,j) * pX->GetDouble(k,i); - } - pC->PutDouble(sum, i, j); - } - } + fSum =lcl_GetColumnSumProduct(pMatA, col, pMatA, c, col, nN); + for (SCSIZE row = col; row <nN; row++) + pMatA->PutDouble( pMatA->GetDouble(c,row) + - fSum * fFactor * pMatA->GetDouble(col,row), c, row); } - else + } + return true; +} + +// same with transposed matrix A, N is count of columns, K count of rows +bool lcl_TCalculateQRdecomposition(ScMatrixRef pMatA, + ::std::vector< double>& pVecR, SCSIZE nK, SCSIZE nN) +{ + double fScale ; + double fEuclid ; + double fFactor ; + double fSignum ; + double fSum ; + // ScMatrix matrices are zero based, index access (column,row) + for (SCSIZE row = 0; row <nK; row++) + { + // calculate vector u of the householder transformation + fScale = lcl_TGetColumnMaximumNorm(pMatA, row, row, nN); + if (fScale == 0.0) + // A is singular + return false; + + for (SCSIZE col = row; col <nN; col++) + pMatA->PutDouble( pMatA->GetDouble(col,row)/fScale, col, row); + + fEuclid = lcl_TGetColumnEuclideanNorm(pMatA, row, row, nN); + fFactor = 1.0/fEuclid/(fEuclid + fabs(pMatA->GetDouble(row,row))); + fSignum = lcl_GetSign(pMatA->GetDouble(row,row)); + pMatA->PutDouble( pMatA->GetDouble(row,row) + fSignum*fEuclid, row,row); + pVecR[row] = -fSignum * fScale * fEuclid; + + // apply Householder transformation to A + for (SCSIZE r=row+1; r<nK; r++) { - for ( i=0; i<nC; i++ ) - { - for ( j=0; j<nC; j++ ) - { - sum = 0.0; - for ( k=0; k<nR; k++ ) - { - sum += pX->GetDouble(j,k) * pX->GetDouble(i,k); - } - pC->PutDouble(sum, i, j); - } - } + fSum =lcl_TGetColumnSumProduct(pMatA, row, pMatA, r, row, nN); + for (SCSIZE col = row; col <nN; col++) + pMatA->PutDouble( pMatA->GetDouble(col,r) + - fSum * fFactor * pMatA->GetDouble(col,row), col, r); } } - // X'X Inverse - sal_Bool bOk = sal_True; - sal_uInt16 nErr = nGlobalError; - PushMatrix(pC); - sal_uInt8 nTmp = cPar; - cPar = 1; - ScMatInv(); - cPar = nTmp; - if ( nGlobalError ) - { - nGlobalError = nErr; - bOk = sal_False; + return true; +} + + +/* Applies a Householder transformation to a column vector Y with is given as + * Nx1 Matrix. The Vektor u, from which the Householder transformation is build, + * is the column part in matrix A, with column index C, starting with row + * index C. A is the result of the QR decomposition as obtained from + * lcl_CaluclateQRdecomposition. + */ +void lcl_ApplyHouseholderTransformation(ScMatrixRef pMatA, SCSIZE nC, + ScMatrixRef pMatY, SCSIZE nN) +{ + // ScMatrix matrices are zero based, index access (column,row) + double fDenominator = lcl_GetColumnSumProduct(pMatA, nC, pMatA, nC, nC, nN); + double fNumerator = lcl_GetColumnSumProduct(pMatA, nC, pMatY, 0, nC, nN); + double fFactor = 2.0 * (fNumerator/fDenominator); + for (SCSIZE row = nC; row < nN; row++) + pMatY->PutDouble( + pMatY->GetDouble(row) - fFactor * pMatA->GetDouble(nC,row), row); +} + +// Same with transposed matrices A and Y. +void lcl_TApplyHouseholderTransformation(ScMatrixRef pMatA, SCSIZE nR, + ScMatrixRef pMatY, SCSIZE nN) +{ + // ScMatrix matrices are zero based, index access (column,row) + double fDenominator = lcl_TGetColumnSumProduct(pMatA, nR, pMatA, nR, nR, nN); + double fNumerator = lcl_TGetColumnSumProduct(pMatA, nR, pMatY, 0, nR, nN); + double fFactor = 2.0 * (fNumerator/fDenominator); + for (SCSIZE col = nR; col < nN; col++) + pMatY->PutDouble( + pMatY->GetDouble(col) - fFactor * pMatA->GetDouble(col,nR), col); +} + +/* Solve for X in R*X=S using back substitution. The solution X overwrites S. + * Uses R from the result of the QR decomposition of a NxK matrix A. + * S is a column vector given as matrix, with at least elements on index + * 0 to K-1; elements on index>=K are ignored. Vector R must not have zero + * elements, no check is done. + */ +void lcl_SolveWithUpperRightTriangle(ScMatrixRef pMatA, + ::std::vector< double>& pVecR, ScMatrixRef pMatS, + SCSIZE nK, bool bIsTransposed) +{ + // ScMatrix matrices are zero based, index access (column,row) + double fSum; + SCSIZE row; + // SCSIZE is never negative, therefore test with rowp1=row+1 + for (SCSIZE rowp1 = nK; rowp1>0; rowp1--) + { + row = rowp1-1; + fSum = pMatS->GetDouble(row); + for (SCSIZE col = rowp1; col<nK ; col++) + if (bIsTransposed) + fSum -= pMatA->GetDouble(row,col) * pMatS->GetDouble(col); + else + fSum -= pMatA->GetDouble(col,row) * pMatS->GetDouble(col); + pMatS->PutDouble( fSum / pVecR[row] , row); } - else +} + +/* Solve for X in R' * X= T using forward substitution. The solution X + * overwrites T. Uses R from the result of the QR decomposition of a NxK + * matrix A. T is a column vectors given as matrix, with at least elements on + * index 0 to K-1; elements on index>=K are ignored. Vector R must not have + * zero elements, no check is done. + */ +void lcl_SolveWithLowerLeftTriangle(ScMatrixRef pMatA, + ::std::vector< double>& pVecR, ScMatrixRef pMatT, + SCSIZE nK, bool bIsTransposed) +{ + // ScMatrix matrices are zero based, index access (column,row) + double fSum; + for (SCSIZE row = 0; row < nK; row++) { - // #i61216# ScMatInv no longer modifies the original matrix, so just calling Pop() doesn't work - pC = PopMatrix(); - if ( pC.Is() ) + fSum = pMatT -> GetDouble(row); + for (SCSIZE col=0; col < row; col++) { - // Varianzen auf der Diagonalen, andere sind Kovarianzen - for (i = 0; i < nC; i++) - pV->PutDouble(pC->GetDouble(i, i), i); + if (bIsTransposed) + fSum -= pMatA->GetDouble(col,row) * pMatT->GetDouble(col); + else + fSum -= pMatA->GetDouble(row,col) * pMatT->GetDouble(col); } + pMatT->PutDouble( fSum / pVecR[row] , row); } - return bOk; } -// ----------------------------------------------------------------------------- -void ScInterpreter::Calculate(ScMatrixRef& pResMat,ScMatrixRef& pE,ScMatrixRef& pQ,ScMatrixRef& pV,ScMatrixRef& pMatX,sal_Bool bConstant,SCSIZE N,SCSIZE M,sal_uInt8 nCase) -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::RGetVariances" ); - // pE[0] := Sigma i=1...n (Yi) - // pE[k] := Sigma i=1...n (Xki*Yi) - // pE[M+1] := Sigma i=1...n (Yi**2) - // pQ[0,M+1]:= B - // pQ[k,M+1]:= Mk - double fSQR, fSQT, fSQE; - fSQT = pE->GetDouble(M+1) - - pE->GetDouble(0) * pE->GetDouble(0) / (double)N; - fSQR = pE->GetDouble(M+1); - SCSIZE i, j; - for (i = 0; i < M+1; i++) - fSQR -= pQ->GetDouble(i, M+1) * pE->GetDouble(i); - fSQE = fSQT-fSQR; - // r2 (Bestimmtheitsmass, 0...1) - if (fSQT == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 2); - else - pResMat->PutDouble (fSQE/fSQT, 0, 2); - // ssReg (Regressions-Quadratsumme) - pResMat->PutDouble(fSQE, 0, 4); - // ssResid (Residual-Quadratsumme, Summe der Abweichungsquadrate) - pResMat->PutDouble(fSQR, 1, 4); - for (i = 2; i < 5; i++) - for (j = 2; j < M+1; j++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), j, i); - if (bConstant) - { - if (N-M-1 == 0) - { - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); - } - else - { - double fSE2 = fSQR/(N-M-1); - // sey (Standardfehler des Schaetzwertes y) - pResMat->PutDouble(sqrt(fSE2), 1, 2); - // sen...se1 (Standardfehler der Koeffizienten mn...m1) - // seb (Standardfehler der Konstanten b) - if ( RGetVariances( pV, pMatX, M+1, N, nCase != 2, sal_False ) ) - { - for (i = 0; i < M+1; i++) - pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i, 1 ); - } + +/* Calculates Z = R * B + * R is given in matrix A and vector VecR as obtained from the QR + * decompostion in lcl_CalculateQRdecomposition. B and Z are column vectors + * given as matrix with at least index 0 to K-1; elements on index>=K are + * not used. + */ +void lcl_ApplyUpperRightTriangle(ScMatrixRef pMatA, + ::std::vector< double>& pVecR, ScMatrixRef pMatB, + ScMatrixRef pMatZ, SCSIZE nK, bool bIsTransposed) +{ + // ScMatrix matrices are zero based, index access (column,row) + double fSum; + for (SCSIZE row = 0; row < nK; row++) + { + fSum = pVecR[row] * pMatB->GetDouble(row); + for (SCSIZE col = row+1; col < nK; col++) + if (bIsTransposed) + fSum += pMatA->GetDouble(row,col) * pMatB->GetDouble(col); else - { - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); - } - } - // F (F-Statistik) - if (fSQR == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); - else - pResMat->PutDouble(((double)(N-M-1))*fSQE/fSQR/((double)M),0, 3); - // df (Freiheitsgrad) - pResMat->PutDouble(((double)(N-M-1)), 1, 3); + fSum += pMatA->GetDouble(col,row) * pMatB->GetDouble(col); + pMatZ->PutDouble( fSum, row); } - else +} + + + +double lcl_GetMeanOverAll(ScMatrixRef pMat, SCSIZE nN) +{ + double fSum = 0.0; + for (SCSIZE i=0 ; i<nN; i++) + fSum += pMat->GetDouble(i); + return fSum/static_cast<double>(nN); +} + +// Calculates means of the columns of matrix X. X is a RxC matrix; +// ResMat is a 1xC matrix (=row). +void lcl_CalculateColumnMeans(ScMatrixRef pX, ScMatrixRef pResMat, + SCSIZE nC, SCSIZE nR) +{ + double fSum = 0.0; + for (SCSIZE i=0; i < nC; i++) { - if (N-M == 0) - { - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); - } - else - { - double fSE2 = fSQR/(N-M); - pResMat->PutDouble(sqrt(fSE2), 1, 2); - if ( RGetVariances( pV, pMatX, M, N, nCase != 2, sal_True ) ) - { - for (i = 0; i < M; i++) - pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i-1, 1 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), M, 1); - } - else - { - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); - } - } - if (fSQR == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); - else - pResMat->PutDouble(((double)(N-M))*fSQE/fSQR/((double)M),0, 3); - pResMat->PutDouble(((double)(N-M)), 1, 3); + fSum =0.0; + for (SCSIZE k=0; k < nR; k++) + fSum += pX->GetDouble(i,k); // GetDouble(Column,Row) + pResMat ->PutDouble( fSum/static_cast<double>(nR),i); } } -void ScInterpreter::ScRGP() +// Calculates means of the rows of matrix X. X is a RxC matrix; +// ResMat is a Rx1 matrix (=column). +void lcl_CalculateRowMeans(ScMatrixRef pX, ScMatrixRef pResMat, + SCSIZE nC, SCSIZE nR) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRGP" ); - CalulateRGPRKP(sal_False); + double fSum = 0.0; + for (SCSIZE k=0; k < nR; k++) + { + fSum =0.0; + for (SCSIZE i=0; i < nC; i++) + fSum += pX->GetDouble(i,k); // GetDouble(Column,Row) + pResMat ->PutDouble( fSum/static_cast<double>(nC),k); + } } -bool ScInterpreter::CheckMatrix(sal_Bool _bLOG,sal_Bool _bTrendGrowth,sal_uInt8& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY) + +void lcl_CalculateColumnsDelta(ScMatrixRef pMat, ScMatrixRef pColumnMeans, + SCSIZE nC, SCSIZE nR) +{ + for (SCSIZE i = 0; i < nC; i++) + for (SCSIZE k = 0; k < nR; k++) + pMat->PutDouble( ::rtl::math::approxSub + (pMat->GetDouble(i,k) , pColumnMeans->GetDouble(i) ) , i, k); +} + +void lcl_CalculateRowsDelta(ScMatrixRef pMat, ScMatrixRef pRowMeans, + SCSIZE nC, SCSIZE nR) { + for (SCSIZE k = 0; k < nR; k++) + for (SCSIZE i = 0; i < nC; i++) + pMat->PutDouble( ::rtl::math::approxSub + ( pMat->GetDouble(i,k) , pRowMeans->GetDouble(k) ) , i, k); +} + +// Case1 = simple regression +// MatX = X - MeanX, MatY = Y - MeanY, y - haty = (y - MeanY) - (haty - MeanY) +// = (y-MeanY)-((slope*x+a)-(slope*MeanX+a)) = (y-MeanY)-slope*(x-MeanX) +double lcl_GetSSresid(ScMatrixRef pMatX, ScMatrixRef pMatY, double fSlope, + SCSIZE nN) +{ + double fSum = 0.0; + double fTemp = 0.0; + for (SCSIZE i=0; i<nN; i++) + { + fTemp = pMatY->GetDouble(i) - fSlope * pMatX->GetDouble(i); + fSum += fTemp * fTemp; + } + return fSum; +} + +// Fill default values in matrix X, transform Y to log(Y) in case LOGEST|GROWTH, +// determine sizes of matrices X and Y, determine kind of regression, clone +// Y in case LOGEST|GROWTH, if constant. +bool ScInterpreter::CheckMatrix(bool _bLOG, sal_uInt8& nCase, SCSIZE& nCX, + SCSIZE& nCY, SCSIZE& nRX, SCSIZE& nRY, SCSIZE& M, + SCSIZE& N, ScMatrixRef& pMatX, ScMatrixRef& pMatY) +{ + nCX = 0; nCY = 0; nRX = 0; @@ -2103,7 +2276,11 @@ bool ScInterpreter::CheckMatrix(sal_Bool _bLOG,sal_Bool _bTrendGrowth,sal_uInt8& return false; } if (nCX == nCY && nRX == nRY) - nCase = 1; // einfache Regression + { + nCase = 1; // simple regression + M = 1; + N = nCountY; + } else if (nCY != 1 && nRY != 1) { PushIllegalArgument(); @@ -2118,7 +2295,7 @@ bool ScInterpreter::CheckMatrix(sal_Bool _bLOG,sal_Bool _bTrendGrowth,sal_uInt8& } else { - nCase = 2; // zeilenweise + nCase = 2; // Y is column N = nRY; M = nCX; } @@ -2130,7 +2307,7 @@ bool ScInterpreter::CheckMatrix(sal_Bool _bLOG,sal_Bool _bTrendGrowth,sal_uInt8& } else { - nCase = 3; // spaltenweise + nCase = 3; // Y is row N = nCY; M = nRX; } @@ -2138,460 +2315,645 @@ bool ScInterpreter::CheckMatrix(sal_Bool _bLOG,sal_Bool _bTrendGrowth,sal_uInt8& else { pMatX = GetNewMat(nCY, nRY); - if ( _bTrendGrowth ) - { - nCX = nCY; - nRX = nRY; - } + nCX = nCY; + nRX = nRY; if (!pMatX) { PushIllegalArgument(); return false; } for ( SCSIZE i = 1; i <= nCountY; i++ ) - pMatX->PutDouble((double)i, i-1); + pMatX->PutDouble(static_cast<double>(i), i-1); nCase = 1; + N = nCountY; + M = 1; } return true; } -void ScInterpreter::CalulateRGPRKP(sal_Bool _bRKP) +// ----------------------------------------------------------------------------- + +// LINEST +void ScInterpreter::ScRGP() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRGP" ); + CalulateRGPRKP(false); +} + +// LOGEST +void ScInterpreter::ScRKP() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRKP" ); + CalulateRGPRKP(true); +} + +void ScInterpreter::CalulateRGPRKP(bool _bRKP) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CheckMatrix" ); sal_uInt8 nParamCount = GetByte(); if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) return; - sal_Bool bConstant, bStats; + bool bConstant, bStats; + + // optional forth parameter if (nParamCount == 4) bStats = GetBool(); else - bStats = sal_False; + bStats = false; + + // The third parameter may not be missing in ODF, if the forth parameter + // is present. But Excel allows it with default true, we too. if (nParamCount >= 3) - bConstant = GetBool(); + { + if (IsMissing()) + { + Pop(); + bConstant = true; + // PushIllegalParameter(); if ODF behavior is desired + // return; + } + else + bConstant = GetBool(); + } else - bConstant = sal_True; + bConstant = true; + ScMatrixRef pMatX; - ScMatrixRef pMatY; if (nParamCount >= 2) - pMatX = GetMatrix(); + { + if (IsMissing()) + { + // In ODF1.2 empty second parameter (which is two ;; ) is allowed + Pop(); + pMatX = NULL; + } + else + { + pMatX = GetMatrix(); + } + } else pMatX = NULL; + + ScMatrixRef pMatY; pMatY = GetMatrix(); if (!pMatY) { PushIllegalParameter(); return; - } // if (!pMatY) - sal_uInt8 nCase; // 1 = normal, 2,3 = mehrfach - SCSIZE nCX, nCY; - SCSIZE nRX, nRY; - SCSIZE M = 0, N = 0; - if ( !CheckMatrix(_bRKP,sal_False,nCase,nCX,nCY,nRX,nRY,M,N,pMatX,pMatY) ) + } + + // 1 = simple; 2 = multiple with Y as column; 3 = multiple with Y as row + sal_uInt8 nCase; + + SCSIZE nCX, nCY; // number of columns + SCSIZE nRX, nRY; // number of rows + SCSIZE K = 0, N = 0; // K=number of variables X, N=number of data samples + if ( !CheckMatrix(_bRKP,nCase,nCX,nCY,nRX,nRY,K,N,pMatX,pMatY) ) + { + PushIllegalParameter(); + return; + } + + // Enough data samples? + if ( (bConstant && (N<K+1)) || (!bConstant && (N<K)) || (N<1) || (K<1) ) + { + PushIllegalParameter(); return; + } ScMatrixRef pResMat; - if (nCase == 1) + if (bStats) + pResMat = GetNewMat(K+1,5); + else + pResMat = GetNewMat(K+1,1); + if (!pResMat) { - if (!bStats) - pResMat = GetNewMat(2,1); - else - pResMat = GetNewMat(2,5); - if (!pResMat) + PushError(errCodeOverflow); + return; + } + // Fill unused cells in pResMat; order (column,row) + if (bStats) + { + for (SCSIZE i=2; i<K+1; i++) { - PushIllegalArgument(); + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 2 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 3 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 4 ); + } + } + + // Uses sum(x-MeanX)^2 and not [sum x^2]-N * MeanX^2 in case bConstant. + // Clone constant matrices, so that Mat = Mat - Mean is possible. + double fMeanY = 0.0; + if (bConstant) + { + ScMatrixRef pNewX = pMatX->CloneIfConst(); + ScMatrixRef pNewY = pMatY->CloneIfConst(); + if (!pNewX || !pNewY) + { + PushError(errCodeOverflow); return; } - double fCount = 0.0; - double fSumX = 0.0; - double fSumSqrX = 0.0; - double fSumY = 0.0; - double fSumSqrY = 0.0; - double fSumXY = 0.0; - double fValX, fValY; - for (SCSIZE i = 0; i < nCY; i++) - for (SCSIZE j = 0; j < nRY; j++) - { - fValX = pMatX->GetDouble(i,j); - fValY = pMatY->GetDouble(i,j); - fSumX += fValX; - fSumSqrX += fValX * fValX; - fSumY += fValY; - fSumSqrY += fValY * fValY; - fSumXY += fValX*fValY; - fCount++; - } - if (fCount < 1.0) - PushNoValue(); - else + pMatX = pNewX; + pMatY = pNewY; + // DeltaY is possible here; DeltaX depends on nCase, so later + fMeanY = lcl_GetMeanOverAll(pMatY, N); + for (SCSIZE i=0; i<N; i++) { - double f1 = fCount*fSumXY-fSumX*fSumY; - double fX = fCount*fSumSqrX-fSumX*fSumX; - double b, m; - if (bConstant) + pMatY->PutDouble( ::rtl::math::approxSub(pMatY->GetDouble(i),fMeanY), i ); + } + } + + if (nCase==1) + { + // calculate simple regression + double fMeanX = 0.0; + if (bConstant) + { // Mat = Mat - Mean + fMeanX = lcl_GetMeanOverAll(pMatX, N); + for (SCSIZE i=0; i<N; i++) { - b = fSumY/fCount - f1/fX*fSumX/fCount; - m = f1/fX; + pMatX->PutDouble( ::rtl::math::approxSub(pMatX->GetDouble(i),fMeanX), i ); } - else - { - b = 0.0; - m = fSumXY/fSumSqrX; + } + double fSumXY = lcl_GetSumProduct(pMatX,pMatY,N); + double fSumX2 = lcl_GetSumProduct(pMatX,pMatX,N); + if (fSumX2==0.0) + { + PushNoValue(); // all x-values are identical + return; + } + double fSlope = fSumXY / fSumX2; + double fIntercept = 0.0; + if (bConstant) + fIntercept = fMeanY - fSlope * fMeanX; + pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, 1, 0); //order (column,row) + pResMat->PutDouble(_bRKP ? exp(fSlope) : fSlope, 0, 0); + + if (bStats) + { + double fSSreg = fSlope * fSlope * fSumX2; + pResMat->PutDouble(fSSreg, 0, 4); + + double fDegreesFreedom =static_cast<double>( (bConstant) ? N-2 : N-1 ); + pResMat->PutDouble(fDegreesFreedom, 1, 3); + + double fSSresid = lcl_GetSSresid(pMatX,pMatY,fSlope,N); + pResMat->PutDouble(fSSresid, 1, 4); + + if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0) + { // exact fit; test SSreg too, because SSresid might be + // unequal zero due to round of errors + pResMat->PutDouble(0.0, 1, 4); // SSresid + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), 0, 3); // F + pResMat->PutDouble(0.0, 1, 2); // RMSE + pResMat->PutDouble(0.0, 0, 1); // SigmaSlope + if (bConstant) + pResMat->PutDouble(0.0, 1, 1); //SigmaIntercept + else + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), 1, 1); + pResMat->PutDouble(1.0, 0, 2); // R^2 } - pResMat->PutDouble(_bRKP ? exp(m) : m, 0, 0); - pResMat->PutDouble(_bRKP ? exp(b) : b, 1, 0); - if (bStats) + else { - double fY = fCount*fSumSqrY-fSumY*fSumY; - double fSyx = fSumSqrY-b*fSumY-m*fSumXY; - double fR2 = f1*f1/(fX*fY); - pResMat->PutDouble (fR2, 0, 2); - if (fCount < 3.0) + double fFstatistic = (fSSreg / static_cast<double>(K)) + / (fSSresid / fDegreesFreedom); + pResMat->PutDouble(fFstatistic, 0, 3); + + // standard error of estimate + double fRMSE = sqrt(fSSresid / fDegreesFreedom); + pResMat->PutDouble(fRMSE, 1, 2); + + double fSigmaSlope = fRMSE / sqrt(fSumX2); + pResMat->PutDouble(fSigmaSlope, 0, 1); + + if (bConstant) { - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 1 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 1 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 ); + double fSigmaIntercept = fRMSE + * sqrt(fMeanX*fMeanX/fSumX2 + 1.0/static_cast<double>(N)); + pResMat->PutDouble(fSigmaIntercept, 1, 1); } else { - pResMat->PutDouble(sqrt(fSyx*fCount/(fX*(fCount-2.0))), 0, 1); - pResMat->PutDouble(sqrt(fSyx*fSumSqrX/fX/(fCount-2.0)), 1, 1); - pResMat->PutDouble( - sqrt((fCount*fSumSqrY - fSumY*fSumY - f1*f1/fX)/ - (fCount*(fCount-2.0))), 1, 2); - if (fR2 == 1.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 ); - else - pResMat->PutDouble(fR2*(fCount-2.0)/(1.0-fR2), 0, 3); + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), 1, 1); } - pResMat->PutDouble(((double)(nCY*nRY))-2.0, 1, 3); - pResMat->PutDouble(fY/fCount-fSyx, 0, 4); - pResMat->PutDouble(fSyx, 1, 4); + + double fR2 = fSSreg / (fSSreg + fSSresid); + pResMat->PutDouble(fR2, 0, 2); } } - } // if (nCase == 1) - if ( nCase != 1 ) + PushMatrix(pResMat); + } + else // calculate multiple regression; { - SCSIZE i, j, k; - if (!bStats) - pResMat = GetNewMat(M+1,1); - else - pResMat = GetNewMat(M+1,5); - if (!pResMat) + // Uses a QR decomposition X = QR. The solution B = (X'X)^(-1) * X' * Y + // becomes B = R^(-1) * Q' * Y + if (nCase ==2) // Y is column { - PushIllegalArgument(); - return; - } - ScMatrixRef pQ = GetNewMat(M+1, M+2); - ScMatrixRef pE = GetNewMat(M+2, 1); - ScMatrixRef pV = GetNewMat(M+1, 1); - pE->PutDouble(0.0, M+1); - pQ->FillDouble(0.0, 0, 0, M, M+1); - if (nCase == 2) - { - for (k = 0; k < N; k++) - { - double Yk = pMatY->GetDouble(k); - pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 ); - double sumYk = pQ->GetDouble(0, M+1) + Yk; - pQ->PutDouble( sumYk, 0, M+1 ); - pE->PutDouble( sumYk, 0 ); - for (i = 0; i < M; i++) - { - double Xik = pMatX->GetDouble(i,k); - double sumXik = pQ->GetDouble(0, i+1) + Xik; - pQ->PutDouble( sumXik, 0, i+1); - pQ->PutDouble( sumXik, i+1, 0); - double sumXikYk = pQ->GetDouble(i+1, M+1) + Xik * Yk; - pQ->PutDouble( sumXikYk, i+1, M+1); - pE->PutDouble( sumXikYk, i+1); - for (j = i; j < M; j++) - { - const double fVal = pMatX->GetDouble(j,k); - double sumXikXjk = pQ->GetDouble(j+1, i+1) + - Xik * fVal; - pQ->PutDouble( sumXikXjk, j+1, i+1); - pQ->PutDouble( sumXikXjk, i+1, j+1); - } - } + ::std::vector< double> aVecR(N); // for QR decomposition + // Enough memory for needed matrices? + ScMatrixRef pMeans = GetNewMat(K, 1); // mean of each column + ScMatrixRef pMatZ; // for Q' * Y , inter alia + if (bStats) + pMatZ = pMatY->Clone(); // Y is used in statistic, keep it + else + pMatZ = pMatY; // Y can be overwritten + ScMatrixRef pSlopes = GetNewMat(1,K); // from b1 to bK + if (!pMeans || !pMatZ || !pSlopes) + { + PushError(errCodeOverflow); + return; } - } - else - { - for (k = 0; k < N; k++) + if (bConstant) { - double Yk = pMatY->GetDouble(k); - pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 ); - double sumYk = pQ->GetDouble(0, M+1) + Yk; - pQ->PutDouble( sumYk, 0, M+1 ); - pE->PutDouble( sumYk, 0 ); - for (i = 0; i < M; i++) - { - double Xki = pMatX->GetDouble(k,i); - double sumXki = pQ->GetDouble(0, i+1) + Xki; - pQ->PutDouble( sumXki, 0, i+1); - pQ->PutDouble( sumXki, i+1, 0); - double sumXkiYk = pQ->GetDouble(i+1, M+1) + Xki * Yk; - pQ->PutDouble( sumXkiYk, i+1, M+1); - pE->PutDouble( sumXkiYk, i+1); - for (j = i; j < M; j++) - { - const double fVal = pMatX->GetDouble(k,j); - double sumXkiXkj = pQ->GetDouble(j+1, i+1) + - Xki * fVal; - pQ->PutDouble( sumXkiXkj, j+1, i+1); - pQ->PutDouble( sumXkiXkj, i+1, j+1); - } - } + lcl_CalculateColumnMeans(pMatX, pMeans, K, N); + lcl_CalculateColumnsDelta(pMatX, pMeans, K, N); } - } - if ( !Calculate4(_bRKP,pResMat,pQ,bConstant,N,M) ) - return; - - if (bStats) - Calculate(pResMat,pE,pQ,pV,pMatX,bConstant,N,M,nCase); - } - PushMatrix(pResMat); -} - -void ScInterpreter::ScRKP() -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScRKP" ); - CalulateRGPRKP(sal_True); -} -// ----------------------------------------------------------------------------- -bool ScInterpreter::Calculate4(sal_Bool _bExp,ScMatrixRef& pResMat,ScMatrixRef& pQ,sal_Bool bConstant,SCSIZE N,SCSIZE M) -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate4" ); - pQ->PutDouble((double)N, 0, 0); - if (bConstant) - { - SCSIZE S, L; - for (S = 0; S < M+1; S++) - { - SCSIZE i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) + if (!lcl_CalculateQRdecomposition(pMatX, aVecR, K, N)) { PushNoValue(); - return false; + return; } - double fVal; - for (L = 0; L < M+2; L++) + // Later on we will divide by elements of aVecR, so make sure + // that they aren't zero. + bool bIsSingular=false; + for (SCSIZE row=0; row < K && !bIsSingular; row++) + bIsSingular = bIsSingular || aVecR[row]==0.0; + if (bIsSingular) { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); + PushNoValue(); + return; } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 0; i < M+1; i++) + // Z = Q' Y; + for (SCSIZE col = 0; col < K; col++) { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } + lcl_ApplyHouseholderTransformation(pMatX, col, pMatZ, N); } - } - } - else - { - if ( !Calculate3(M,pQ) ) - return false; + // B = R^(-1) * Q' * Y <=> B = R^(-1) * Z <=> R * B = Z + // result Z should have zeros for index>=K; if not, ignore values + for (SCSIZE col = 0; col < K ; col++) + { + pSlopes->PutDouble( pMatZ->GetDouble(col), col); + } + lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K, false); + double fIntercept = 0.0; + if (bConstant) + fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K); + // Fill first line in result matrix + pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, K, 0 ); + for (SCSIZE i = 0; i < K; i++) + pResMat->PutDouble(_bRKP ? exp(pSlopes->GetDouble(i)) + : pSlopes->GetDouble(i) , K-1-i, 0); - } - for (SCSIZE i = 0; i < M+1; i++) - { - const double d = pQ->GetDouble(M-i,M+1); - pResMat->PutDouble(_bExp ? exp(d) : d, i, 0); - } // for (SCSIZE i = 0; i < M+1; i++) - return true; -} -ScMatrixRef ScInterpreter::Calculate2(const sal_Bool bConstant,const SCSIZE M ,const SCSIZE N,ScMatrixRef& pMatX,ScMatrixRef& pMatY,sal_uInt8 nCase) -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate2" ); - SCSIZE i, j, k; - ScMatrixRef pQ = GetNewMat(M+1, M+2); - ScMatrixRef pE = GetNewMat(M+2, 1); - pE->PutDouble(0.0, M+1); - pQ->FillDouble(0.0, 0, 0, M, M+1); - if (nCase == 2) - { - for (k = 0; k < N; k++) - { - pE->PutDouble( - pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); - pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); - pE->PutDouble(pQ->GetDouble(0, M+1), 0); - for (i = 0; i < M; i++) + if (bStats) { - pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(i,k), 0, i+1); - pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); - pQ->PutDouble(pQ->GetDouble(i+1, M+1) + - pMatX->GetDouble(i,k)*pMatY->GetDouble(k), i+1, M+1); - pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); - for (j = i; j < M; j++) + double fSSreg = 0.0; + double fSSresid = 0.0; + // re-use memory of Z; + pMatZ->FillDouble(0.0, 0, 0, 0, N-1); + // Z = R * Slopes + lcl_ApplyUpperRightTriangle(pMatX, aVecR, pSlopes, pMatZ, K, false); + // Z = Q * Z, that is Q * R * Slopes = X * Slopes + for (SCSIZE colp1 = K; colp1 > 0; colp1--) { - pQ->PutDouble(pQ->GetDouble(j+1, i+1) + - pMatX->GetDouble(i,k)*pMatX->GetDouble(j,k), j+1, i+1); - pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); + lcl_ApplyHouseholderTransformation(pMatX, colp1-1, pMatZ,N); } - } - } - } - else - { - for (k = 0; k < N; k++) - { - pE->PutDouble( - pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); - pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); - pE->PutDouble(pQ->GetDouble(0, M+1), 0); - for (i = 0; i < M; i++) - { - pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(k,i), 0, i+1); - pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); - pQ->PutDouble(pQ->GetDouble(i+1, M+1) + - pMatX->GetDouble(k,i)*pMatY->GetDouble(k), i+1, M+1); - pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); - for (j = i; j < M; j++) + fSSreg =lcl_GetSumProduct(pMatZ, pMatZ, N); + // re-use Y for residuals, Y = Y-Z + for (SCSIZE row = 0; row < N; row++) + pMatY->PutDouble(pMatY->GetDouble(row) - pMatZ->GetDouble(row), row); + fSSresid = lcl_GetSumProduct(pMatY, pMatY, N); + pResMat->PutDouble(fSSreg, 0, 4); + pResMat->PutDouble(fSSresid, 1, 4); + + double fDegreesFreedom =static_cast<double>( (bConstant) ? N-K-1 : N-K ); + pResMat->PutDouble(fDegreesFreedom, 1, 3); + + if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0) + { // exact fit; incl. observed values Y are identical + pResMat->PutDouble(0.0, 1, 4); // SSresid + // F = (SSreg/K) / (SSresid/df) = #DIV/0! + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), 0, 3); // F + // RMSE = sqrt(SSresid / df) = sqrt(0 / df) = 0 + pResMat->PutDouble(0.0, 1, 2); // RMSE + // SigmaSlope[i] = RMSE * sqrt(matrix[i,i]) = 0 * sqrt(...) = 0 + for (SCSIZE i=0; i<K; i++) + pResMat->PutDouble(0.0, K-1-i, 1); + + // SigmaIntercept = RMSE * sqrt(...) = 0 + if (bConstant) + pResMat->PutDouble(0.0, K, 1); //SigmaIntercept + else + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), K, 1); + + // R^2 = SSreg / (SSreg + SSresid) = 1.0 + pResMat->PutDouble(1.0, 0, 2); // R^2 + } + else { - pQ->PutDouble(pQ->GetDouble(j+1, i+1) + - pMatX->GetDouble(k, i)*pMatX->GetDouble(k, j), j+1, i+1); - pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); + double fFstatistic = (fSSreg / static_cast<double>(K)) + / (fSSresid / fDegreesFreedom); + pResMat->PutDouble(fFstatistic, 0, 3); + + // standard error of estimate = root mean SSE + double fRMSE = sqrt(fSSresid / fDegreesFreedom); + pResMat->PutDouble(fRMSE, 1, 2); + + // standard error of slopes + // = RMSE * sqrt(diagonal element of (R' R)^(-1) ) + // standard error of intercept + // = RMSE * sqrt( Xmean * (R' R)^(-1) * Xmean' + 1/N) + // (R' R)^(-1) = R^(-1) * (R')^(-1). Do not calculate it as + // a whole matrix, but iterate over unit vectors. + double fSigmaSlope = 0.0; + double fSigmaIntercept = 0.0; + double fPart; // for Xmean * single column of (R' R)^(-1) + for (SCSIZE col = 0; col < K; col++) + { + //re-use memory of MatZ + pMatZ->FillDouble(0.0,0,0,0,K-1); // Z = unit vector e + pMatZ->PutDouble(1.0, col); + //Solve R' * Z = e + lcl_SolveWithLowerLeftTriangle(pMatX, aVecR, pMatZ, K, false); + // Solve R * Znew = Zold + lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pMatZ, K, false); + // now Z is column col in (R' R)^(-1) + fSigmaSlope = fRMSE * sqrt(pMatZ->GetDouble(col)); + pResMat->PutDouble(fSigmaSlope, K-1-col, 1); + // (R' R) ^(-1) is symmetric + if (bConstant) + { + fPart = lcl_GetSumProduct(pMeans, pMatZ, K); + fSigmaIntercept += fPart * pMeans->GetDouble(col); + } + } + if (bConstant) + { + fSigmaIntercept = fRMSE + * sqrt(fSigmaIntercept + 1.0 / static_cast<double>(N)); + pResMat->PutDouble(fSigmaIntercept, K, 1); + } + else + { + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), K, 1); + } + + double fR2 = fSSreg / (fSSreg + fSSresid); + pResMat->PutDouble(fR2, 0, 2); } } + PushMatrix(pResMat); } - } - pQ->PutDouble((double)N, 0, 0); - if (bConstant) - { - SCSIZE S, L; - for (S = 0; S < M+1; S++) + else // nCase == 3, Y is row, all matrices are transposed { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) + ::std::vector< double> aVecR(N); // for QR decomposition + // Enough memory for needed matrices? + ScMatrixRef pMeans = GetNewMat(1, K); // mean of each row + ScMatrixRef pMatZ; // for Q' * Y , inter alia + if (bStats) + pMatZ = pMatY->Clone(); // Y is used in statistic, keep it + else + pMatZ = pMatY; // Y can be overwritten + ScMatrixRef pSlopes = GetNewMat(K,1); // from b1 to bK + if (!pMeans || !pMatZ || !pSlopes) + { + PushError(errCodeOverflow); + return; + } + if (bConstant) + { + lcl_CalculateRowMeans(pMatX, pMeans, N, K); + lcl_CalculateRowsDelta(pMatX, pMeans, N, K); + } + + if (!lcl_TCalculateQRdecomposition(pMatX, aVecR, K, N)) + { + PushNoValue(); + return; + } + + // Later on we will divide by elements of aVecR, so make sure + // that they aren't zero. + bool bIsSingular=false; + for (SCSIZE row=0; row < K && !bIsSingular; row++) + bIsSingular = bIsSingular || aVecR[row]==0.0; + if (bIsSingular) { PushNoValue(); - return ScMatrixRef(); + return; + } + // Z = Q' Y + for (SCSIZE row = 0; row < K; row++) + { + lcl_TApplyHouseholderTransformation(pMatX, row, pMatZ, N); } - double fVal; - for (L = 0; L < M+2; L++) + // B = R^(-1) * Q' * Y <=> B = R^(-1) * Z <=> R * B = Z + // result Z should have zeros for index>=K; if not, ignore values + for (SCSIZE col = 0; col < K ; col++) { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); + pSlopes->PutDouble( pMatZ->GetDouble(col), col); } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 0; i < M+1; i++) + lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K, true); + double fIntercept = 0.0; + if (bConstant) + fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K); + // Fill first line in result matrix + pResMat->PutDouble(_bRKP ? exp(fIntercept) : fIntercept, K, 0 ); + for (SCSIZE i = 0; i < K; i++) + pResMat->PutDouble(_bRKP ? exp(pSlopes->GetDouble(i)) + : pSlopes->GetDouble(i) , K-1-i, 0); + + + if (bStats) { - if (i != S) + double fSSreg = 0.0; + double fSSresid = 0.0; + // re-use memory of Z; + pMatZ->FillDouble(0.0, 0, 0, N-1, 0); + // Z = R * Slopes + lcl_ApplyUpperRightTriangle(pMatX, aVecR, pSlopes, pMatZ, K, true); + // Z = Q * Z, that is Q * R * Slopes = X * Slopes + for (SCSIZE rowp1 = K; rowp1 > 0; rowp1--) + { + lcl_TApplyHouseholderTransformation(pMatX, rowp1-1, pMatZ,N); + } + fSSreg =lcl_GetSumProduct(pMatZ, pMatZ, N); + // re-use Y for residuals, Y = Y-Z + for (SCSIZE col = 0; col < N; col++) + pMatY->PutDouble(pMatY->GetDouble(col) - pMatZ->GetDouble(col), col); + fSSresid = lcl_GetSumProduct(pMatY, pMatY, N); + pResMat->PutDouble(fSSreg, 0, 4); + pResMat->PutDouble(fSSresid, 1, 4); + + double fDegreesFreedom =static_cast<double>( (bConstant) ? N-K-1 : N-K ); + pResMat->PutDouble(fDegreesFreedom, 1, 3); + + if (fDegreesFreedom == 0.0 || fSSresid == 0.0 || fSSreg == 0.0) + { // exact fit; incl. case observed values Y are identical + pResMat->PutDouble(0.0, 1, 4); // SSresid + // F = (SSreg/K) / (SSresid/df) = #DIV/0! + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), 0, 3); // F + // RMSE = sqrt(SSresid / df) = sqrt(0 / df) = 0 + pResMat->PutDouble(0.0, 1, 2); // RMSE + // SigmaSlope[i] = RMSE * sqrt(matrix[i,i]) = 0 * sqrt(...) = 0 + for (SCSIZE i=0; i<K; i++) + pResMat->PutDouble(0.0, K-1-i, 1); + + // SigmaIntercept = RMSE * sqrt(...) = 0 + if (bConstant) + pResMat->PutDouble(0.0, K, 1); //SigmaIntercept + else + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), K, 1); + + // R^2 = SSreg / (SSreg + SSresid) = 1.0 + pResMat->PutDouble(1.0, 0, 2); // R^2 + } + else { - fVal = -pQ->GetDouble(i, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); + double fFstatistic = (fSSreg / static_cast<double>(K)) + / (fSSresid / fDegreesFreedom); + pResMat->PutDouble(fFstatistic, 0, 3); + + // standard error of estimate = root mean SSE + double fRMSE = sqrt(fSSresid / fDegreesFreedom); + pResMat->PutDouble(fRMSE, 1, 2); + + // standard error of slopes + // = RMSE * sqrt(diagonal element of (R' R)^(-1) ) + // standard error of intercept + // = RMSE * sqrt( Xmean * (R' R)^(-1) * Xmean' + 1/N) + // (R' R)^(-1) = R^(-1) * (R')^(-1). Do not calculate it as + // a whole matrix, but iterate over unit vectors. + // (R' R) ^(-1) is symmetric + double fSigmaSlope = 0.0; + double fSigmaIntercept = 0.0; + double fPart; // for Xmean * single col of (R' R)^(-1) + for (SCSIZE row = 0; row < K; row++) + { + //re-use memory of MatZ + pMatZ->FillDouble(0.0,0,0,K-1,0); // Z = unit vector e + pMatZ->PutDouble(1.0, row); + //Solve R' * Z = e + lcl_SolveWithLowerLeftTriangle(pMatX, aVecR, pMatZ, K, true); + // Solve R * Znew = Zold + lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pMatZ, K, true); + // now Z is column col in (R' R)^(-1) + fSigmaSlope = fRMSE * sqrt(pMatZ->GetDouble(row)); + pResMat->PutDouble(fSigmaSlope, K-1-row, 1); + if (bConstant) + { + fPart = lcl_GetSumProduct(pMeans, pMatZ, K); + fSigmaIntercept += fPart * pMeans->GetDouble(row); + } + } + if (bConstant) + { + fSigmaIntercept = fRMSE + * sqrt(fSigmaIntercept + 1.0 / static_cast<double>(N)); + pResMat->PutDouble(fSigmaIntercept, K, 1); + } + else + { + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), K, 1); + } + + double fR2 = fSSreg / (fSSreg + fSSresid); + pResMat->PutDouble(fR2, 0, 2); } } + PushMatrix(pResMat); } } - else - { - if ( !Calculate3(M,pQ) ) - return ScMatrixRef(); - } - return pQ; -} -bool ScInterpreter::Calculate3(const SCSIZE M ,ScMatrixRef& pQ) -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Calculate3" ); - SCSIZE S, L; - for (S = 1; S < M+1; S++) - { - SCSIZE i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) - { - PushNoValue(); - return ScMatrixRef(); - } - double fVal; - for (L = 1; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 1; i < M+1; i++) - { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } - } - pQ->PutDouble(0.0, 0, M+1); - } // for (S = 1; S < M+1; S++) - return true; + return; } void ScInterpreter::ScTrend() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTrend" ); - CalculateTrendGrowth(sal_False); + CalculateTrendGrowth(false); } -void ScInterpreter::CalculateTrendGrowth(sal_Bool _bGrowth) + +void ScInterpreter::ScGrowth() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGrowth" ); + CalculateTrendGrowth(true); +} + +void ScInterpreter::CalculateTrendGrowth(bool _bGrowth) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CalculateTrendGrowth" ); sal_uInt8 nParamCount = GetByte(); if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) return; - sal_Bool bConstant; + + // optional fourth parameter + bool bConstant; if (nParamCount == 4) bConstant = GetBool(); else - bConstant = sal_True; - ScMatrixRef pMatX; - ScMatrixRef pMatY; + bConstant = true; + + // The third parameter may be missing in ODF, although the fourth parameter + // is present. Default values depend on data not yet read. ScMatrixRef pMatNewX; if (nParamCount >= 3) - pMatNewX = GetMatrix(); + { + if (IsMissing()) + { + Pop(); + pMatNewX = NULL; + } + else + pMatNewX = GetMatrix(); + } else pMatNewX = NULL; + + // In ODF1.2 empty second parameter (which is two ;; ) is allowed. + // Defaults will be set in CheckMatrix. + ScMatrixRef pMatX; if (nParamCount >= 2) - pMatX = GetMatrix(); + { + if (IsMissing()) + { + Pop(); + pMatX = NULL; + } + else + { + pMatX = GetMatrix(); + } + } else pMatX = NULL; + + ScMatrixRef pMatY; pMatY = GetMatrix(); if (!pMatY) { PushIllegalParameter(); return; - } // if (!pMatY) + } + + // 1 = simple; 2 = multiple with Y as column; 3 = multiple with Y as row + sal_uInt8 nCase; - sal_uInt8 nCase; // 1 = normal, 2,3 = mehrfach - SCSIZE nCX, nCY; - SCSIZE nRX, nRY; - SCSIZE M = 0, N = 0; - if ( !CheckMatrix(_bGrowth,sal_True,nCase,nCX,nCY,nRX,nRY,M,N,pMatX,pMatY) ) + SCSIZE nCX, nCY; // number of columns + SCSIZE nRX, nRY; // number of rows + SCSIZE K = 0, N = 0; // K=number of variables X, N=number of data samples + if ( !CheckMatrix(_bGrowth,nCase,nCX,nCY,nRX,nRY,K,N,pMatX,pMatY) ) + { + PushIllegalParameter(); return; + } + // Enough data samples? + if ( (bConstant && (N<K+1)) || (!bConstant && (N<K)) || (N<1) || (K<1) ) + { + PushIllegalParameter(); + return; + } + // Set default pMatNewX if necessary SCSIZE nCXN, nRXN; SCSIZE nCountXN; if (!pMatNewX) @@ -2599,12 +2961,12 @@ void ScInterpreter::CalculateTrendGrowth(sal_Bool _bGrowth) nCXN = nCX; nRXN = nRX; nCountXN = nCXN * nRXN; - pMatNewX = pMatX; + pMatNewX = pMatX->Clone(); // pMatX will be changed to X-meanX } else { pMatNewX->GetDimensions(nCXN, nRXN); - if ((nCase == 2 && nCX != nCXN) || (nCase == 3 && nRX != nRXN)) + if ((nCase == 2 && K != nCXN) || (nCase == 3 && K != nRXN)) { PushIllegalArgument(); return; @@ -2617,109 +2979,205 @@ void ScInterpreter::CalculateTrendGrowth(sal_Bool _bGrowth) return; } } - ScMatrixRef pResMat; + ScMatrixRef pResMat; // size depends on nCase if (nCase == 1) + pResMat = GetNewMat(nCXN,nRXN); + else + { + if (nCase==2) + pResMat = GetNewMat(1,nRXN); + else + pResMat = GetNewMat(nCXN,1); + } + if (!pResMat) + { + PushError(errCodeOverflow); + return; + } + // Uses sum(x-MeanX)^2 and not [sum x^2]-N * MeanX^2 in case bConstant. + // Clone constant matrices, so that Mat = Mat - Mean is possible. + double fMeanY = 0.0; + if (bConstant) { - double fCount = 0.0; - double fSumX = 0.0; - double fSumSqrX = 0.0; - double fSumY = 0.0; - double fSumSqrY = 0.0; - double fSumXY = 0.0; - double fValX, fValY; - SCSIZE i; - for (i = 0; i < nCY; i++) - for (SCSIZE j = 0; j < nRY; j++) - { - fValX = pMatX->GetDouble(i,j); - fValY = pMatY->GetDouble(i,j); - fSumX += fValX; - fSumSqrX += fValX * fValX; - fSumY += fValY; - fSumSqrY += fValY * fValY; - fSumXY += fValX*fValY; - fCount++; - } - if (fCount < 1.0) + ScMatrixRef pCopyX = pMatX->CloneIfConst(); + ScMatrixRef pCopyY = pMatY->CloneIfConst(); + if (!pCopyX || !pCopyY) { - PushNoValue(); + PushError(errStackOverflow); return; } - else + pMatX = pCopyX; + pMatY = pCopyY; + // DeltaY is possible here; DeltaX depends on nCase, so later + fMeanY = lcl_GetMeanOverAll(pMatY, N); + for (SCSIZE i=0; i<N; i++) { - double f1 = fCount*fSumXY-fSumX*fSumY; - double fX = fCount*fSumSqrX-fSumX*fSumX; - double b, m; - if (bConstant) - { - b = fSumY/fCount - f1/fX*fSumX/fCount; - m = f1/fX; - } - else + pMatY->PutDouble( ::rtl::math::approxSub(pMatY->GetDouble(i),fMeanY), i ); + } + } + + if (nCase==1) + { + // calculate simple regression + double fMeanX = 0.0; + if (bConstant) + { // Mat = Mat - Mean + fMeanX = lcl_GetMeanOverAll(pMatX, N); + for (SCSIZE i=0; i<N; i++) { - b = 0.0; - m = fSumXY/fSumSqrX; + pMatX->PutDouble( ::rtl::math::approxSub(pMatX->GetDouble(i),fMeanX), i ); } - pResMat = GetNewMat(nCXN, nRXN); - if (!pResMat) + } + double fSumXY = lcl_GetSumProduct(pMatX,pMatY,N); + double fSumX2 = lcl_GetSumProduct(pMatX,pMatX,N); + if (fSumX2==0.0) + { + PushNoValue(); // all x-values are identical + return; + } + double fSlope = fSumXY / fSumX2; + double fIntercept = 0.0; + double fHelp; + if (bConstant) + { + fIntercept = fMeanY - fSlope * fMeanX; + for (SCSIZE i = 0; i < nCountXN; i++) { - PushIllegalArgument(); - return; + fHelp = pMatNewX->GetDouble(i)*fSlope + fIntercept; + pResMat->PutDouble(_bGrowth ? exp(fHelp) : fHelp, i); } - for (i = 0; i < nCountXN; i++) + } + else + { + for (SCSIZE i = 0; i < nCountXN; i++) { - const double d = pMatNewX->GetDouble(i)*m+b; - pResMat->PutDouble(_bGrowth ? exp(d) : d, i); + fHelp = pMatNewX->GetDouble(i)*fSlope; + pResMat->PutDouble(_bGrowth ? exp(fHelp) : fHelp, i); } } } - else + else // calculate multiple regression; { - ScMatrixRef pQ = Calculate2(bConstant,M ,N,pMatX,pMatY,nCase); - if ( !pQ.Is() ) - return; - if (nCase == 2) + if (nCase ==2) // Y is column { - pResMat = GetNewMat(1, nRXN); - if (!pResMat) + ::std::vector< double> aVecR(N); // for QR decomposition + // Enough memory for needed matrices? + ScMatrixRef pMeans = GetNewMat(K, 1); // mean of each column + ScMatrixRef pSlopes = GetNewMat(1,K); // from b1 to bK + if (!pMeans || !pSlopes) { - PushIllegalArgument(); + PushError(errCodeOverflow); + return; + } + if (bConstant) + { + lcl_CalculateColumnMeans(pMatX, pMeans, K, N); + lcl_CalculateColumnsDelta(pMatX, pMeans, K, N); + } + if (!lcl_CalculateQRdecomposition(pMatX, aVecR, K, N)) + { + PushNoValue(); + return; + } + // Later on we will divide by elements of aVecR, so make sure + // that they aren't zero. + bool bIsSingular=false; + for (SCSIZE row=0; row < K && !bIsSingular; row++) + bIsSingular = bIsSingular || aVecR[row]==0.0; + if (bIsSingular) + { + PushNoValue(); return; } - double fVal; - for (SCSIZE i = 0; i < nRXN; i++) + // Z := Q' Y; Y is overwritten with result Z + for (SCSIZE col = 0; col < K; col++) + { + lcl_ApplyHouseholderTransformation(pMatX, col, pMatY, N); + } + // B = R^(-1) * Q' * Y <=> B = R^(-1) * Z <=> R * B = Z + // result Z should have zeros for index>=K; if not, ignore values + for (SCSIZE col = 0; col < K ; col++) + { + pSlopes->PutDouble( pMatY->GetDouble(col), col); + } + lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K, false); + + // Fill result matrix + lcl_MFastMult(pMatNewX,pSlopes,pResMat,nRXN,K,1); + if (bConstant) + { + double fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K); + for (SCSIZE row = 0; row < nRXN; row++) + pResMat->PutDouble(pResMat->GetDouble(row)+fIntercept, row); + } + if (_bGrowth) { - fVal = pQ->GetDouble(0, M+1); - for (SCSIZE j = 0; j < M; j++) - fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(j, i); - pResMat->PutDouble(_bGrowth ? exp(fVal) : fVal, i); + for (SCSIZE i = 0; i < nRXN; i++) + pResMat->PutDouble(exp(pResMat->GetDouble(i)), i); } } else - { - pResMat = GetNewMat(nCXN, 1); - if (!pResMat) + { // nCase == 3, Y is row, all matrices are transposed + + ::std::vector< double> aVecR(N); // for QR decomposition + // Enough memory for needed matrices? + ScMatrixRef pMeans = GetNewMat(1, K); // mean of each row + ScMatrixRef pSlopes = GetNewMat(K,1); // row from b1 to bK + if (!pMeans || !pSlopes) { - PushIllegalArgument(); + PushError(errCodeOverflow); + return; + } + if (bConstant) + { + lcl_CalculateRowMeans(pMatX, pMeans, N, K); + lcl_CalculateRowsDelta(pMatX, pMeans, N, K); + } + if (!lcl_TCalculateQRdecomposition(pMatX, aVecR, K, N)) + { + PushNoValue(); + return; + } + // Later on we will divide by elements of aVecR, so make sure + // that they aren't zero. + bool bIsSingular=false; + for (SCSIZE row=0; row < K && !bIsSingular; row++) + bIsSingular = bIsSingular || aVecR[row]==0.0; + if (bIsSingular) + { + PushNoValue(); return; } - double fVal; - for (SCSIZE i = 0; i < nCXN; i++) + // Z := Q' Y; Y is overwritten with result Z + for (SCSIZE row = 0; row < K; row++) + { + lcl_TApplyHouseholderTransformation(pMatX, row, pMatY, N); + } + // B = R^(-1) * Q' * Y <=> B = R^(-1) * Z <=> R * B = Z + // result Z should have zeros for index>=K; if not, ignore values + for (SCSIZE col = 0; col < K ; col++) + { + pSlopes->PutDouble( pMatY->GetDouble(col), col); + } + lcl_SolveWithUpperRightTriangle(pMatX, aVecR, pSlopes, K, true); + + // Fill result matrix + lcl_MFastMult(pSlopes,pMatNewX,pResMat,1,K,nCXN); + if (bConstant) + { + double fIntercept = fMeanY - lcl_GetSumProduct(pMeans,pSlopes,K); + for (SCSIZE col = 0; col < nCXN; col++) + pResMat->PutDouble(pResMat->GetDouble(col)+fIntercept, col); + } + if (_bGrowth) { - fVal = pQ->GetDouble(0, M+1); - for (SCSIZE j = 0; j < M; j++) - fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(i, j); - pResMat->PutDouble(_bGrowth ? exp(fVal) : fVal, i); + for (SCSIZE i = 0; i < nCXN; i++) + pResMat->PutDouble(exp(pResMat->GetDouble(i)), i); } } } PushMatrix(pResMat); -} - -void ScInterpreter::ScGrowth() -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGrowth" ); - CalculateTrendGrowth(sal_True); + return; } void ScInterpreter::ScMatRef() diff --git a/sc/source/core/tool/rangeseq.cxx b/sc/source/core/tool/rangeseq.cxx index ac1934302b6e..78ff7259e031 100644 --- a/sc/source/core/tool/rangeseq.cxx +++ b/sc/source/core/tool/rangeseq.cxx @@ -39,6 +39,7 @@ #include "rangeseq.hxx" #include "document.hxx" +#include "dociter.hxx" #include "scmatrix.hxx" #include "cell.hxx" @@ -46,6 +47,20 @@ using namespace com::sun::star; //------------------------------------------------------------------------ +bool lcl_HasErrors( ScDocument* pDoc, const ScRange& rRange ) +{ + // no need to look at empty cells - just use ScCellIterator + ScCellIterator aIter( pDoc, rRange ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell) + { + if ( pCell->GetCellType() == CELLTYPE_FORMULA && static_cast<ScFormulaCell*>(pCell)->GetErrCode() != 0 ) + return true; + pCell = aIter.GetNext(); + } + return false; // no error found +} + long lcl_DoubleToLong( double fVal ) { double fInt = (fVal >= 0.0) ? ::rtl::math::approxFloor( fVal ) : @@ -78,7 +93,7 @@ sal_Bool ScRangeToSequence::FillLongArray( uno::Any& rAny, ScDocument* pDoc, con } rAny <<= aRowSeq; - return sal_True; //! check for errors + return !lcl_HasErrors( pDoc, rRange ); } @@ -134,7 +149,7 @@ sal_Bool ScRangeToSequence::FillDoubleArray( uno::Any& rAny, ScDocument* pDoc, c } rAny <<= aRowSeq; - return sal_True; //! check for errors + return !lcl_HasErrors( pDoc, rRange ); } @@ -176,7 +191,7 @@ sal_Bool ScRangeToSequence::FillStringArray( uno::Any& rAny, ScDocument* pDoc, c long nColCount = rRange.aEnd.Col() + 1 - rRange.aStart.Col(); long nRowCount = rRange.aEnd.Row() + 1 - rRange.aStart.Row(); - String aDocStr; + bool bHasErrors = false; uno::Sequence< uno::Sequence<rtl::OUString> > aRowSeq( nRowCount ); uno::Sequence<rtl::OUString>* pRowAry = aRowSeq.getArray(); @@ -186,14 +201,17 @@ sal_Bool ScRangeToSequence::FillStringArray( uno::Any& rAny, ScDocument* pDoc, c rtl::OUString* pColAry = aColSeq.getArray(); for (long nCol = 0; nCol < nColCount; nCol++) { - pDoc->GetString( (SCCOL)(nStartCol+nCol), (SCROW)(nStartRow+nRow), nTab, aDocStr ); - pColAry[nCol] = rtl::OUString( aDocStr ); + sal_uInt16 nErrCode = pDoc->GetStringForFormula( + ScAddress((SCCOL)(nStartCol+nCol), (SCROW)(nStartRow+nRow), nTab), + pColAry[nCol] ); + if ( nErrCode != 0 ) + bHasErrors = true; } pRowAry[nRow] = aColSeq; } rAny <<= aRowSeq; - return sal_True; //! check for errors + return !bHasErrors; } diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index a270969e100c..83ee5d365e63 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -561,6 +561,9 @@ sal_Bool ScToken::Is3DRef() const if ( GetSingleRef().IsFlag3D() ) return sal_True; break; + case svExternalSingleRef: + case svExternalDoubleRef: + return sal_True; default: { // added to avoid warnings @@ -922,6 +925,14 @@ ScExternalDoubleRefToken::ScExternalDoubleRefToken( const ScExternalDoubleRefTok { } +ScExternalDoubleRefToken::ScExternalDoubleRefToken( const ScExternalSingleRefToken& r ) : + ScToken( svExternalDoubleRef, ocExternalRef), + mnFileId( r.GetIndex()), + maTabName( r.GetString()) +{ + maDoubleRef.Ref1 = maDoubleRef.Ref2 = r.GetSingleRef(); +} + ScExternalDoubleRefToken::~ScExternalDoubleRefToken() { } @@ -1825,6 +1836,20 @@ void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos, } } break; + case svExternalDoubleRef: + { + ScSingleRefData& rRef2 = static_cast<ScToken*>(pCode[j])->GetSingleRef2(); + rRef2.CalcAbsIfRel( rOldPos ); + rRef2.CalcRelFromAbs( rNewPos ); + } + //! fallthru + case svExternalSingleRef: + { + ScSingleRefData& rRef1 = static_cast<ScToken*>(pCode[j])->GetSingleRef(); + rRef1.CalcAbsIfRel( rOldPos ); + rRef1.CalcRelFromAbs( rNewPos ); + } + break; default: { // added to avoid warnings diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx index 00862032603c..ea2225915026 100644 --- a/sc/source/filter/excel/excform.cxx +++ b/sc/source/filter/excel/excform.cxx @@ -84,8 +84,6 @@ void ImportExcel::Formula25() bShrFmla = nFlag0 & 0x08; // shared or not shared } - nLastXF = nXF; - Formula( aXclPos, nXF, nFormLen, fCurVal, bShrFmla ); } @@ -107,8 +105,6 @@ void ImportExcel::Formula4() aIn.Ignore( 1 ); aIn >> nFormLen; - nLastXF = nXF; - Formula( aXclPos, nXF, nFormLen, fCurVal, sal_False ); } diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx index f55911f3f3fb..b5bb9e6e79ce 100644 --- a/sc/source/filter/excel/impop.cxx +++ b/sc/source/filter/excel/impop.cxx @@ -123,11 +123,13 @@ ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ): XclImpRoot( rImpData ), maStrm( rStrm, GetRoot() ), aIn( maStrm ), - maScOleSize( ScAddress::INITIALIZE_INVALID ) + maScOleSize( ScAddress::INITIALIZE_INVALID ), + mnLastRefIdx( 0 ), + mnIxfeIndex( 0 ), + mbBiff2HasXfs( false ), + mbBiff2HasXfsValid( false ) { - mnLastRefIdx = 0; nBdshtTab = 0; - nIxfeIndex = 0; // zur Sicherheit auf 0 // Root-Daten fuellen - nach new's ohne Root als Parameter pExcRoot = &GetOldRoot(); @@ -193,17 +195,40 @@ void ImportExcel::ReadFileSharing() } } -sal_uInt16 ImportExcel::ReadXFIndex( bool bBiff2 ) +sal_uInt16 ImportExcel::ReadXFIndex( const ScAddress& rScPos, bool bBiff2 ) { sal_uInt16 nXFIdx = 0; if( bBiff2 ) { - sal_uInt8 nXFIdx2; - maStrm >> nXFIdx2; - maStrm.Ignore( 2 ); - nXFIdx = nXFIdx2 & 0x3F; - if( nXFIdx == 63 ) - nXFIdx = nIxfeIndex; + /* #i71453# On first call, check if the file contains XF records (by + trying to access the first XF with index 0). If there are no XFs, + the explicit formatting information contained in each cell record + will be used instead. */ + if( !mbBiff2HasXfsValid ) + { + mbBiff2HasXfsValid = true; + mbBiff2HasXfs = GetXFBuffer().GetXF( 0 ) != 0; + } + // read formatting information (includes the XF identifier) + sal_uInt8 nFlags1, nFlags2, nFlags3; + maStrm >> nFlags1 >> nFlags2 >> nFlags3; + /* If the file contains XFs, extract and set the XF identifier, + otherwise get the explicit formatting. */ + if( mbBiff2HasXfs ) + { + nXFIdx = ::extract_value< sal_uInt16 >( nFlags1, 0, 6 ); + /* If the identifier is equal to 63, then the real identifier is + contained in the preceding IXFE record (stored in mnBiff2XfId). */ + if( nXFIdx == 63 ) + nXFIdx = mnIxfeIndex; + } + else + { + /* Let the XclImpXF class do the conversion of the imported + formatting. The XF buffer is empty, therefore will not do any + conversion based on the XF index later on. */ + XclImpXF::ApplyPatternForBiff2CellFormat( GetRoot(), rScPos, nFlags1, nFlags2, nFlags3 ); + } } else aIn >> nXFIdx; @@ -258,7 +283,7 @@ void ImportExcel::ReadBlank() ScAddress aScPos( ScAddress::UNINITIALIZED ); if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) ) { - sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_BLANK ); + sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_BLANK ); GetXFRangeBuffer().SetBlankXF( aScPos, nXFIdx ); } @@ -272,7 +297,7 @@ void ImportExcel::ReadInteger() ScAddress aScPos( ScAddress::UNINITIALIZED ); if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) ) { - sal_uInt16 nXFIdx = ReadXFIndex( true ); + sal_uInt16 nXFIdx = ReadXFIndex( aScPos, true ); sal_uInt16 nValue; maStrm >> nValue; @@ -289,7 +314,7 @@ void ImportExcel::ReadNumber() ScAddress aScPos( ScAddress::UNINITIALIZED ); if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) ) { - sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_NUMBER ); + sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_NUMBER ); double fValue; maStrm >> fValue; @@ -312,7 +337,7 @@ void ImportExcel::ReadLabel() 0x0204 2-7 2 byte 16-bit length, byte string 0x0204 8 2 byte 16-bit length, unicode string */ bool bBiff2 = maStrm.GetRecId() == EXC_ID2_LABEL; - sal_uInt16 nXFIdx = ReadXFIndex( bBiff2 ); + sal_uInt16 nXFIdx = ReadXFIndex( aScPos, bBiff2 ); XclStrFlags nFlags = (bBiff2 && (GetBiff() <= EXC_BIFF5)) ? EXC_STR_8BITLENGTH : EXC_STR_DEFAULT; XclImpString aString; @@ -337,7 +362,7 @@ void ImportExcel::ReadBoolErr() ScAddress aScPos( ScAddress::UNINITIALIZED ); if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) ) { - sal_uInt16 nXFIdx = ReadXFIndex( maStrm.GetRecId() == EXC_ID2_BOOLERR ); + sal_uInt16 nXFIdx = ReadXFIndex( aScPos, maStrm.GetRecId() == EXC_ID2_BOOLERR ); sal_uInt8 nValue, nType; maStrm >> nValue >> nType; @@ -362,7 +387,7 @@ void ImportExcel::ReadRk() ScAddress aScPos( ScAddress::UNINITIALIZED ); if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) ) { - sal_uInt16 nXFIdx = ReadXFIndex( false ); + sal_uInt16 nXFIdx = ReadXFIndex( aScPos, false ); sal_Int32 nRk; maStrm >> nRk; @@ -628,7 +653,7 @@ void ImportExcel::Codepage( void ) void ImportExcel::Ixfe( void ) { - aIn >> nIxfeIndex; + maStrm >> mnIxfeIndex; } diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 55f1f97ceea0..5bbd3ccaa9ec 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -836,11 +836,56 @@ FltError ImportExcel8::Read( void ) if( eAkt == EXC_STATE_BEFORE_SHEET ) { sal_uInt16 nScTab = GetCurrScTab(); - if( nScTab < maSheetOffsets.size() ) + if( nScTab < maSheetOffsets.size() ) { - nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos); + nProgressBaseSize += (maStrm.GetSvStreamPos() - nProgressBasePos); nProgressBasePos = maSheetOffsets[ nScTab ]; - aIn.StartNextRecord( nProgressBasePos ); + maStrm.StartNextRecord( nProgressBasePos ); + + // #94191# import only 256 sheets + if( nScTab > GetScMaxPos().Tab() ) + { + if( maStrm.GetRecId() != EXC_ID_EOF ) + XclTools::SkipSubStream( maStrm ); + // #i29930# show warning box + GetAddressConverter().CheckScTab( nScTab, true ); + eAkt = EXC_STATE_END; + } + else + { + // #i109800# SHEET record may point to any record inside the sheet substream + bool bIsBof = maStrm.GetRecId() == EXC_ID5_BOF; + if( bIsBof ) + Bof5(); // read the BOF record + else + pExcRoot->eDateiTyp = Biff8; // on missing BOF, assume a standard worksheet + + NeueTabelle(); + switch( pExcRoot->eDateiTyp ) + { + case Biff8: // worksheet + case Biff8M4: // macro sheet + eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch + // go to next record + if( bIsBof ) maStrm.StartNextRecord(); + maStrm.StoreGlobalPosition(); + break; + case Biff8C: // chart sheet + GetCurrSheetDrawing().ReadTabChart( maStrm ); + Eof(); + GetTracer().TraceChartOnlySheet(); + break; + case Biff8W: // workbook + DBG_ERRORFILE( "ImportExcel8::Read - double workbook globals" ); + // run through + case Biff8V: // VB module + default: + // TODO: do not create a sheet in the Calc document + pD->SetVisible( GetCurrScTab(), sal_False ); + XclTools::SkipSubStream( maStrm ); + IncCurrScTab(); + } + } } else eAkt = EXC_STATE_END; @@ -1018,51 +1063,6 @@ FltError ImportExcel8::Read( void ) break; // ---------------------------------------------------------------- - // before worksheet: wait for new worksheet BOF - case EXC_STATE_BEFORE_SHEET: - { - if( nRecId == EXC_ID5_BOF ) - { - // #94191# import only 256 sheets - if( GetCurrScTab() > GetScMaxPos().Tab() ) - { - XclTools::SkipSubStream( maStrm ); - // #i29930# show warning box - GetAddressConverter().CheckScTab( GetCurrScTab(), true ); - eAkt = EXC_STATE_END; - } - else - { - Bof5(); - NeueTabelle(); - switch( pExcRoot->eDateiTyp ) - { - case Biff8: // worksheet - case Biff8M4: // macro sheet - eAkt = EXC_STATE_SHEET_PRE; // Shrfmla Prefetch, Row-Prefetch - aIn.StoreGlobalPosition(); - break; - case Biff8C: // chart sheet - GetCurrSheetDrawing().ReadTabChart( maStrm ); - Eof(); - GetTracer().TraceChartOnlySheet(); - break; - case Biff8W: // workbook - DBG_ERRORFILE( "ImportExcel8::Read - double workbook globals" ); - // run through - case Biff8V: // VB module - default: - // TODO: do not create a sheet in the Calc document - pD->SetVisible( GetCurrScTab(), sal_False ); - XclTools::SkipSubStream( maStrm ); - IncCurrScTab(); - } - } - } - } - break; - - // ---------------------------------------------------------------- // prefetch for worksheet case EXC_STATE_SHEET_PRE: { diff --git a/sc/source/filter/excel/xechart.cxx b/sc/source/filter/excel/xechart.cxx index 07b4a76a9c82..6aab83a050f7 100644 --- a/sc/source/filter/excel/xechart.cxx +++ b/sc/source/filter/excel/xechart.cxx @@ -718,7 +718,7 @@ bool XclExpChEscherFormat::HasSubRecords() const void XclExpChEscherFormat::WriteSubRecords( XclExpStream& rStrm ) { rStrm.StartRecord( EXC_ID_CHPICFORMAT, 14 ); - rStrm << maPicFmt.mnBmpMode << maPicFmt.mnFormat << maPicFmt.mnFlags << maPicFmt.mfScale; + rStrm << maPicFmt.mnBmpMode << sal_uInt16( 0 ) << maPicFmt.mnFlags << maPicFmt.mfScale; rStrm.EndRecord(); } diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx index 7b3f84c42643..429d15f3dbfa 100644 --- a/sc/source/filter/excel/xeformula.cxx +++ b/sc/source/filter/excel/xeformula.cxx @@ -28,11 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" -// XXX xelink.hxx MUST be included before xeformula.hxx because of the -// redifinition of the CREATE_OUSTRING() macro, which is in oox/helper.hxx -// (indirectly included via xelink.hxx) and ../inc/ftools.hxx (indirectly -// included via xeformula.hxx) that does an undef first. Ugly. -#include "xelink.hxx" #include "xeformula.hxx" #include <list> @@ -46,6 +41,7 @@ #include "token.hxx" #include "tokenarray.hxx" #include "xehelper.hxx" +#include "xelink.hxx" #include "xename.hxx" #include "xestream.hxx" @@ -508,7 +504,7 @@ XclExpFmlaCompImpl::XclExpFmlaCompImpl( const XclExpRoot& rRoot ) : mnMaxRowMask( static_cast< sal_uInt16 >( rRoot.GetXclMaxPos().Row() ) ) { // build the configuration map - for( const XclExpCompConfig* pEntry = spConfigTable; pEntry != STATIC_TABLE_END( spConfigTable ); ++pEntry ) + for( const XclExpCompConfig* pEntry = spConfigTable; pEntry != STATIC_ARRAY_END( spConfigTable ); ++pEntry ) maCfgMap[ pEntry->meType ] = *pEntry; } @@ -1439,7 +1435,11 @@ void XclExpFmlaCompImpl::PrepareFunction( XclExpFuncData& rFuncData ) { switch( rFuncData.GetOpCode() ) { + case ocCosecant: // simulate CSC(x) by (1/SIN(x)) + case ocSecant: // simulate SEC(x) by (1/COS(x)) case ocCot: // simulate COT(x) by (1/TAN(x)) + case ocCosecantHyp: // simulate CSCH(x) by (1/SINH(x)) + case ocSecantHyp: // simulate SECH(x) by (1/COSH(x)) case ocCotHyp: // simulate COTH(x) by (1/TANH(x)) AppendIntToken( 1 ); break; @@ -1489,7 +1489,11 @@ void XclExpFmlaCompImpl::FinishFunction( XclExpFuncData& rFuncData, sal_uInt8 nC FinishChooseFunction( rFuncData ); break; + case ocCosecant: // simulate CSC(x) by (1/SIN(x)) + case ocSecant: // simulate SEC(x) by (1/COS(x)) case ocCot: // simulate COT(x) by (1/TAN(x)) + case ocCosecantHyp: // simulate CSCH(x) by (1/SINH(x)) + case ocSecantHyp: // simulate SECH(x) by (1/COSH(x)) case ocCotHyp: // simulate COTH(x) by (1/TANH(x)) AppendBinaryOperatorToken( EXC_TOKID_DIV, true ); AppendParenToken(); diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx index b5eb50f7941b..f38b941cdfce 100644 --- a/sc/source/filter/excel/xepivot.cxx +++ b/sc/source/filter/excel/xepivot.cxx @@ -976,8 +976,10 @@ const String& XclExpPTItem::GetItemName() const void XclExpPTItem::SetPropertiesFromMember( const ScDPSaveMember& rSaveMem ) { - ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, !rSaveMem.GetIsVisible() ); - ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, !rSaveMem.GetShowDetails() ); + // #i115659# GetIsVisible() is not valid if HasIsVisible() returns false, default is 'visible' then + ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, rSaveMem.HasIsVisible() && !rSaveMem.GetIsVisible() ); + // #i115659# GetShowDetails() is not valid if HasShowDetails() returns false, default is 'show detail' then + ::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, rSaveMem.HasShowDetails() && !rSaveMem.GetShowDetails() ); // visible name const OUString* pVisName = rSaveMem.GetLayoutName(); @@ -1072,8 +1074,8 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim ) DBG_ASSERT( eOrient != DataPilotFieldOrientation_DATA, "XclExpPTField::SetPropertiesFromDim - called for data field" ); maFieldInfo.AddApiOrient( eOrient ); - // show empty items - ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.GetShowEmpty() ); + // show empty items (#i115659# GetShowEmpty() is not valid if HasShowEmpty() returns false, default is false then) + ::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.HasShowEmpty() && rSaveDim.GetShowEmpty() ); // visible name const OUString* pLayoutName = rSaveDim.GetLayoutName(); diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx index dcd9fc5db164..c2d61921c924 100644 --- a/sc/source/filter/excel/xichart.cxx +++ b/sc/source/filter/excel/xichart.cxx @@ -373,12 +373,12 @@ void XclImpChRoot::ConvertAreaFormat( ScfPropertySet& rPropSet, } void XclImpChRoot::ConvertEscherFormat( ScfPropertySet& rPropSet, - const XclChEscherFormat& rEscherFmt, const XclChPicFormat& rPicFmt, - XclChPropertyMode ePropMode ) const + const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt, + sal_uInt32 nDffFillType, XclChPropertyMode ePropMode ) const { GetChartPropSetHelper().WriteEscherProperties( rPropSet, *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable, - rEscherFmt, rPicFmt, ePropMode ); + rEscherFmt, pPicFmt, nDffFillType, ePropMode ); } void XclImpChRoot::ConvertFont( ScfPropertySet& rPropSet, @@ -526,7 +526,8 @@ void XclImpChAreaFormat::Convert( const XclImpChRoot& rRoot, // ---------------------------------------------------------------------------- -XclImpChEscherFormat::XclImpChEscherFormat( const XclImpRoot& rRoot ) +XclImpChEscherFormat::XclImpChEscherFormat( const XclImpRoot& rRoot ) : + mnDffFillType( mso_fillSolid ) { maData.mxItemSet.reset( new SfxItemSet( rRoot.GetDoc().GetDrawLayer()->GetItemPool() ) ); @@ -540,9 +541,8 @@ void XclImpChEscherFormat::ReadHeaderRecord( XclImpStream& rStrm ) rStrm >> aPropSet; // get the data aPropSet.FillToItemSet( *maData.mxItemSet ); - // get bitmap mode from DFF item set - sal_uInt32 nType = aPropSet.GetPropertyValue( DFF_Prop_fillType, mso_fillSolid ); - maPicFmt.mnBmpMode = (nType == mso_fillPicture) ? EXC_CHPICFORMAT_STRETCH : EXC_CHPICFORMAT_STACK; + // get fill type from DFF property set + mnDffFillType = aPropSet.GetPropertyValue( DFF_Prop_fillType, mso_fillSolid ); } void XclImpChEscherFormat::ReadSubRecord( XclImpStream& rStrm ) @@ -550,16 +550,18 @@ void XclImpChEscherFormat::ReadSubRecord( XclImpStream& rStrm ) switch( rStrm.GetRecId() ) { case EXC_ID_CHPICFORMAT: - rStrm >> maPicFmt.mnBmpMode >> maPicFmt.mnFormat >> maPicFmt.mnFlags >> maPicFmt.mfScale; + rStrm >> maPicFmt.mnBmpMode; + rStrm.Ignore( 2 ); + rStrm >> maPicFmt.mnFlags >> maPicFmt.mfScale; break; } } void XclImpChEscherFormat::Convert( const XclImpChRoot& rRoot, - ScfPropertySet& rPropSet, XclChObjectType eObjType ) const + ScfPropertySet& rPropSet, XclChObjectType eObjType, bool bUsePicFmt ) const { const XclChFormatInfo& rFmtInfo = rRoot.GetFormatInfo( eObjType ); - rRoot.ConvertEscherFormat( rPropSet, maData, maPicFmt, rFmtInfo.mePropMode ); + rRoot.ConvertEscherFormat( rPropSet, maData, bUsePicFmt ? &maPicFmt : 0, mnDffFillType, rFmtInfo.mePropMode ); } // ---------------------------------------------------------------------------- @@ -620,23 +622,23 @@ void XclImpChFrameBase::ConvertLineBase( const XclImpChRoot& rRoot, } void XclImpChFrameBase::ConvertAreaBase( const XclImpChRoot& rRoot, - ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const + ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const { if( rRoot.GetFormatInfo( eObjType ).mbIsFrame ) { // CHESCHERFORMAT overrides CHAREAFORMAT (even if it is auto) if( mxEscherFmt.is() ) - mxEscherFmt->Convert( rRoot, rPropSet, eObjType ); + mxEscherFmt->Convert( rRoot, rPropSet, eObjType, bUsePicFmt ); else if( mxAreaFmt.is() ) mxAreaFmt->Convert( rRoot, rPropSet, eObjType, nFormatIdx ); } } void XclImpChFrameBase::ConvertFrameBase( const XclImpChRoot& rRoot, - ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx ) const + ScfPropertySet& rPropSet, XclChObjectType eObjType, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const { ConvertLineBase( rRoot, rPropSet, eObjType, nFormatIdx ); - ConvertAreaBase( rRoot, rPropSet, eObjType, nFormatIdx ); + ConvertAreaBase( rRoot, rPropSet, eObjType, nFormatIdx, bUsePicFmt ); } // ---------------------------------------------------------------------------- @@ -699,9 +701,9 @@ void XclImpChFrame::UpdateObjFrame( const XclObjLineData& rLineData, const XclOb } } -void XclImpChFrame::Convert( ScfPropertySet& rPropSet ) const +void XclImpChFrame::Convert( ScfPropertySet& rPropSet, bool bUsePicFmt ) const { - ConvertFrameBase( GetChRoot(), rPropSet, meObjType ); + ConvertFrameBase( GetChRoot(), rPropSet, meObjType, EXC_CHDATAFORMAT_UNKNOWN, bUsePicFmt ); } // Source links =============================================================== @@ -1520,8 +1522,15 @@ void XclImpChDataFormat::UpdateTrendLineFormat() void XclImpChDataFormat::Convert( ScfPropertySet& rPropSet, const XclChExtTypeInfo& rTypeInfo ) const { - // line and area format - ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType(), maData.mnFormatIdx ); + /* Line and area format. + #i71810# If the data points are filled with bitmaps, textures, or + patterns, then only bar charts will use the CHPICFORMAT record to + determine stacking/streching mode. All other chart types ignore this + record and always use the property 'fill-type' from the DFF property + set (streched for bitmaps, and stacked for textures and patterns). */ + bool bUsePicFmt = rTypeInfo.meTypeCateg == EXC_CHTYPECATEG_BAR; + ConvertFrameBase( GetChRoot(), rPropSet, rTypeInfo.GetSeriesObjectType(), maData.mnFormatIdx, bUsePicFmt ); + #if EXC_CHART2_3DBAR_HAIRLINES_ONLY // #i83151# only hair lines in 3D charts with filled data points if( rTypeInfo.mb3dChart && rTypeInfo.IsSeriesFrameFormat() && mxLineFmt.is() && mxLineFmt->HasLine() ) @@ -1553,9 +1562,9 @@ void XclImpChDataFormat::ConvertLine( ScfPropertySet& rPropSet, XclChObjectType ConvertLineBase( GetChRoot(), rPropSet, eObjType ); } -void XclImpChDataFormat::ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const +void XclImpChDataFormat::ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const { - ConvertAreaBase( GetChRoot(), rPropSet, EXC_CHOBJTYPE_FILLEDSERIES, nFormatIdx ); + ConvertAreaBase( GetChRoot(), rPropSet, EXC_CHOBJTYPE_FILLEDSERIES, nFormatIdx, bUsePicFmt ); } void XclImpChDataFormat::RemoveUnusedFormats( const XclChExtTypeInfo& rTypeInfo ) @@ -1999,7 +2008,7 @@ Reference< XDataSeries > XclImpChSeries::CreateDataSeries() const for( sal_uInt16 nPointIdx = 0, nPointCount = mxValueLink->GetCellCount(); nPointIdx < nPointCount; ++nPointIdx ) { ScfPropertySet aPointProp = lclGetPointPropSet( xDataSeries, nPointIdx ); - mxSeriesFmt->ConvertArea( aPointProp, bVarPointFmt ? nPointIdx : mnSeriesIdx ); + mxSeriesFmt->ConvertArea( aPointProp, bVarPointFmt ? nPointIdx : mnSeriesIdx, false ); } } @@ -3338,8 +3347,9 @@ Reference< XAxis > XclImpChAxis::CreateAxis( const XclImpChTypeGroup& rTypeGroup void XclImpChAxis::ConvertWall( ScfPropertySet& rPropSet ) const { + // #i71810# walls and floor in 3D charts use the CHPICFORMAT record for bitmap mode if( mxWallFrame.is() ) - mxWallFrame->Convert( rPropSet ); + mxWallFrame->Convert( rPropSet, true ); } void XclImpChAxis::ConvertAxisPosition( ScfPropertySet& rPropSet, const XclImpChTypeGroup& rTypeGroup ) const diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index dcce436aebdb..60e567a1c408 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -653,7 +653,7 @@ void XclImpDrawObjBase::ConvertFillStyle( SdrObject& rSdrObj, const XclObjFillDa { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 }, { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 } }; - const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, STATIC_TABLE_SIZE( sppnPatterns ) ) ]; + const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, STATIC_ARRAY_SIZE( sppnPatterns ) ) ]; // create 2-colored 8x8 DIB SvMemoryStream aMemStrm; aMemStrm << sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 ); @@ -1540,23 +1540,39 @@ XclImpChartObj::XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab ) : void XclImpChartObj::ReadChartSubStream( XclImpStream& rStrm ) { - if( mbOwnTab ? (rStrm.GetRecId() == EXC_ID5_BOF) : ((rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord()) ) + /* If chart is read from a chartsheet (mbOwnTab == true), the BOF record + has already been read. If chart is embedded as object, the next record + has to be the BOF record. */ + if( mbOwnTab ) { - sal_uInt16 nBofType; - rStrm.Seek( 2 ); - rStrm >> nBofType; - DBG_ASSERT( nBofType == EXC_BOF_CHART, "XclImpChartObj::ReadChartSubStream - no chart BOF record" ); - - // read chart, even if BOF record contains wrong substream identifier - mxChart.reset( new XclImpChart( GetRoot(), mbOwnTab ) ); - mxChart->ReadChartSubStream( rStrm ); - if( mbOwnTab ) - FinalizeTabChart(); + /* #i109800# The input stream may point somewhere inside the chart + substream and not exactly to the leading BOF record. To read this + record correctly in the following, the stream has to rewind it, so + that the next call to StartNextRecord() will find it correctly. */ + if( rStrm.GetRecId() != EXC_ID5_BOF ) + rStrm.RewindRecord(); } else { - DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" ); + if( (rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord() ) + { + sal_uInt16 nBofType; + rStrm.Seek( 2 ); + rStrm >> nBofType; + DBG_ASSERT( nBofType == EXC_BOF_CHART, "XclImpChartObj::ReadChartSubStream - no chart BOF record" ); + } + else + { + DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" ); + return; + } } + + // read chart, even if BOF record contains wrong substream identifier + mxChart.reset( new XclImpChart( GetRoot(), mbOwnTab ) ); + mxChart->ReadChartSubStream( rStrm ); + if( mbOwnTab ) + FinalizeTabChart(); } void XclImpChartObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx index 534d40fa5cd5..27e6fce237d8 100644 --- a/sc/source/filter/excel/xistream.cxx +++ b/sc/source/filter/excel/xistream.cxx @@ -495,6 +495,12 @@ void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId ) } } +void XclImpStream::RewindRecord() +{ + mnNextRecPos = maFirstRec.GetPos(); + mbValid = mbValidRec = false; +} + void XclImpStream::SetDecrypter( XclImpDecrypterRef xDecrypter ) { mxDecrypter = xDecrypter; diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx index 0a57a5970800..e7efb6c096e9 100644 --- a/sc/source/filter/excel/xistyle.cxx +++ b/sc/source/filter/excel/xistyle.cxx @@ -846,7 +846,7 @@ bool lclConvertBorderLine( SvxBorderLine& rLine, const XclImpPalette& rPalette, if( nXclLine == EXC_LINE_NONE ) return false; - if( nXclLine >= STATIC_TABLE_SIZE( ppnLineParam ) ) + if( nXclLine >= STATIC_ARRAY_SIZE( ppnLineParam ) ) nXclLine = EXC_LINE_THIN; rLine.SetColor( rPalette.GetColor( nXclColor ) ); @@ -1217,6 +1217,28 @@ void XclImpXF::ApplyPattern( } } +/*static*/ void XclImpXF::ApplyPatternForBiff2CellFormat( const XclImpRoot& rRoot, + const ScAddress& rScPos, sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 ) +{ + /* Create an XF object and let it do the work. We will have access to its + private members here. */ + XclImpXF aXF( rRoot ); + + // no used flags available in BIFF2 (always true) + aXF.SetAllUsedFlags( true ); + + // set the attributes + aXF.maProtection.FillFromXF2( nFlags1 ); + aXF.maAlignment.FillFromXF2( nFlags3 ); + aXF.maBorder.FillFromXF2( nFlags3 ); + aXF.maArea.FillFromXF2( nFlags3 ); + aXF.mnXclNumFmt = ::extract_value< sal_uInt16 >( nFlags2, 0, 6 ); + aXF.mnXclFont = ::extract_value< sal_uInt16 >( nFlags2, 6, 2 ); + + // write the attributes to the cell + aXF.ApplyPattern( rScPos.Col(), rScPos.Row(), rScPos.Col(), rScPos.Row(), rScPos.Tab() ); +} + void XclImpXF::SetUsedFlags( sal_uInt8 nUsedFlags ) { /* Notes about finding the mb***Used flags: diff --git a/sc/source/filter/excel/xladdress.cxx b/sc/source/filter/excel/xladdress.cxx index d0c1a925f8ab..62addbc1f4ee 100644 --- a/sc/source/filter/excel/xladdress.cxx +++ b/sc/source/filter/excel/xladdress.cxx @@ -138,8 +138,6 @@ XclAddressConverterBase::XclAddressConverterBase( XclTracer& rTracer, const ScAd mbRowTrunc( false ), mbTabTrunc( false ) { - DBG_ASSERT( static_cast< size_t >( rMaxPos.Col() ) <= SAL_MAX_UINT16, "XclAddressConverterBase::XclAddressConverterBase - invalid max column" ); - DBG_ASSERT( static_cast< size_t >( rMaxPos.Row() ) <= SAL_MAX_UINT16, "XclAddressConverterBase::XclAddressConverterBase - invalid max row" ); } XclAddressConverterBase::~XclAddressConverterBase() diff --git a/sc/source/filter/excel/xlchart.cxx b/sc/source/filter/excel/xlchart.cxx index 584d55021cd8..185f64b2dca4 100755 --- a/sc/source/filter/excel/xlchart.cxx +++ b/sc/source/filter/excel/xlchart.cxx @@ -147,8 +147,7 @@ XclChEscherFormat::~XclChEscherFormat() XclChPicFormat::XclChPicFormat() : mnBmpMode( EXC_CHPICFORMAT_NONE ), - mnFormat( EXC_CHPICFORMAT_DEFAULT ), - mnFlags( EXC_CHPICFORMAT_DEFAULTFLAGS ), + mnFlags( EXC_CHPICFORMAT_TOPBOTTOM | EXC_CHPICFORMAT_FRONTBACK | EXC_CHPICFORMAT_LEFTRIGHT ), mfScale( 0.5 ) { } @@ -423,7 +422,7 @@ sal_uInt16 XclChartHelper::GetSeriesLineAutoColorIdx( sal_uInt16 nFormatIdx ) 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 63 }; - return spnLineColors[ nFormatIdx % STATIC_TABLE_SIZE( spnLineColors ) ]; + return spnLineColors[ nFormatIdx % STATIC_ARRAY_SIZE( spnLineColors ) ]; } sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx ) @@ -438,13 +437,13 @@ sal_uInt16 XclChartHelper::GetSeriesFillAutoColorIdx( sal_uInt16 nFormatIdx ) 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; - return spnFillColors[ nFormatIdx % STATIC_TABLE_SIZE( spnFillColors ) ]; + return spnFillColors[ nFormatIdx % STATIC_ARRAY_SIZE( spnFillColors ) ]; } sal_uInt8 XclChartHelper::GetSeriesFillAutoTransp( sal_uInt16 nFormatIdx ) { static const sal_uInt8 spnTrans[] = { 0x00, 0x40, 0x20, 0x60, 0x70 }; - return spnTrans[ (nFormatIdx / 56) % STATIC_TABLE_SIZE( spnTrans ) ]; + return spnTrans[ (nFormatIdx / 56) % STATIC_ARRAY_SIZE( spnTrans ) ]; } sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx ) @@ -453,14 +452,14 @@ sal_uInt16 XclChartHelper::GetAutoMarkerType( sal_uInt16 nFormatIdx ) EXC_CHMARKERFORMAT_DIAMOND, EXC_CHMARKERFORMAT_SQUARE, EXC_CHMARKERFORMAT_TRIANGLE, EXC_CHMARKERFORMAT_CROSS, EXC_CHMARKERFORMAT_STAR, EXC_CHMARKERFORMAT_CIRCLE, EXC_CHMARKERFORMAT_PLUS, EXC_CHMARKERFORMAT_DOWJ, EXC_CHMARKERFORMAT_STDDEV }; - return spnSymbols[ nFormatIdx % STATIC_TABLE_SIZE( spnSymbols ) ]; + return spnSymbols[ nFormatIdx % STATIC_ARRAY_SIZE( spnSymbols ) ]; } bool XclChartHelper::HasMarkerFillColor( sal_uInt16 nMarkerType ) { static const bool spbFilled[] = { false, true, true, true, false, false, false, false, true, false }; - return (nMarkerType < STATIC_TABLE_SIZE( spbFilled )) && spbFilled[ nMarkerType ]; + return (nMarkerType < STATIC_ARRAY_SIZE( spbFilled )) && spbFilled[ nMarkerType ]; } OUString XclChartHelper::GetErrorBarValuesRole( sal_uInt8 nBarType ) @@ -507,7 +506,7 @@ static const XclChFormatInfo spFmtInfos[] = XclChFormatInfoProvider::XclChFormatInfoProvider() { - const XclChFormatInfo* pEnd = STATIC_TABLE_END( spFmtInfos ); + const XclChFormatInfo* pEnd = STATIC_ARRAY_END( spFmtInfos ); for( const XclChFormatInfo* pIt = spFmtInfos; pIt != pEnd; ++pIt ) maInfoMap[ pIt->meObjType ] = pIt; } @@ -548,7 +547,7 @@ static const XclChTypeInfo spTypeInfos[] = { EXC_CHTYPEID_RADARLINE, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARLINE, SERVICE_CHART2_NET, EXC_CHVARPOINT_SINGLE, csscd::TOP, false, false, true, false, true, false, true, false, false, false, false }, { EXC_CHTYPEID_RADARAREA, EXC_CHTYPECATEG_RADAR, EXC_ID_CHRADARAREA, SERVICE_CHART2_FILLEDNET, EXC_CHVARPOINT_NONE, csscd::TOP, false, false, true, true, true, false, true, false, false, true, false }, { EXC_CHTYPEID_PIE, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, true, true, false, false, false, false }, - { EXC_CHTYPEID_DONUT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, false, true, false, false, true, false }, + { EXC_CHTYPEID_DONUT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIE, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, true, true, true, true, false, true, false, false, false, false }, { EXC_CHTYPEID_PIEEXT, EXC_CHTYPECATEG_PIE, EXC_ID_CHPIEEXT, SERVICE_CHART2_PIE, EXC_CHVARPOINT_MULTI, csscd::AVOID_OVERLAP, false, false, true, true, true, true, true, false, false, false, false }, { EXC_CHTYPEID_SCATTER, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_SCATTER, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, true, false, false, false, true, false, false, false, false, false, false }, { EXC_CHTYPEID_BUBBLES, EXC_CHTYPECATEG_SCATTER, EXC_ID_CHSCATTER, SERVICE_CHART2_BUBBLE, EXC_CHVARPOINT_SINGLE, csscd::RIGHT, false, false, false, true, true, false, false, false, false, false, false }, @@ -576,7 +575,7 @@ void XclChExtTypeInfo::Set( const XclChTypeInfo& rTypeInfo, bool b3dChart, bool XclChTypeInfoProvider::XclChTypeInfoProvider() { - const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos ); + const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos ); for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt ) maInfoMap[ pIt->meTypeId ] = pIt; } @@ -590,7 +589,7 @@ const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfo( XclChTypeId eTypeId ) c const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRecId ) const { - const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos ); + const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos ); for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt ) if( pIt->mnRecId == nRecId ) return *pIt; @@ -600,7 +599,7 @@ const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromRecId( sal_uInt16 nRe const XclChTypeInfo& XclChTypeInfoProvider::GetTypeInfoFromService( const OUString& rServiceName ) const { - const XclChTypeInfo* pEnd = STATIC_TABLE_END( spTypeInfos ); + const XclChTypeInfo* pEnd = STATIC_ARRAY_END( spTypeInfos ); for( const XclChTypeInfo* pIt = spTypeInfos; pIt != pEnd; ++pIt ) if( rServiceName.equalsAscii( pIt->mpcServiceName ) ) return *pIt; @@ -1069,8 +1068,8 @@ void XclChPropSetHelper::WriteAreaProperties( ScfPropertySet& rPropSet, void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet, XclChObjectTable& rGradientTable, XclChObjectTable& /*rHatchTable*/, XclChObjectTable& rBitmapTable, - const XclChEscherFormat& rEscherFmt, const XclChPicFormat& rPicFmt, - XclChPropertyMode ePropMode ) + const XclChEscherFormat& rEscherFmt, const XclChPicFormat* pPicFmt, + sal_uInt32 nDffFillType, XclChPropertyMode ePropMode ) { if( rEscherFmt.mxItemSet.is() ) { @@ -1120,8 +1119,10 @@ void XclChPropSetHelper::WriteEscherProperties( ScfPropertySet& rPropSet, if( aBmpName.getLength() ) { namespace cssd = ::com::sun::star::drawing; - cssd::BitmapMode eApiBmpMode = (rPicFmt.mnBmpMode == EXC_CHPICFORMAT_STRETCH) ? - cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT; + /* #i71810# Caller decides whether to use a CHPICFORMAT record for bitmap mode. + If not passed, detect fill mode from the DFF property 'fill-type'. */ + bool bStretch = pPicFmt ? (pPicFmt->mnBmpMode == EXC_CHPICFORMAT_STRETCH) : (nDffFillType == mso_fillPicture); + cssd::BitmapMode eApiBmpMode = bStretch ? cssd::BitmapMode_STRETCH : cssd::BitmapMode_REPEAT; maBitmapHlp.InitializeWrite(); maBitmapHlp << cssd::FillStyle_BITMAP << aBmpName << eApiBmpMode; maBitmapHlp.WriteToPropertySet( rPropSet ); diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx index e6c23bb63689..1f5cc56a0934 100755 --- a/sc/source/filter/excel/xlformula.cxx +++ b/sc/source/filter/excel/xlformula.cxx @@ -93,7 +93,9 @@ static const XclFunctionInfo saFuncTable_2[] = { ocCurrency, 13, 1, 2, V, { VR }, 0, 0 }, { ocFixed, 14, 1, 2, V, { VR, VR, C }, 0, 0 }, { ocSin, 15, 1, 1, V, { VR }, 0, 0 }, + { ocCosecant, 15, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 }, { ocCos, 16, 1, 1, V, { VR }, 0, 0 }, + { ocSecant, 16, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 }, { ocTan, 17, 1, 1, V, { VR }, 0, 0 }, { ocCot, 17, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 }, { ocArcTan, 18, 1, 1, V, { VR }, 0, 0 }, @@ -230,7 +232,9 @@ static const XclFunctionInfo saFuncTable_3[] = { ocMedian, 227, 1, MX, V, { RX }, 0, 0 }, { ocSumProduct, 228, 1, MX, V, { VA }, 0, 0 }, { ocSinHyp, 229, 1, 1, V, { VR }, 0, 0 }, + { ocCosecantHyp, 229, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 }, { ocCosHyp, 230, 1, 1, V, { VR }, 0, 0 }, + { ocSecantHyp, 230, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 }, { ocTanHyp, 231, 1, 1, V, { VR }, 0, 0 }, { ocCotHyp, 231, 1, 1, V, { VR }, EXC_FUNCFLAG_EXPORTONLY, 0 }, { ocArcSinHyp, 232, 1, 1, V, { VR }, 0, 0 }, @@ -415,16 +419,16 @@ XclFunctionProvider::XclFunctionProvider( const XclRoot& rRoot ) from earlier tables. */ XclBiff eBiff = rRoot.GetBiff(); if( eBiff >= EXC_BIFF2 ) - (this->*pFillFunc)( saFuncTable_2, STATIC_TABLE_END( saFuncTable_2 ) ); + (this->*pFillFunc)( saFuncTable_2, STATIC_ARRAY_END( saFuncTable_2 ) ); if( eBiff >= EXC_BIFF3 ) - (this->*pFillFunc)( saFuncTable_3, STATIC_TABLE_END( saFuncTable_3 ) ); + (this->*pFillFunc)( saFuncTable_3, STATIC_ARRAY_END( saFuncTable_3 ) ); if( eBiff >= EXC_BIFF4 ) - (this->*pFillFunc)( saFuncTable_4, STATIC_TABLE_END( saFuncTable_4 ) ); + (this->*pFillFunc)( saFuncTable_4, STATIC_ARRAY_END( saFuncTable_4 ) ); if( eBiff >= EXC_BIFF5 ) - (this->*pFillFunc)( saFuncTable_5, STATIC_TABLE_END( saFuncTable_5 ) ); + (this->*pFillFunc)( saFuncTable_5, STATIC_ARRAY_END( saFuncTable_5 ) ); if( eBiff >= EXC_BIFF8 ) - (this->*pFillFunc)( saFuncTable_8, STATIC_TABLE_END( saFuncTable_8 ) ); - (this->*pFillFunc)( saFuncTable_Odf, STATIC_TABLE_END( saFuncTable_Odf ) ); + (this->*pFillFunc)( saFuncTable_8, STATIC_ARRAY_END( saFuncTable_8 ) ); + (this->*pFillFunc)( saFuncTable_Odf, STATIC_ARRAY_END( saFuncTable_Odf ) ); } const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const diff --git a/sc/source/filter/excel/xlpage.cxx b/sc/source/filter/excel/xlpage.cxx index a59c6f761667..36b451e17f65 100644 --- a/sc/source/filter/excel/xlpage.cxx +++ b/sc/source/filter/excel/xlpage.cxx @@ -203,7 +203,7 @@ void XclPageData::SetDefaults() Size XclPageData::GetScPaperSize() const { const XclPaperSize* pEntry = pPaperSizeTable; - if( mnPaperSize < STATIC_TABLE_SIZE( pPaperSizeTable ) ) + if( mnPaperSize < STATIC_ARRAY_SIZE( pPaperSizeTable ) ) pEntry += mnPaperSize; Size aSize; @@ -230,7 +230,7 @@ void XclPageData::SetScPaperSize( const Size& rSize, bool bPortrait ) long nHeight = bPortrait ? rSize.Height() : rSize.Width(); long nMaxWDiff = 80; long nMaxHDiff = 50; - for( const XclPaperSize* pEntry = pPaperSizeTable; pEntry != STATIC_TABLE_END( pPaperSizeTable ); ++pEntry ) + for( const XclPaperSize* pEntry = pPaperSizeTable; pEntry != STATIC_ARRAY_END( pPaperSizeTable ); ++pEntry ) { long nWDiff = Abs( pEntry->mnWidth - nWidth ); long nHDiff = Abs( pEntry->mnHeight - nHeight ); diff --git a/sc/source/filter/excel/xlstyle.cxx b/sc/source/filter/excel/xlstyle.cxx index 4a48584da7fa..a6d94e5efc31 100644 --- a/sc/source/filter/excel/xlstyle.cxx +++ b/sc/source/filter/excel/xlstyle.cxx @@ -111,20 +111,20 @@ XclDefaultPalette::XclDefaultPalette( const XclRoot& rRoot ) : { case EXC_BIFF2: mpnColorTable = spnDefColorTable2; - mnTableSize = STATIC_TABLE_SIZE( spnDefColorTable2 ); + mnTableSize = STATIC_ARRAY_SIZE( spnDefColorTable2 ); break; case EXC_BIFF3: case EXC_BIFF4: mpnColorTable = spnDefColorTable3; - mnTableSize = STATIC_TABLE_SIZE( spnDefColorTable3 ); + mnTableSize = STATIC_ARRAY_SIZE( spnDefColorTable3 ); break; case EXC_BIFF5: mpnColorTable = spnDefColorTable5; - mnTableSize = STATIC_TABLE_SIZE( spnDefColorTable5 ); + mnTableSize = STATIC_ARRAY_SIZE( spnDefColorTable5 ); break; case EXC_BIFF8: mpnColorTable = spnDefColorTable8; - mnTableSize = STATIC_TABLE_SIZE( spnDefColorTable8 ); + mnTableSize = STATIC_ARRAY_SIZE( spnDefColorTable8 ); break; default: DBG_ERROR_BIFF(); @@ -1513,7 +1513,7 @@ void XclNumFmtBuffer::InsertBuiltinFormats() typedef ::std::map< LanguageType, const XclBuiltInFormatTable* > XclBuiltInMap; XclBuiltInMap aBuiltInMap; for( const XclBuiltInFormatTable* pTable = spBuiltInFormatTables; - pTable != STATIC_TABLE_END( spBuiltInFormatTables ); ++pTable ) + pTable != STATIC_ARRAY_END( spBuiltInFormatTables ); ++pTable ) aBuiltInMap[ pTable->meLanguage ] = pTable; // build a list of table pointers for the current language, with all parent tables diff --git a/sc/source/filter/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx index d62a51f5388f..70a0fbae7a88 100644 --- a/sc/source/filter/excel/xltools.cxx +++ b/sc/source/filter/excel/xltools.cxx @@ -53,7 +53,7 @@ using ::rtl::OUString; XclGuid::XclGuid() { - ::std::fill( mpnData, STATIC_TABLE_END( mpnData ), 0 ); + ::std::fill( mpnData, STATIC_ARRAY_END( mpnData ), 0 ); } XclGuid::XclGuid( @@ -77,14 +77,14 @@ XclGuid::XclGuid( bool operator==( const XclGuid& rCmp1, const XclGuid& rCmp2 ) { - return ::std::equal( rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ), rCmp2.mpnData ); + return ::std::equal( rCmp1.mpnData, STATIC_ARRAY_END( rCmp1.mpnData ), rCmp2.mpnData ); } bool operator<( const XclGuid& rCmp1, const XclGuid& rCmp2 ) { return ::std::lexicographical_compare( - rCmp1.mpnData, STATIC_TABLE_END( rCmp1.mpnData ), - rCmp2.mpnData, STATIC_TABLE_END( rCmp2.mpnData ) ); + rCmp1.mpnData, STATIC_ARRAY_END( rCmp1.mpnData ), + rCmp2.mpnData, STATIC_ARRAY_END( rCmp2.mpnData ) ); } XclImpStream& operator>>( XclImpStream& rStrm, XclGuid& rGuid ) @@ -357,7 +357,7 @@ Color XclTools::GetPatternColor( const Color& rPattColor, const Color& rBackColo 0x40, 0x40, 0x20, 0x60, 0x60, 0x60, 0x60, 0x48, // 08 - 15 0x50, 0x70, 0x78 // 16 - 18 }; - return (nXclPattern < STATIC_TABLE_SIZE( pnRatioTable )) ? + return (nXclPattern < STATIC_ARRAY_SIZE( pnRatioTable )) ? ScfTools::GetMixedColor( rPattColor, rBackColor, pnRatioTable[ nXclPattern ] ) : rPattColor; } @@ -409,7 +409,7 @@ pCodePageTable[] = { 32768, RTL_TEXTENCODING_APPLE_ROMAN }, // Apple Roman { 32769, RTL_TEXTENCODING_MS_1252 } // MS Windows Latin I (BIFF2-BIFF3) }; -const XclCodePageEntry* const pCodePageTableEnd = STATIC_TABLE_END( pCodePageTable ); +const XclCodePageEntry* const pCodePageTableEnd = STATIC_ARRAY_END( pCodePageTable ); struct XclCodePageEntry_CPPred { @@ -487,10 +487,10 @@ static const sal_Char* const ppcDefNames[] = String XclTools::GetXclBuiltInDefName( sal_Unicode cBuiltIn ) { - DBG_ASSERT( STATIC_TABLE_SIZE( ppcDefNames ) == EXC_BUILTIN_UNKNOWN, + DBG_ASSERT( STATIC_ARRAY_SIZE( ppcDefNames ) == EXC_BUILTIN_UNKNOWN, "XclTools::GetXclBuiltInDefName - built-in defined name list modified" ); String aDefName; - if( cBuiltIn < STATIC_TABLE_SIZE( ppcDefNames ) ) + if( cBuiltIn < STATIC_ARRAY_SIZE( ppcDefNames ) ) aDefName.AssignAscii( ppcDefNames[ cBuiltIn ] ); else aDefName = String::CreateFromInt32( cBuiltIn ); @@ -554,7 +554,7 @@ String XclTools::GetBuiltInStyleName( sal_uInt8 nStyleId, const String& rName, s else { aStyleName = maStyleNamePrefix1; - if( nStyleId < STATIC_TABLE_SIZE( ppcStyleNames ) ) + if( nStyleId < STATIC_ARRAY_SIZE( ppcStyleNames ) ) aStyleName.AppendAscii( ppcStyleNames[ nStyleId ] ); else if( rName.Len() > 0 ) aStyleName.Append( rName ); @@ -594,7 +594,7 @@ bool XclTools::IsBuiltInStyleName( const String& rStyleName, sal_uInt8* pnStyleI if( nPrefixLen > 0 ) { String aShortName; - for( sal_uInt8 nId = 0; nId < STATIC_TABLE_SIZE( ppcStyleNames ); ++nId ) + for( sal_uInt8 nId = 0; nId < STATIC_ARRAY_SIZE( ppcStyleNames ); ++nId ) { if( nId != EXC_STYLE_NORMAL ) { diff --git a/sc/source/filter/inc/ftools.hxx b/sc/source/filter/inc/ftools.hxx index 2860290cc169..f2e7967a0448 100644 --- a/sc/source/filter/inc/ftools.hxx +++ b/sc/source/filter/inc/ftools.hxx @@ -41,11 +41,6 @@ // Common macros ============================================================== -/** Expands to the size of a STATIC data array. */ -#define STATIC_TABLE_SIZE( array ) (sizeof(array)/sizeof(*(array))) -/** Expands to a pointer behind the last element of a STATIC data array (like STL end()). */ -#define STATIC_TABLE_END( array ) ((array)+STATIC_TABLE_SIZE(array)) - /** Expands to a temporary String, created from an ASCII character array. */ #define CREATE_STRING( ascii ) String( RTL_CONSTASCII_USTRINGPARAM( ascii ) ) diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx index 046c338c042d..0e1315fdb311 100644 --- a/sc/source/filter/inc/imp_op.hxx +++ b/sc/source/filter/inc/imp_op.hxx @@ -110,8 +110,10 @@ protected: XclImpOutlineListBuffer* pOutlineListBuffer; sal_Int16 mnLastRefIdx; - sal_uInt16 nIxfeIndex; // merkt sich Angabe im IXFE-Record - sal_uInt16 nLastXF; // letzter XF in Formula-Record + sal_uInt16 mnIxfeIndex; /// Current XF identifier from IXFE record. + bool mbBiff2HasXfs; /// Select XF formatting or direct formatting in BIFF2. + bool mbBiff2HasXfsValid; /// False = mbBiff2HasXfs is undetermined yet. + SCTAB nBdshtTab; // Counter fuer Boundsheet ScFormulaCell* pLastFormCell; // fuer String-Records @@ -121,7 +123,7 @@ protected: // Record-Funktionen void ReadFileSharing(); - sal_uInt16 ReadXFIndex( bool bBiff2 ); + sal_uInt16 ReadXFIndex( const ScAddress& rScPos, bool bBiff2 ); void ReadDimensions(); void ReadBlank(); diff --git a/sc/source/filter/inc/xichart.hxx b/sc/source/filter/inc/xichart.hxx index 097ce1801896..c986544da0cf 100644 --- a/sc/source/filter/inc/xichart.hxx +++ b/sc/source/filter/inc/xichart.hxx @@ -158,7 +158,8 @@ public: void ConvertEscherFormat( ScfPropertySet& rPropSet, const XclChEscherFormat& rEscherFmt, - const XclChPicFormat& rPicFmt, + const XclChPicFormat* pPicFmt, + sal_uInt32 nDffFillType, XclChPropertyMode ePropMode ) const; /** Writes font properties to the passed property set. */ void ConvertFont( @@ -299,12 +300,13 @@ public: virtual void ReadSubRecord( XclImpStream& rStrm ); /** Converts and writes the contained data to the passed property set. */ - void Convert( const XclImpChRoot& rRoot, - ScfPropertySet& rPropSet, XclChObjectType eObjType ) const; + void Convert( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, + XclChObjectType eObjType, bool bUsePicFmt ) const; private: XclChEscherFormat maData; /// Fill properties for complex areas (CHESCHERFORMAT record). XclChPicFormat maPicFmt; /// Image options, e.g. stretched, stacked (CHPICFORMAT record). + sal_uInt32 mnDffFillType; /// Fill type imported from the DFF property set. }; typedef ScfRef< XclImpChEscherFormat > XclImpChEscherFormatRef; @@ -348,11 +350,11 @@ protected: /** Converts and writes the contained area formatting to the passed property set. */ void ConvertAreaBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, XclChObjectType eObjType, - sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const; + sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN, bool bUsePicFmt = false ) const; /** Converts and writes the contained data to the passed property set. */ void ConvertFrameBase( const XclImpChRoot& rRoot, ScfPropertySet& rPropSet, XclChObjectType eObjType, - sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN ) const; + sal_uInt16 nFormatIdx = EXC_CHDATAFORMAT_UNKNOWN, bool bUsePicFmt = false ) const; protected: XclImpChLineFormatRef mxLineFmt; /// Line format (CHLINEFORMAT record). @@ -382,7 +384,7 @@ public: void UpdateObjFrame( const XclObjLineData& rLineData, const XclObjFillData& rFillData ); /** Converts and writes the contained data to the passed property set. */ - void Convert( ScfPropertySet& rPropSet ) const; + void Convert( ScfPropertySet& rPropSet, bool bUsePicFmt = false ) const; private: XclChFrame maData; /// Contents of the CHFRAME record. @@ -705,7 +707,7 @@ public: /** Writes the line format only, e.g. for trend lines or error bars. */ void ConvertLine( ScfPropertySet& rPropSet, XclChObjectType eObjType ) const; /** Writes the area format only for the series or a data point. */ - void ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx ) const; + void ConvertArea( ScfPropertySet& rPropSet, sal_uInt16 nFormatIdx, bool bUsePicFmt ) const; private: /** Removes unused formatting (e.g. pie distance in a bar chart). */ diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx index 4aec7c337a32..28916eba37dc 100644 --- a/sc/source/filter/inc/xistream.hxx +++ b/sc/source/filter/inc/xistream.hxx @@ -188,6 +188,9 @@ public: sal_uInt16& rnRawRecId, sal_uInt16& rnRawRecSize, sal_uInt16& rnRawRecLeft, bool& rbValid ) const; + /** Returns the stored stream position. */ + inline sal_Size GetPos() const { return mnPos; } + private: sal_Size mnPos; /// Absolute position of the stream. sal_Size mnNextPos; /// Absolute position of next record. @@ -286,6 +289,14 @@ public: started with StartNextRecord(). */ void ResetRecord( bool bContLookup, sal_uInt16 nAltContId = EXC_ID_UNKNOWN ); + /** Sets stream pointer before current record and invalidates stream. + @descr The next call to StartNextRecord() will start again the current + record. This can be used in situations where a loop or a function + leaves on a specific record, but the parent context expects to start + this record by itself. The stream is invalid as long as the first + record has not been started (it is not allowed to call any other stream + operation then). */ + void RewindRecord(); /** Enables decryption of record contents for the rest of the stream. */ void SetDecrypter( XclImpDecrypterRef xDecrypter ); diff --git a/sc/source/filter/inc/xistyle.hxx b/sc/source/filter/inc/xistyle.hxx index abe08c9eb945..2ada794eb216 100644 --- a/sc/source/filter/inc/xistyle.hxx +++ b/sc/source/filter/inc/xistyle.hxx @@ -418,6 +418,11 @@ public: SCTAB nScTab, sal_uLong nForceScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND ); + /** Converts formatting information from BIFF2 cell record data directly. */ + static void ApplyPatternForBiff2CellFormat( + const XclImpRoot& rRoot, const ScAddress& rScPos, + sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 ); + private: void ReadXF2( XclImpStream& rStrm ); void ReadXF3( XclImpStream& rStrm ); diff --git a/sc/source/filter/inc/xlchart.hxx b/sc/source/filter/inc/xlchart.hxx index 925b1d14e805..211f375351a5 100755 --- a/sc/source/filter/inc/xlchart.hxx +++ b/sc/source/filter/inc/xlchart.hxx @@ -569,14 +569,9 @@ const sal_uInt16 EXC_CHPICFORMAT_STRETCH = 1; /// Bitmap stretched const sal_uInt16 EXC_CHPICFORMAT_STACK = 2; /// Bitmap stacked. const sal_uInt16 EXC_CHPICFORMAT_SCALE = 3; /// Bitmap scaled to axis scale. -const sal_uInt16 EXC_CHPICFORMAT_WMF = 2; -const sal_uInt16 EXC_CHPICFORMAT_BMP = 9; -const sal_uInt16 EXC_CHPICFORMAT_DEFAULT = 19; - -const sal_uInt16 EXC_CHPICFORMAT_WINDOWS = 0x0001; -const sal_uInt16 EXC_CHPICFORMAT_MACOS = 0x0002; -const sal_uInt16 EXC_CHPICFORMAT_FORMATONLY = 0x0100; -const sal_uInt16 EXC_CHPICFORMAT_DEFAULTFLAGS = 0x0E00; /// Default flags for export. +const sal_uInt16 EXC_CHPICFORMAT_TOPBOTTOM = 0x0200; +const sal_uInt16 EXC_CHPICFORMAT_FRONTBACK = 0x0400; +const sal_uInt16 EXC_CHPICFORMAT_LEFTRIGHT = 0x0800; // (0x103D) CHDROPBAR --------------------------------------------------------- @@ -856,7 +851,6 @@ struct XclChEscherFormat struct XclChPicFormat { sal_uInt16 mnBmpMode; /// Bitmap mode, e.g. stretched, stacked. - sal_uInt16 mnFormat; /// Image data format (WMF, BMP). sal_uInt16 mnFlags; /// Additional flags. double mfScale; /// Picture scaling (units). @@ -1440,7 +1434,8 @@ public: XclChObjectTable& rHatchTable, XclChObjectTable& rBitmapTable, const XclChEscherFormat& rEscherFmt, - const XclChPicFormat& rPicFmt, + const XclChPicFormat* pPicFmt, + sal_uInt32 nDffFillType, XclChPropertyMode ePropMode ); /** Writes all marker properties to the passed property set. */ void WriteMarkerProperties( diff --git a/sc/source/filter/starcalc/scflt.cxx b/sc/source/filter/starcalc/scflt.cxx index a7d0150ee220..07f2462041d4 100644 --- a/sc/source/filter/starcalc/scflt.cxx +++ b/sc/source/filter/starcalc/scflt.cxx @@ -414,7 +414,10 @@ Sc10FontData::Sc10FontData(SvStream& rStream) rStream >> PitchAndFamily; sal_uInt16 nLen; rStream >> nLen; - rStream.Read(FaceName, nLen); + if (nLen < sizeof(FaceName)) + rStream.Read(FaceName, nLen); + else + rStream.SetError(ERRCODE_IO_WRONGFORMAT); } @@ -452,10 +455,14 @@ Sc10NameData::Sc10NameData(SvStream& rStream) sal_uInt8 nLen; rStream >> nLen; rStream.Read(Name, sizeof(Name) - 1); + if (nLen >= sizeof(Name)) + nLen = sizeof(Name) - 1; Name[nLen] = 0; rStream >> nLen; rStream.Read(Reference, sizeof(Reference) - 1); + if (nLen >= sizeof(Reference)) + nLen = sizeof(Reference) - 1; Reference[nLen] = 0; rStream.Read(Reserved, sizeof(Reserved)); } @@ -1452,6 +1459,8 @@ void Sc10Import::LoadTables() sal_uInt8 nLen; rStream >> nLen; rStream.Read(TabName, sizeof(TabName) - 1); + if (nLen >= sizeof(TabName)) + nLen = sizeof(TabName) - 1; TabName[nLen] = 0; //---------------------------------------------------------- @@ -1684,7 +1693,7 @@ void Sc10Import::LoadCol(SCCOL Col, SCTAB Tab) { /*double Value =*/ ScfTools::ReadLongDouble(rStream); sal_uInt8 Len; - sal_Char s[256]; + sal_Char s[256+1]; //rStream.Read(&Value, sizeof(Value)); rStream >> Len; rStream.Read(&s[1], Len); diff --git a/sc/source/filter/xml/XMLConverter.cxx b/sc/source/filter/xml/XMLConverter.cxx index 4de6246f4f28..a23a80c9d9ac 100644 --- a/sc/source/filter/xml/XMLConverter.cxx +++ b/sc/source/filter/xml/XMLConverter.cxx @@ -436,7 +436,7 @@ const ScXMLConditionInfo* lclGetConditionInfo( const sal_Unicode*& rpcString, co // search the table for an entry if( nLength > 0 ) - for( const ScXMLConditionInfo* pInfo = spConditionInfos; pInfo < STATIC_TABLE_END( spConditionInfos ); ++pInfo ) + for( const ScXMLConditionInfo* pInfo = spConditionInfos; pInfo < STATIC_ARRAY_END( spConditionInfos ); ++pInfo ) if( (nLength == pInfo->mnIdentLength) && (::rtl_ustr_ascii_shortenedCompare_WithLength( pcIdStart, nLength, pInfo->mpcIdentifier, nLength ) == 0) ) return pInfo; diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index f8cba5ecf6c3..07d1250a76aa 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -743,7 +743,7 @@ void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient if (pGrandTotal) rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal); - SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True); + SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE_EXT, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True); } void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreadsheetDocument>& /* xSpreadDoc */) diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 09d8a25fa86d..c9506edbfdf9 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -128,7 +128,6 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, pDPDimSaveData(NULL), sDataPilotTableName(), sApplicationData(), - sGrandTotal(GetXMLToken(XML_BOTH)), mnRowFieldCount(0), mnColFieldCount(0), mnPageFieldCount(0), @@ -165,7 +164,6 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport, break; case XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL : { - sGrandTotal = sValue; if (IsXMLToken(sValue, XML_BOTH)) { maRowGrandTotal.mbVisible = true; @@ -266,6 +264,7 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( sal_uInt16 n } break; case XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL: + case XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL_EXT: { pContext = new ScXMLDataPilotGrandTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this); } @@ -794,9 +793,9 @@ ScXMLDataPilotGrandTotalContext::~ScXMLDataPilotGrandTotalContext() } SvXMLImportContext* ScXMLDataPilotGrandTotalContext::CreateChildContext( - sal_uInt16 /*nPrefix*/, const ::rtl::OUString& /*rLocalName*/, const Reference<XAttributeList>& /*xAttrList*/ ) + sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ ) { - return NULL; + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); } void ScXMLDataPilotGrandTotalContext::EndElement() diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx index 5ff84c587b54..702e42a0916b 100644 --- a/sc/source/filter/xml/xmldpimp.hxx +++ b/sc/source/filter/xml/xmldpimp.hxx @@ -96,7 +96,6 @@ class ScXMLDataPilotTableContext : public SvXMLImportContext GrandTotalItem maColGrandTotal; rtl::OUString sDataPilotTableName; rtl::OUString sApplicationData; - rtl::OUString sGrandTotal; rtl::OUString sDatabaseName; rtl::OUString sSourceObject; rtl::OUString sServiceName; diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index f8769cc95ffb..45c9b9dcc4c7 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -1814,16 +1814,14 @@ void ScXMLExport::_ExportContent() ++nEqualCells; else { - SetRepeatAttribute(nEqualCells); - WriteCell(aPrevCell); + WriteCell(aPrevCell, nEqualCells); nEqualCells = 0; aPrevCell = aCell; } } else { - SetRepeatAttribute(nEqualCells); - WriteCell(aPrevCell); + WriteCell(aPrevCell, nEqualCells); ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row, aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable); nEqualCells = 0; @@ -1833,8 +1831,7 @@ void ScXMLExport::_ExportContent() } if (!bIsFirst) { - SetRepeatAttribute(nEqualCells); - WriteCell(aPrevCell); + WriteCell(aPrevCell, nEqualCells); ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); } @@ -2898,8 +2895,11 @@ sal_Bool ScXMLExport::GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) con } } -void ScXMLExport::WriteCell (ScMyCell& aCell) +void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount) { + // nEqualCellCount is the number of additional cells + SetRepeatAttribute(nEqualCellCount, (aCell.nType != table::CellContentType_EMPTY)); + ScAddress aCellPos; ScUnoConversion::FillScAddress( aCellPos, aCell.aCellAddress ); if (aCell.nStyleIndex != -1) @@ -3255,6 +3255,9 @@ void ScXMLExport::WriteShapes(const ScMyCell& rMyCell) AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear()); } ExportShape(aItr->xShape, &aPoint); + // if there's an error in ExportShape, the attributes from above must be removed + CheckAttrList(); // asserts in non pro if we have attributes left + ClearAttrList(); // clears the attributes } ++aItr; } @@ -3470,14 +3473,16 @@ void ScXMLExport::WriteDetective( const ScMyCell& rMyCell ) } } -void ScXMLExport::SetRepeatAttribute (const sal_Int32 nEqualCellCount) +void ScXMLExport::SetRepeatAttribute(sal_Int32 nEqualCellCount, bool bIncProgress) { + // nEqualCellCount is additional cells, so the attribute value is nEqualCellCount+1 if (nEqualCellCount > 0) { sal_Int32 nTemp(nEqualCellCount + 1); OUString sOUEqualCellCount(OUString::valueOf(nTemp)); AddAttribute(sAttrColumnsRepeated, sOUEqualCellCount); - IncrementProgressBar(sal_False, nEqualCellCount); + if (bIncProgress) + IncrementProgressBar(sal_False, nEqualCellCount); } } diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx index e024fc6a0de0..ec273dea8db1 100644 --- a/sc/source/filter/xml/xmlexprt.hxx +++ b/sc/source/filter/xml/xmlexprt.hxx @@ -182,14 +182,14 @@ class ScXMLExport : public SvXMLExport sal_Bool GetCellText (ScMyCell& rMyCell, const ScAddress& aPos) const; - void WriteCell (ScMyCell& aCell); + void WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount); void WriteAreaLink(const ScMyCell& rMyCell); void WriteAnnotation(ScMyCell& rMyCell); void WriteDetective(const ScMyCell& rMyCell); void ExportShape(const com::sun::star::uno::Reference < com::sun::star::drawing::XShape >& xShape, com::sun::star::awt::Point* pPoint); void WriteShapes(const ScMyCell& rMyCell); void WriteTableShapes(); - void SetRepeatAttribute (const sal_Int32 nEqualCellCount); + void SetRepeatAttribute(sal_Int32 nEqualCellCount, bool bIncProgress); sal_Bool IsCellTypeEqual (const ScMyCell& aCell1, const ScMyCell& aCell2) const; sal_Bool IsEditCell(const com::sun::star::table::CellAddress& aAddress, ScMyCell* pMyCell = NULL) const; diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index d840c39f5939..fb9241549817 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -73,6 +73,7 @@ #include "rangeutl.hxx" #include "postit.hxx" #include "formulaparserpool.hxx" +#include "externalrefmgr.hxx" #include <comphelper/extract.hxx> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> @@ -1347,6 +1348,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableElemTokenMap() { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL }, { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE }, { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL }, + { XML_NAMESPACE_TABLE_EXT, XML_DATA_PILOT_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL_EXT }, { XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY }, { XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE }, { XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE }, @@ -1911,7 +1913,7 @@ SvXMLImportContext *ScXMLImport::CreateMetaContext( { SvXMLImportContext *pContext(0); - if( !IsStylesOnlyMode() && (getImportFlags() & IMPORT_META)) + if (getImportFlags() & IMPORT_META) { uno::Reference<xml::sax::XDocumentHandler> xDocBuilder( mxServiceFactory->createInstance(::rtl::OUString::createFromAscii( @@ -1919,9 +1921,11 @@ SvXMLImportContext *ScXMLImport::CreateMetaContext( uno::UNO_QUERY_THROW); uno::Reference<document::XDocumentPropertiesSupplier> xDPS( GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> const xDocProps( + (IsStylesOnlyMode()) ? 0 : xDPS->getDocumentProperties()); pContext = new SvXMLMetaDocumentContext(*this, XML_NAMESPACE_OFFICE, rLocalName, - xDPS->getDocumentProperties(), xDocBuilder); + xDocProps, xDocBuilder); } if( !pContext ) @@ -2635,6 +2639,23 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE } } + uno::Reference< beans::XPropertySet > const xImportInfo( getImportInfo() ); + uno::Reference< beans::XPropertySetInfo > const xPropertySetInfo( + xImportInfo.is() ? xImportInfo->getPropertySetInfo() : 0); + if (xPropertySetInfo.is()) + { + ::rtl::OUString const sOrganizerMode( + RTL_CONSTASCII_USTRINGPARAM("OrganizerMode")); + if (xPropertySetInfo->hasPropertyByName(sOrganizerMode)) + { + sal_Bool bStyleOnly(sal_False); + if (xImportInfo->getPropertyValue(sOrganizerMode) >>= bStyleOnly) + { + bLoadDoc = !bStyleOnly; + } + } + } + UnlockSolarMutex(); } @@ -2837,9 +2858,19 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE } GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars if (pDoc) + { pDoc->CompileXML(); - if (pDoc && GetModel().is()) + // After CompileXML, links must be completely changed to the new URLs. + // Otherwise, hasExternalFile for API wouldn't work (#i116940#), + // and typing a new formula would create a second link with the same "real" file name. + if (pDoc->HasExternalRefManager()) + pDoc->GetExternalRefManager()->updateAbsAfterLoad(); + } + + // If the stream contains cells outside of the current limits, the styles can't be re-created, + // so stream copying is disabled then. + if (pDoc && GetModel().is() && !pDoc->HasRangeOverflow()) { // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results // in UpdateRowHeights can already clear the flags again) diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx index d11a5bc0e76a..c96c614756bd 100644 --- a/sc/source/filter/xml/xmlimprt.hxx +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -489,6 +489,7 @@ enum ScXMLDataPilotTableElemTokens XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL, + XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL_EXT, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE, diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx index e6cc7b853764..3e182c919032 100644 --- a/sc/source/filter/xml/xmlsubti.cxx +++ b/sc/source/filter/xml/xmlsubti.cxx @@ -614,7 +614,8 @@ void ScMyTables::UpdateRowHeights() if (aUpdateSheets.GetSelectCount()) { pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results) - ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets); + // #i114839# make sure the output factor is valid for UpdateAllRowHeights + ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets, true); pDoc->LockStreamValid( false ); } } diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx index 1644ad7e7ffe..dd234bb9a76a 100644 --- a/sc/source/filter/xml/xmltabi.cxx +++ b/sc/source/filter/xml/xmltabi.cxx @@ -55,6 +55,8 @@ #include <xmloff/xmltoken.hxx> #include <xmloff/XMLEventsImportContext.hxx> +#include <tools/urlobj.hxx> + #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> #include <com/sun/star/sheet/XSpreadsheet.hpp> @@ -83,27 +85,29 @@ static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rU // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name. // That's allowed.) - static const sal_Unicode aPrefix[] = { - '\'', 'f', 'i', 'l', 'e', ':', '/', '/' - }; + if ( rName.toChar() != '\'' ) // initial quote + return false; + + // #i114504# Other schemes besides "file:" are also allowed. + // CompareProtocolScheme is quick, only looks at the start of the string. + INetProtocol eProt = INetURLObject::CompareProtocolScheme( rName.copy(1) ); + if ( eProt == INET_PROT_NOT_VALID ) + return false; + + rtl::OUString aPrefix = INetURLObject::GetScheme( eProt ); + sal_Int32 nPrefLen = aPrefix.getLength(); rtl::OUStringBuffer aUrlBuf, aTabNameBuf; - aUrlBuf.appendAscii("file://"); + aUrlBuf.append( aPrefix ); sal_Int32 n = rName.getLength(); const sal_Unicode* p = rName.getStr(); bool bInUrl = true; sal_Unicode cPrev = 0; - for (sal_Int32 i = 0; i < n; ++i) + for (sal_Int32 i = nPrefLen+1; i < n; ++i) // start the loop after quote and prefix { const sal_Unicode c = p[i]; - if (i <= 7) - { - // Checking the prefix 'file://'. - if (c != aPrefix[i]) - return false; - } - else if (bInUrl) + if (bInUrl) { // parsing file URL if (c == '#') diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx index 9e721b7e9b1a..f3270ff12ade 100644 --- a/sc/source/filter/xml/xmlwrap.cxx +++ b/sc/source/filter/xml/xmlwrap.cxx @@ -429,6 +429,8 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "VBACompatibilityMode" ), 0, &::getBooleanCppuType(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "ScriptConfiguration" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, + { MAP_LEN( "OrganizerMode" ), 0, &::getBooleanCppuType(), + ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { NULL, 0, 0, NULL, 0, 0 } }; @@ -488,26 +490,32 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) } } + if (bStylesOnly) + { + ::rtl::OUString const sOrganizerMode( + RTL_CONSTASCII_USTRINGPARAM("OrganizerMode")); + xInfoSet->setPropertyValue(sOrganizerMode, uno::makeAny(sal_True)); + } + sal_Bool bOasis = ( SotStorage::GetVersion( xStorage ) > SOFFICE_FILEFORMAT_60 ); + // #i103539#: always read meta.xml for generator sal_uInt32 nMetaRetval(0); - if(!bStylesOnly) - { - uno::Sequence<uno::Any> aMetaArgs(1); - uno::Any* pMetaArgs = aMetaArgs.getArray(); - pMetaArgs[0] <<= xInfoSet; + uno::Sequence<uno::Any> aMetaArgs(1); + uno::Any* pMetaArgs = aMetaArgs.getArray(); + pMetaArgs[0] <<= xInfoSet; - RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import start" ); + RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import start" ); - nMetaRetval = ImportFromComponent(xServiceFactory, xModel, xXMLParser, aParserInput, - bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaImporter")) - : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaImporter")), - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta.xml")), - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Meta.xml")), aMetaArgs, - sal_False); + nMetaRetval = ImportFromComponent( + xServiceFactory, xModel, xXMLParser, aParserInput, + bOasis ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLOasisMetaImporter")) + : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Calc.XMLMetaImporter")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("meta.xml")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Meta.xml")), aMetaArgs, + sal_False); - RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import end" ); - } + RTL_LOGFILE_CONTEXT_TRACE( aLog, "meta import end" ); SvXMLGraphicHelper* pGraphicHelper = NULL; uno::Reference< document::XGraphicObjectResolver > xGrfContainer; diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index fac3b1bb1a0f..a6de38258d06 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -514,6 +514,13 @@ void ScInputHandler::UpdateRefDevice() return; sal_Bool bTextWysiwyg = SC_MOD()->GetInputOptions().GetTextWysiwyg(); + bool bInPlace = pActiveViewSh && pActiveViewSh->GetViewFrame()->GetFrame().IsInPlace(); + sal_uInt32 nCtrl = pEngine->GetControlWord(); + if ( bTextWysiwyg || bInPlace ) + nCtrl |= EE_CNTRL_FORMAT100; // EditEngine default: always format for 100% + else + nCtrl &= ~EE_CNTRL_FORMAT100; // when formatting for screen, use the actual MapMode + pEngine->SetControlWord( nCtrl ); if ( bTextWysiwyg && pActiveViewSh ) pEngine->SetRefDevice( pActiveViewSh->GetViewData()->GetDocument()->GetPrinter() ); else @@ -601,9 +608,7 @@ void ScInputHandler::UpdateSpellSettings( sal_Bool bFromStartTab ) pEngine->SetControlWord(nCntrl); ScDocument* pDoc = pViewData->GetDocument(); - pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() ); - pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() ); - pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() ); + pDoc->ApplyAsianEditSettings( *pEngine ); pEngine->SetDefaultHorizontalTextDirection( (EEHorizontalTextDirection)pDoc->GetEditTextDirection( pViewData->GetTabNo() ) ); pEngine->SetFirstWordCapitalization( sal_False ); @@ -2092,7 +2097,7 @@ sal_Bool ScInputHandler::DataChanging( sal_Unicode cTyped, sal_Bool bFromCommand return sal_False; } -void ScInputHandler::DataChanged( sal_Bool bFromTopNotify ) +void ScInputHandler::DataChanged( sal_Bool bFromTopNotify, sal_Bool bSetModified ) { ImplCreateEditEngine(); @@ -2111,7 +2116,8 @@ void ScInputHandler::DataChanged( sal_Bool bFromTopNotify ) pTopView->ShowCursor(); } - bModified = sal_True; + if (bSetModified) + bModified = sal_True; bSelIsRef = sal_False; if ( pRangeFindList && !bInRangeUpdate ) @@ -3202,7 +3208,9 @@ sal_Bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, sal_Bool bStartEdit /* } } - DataChanged(); // ruft auch UpdateParenthesis() + // #i114511# don't count cursor keys as modification + sal_Bool bSetModified = !bCursorKey; + DataChanged(sal_False, bSetModified); // also calls UpdateParenthesis() InvalidateAttribs(); //! in DataChanged ? } } diff --git a/sc/source/ui/app/typemap.cxx b/sc/source/ui/app/typemap.cxx index 4450c00db807..73d0ac786971 100644 --- a/sc/source/ui/app/typemap.cxx +++ b/sc/source/ui/app/typemap.cxx @@ -124,6 +124,7 @@ #include <svl/aeitem.hxx> #include <avmedia/mediaitem.hxx> +#include <sfx2/frame.hxx> #include "attrib.hxx" #define SvxDrawToolItem SfxAllEnumItem diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index 5ee9b320a04e..1bf258264dc9 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -748,8 +748,11 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, sal_u if (pLayoutName) aName = *pLayoutName; } - maLbDims.InsertEntry( aName ); - maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim)); + if ( aName.Len() ) + { + maLbDims.InsertEntry( aName ); + maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim)); + } } } } diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index b43779ffa62b..e5709197748e 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -99,7 +99,7 @@ ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window maFlAreas( this, ScResId( FL_OUTPUT ) ), maFtInArea( this, ScResId( FT_INAREA) ), - maEdInPos( this, ScResId( ED_INAREA) ), + maEdInPos( this, this, ScResId( ED_INAREA) ), maRbInPos( this, ScResId( RB_INAREA ), &maEdInPos, this ), maLbOutPos( this, ScResId( LB_OUTAREA ) ), maFtOutArea( this, ScResId( FT_OUTAREA ) ), @@ -749,6 +749,14 @@ IMPL_LINK( ScPivotLayoutDlg, OkHdl, OKButton *, EMPTYARG ) } } + // also transfer grand total name + if (pOldSaveData) + { + const OUString* pGrandTotalName = pOldSaveData->GetGrandTotalName(); + if (pGrandTotalName) + aSaveData.SetGrandTotalName(*pGrandTotalName); + } + sal_uInt16 nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE ); ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable ); diff --git a/sc/source/ui/dbgui/scuiasciiopt.cxx b/sc/source/ui/dbgui/scuiasciiopt.cxx index 2cf981a15ff3..d45b212b1208 100644 --- a/sc/source/ui/dbgui/scuiasciiopt.cxx +++ b/sc/source/ui/dbgui/scuiasciiopt.cxx @@ -201,7 +201,7 @@ static void save_Separators( // ---------------------------------------------------------------------------- ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, - SvStream* pInStream, sal_Unicode /*cSep*/ ) : + SvStream* pInStream, sal_Unicode cSep ) : ModalDialog ( pParent, ScResId( RID_SCDLG_ASCII ) ), mpDatStream ( pInStream ), mnStreamPos( pInStream ? pInStream->Tell() : 0 ), @@ -268,7 +268,6 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, } SetText( aName ); - OUString sFieldSeparators; OUString sTextSeparators; bool bMergeDelimiters = false; @@ -282,6 +281,12 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, // load separators only when importing csv files. load_Separators (sFieldSeparators, sTextSeparators, bMergeDelimiters, bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow, nCharSet, nLanguage); + else + { + // #i115474# otherwise use sensible defaults + sFieldSeparators = OUString( cSep ); + sTextSeparators = OUString( ScAsciiOptions::cDefaultTextSep ); + } maFieldSeparators = String(sFieldSeparators); if( bMergeDelimiters ) diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index cf114cf8479e..f0378beced22 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -35,8 +35,9 @@ #include <sfx2/app.hxx> #include <vcl/msgbox.hxx> #include <vcl/waitobj.hxx> +#include <svx/dataaccessdescriptor.hxx> -#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdb/CommandType.hpp> #include "dbdocfun.hxx" #include "sc.hrc" @@ -58,6 +59,8 @@ #include "dpshttab.hxx" #include "hints.hxx" +using namespace ::com::sun::star; + // ----------------------------------------------------------------- sal_Bool ScDBDocFunc::AddDBRange( const String& rName, const ScRange& rRange, sal_Bool /* bApi */ ) @@ -1429,15 +1432,11 @@ sal_Bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pN //================================================================== // -// Datenbank-Import... +// database import -void ScDBDocFunc::UpdateImport( const String& rTarget, const String& rDBName, - const String& rTableName, const String& rStatement, sal_Bool bNative, - sal_uInt8 nType, const ::com::sun::star::uno::Reference< - ::com::sun::star::sdbc::XResultSet >& xResultSet, - const SbaSelectionList* pSelection ) +void ScDBDocFunc::UpdateImport( const String& rTarget, const svx::ODataAccessDescriptor& rDescriptor ) { - // Target ist jetzt einfach der Bereichsname + // rTarget is the name of a database range ScDocument* pDoc = rDocShell.GetDocument(); ScDBCollection& rDBColl = *pDoc->GetDBCollection(); @@ -1465,15 +1464,21 @@ void ScDBDocFunc::UpdateImport( const String& rTarget, const String& rDBName, pData->GetArea( nTab, nDummyCol,nDummyRow,nDummyCol,nDummyRow ); pData->GetImportParam( aImportParam ); - sal_Bool bSql = ( rStatement.Len() != 0 ); - - aImportParam.aDBName = rDBName; - aImportParam.bSql = bSql; - aImportParam.aStatement = bSql ? rStatement : rTableName; - aImportParam.bNative = bNative; - aImportParam.nType = nType; + rtl::OUString sDBName; + rtl::OUString sDBTable; + sal_Int32 nCommandType = 0; + rDescriptor[svx::daDataSource] >>= sDBName; + rDescriptor[svx::daCommand] >>= sDBTable; + rDescriptor[svx::daCommandType] >>= nCommandType; + + aImportParam.aDBName = sDBName; + aImportParam.bSql = ( nCommandType == sdb::CommandType::COMMAND ); + aImportParam.aStatement = sDBTable; + aImportParam.bNative = sal_False; + aImportParam.nType = static_cast<sal_uInt8>( ( nCommandType == sdb::CommandType::QUERY ) ? ScDbQuery : ScDbTable ); aImportParam.bImport = sal_True; - sal_Bool bContinue = DoImport( nTab, aImportParam, xResultSet, pSelection, sal_True ); + + sal_Bool bContinue = DoImport( nTab, aImportParam, &rDescriptor, sal_True ); // DB-Operationen wiederholen diff --git a/sc/source/ui/docshell/dbdocimp.cxx b/sc/source/ui/docshell/dbdocimp.cxx index 2537bfa0be56..368850b40399 100644 --- a/sc/source/ui/docshell/dbdocimp.cxx +++ b/sc/source/ui/docshell/dbdocimp.cxx @@ -44,6 +44,7 @@ #include <com/sun/star/sdbc/XRow.hpp> #include <com/sun/star/sdbc/XRowSet.hpp> #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/sdbcx/XRowLocate.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/frame/XDispatchProvider.hpp> @@ -65,6 +66,7 @@ #include "dbdocutl.hxx" #include "editable.hxx" #include "hints.hxx" +#include "miscuno.hxx" using namespace com::sun::star; @@ -121,99 +123,22 @@ void ScDBDocFunc::ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFram sal_Bool ScDBDocFunc::DoImportUno( const ScAddress& rPos, const uno::Sequence<beans::PropertyValue>& aArgs ) { - sal_Bool bDone = sal_False; + svx::ODataAccessDescriptor aDesc( aArgs ); // includes selection and result set - ScImportParam aImParam; - aImParam.nCol1 = aImParam.nCol2 = rPos.Col(); - aImParam.nRow1 = aImParam.nRow2 = rPos.Row(); - aImParam.bImport = sal_True; + // create database range + ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, SC_DBSEL_KEEP ); + DBG_ASSERT(pDBData, "can't create DB data"); + String sTarget = pDBData->GetName(); - uno::Reference<sdbc::XResultSet> xResSet; - uno::Sequence<uno::Any> aSelection; - - rtl::OUString aStrVal; - const beans::PropertyValue* pPropArray = aArgs.getConstArray(); - long nPropCount = aArgs.getLength(); - long i; - for (i = 0; i < nPropCount; i++) - { - const beans::PropertyValue& rProp = pPropArray[i]; - String aPropName = rProp.Name; - - if ( aPropName.EqualsAscii( SC_DBPROP_DATASOURCENAME )) - { - if ( rProp.Value >>= aStrVal ) - aImParam.aDBName = aStrVal; - } - else if ( aPropName.EqualsAscii( SC_DBPROP_COMMAND )) - { - if ( rProp.Value >>= aStrVal ) - aImParam.aStatement = aStrVal; - } - else if ( aPropName.EqualsAscii( SC_DBPROP_COMMANDTYPE )) - { - sal_Int32 nType = 0; - if ( rProp.Value >>= nType ) - { - aImParam.bSql = ( nType == sdb::CommandType::COMMAND ); - aImParam.nType = sal::static_int_cast<sal_uInt8>( ( nType == sdb::CommandType::QUERY ) ? ScDbQuery : ScDbTable ); - // nType is ignored if bSql is set - } - } - else if ( aPropName.EqualsAscii( SC_DBPROP_SELECTION )) - { - rProp.Value >>= aSelection; - } - else if ( aPropName.EqualsAscii( SC_DBPROP_CURSOR )) - { - rProp.Value >>= xResSet; - } - } - - SbaSelectionList aList; - long nSelLen = aSelection.getLength(); - for (i = 0; i < nSelLen; i++) - { - sal_Int32 nEntry = 0; - if ( aSelection[i] >>= nEntry ) - aList.Insert( (void*)nEntry, LIST_APPEND ); - } - - sal_Bool bAddrInsert = sal_False; //!??? - if ( bAddrInsert ) - { - bDone = DoImport( rPos.Tab(), aImParam, xResSet, &aList, sal_True, bAddrInsert ); - } - else - { - // create database range - //! merge this with SID_SBA_IMPORT execute in docsh4.cxx - - ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, SC_DBSEL_KEEP ); - DBG_ASSERT(pDBData, "can't create DB data"); - String sTarget = pDBData->GetName(); - - //! change UpdateImport to use only one of rTableName, rStatement - - String aTableName, aStatement; - if ( aImParam.bSql ) - aStatement = aImParam.aStatement; - else - aTableName = aImParam.aStatement; + UpdateImport( sTarget, aDesc ); - UpdateImport( sTarget, aImParam.aDBName, aTableName, aStatement, - aImParam.bNative, aImParam.nType, xResSet, &aList ); - bDone = sal_True; - } - - return bDone; + return sal_True; } // ----------------------------------------------------------------- sal_Bool ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam, - const uno::Reference< sdbc::XResultSet >& xResultSet, - const SbaSelectionList* pSelection, sal_Bool bRecord, sal_Bool bAddrInsert ) + const svx::ODataAccessDescriptor* pDescriptor, sal_Bool bRecord, sal_Bool bAddrInsert ) { ScDocument* pDoc = rDocShell.GetDocument(); @@ -251,17 +176,34 @@ sal_Bool ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam, sal_Bool bDoSelection = sal_False; sal_Bool bRealSelection = sal_False; // sal_True if not everything is selected - sal_uLong nListPos = 0; - sal_uLong nRowsRead = 0; - sal_uLong nListCount = 0; + sal_Bool bBookmarkSelection = sal_False; + sal_Int32 nListPos = 0; + sal_Int32 nRowsRead = 0; + sal_Int32 nListCount = 0; - // -1 is special - if ( pSelection && pSelection->Count() && (long)pSelection->GetObject(0) != -1L ) + uno::Sequence<uno::Any> aSelection; + if ( pDescriptor && pDescriptor->has(svx::daSelection) ) { - bDoSelection = sal_True; - nListCount = pSelection->Count(); + (*pDescriptor)[svx::daSelection] >>= aSelection; + nListCount = aSelection.getLength(); + if ( nListCount > 0 ) + { + bDoSelection = sal_True; + if ( pDescriptor->has(svx::daBookmarkSelection) ) + bBookmarkSelection = ScUnoHelpFunctions::GetBoolFromAny( (*pDescriptor)[svx::daBookmarkSelection] ); + if ( bBookmarkSelection ) + { + // From bookmarks, there's no way to detect if all records are selected. + // Rely on base to pass no selection in that case. + bRealSelection = sal_True; + } + } } + uno::Reference<sdbc::XResultSet> xResultSet; + if ( pDescriptor && pDescriptor->has(svx::daCursor) ) + xResultSet.set((*pDescriptor)[svx::daCursor], uno::UNO_QUERY); + // ImportDoc - also used for Redo ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO ); pImportDoc->InitUndo( pDoc, nTab, nTab ); @@ -346,6 +288,17 @@ sal_Bool ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam, //! error message } + uno::Reference<sdbcx::XRowLocate> xLocate; + if ( bBookmarkSelection ) + { + xLocate.set( xRowSet, uno::UNO_QUERY ); + if ( !xLocate.is() ) + { + DBG_ERRORFILE("can't get XRowLocate"); + bDoSelection = bRealSelection = bBookmarkSelection = sal_False; + } + } + uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY ); if ( nColCount > 0 && xRow.is() ) { @@ -388,16 +341,25 @@ sal_Bool ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam, { if (nListPos < nListCount) { - sal_uLong nNextRow = (sal_uLong) pSelection->GetObject(nListPos); - if ( nRowsRead+1 < nNextRow ) - bRealSelection = sal_True; - bEnd = !xRowSet->absolute(nRowsRead = nNextRow); + if ( bBookmarkSelection ) + { + bEnd = !xLocate->moveToBookmark(aSelection[nListPos]); + } + else // use record numbers + { + sal_Int32 nNextRow = 0; + aSelection[nListPos] >>= nNextRow; + if ( nRowsRead+1 < nNextRow ) + bRealSelection = sal_True; + bEnd = !xRowSet->absolute(nRowsRead = nNextRow); + } ++nListPos; } else { - bRealSelection = xRowSet->next(); - bEnd = sal_True; // more data available but not used + if ( !bBookmarkSelection && xRowSet->next() ) + bRealSelection = sal_True; // more data available but not used + bEnd = sal_True; } } diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 152f9f206cbe..e69458fd418b 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -2291,7 +2291,7 @@ sal_Bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos } ScDrawLayer::SetGlobalDrawPersist(aDragShellRef); - ScClipParam aClipParam(ScRange(nStartCol, nStartRow, 0, nEndCol, nEndRow, 0), bCut); + ScClipParam aClipParam(ScRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nStartTab), bCut); pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bScenariosAdded, true); ScDrawLayer::SetGlobalDrawPersist(NULL); @@ -4479,7 +4479,11 @@ sal_Bool ScDocFunc::SetNewRangeNames( ScRangeName* pNewRanges, sal_Bool /* bApi pDoc->CompileNameFormula( sal_False ); // CompileFormulaString aModificator.SetDocumentModified(); - SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) ); + + // #i114072# don't broadcast while loading a file + // (navigator and input line for other open documents would be notified) + if ( bCompile ) + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) ); return sal_True; } diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 734fd20a71d7..fc854e63ecbb 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -120,6 +120,7 @@ #include "optsolver.hxx" #include "sheetdata.hxx" #include "tabprotection.hxx" +#include "dpobject.hxx" #include "docsh.hxx" #include "docshimp.hxx" @@ -498,74 +499,23 @@ sal_Bool __EXPORT ScDocShell::Load( SfxMedium& rMedium ) void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) { - uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor(); - if ( xVbaEvents.is() ) try + if (rHint.ISA(ScTablesHint) ) { - using namespace ::com::sun::star::script::vba::VBAEventId; - if (rHint.ISA(ScTablesHint) ) + const ScTablesHint& rScHint = static_cast< const ScTablesHint& >( rHint ); + if (rScHint.GetId() == SC_TAB_INSERTED) { - const ScTablesHint& rScHint = static_cast< const ScTablesHint& >( rHint ); - if (rScHint.GetId() == SC_TAB_INSERTED) + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor(); + if ( xVbaEvents.is() ) try { uno::Sequence< uno::Any > aArgs( 1 ); aArgs[0] <<= rScHint.GetTab1(); - xVbaEvents->processVbaEvent( WORKBOOK_NEWSHEET, aArgs ); + xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET, aArgs ); } - } - else if ( rHint.ISA( SfxEventHint ) ) - { - sal_uLong nEventId = static_cast< const SfxEventHint& >( rHint ).GetEventId(); - switch ( nEventId ) + catch( uno::Exception& ) { - case SFX_EVENT_ACTIVATEDOC: - { - uno::Sequence< uno::Any > aArgs; - xVbaEvents->processVbaEvent( WORKBOOK_ACTIVATE, aArgs ); - } - break; - case SFX_EVENT_DEACTIVATEDOC: - { - uno::Sequence< uno::Any > aArgs; - xVbaEvents->processVbaEvent( WORKBOOK_DEACTIVATE, aArgs ); - } - break; - case SFX_EVENT_OPENDOC: - { - uno::Sequence< uno::Any > aArgs; - xVbaEvents->processVbaEvent( WORKBOOK_OPEN, aArgs ); - } - break; - case SFX_EVENT_SAVEDOCDONE: - case SFX_EVENT_SAVEASDOCDONE: - case SFX_EVENT_SAVETODOCDONE: - { - uno::Sequence< uno::Any > aArgs( 1 ); - aArgs[ 0 ] <<= true; - xVbaEvents->processVbaEvent( WORKBOOK_AFTERSAVE, aArgs ); - } - break; - case SFX_EVENT_SAVEASDOCFAILED: - case SFX_EVENT_SAVEDOCFAILED: - case SFX_EVENT_SAVETODOCFAILED: - { - uno::Sequence< uno::Any > aArgs( 1 ); - aArgs[ 0 ] <<= false; - xVbaEvents->processVbaEvent( WORKBOOK_AFTERSAVE, aArgs ); - } - break; - case SFX_EVENT_CLOSEDOC: - { - // #163655# prevent event processing after model is disposed - aDocument.SetVbaEventProcessor( uno::Reference< script::vba::XVBAEventProcessor >() ); - uno::Reference< lang::XEventListener >( xVbaEvents, uno::UNO_QUERY_THROW )->disposing( lang::EventObject() ); - } - break; } } } - catch( uno::Exception& ) - { - } if (rHint.ISA(SfxSimpleHint)) // ohne Parameter { @@ -2629,7 +2579,9 @@ void ScDocShell::SetDocumentModified( sal_Bool bIsModified /* = sal_True */ ) if ( pPaintLockData && bIsModified ) { - //! BCA_BRDCST_ALWAYS etc. also needed here? + // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results + // of RecalcModeAlways formulas (like OFFSET) after modifying cells + aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL ); aDocument.InvalidateTableArea(); // #i105279# needed here aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) ); diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index c64a65b25a55..6c799311a37b 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -59,6 +59,7 @@ using namespace ::com::sun::star; #include <vcl/msgbox.hxx> #include <vcl/waitobj.hxx> #include <tools/multisel.hxx> +#include <svx/dataaccessdescriptor.hxx> #include <svx/drawitem.hxx> #include <svx/fmview.hxx> #include <svx/pageitem.hxx> @@ -200,19 +201,21 @@ void ScDocShell::Execute( SfxRequest& rReq ) } break; - - // SID_SBA_QRY_CHANGETARGET gibts nicht mehr - auch in idl raus - case SID_SBA_IMPORT: { if (pReqArgs) { - const sal_Unicode cSbaSep = 11; // Trennzeichen - const SfxPoolItem* pItem; - String sSbaData, sTarget; + svx::ODataAccessDescriptor aDesc; if ( pReqArgs->GetItemState( nSlot, sal_True, &pItem ) == SFX_ITEM_SET ) - sSbaData = ((const SfxStringItem*)pItem)->GetValue(); + { + uno::Any aAny = static_cast<const SfxUsrAnyItem*>(pItem)->GetValue(); + uno::Sequence<beans::PropertyValue> aProperties; + if ( aAny >>= aProperties ) + aDesc.initializeFrom( aProperties ); + } + + String sTarget; if ( pReqArgs->GetItemState( FN_PARAM_1, sal_True, &pItem ) == SFX_ITEM_SET ) sTarget = ((const SfxStringItem*)pItem)->GetValue(); @@ -220,33 +223,6 @@ void ScDocShell::Execute( SfxRequest& rReq ) if ( pReqArgs->GetItemState( FN_PARAM_2, sal_True, &pItem ) == SFX_ITEM_SET ) bIsNewArea = ((const SfxBoolItem*)pItem)->GetValue(); - ::com::sun::star::uno::Reference< - ::com::sun::star::sdbc::XResultSet > xResultSet; - if ( pReqArgs->GetItemState( FN_PARAM_3, sal_False, &pItem ) == SFX_ITEM_SET && pItem ) - xResultSet.set(((const SfxUsrAnyItem*)pItem)->GetValue(),::com::sun::star::uno::UNO_QUERY); - - String sDBName = sSbaData.GetToken(0,cSbaSep); // Datenbankname - String sDBTable = sSbaData.GetToken(1,cSbaSep); // Tabellen- oder Query-Name - String sTabFlag = sSbaData.GetToken(2,cSbaSep); - String sDBSql = sSbaData.GetToken(3,cSbaSep); // SQL im Klartext - - sal_uInt8 nType = ScDbTable; // "0" oder "1" - if ( sTabFlag.EqualsAscii("0") ) // "0" = Query, "1" = Table (Default) - nType = ScDbQuery; - - SbaSelectionListRef pSelectionList = new SbaSelectionList; - xub_StrLen nCount = sSbaData.GetTokenCount(cSbaSep); - - for (xub_StrLen i = 4; i < nCount; i++) - { - String aSelItem = sSbaData.GetToken(i,cSbaSep); - if (aSelItem.Len()) - { - void *pPtr = (void*)aSelItem.ToInt32(); - pSelectionList->Insert( pPtr, LIST_APPEND ); - } - } - // bei Bedarf neuen Datenbankbereich anlegen sal_Bool bMakeArea = sal_False; if (bIsNewArea) @@ -287,9 +263,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) if (bDo) { - ScDBDocFunc(*this).UpdateImport( sTarget, sDBName, - sDBTable, sDBSql, sal_True, nType, xResultSet, - pSelectionList ); + ScDBDocFunc(*this).UpdateImport( sTarget, aDesc ); rReq.Done(); // UpdateImport aktualisiert auch die internen Operationen diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx index fb5c30c5826e..60b872362004 100644 --- a/sc/source/ui/docshell/docsh5.cxx +++ b/sc/source/ui/docshell/docsh5.cxx @@ -41,8 +41,6 @@ #include <sfx2/bindings.hxx> #include <svl/smplhint.hxx> -#include <com/sun/star/sdbc/XResultSet.hpp> - // INCLUDE --------------------------------------------------------------- #include "docsh.hxx" @@ -980,8 +978,7 @@ IMPL_LINK( ScDocShell, RefreshDBDataHdl, ScRefreshTimer*, pRefreshTimer ) { ScRange aRange; pDBData->GetArea( aRange ); - ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet> xResultSet; - bContinue = aFunc.DoImport( aRange.aStart.Tab(), aImportParam, xResultSet, NULL, sal_True, sal_False ); //! Api-Flag as parameter + bContinue = aFunc.DoImport( aRange.aStart.Tab(), aImportParam, NULL, sal_True, sal_False ); //! Api-Flag as parameter // internal operations (sort, query, subtotal) only if no error if (bContinue) { diff --git a/sc/source/ui/docshell/docsh8.cxx b/sc/source/ui/docshell/docsh8.cxx index 93101e802651..675f9ea109c0 100644 --- a/sc/source/ui/docshell/docsh8.cxx +++ b/sc/source/ui/docshell/docsh8.cxx @@ -251,6 +251,7 @@ sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet { sal_uLong nErr = eERR_OK; long i; + long nColCount = 0; try { @@ -262,14 +263,7 @@ sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet return nRet; ::utl::DisposableComponent aConnectionHelper(xConnection); - long nRowCount = 0; - if ( nRowCount < 0 ) - { - DBG_ERROR("can't get row count"); - nRowCount = 0; - } - - ScProgress aProgress( this, ScGlobal::GetRscString( STR_LOAD_DOC ), nRowCount ); + ScProgress aProgress( this, ScGlobal::GetRscString( STR_LOAD_DOC ), 0 ); uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory(); uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance( rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), @@ -296,7 +290,6 @@ sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet xRowSet->execute(); - long nColCount = 0; uno::Reference<sdbc::XResultSetMetaData> xMeta; uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY ); if ( xMetaSupp.is() ) @@ -310,10 +303,6 @@ sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning } - if ( nColCount > 0 ) - aDocument.DoColResize( 0, 0, static_cast<SCCOL>(nColCount) - 1, - static_cast<SCSIZE>(nRowCount) + 1 ); - uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY ); DBG_ASSERT( xRow.is(), "can't get Row" ); if (!xRow.is()) return SCERR_IMPORT_CONNECT; @@ -327,6 +316,9 @@ sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet // read column names //! add type descriptions + aProgress.SetState( 0 ); + ScColumn::bDoubleAlloc = sal_True; // row count isn't readily available in advance + for (i=0; i<nColCount; i++) { String aHeader = xMeta->getColumnLabel( i+1 ); @@ -384,9 +376,6 @@ sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet bEnd = sal_True; // don't continue nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning message } - - if ( nRowCount ) - aProgress.SetStateOnPercent( nRow ); } } catch ( sdbc::SQLException& ) @@ -399,6 +388,10 @@ sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet nErr = ERRCODE_IO_GENERAL; } + ScColumn::bDoubleAlloc = sal_False; + if ( nColCount > 0 ) + aDocument.DoColResize( 0, 0, static_cast<SCCOL>(nColCount) - 1, 0 ); + return nErr; } diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index e3293a7eed5b..a0581ec0d1c3 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -61,6 +61,7 @@ #include "sfx2/linkmgr.hxx" #include "tools/urlobj.hxx" #include "unotools/ucbhelper.hxx" +#include "unotools/localfilehelper.hxx" #include <memory> #include <algorithm> @@ -934,26 +935,6 @@ void ScExternalRefCache::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const rNumFmts.swap(aNumFmts); } -bool ScExternalRefCache::hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const -{ - DocItem* pDoc = getDocItem(nFileId); - if (!pDoc) - return false; - - String aUpperName = ScGlobal::pCharClass->upper(rTabName); - vector<TableName>::const_iterator itrBeg = pDoc->maTableNames.begin(), itrEnd = pDoc->maTableNames.end(); - vector<TableName>::const_iterator itr = ::std::find_if( - itrBeg, itrEnd, TabNameSearchPredicate(aUpperName)); - - return itr != itrEnd; -} - -size_t ScExternalRefCache::getCacheTableCount(sal_uInt16 nFileId) const -{ - DocItem* pDoc = getDocItem(nFileId); - return pDoc ? pDoc->maTables.size() : 0; -} - bool ScExternalRefCache::setCacheDocReferenced( sal_uInt16 nFileId ) { DocItem* pDocItem = getDocItem(nFileId); @@ -1576,16 +1557,6 @@ void ScExternalRefManager::getAllCachedNumberFormats(vector<sal_uInt32>& rNumFmt maRefCache.getAllNumberFormats(rNumFmts); } -bool ScExternalRefManager::hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const -{ - return maRefCache.hasCacheTable(nFileId, rTabName); -} - -size_t ScExternalRefManager::getCacheTableCount(sal_uInt16 nFileId) const -{ - return maRefCache.getCacheTableCount(nFileId); -} - sal_uInt16 ScExternalRefManager::getExternalFileCount() const { return static_cast< sal_uInt16 >( maSrcFiles.size() ); @@ -2026,7 +1997,10 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, Stri return NULL; String aOptions( pFileData->maFilterOptions ); - ScDocumentLoader::GetFilterName(aFile, rFilter, aOptions, true, false); + if ( pFileData->maFilterName.Len() ) + rFilter = pFileData->maFilterName; // don't overwrite stored filter with guessed filter + else + ScDocumentLoader::GetFilterName(aFile, rFilter, aOptions, true, false); const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName(rFilter); if (!pFileData->maRelativeName.Len()) @@ -2093,10 +2067,18 @@ bool ScExternalRefManager::isFileLoadable(const String& rFile) const if (isOwnDocument(rFile)) return false; - if (utl::UCBContentHelper::IsFolder(rFile)) - return false; + String aPhysical; + if (utl::LocalFileHelper::ConvertURLToPhysicalName(rFile, aPhysical) && aPhysical.Len()) + { + // #i114504# try IsFolder/Exists only for file URLs + + if (utl::UCBContentHelper::IsFolder(rFile)) + return false; - return utl::UCBContentHelper::Exists(rFile); + return utl::UCBContentHelper::Exists(rFile); + } + else + return true; // for http and others, Exists doesn't work, but the URL can still be opened } void ScExternalRefManager::maybeLinkExternalFile(sal_uInt16 nFileId) @@ -2111,7 +2093,16 @@ void ScExternalRefManager::maybeLinkExternalFile(sal_uInt16 nFileId) return; String aFilter, aOptions; - ScDocumentLoader::GetFilterName(*pFileName, aFilter, aOptions, true, false); + const SrcFileData* pFileData = getExternalFileData(nFileId); + if (pFileData) + { + aFilter = pFileData->maFilterName; + aOptions = pFileData->maFilterOptions; + } + // If a filter was already set (for example, loading the cached table), + // don't call GetFilterName which has to access the source file. + if (!aFilter.Len()) + ScDocumentLoader::GetFilterName(*pFileName, aFilter, aOptions, true, false); sfx2::LinkManager* pLinkMgr = mpDoc->GetLinkManager(); ScExternalRefLink* pLink = new ScExternalRefLink(mpDoc, nFileId, aFilter); DBG_ASSERT(pFileName, "ScExternalRefManager::insertExternalFileLink: file name pointer is NULL"); @@ -2344,6 +2335,22 @@ void ScExternalRefManager::resetSrcFileData(const String& rBaseFileUrl) } } +void ScExternalRefManager::updateAbsAfterLoad() +{ + String aOwn( getOwnDocumentName() ); + for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end(); + itr != itrEnd; ++itr) + { + // update maFileName to the real file name, + // to be called when the original name is no longer needed (after CompileXML) + + itr->maybeCreateRealFileName( aOwn ); + String aReal = itr->maRealFileName; + if (aReal.Len()) + itr->maFileName = aReal; + } +} + void ScExternalRefManager::removeRefCell(ScFormulaCell* pCell) { for_each(maRefCells.begin(), maRefCells.end(), RemoveFormulaCell(pCell)); diff --git a/sc/source/ui/drawfunc/drawsh5.cxx b/sc/source/ui/drawfunc/drawsh5.cxx index 3130e39b79f1..70b5db6b5147 100644 --- a/sc/source/ui/drawfunc/drawsh5.cxx +++ b/sc/source/ui/drawfunc/drawsh5.cxx @@ -299,8 +299,7 @@ void ScDrawShell::ExecDrawFunc( SfxRequest& rReq ) rBindings.Invalidate(SID_OBJECT_HEAVEN); rBindings.Invalidate(SID_OBJECT_HELL); // leave draw shell if nothing selected (layer may be locked) - if ( pView->GetMarkedObjectList().GetMarkCount() == 0 ) - pViewData->GetViewShell()->SetDrawShell( sal_False ); + pViewData->GetViewShell()->UpdateDrawShell(); break; case SID_FRAME_TO_TOP: @@ -370,14 +369,12 @@ void ScDrawShell::ExecDrawFunc( SfxRequest& rReq ) case SID_DELETE: case SID_DELETE_CONTENTS: pView->DeleteMarked(); - if (!pTabView->IsDrawSelMode()) - pViewData->GetViewShell()->SetDrawShell( sal_False ); + pViewData->GetViewShell()->UpdateDrawShell(); break; case SID_CUT: pView->DoCut(); - if (!pTabView->IsDrawSelMode()) - pViewData->GetViewShell()->SetDrawShell( sal_False ); + pViewData->GetViewShell()->UpdateDrawShell(); break; case SID_COPY: diff --git a/sc/source/ui/drawfunc/drtxtob2.cxx b/sc/source/ui/drawfunc/drtxtob2.cxx index 137ddfa654d2..2f898068399a 100644 --- a/sc/source/ui/drawfunc/drtxtob2.cxx +++ b/sc/source/ui/drawfunc/drtxtob2.cxx @@ -83,8 +83,7 @@ void __EXPORT ScDrawTextObjectBar::ExecuteGlobal( SfxRequest &rReq ) case SID_CUT: pView->DoCut(); - if (!pTabView->IsDrawSelMode()) - pViewData->GetViewShell()->SetDrawShell( sal_False ); + pViewData->GetViewShell()->UpdateDrawShell(); break; case SID_PASTE: diff --git a/sc/source/ui/drawfunc/fusel.cxx b/sc/source/ui/drawfunc/fusel.cxx index 80a8d46de9da..368a27b4bd5d 100644 --- a/sc/source/ui/drawfunc/fusel.cxx +++ b/sc/source/ui/drawfunc/fusel.cxx @@ -56,6 +56,7 @@ #include "drwlayer.hxx" #include "userdat.hxx" #include "scmod.hxx" +#include "client.hxx" #include "charthelper.hxx" #include "docuno.hxx" #include "docsh.hxx" diff --git a/sc/source/ui/inc/dbdocfun.hxx b/sc/source/ui/inc/dbdocfun.hxx index c443be157f8c..d22dc4969cff 100644 --- a/sc/source/ui/inc/dbdocfun.hxx +++ b/sc/source/ui/inc/dbdocfun.hxx @@ -40,7 +40,6 @@ struct ScSortParam; struct ScSubTotalParam; class SfxViewFrame; -class SbaSelectionList; class ScDBData; class ScDocShell; class ScAddress; @@ -51,21 +50,14 @@ namespace com { namespace sun { namespace star { namespace beans { struct PropertyValue; } - namespace sdbc { - class XResultSet; - } } } } +namespace svx { + class ODataAccessDescriptor; +} + // --------------------------------------------------------------------------- // ----------------------------------------------------------------- -class SbaSelectionList: public List , public SvRefBase -{ -public: - SbaSelectionList(): - List(CONTAINER_MAXBLOCKSIZE,100,100){} -}; - -SV_DECL_IMPL_REF(SbaSelectionList) class ScDBDocFunc @@ -79,29 +71,23 @@ public: ScDBDocFunc( ScDocShell& rDocSh ): rDocShell(rDocSh) {} ~ScDBDocFunc() {} - void UpdateImport( const String& rTarget, const String& rDBName, - const String& rTableName, const String& rStatement, - sal_Bool bNative, sal_uInt8 nType, - const ::com::sun::star::uno::Reference< - ::com::sun::star::sdbc::XResultSet >& xResultSet, - const SbaSelectionList* pSelection ); - - sal_Bool DoImport( SCTAB nTab, const ScImportParam& rParam, - const ::com::sun::star::uno::Reference< - ::com::sun::star::sdbc::XResultSet >& xResultSet, - const SbaSelectionList* pSelection, sal_Bool bRecord, + void UpdateImport( const String& rTarget, const svx::ODataAccessDescriptor& rDescriptor ); + + sal_Bool DoImport( SCTAB nTab, const ScImportParam& rParam, + const svx::ODataAccessDescriptor* pDescriptor, // used for selection and existing ResultSet + sal_Bool bRecord, sal_Bool bAddrInsert = sal_False ); - sal_Bool DoImportUno( const ScAddress& rPos, + sal_Bool DoImportUno( const ScAddress& rPos, const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue>& aArgs ); static void ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFrame ); - sal_Bool Sort( SCTAB nTab, const ScSortParam& rSortParam, + sal_Bool Sort( SCTAB nTab, const ScSortParam& rSortParam, sal_Bool bRecord, sal_Bool bPaint, sal_Bool bApi ); - SC_DLLPUBLIC sal_Bool Query( SCTAB nTab, const ScQueryParam& rQueryParam, + SC_DLLPUBLIC sal_Bool Query( SCTAB nTab, const ScQueryParam& rQueryParam, const ScRange* pAdvSource, sal_Bool bRecord, sal_Bool bApi ); sal_Bool DoSubTotals( SCTAB nTab, const ScSubTotalParam& rParam, diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index aad45058de2c..3e6a7eb6085a 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -395,6 +395,8 @@ public: void UpdateDPFromFieldPopupMenu(); + void UpdateVisibleRange(); + // #114409# void CursorChanged(); void DrawLayerCreated(); diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx index 8291877bbc57..9f745b4cd96c 100644 --- a/sc/source/ui/inc/inputhdl.hxx +++ b/sc/source/ui/inc/inputhdl.hxx @@ -211,7 +211,7 @@ public: EditView* GetTopView() { return pTopView; } sal_Bool DataChanging( sal_Unicode cTyped = 0, sal_Bool bFromCommand = sal_False ); - void DataChanged( sal_Bool bFromTopNotify = sal_False ); + void DataChanged( sal_Bool bFromTopNotify = sal_False, sal_Bool bSetModified = sal_True ); sal_Bool TakesReturn() const { return ( nTipVisible != 0 ); } diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx index 26d2262b5a8e..1e3d64bf2f74 100644 --- a/sc/source/ui/inc/output.hxx +++ b/sc/source/ui/inc/output.hxx @@ -50,6 +50,7 @@ struct ScTableInfo; class ScTabViewShell; class ScPageBreakData; class FmFormView; +class ScFieldEditEngine; // #i74769# SdrPaintWindow predefine class SdrPaintWindow; @@ -182,6 +183,8 @@ private: void DrawRotatedFrame( const Color* pForceColor ); // pixel + ScFieldEditEngine* CreateOutputEditEngine(); + public: ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType, ScTableInfo& rTabInfo, ScDocument* pNewDoc, diff --git a/sc/source/ui/inc/preview.hxx b/sc/source/ui/inc/preview.hxx index e5f901720b36..3f23b830dea8 100644 --- a/sc/source/ui/inc/preview.hxx +++ b/sc/source/ui/inc/preview.hxx @@ -64,8 +64,9 @@ private: FmFormView* pDrawView; // intern: - sal_Bool bInPaint; - sal_Bool bInGetState; + bool bInPaint; + bool bInSetZoom; + sal_Bool bInGetState; ScDocShell* pDocShell; ScPreviewShell* pViewShell; diff --git a/sc/source/ui/inc/printfun.hxx b/sc/source/ui/inc/printfun.hxx index 601496c315eb..264ec76d13b7 100644 --- a/sc/source/ui/inc/printfun.hxx +++ b/sc/source/ui/inc/printfun.hxx @@ -247,14 +247,6 @@ public: const ScPrintState& rState, const ScPrintOptions* pOptions ); - ScPrintFunc( ScDocShell* pShell, Window* pWindow, SCTAB nTab, - long nPage = 0, long nDocP = 0, - const ScRange* pArea = NULL, - const ScPrintOptions* pOptions = NULL ); - - ScPrintFunc( ScDocShell* pShell, Window* pWindow, - const ScPrintState& rState, - const ScPrintOptions* pOptions ); ~ScPrintFunc(); static void DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double nPrintFactor, @@ -276,10 +268,8 @@ public: void ApplyPrintSettings(); // aus DoPrint() schon gerufen long DoPrint( const MultiSelection& rPageRanges, - /*long nStartPage, long nDisplayStart, sal_Bool bDoPrint, - SfxProgress* pProgress, ScPreviewLocationData* pLocationData );*/ - long nStartPage, long nDisplayStart, sal_Bool bDoPrint = sal_True, - SfxProgress* pProgress = NULL, ScPreviewLocationData* pLocationData = NULL); + long nStartPage, long nDisplayStart, sal_Bool bDoPrint, + ScPreviewLocationData* pLocationData ); // Werte abfragen - sofort diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index 9c3327805a88..09861e778826 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -194,6 +194,8 @@ private: void UpdateVarZoom(); + void UpdateVisibleRange(); + static void SetScrollBar( ScrollBar& rScroll, long nRangeMax, long nVisible, long nPos, sal_Bool bLayoutRTL ); static long GetScrollBarPos( ScrollBar& rScroll, sal_Bool bLayoutRTL ); diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx index 241b1842ad07..b310eaa244b2 100644 --- a/sc/source/ui/inc/tabvwsh.hxx +++ b/sc/source/ui/inc/tabvwsh.hxx @@ -309,7 +309,7 @@ public: void ExecDrawOpt(SfxRequest& rReq); void GetDrawOptState(SfxItemSet &rSet); - + void UpdateDrawShell(); void SetDrawShell( sal_Bool bActive ); void SetDrawTextShell( sal_Bool bActive ); diff --git a/sc/source/ui/inc/undodraw.hxx b/sc/source/ui/inc/undodraw.hxx index 20db8643e3ca..cc2264807ace 100644 --- a/sc/source/ui/inc/undodraw.hxx +++ b/sc/source/ui/inc/undodraw.hxx @@ -37,6 +37,8 @@ class ScUndoDraw: public SfxUndoAction SfxUndoAction* pDrawUndo; ScDocShell* pDocShell; + void UpdateSubShell(); + public: TYPEINFO(); ScUndoDraw( SfxUndoAction* pUndo, ScDocShell* pDocSh ); diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src index 4f99f90b8437..a63a897b007c 100644 --- a/sc/source/ui/src/scfuncs.src +++ b/sc/source/ui/src/scfuncs.src @@ -3468,6 +3468,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 Text [ en-US ] = "The value for the y coordinate." ; }; }; + // -=*# Resource for function DEG #*=- Resource SC_OPCODE_DEG { diff --git a/sc/source/ui/styleui/scstyles.src b/sc/source/ui/styleui/scstyles.src index 1968b6dca877..07e4dbd85151 100644 --- a/sc/source/ui/styleui/scstyles.src +++ b/sc/source/ui/styleui/scstyles.src @@ -31,6 +31,19 @@ StyleFamily = family; \ FilterList = { filter } +String STR_STYLE_FILTER_USED +{ + Text [ en-US ] = "Applied Styles" ; +}; +String STR_STYLE_FILTER_USERDEF +{ + Text [ en-US ] = "Custom Styles" ; +}; +String STR_STYLE_FILTER_ALL +{ + Text [ en-US ] = "All Styles" ; +}; + //------------------------------------------------------------------------ SfxStyleFamilies DLG_STYLE_DESIGNER { diff --git a/sc/source/ui/undo/undodraw.cxx b/sc/source/ui/undo/undodraw.cxx index 860796fc9a15..1c7a65d3563c 100644 --- a/sc/source/ui/undo/undodraw.cxx +++ b/sc/source/ui/undo/undodraw.cxx @@ -28,141 +28,13 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - -//------------------------------------------------------------------ - -// TOOLS -#define _BIGINT_HXX -#define _SFXMULTISEL_HXX -#define _STACK_HXX -#define _QUEUE_HXX -#define _DYNARR_HXX -#define _TREELIST_HXX -#define _CACHESTR_HXX -#define _NEW_HXX -//#define _SHL_HXX -//#define _LINK_HXX -//#define _ERRCODE_HXX -//#define _GEN_HXX -//#define _FRACT_HXX -//#define _STRING_HXX -//#define _MTF_HXX -//#define _CONTNR_HXX -//#define _LIST_HXX -//#define _TABLE_HXX -#define _DYNARY_HXX -//#define _UNQIDX_HXX -#define _SVMEMPOOL_HXX -//#define _UNQID_HXX -//#define _DEBUG_HXX -//#define _DATE_HXX -//#define _TIME_HXX -//#define _DATETIME_HXX -//#define _INTN_HXX -//#define _WLDCRD_HXX -//#define _FSYS_HXX -//#define _STREAM_HXX -#define _CACHESTR_HXX -#define _SV_MULTISEL_HXX - -//SV -//#define _CLIP_HXX -#define _CONFIG_HXX -#define _CURSOR_HXX -#define _FONTDLG_HXX -#define _PRVWIN_HXX -//#define _COLOR_HXX -//#define _PAL_HXX -//#define _BITMAP_HXX -//#define _GDIOBJ_HXX -//#define _POINTR_HXX -//#define _ICON_HXX -//#define _IMAGE_HXX -//#define _KEYCOD_HXX -//#define _EVENT_HXX -#define _HELP_HXX -//#define _APP_HXX -//#define _MDIAPP_HXX -//#define _TIMER_HXX -//#define _METRIC_HXX -//#define _REGION_HXX -//#define _OUTDEV_HXX -//#define _SYSTEM_HXX -//#define _VIRDEV_HXX -//#define _JOBSET_HXX -//#define _PRINT_HXX -//#define _WINDOW_HXX -//#define _SYSWIN_HXX -//#define _WRKWIN_HXX -#define _MDIWIN_HXX -//#define _FLOATWIN_HXX -//#define _DOCKWIN_HXX -//#define _CTRL_HXX -//#define _SCRBAR_HXX -//#define _BUTTON_HXX -//#define _IMAGEBTN_HXX -//#define _FIXED_HXX -//#define _GROUP_HXX -//#define _EDIT_HXX -//#define _COMBOBOX_HXX -//#define _LSTBOX_HXX -//#define _SELENG_HXX -//#define _SPLIT_HXX -#define _SPIN_HXX -//#define _FIELD_HXX -//#define _MOREBTN_HXX -//#define _TOOLBOX_HXX -//#define _STATUS_HXX -//#define _DIALOG_HXX -//#define _MSGBOX_HXX -//#define _SYSDLG_HXX -#define _FILDLG_HXX -//#define _PRNDLG_HXX -#define _COLDLG_HXX -//#define _TABDLG_HXX -//#define _MENU_HXX -//#define _GDIMTF_HXX -//#define _POLY_HXX -//#define _ACCEL_HXX -//#define _GRAPH_HXX -#define _SOUND_HXX - - -#define SI_NOITEMS -//#define SI_NODRW -#define _SI_NOSBXCONTROLS -#define _SI_NOOTHERFORMS -#define _SI_NOCONTROL -#define _SI_NOSBXCONTROLS -#define _SIDLL_HXX - -// SFX -#define _SFXAPPWIN_HXX -#define _SFX_SAVEOPT_HXX -//#define _SFX_CHILDWIN_HXX -//#define _SFXCTRLITEM_HXX -#define _SFXPRNMON_HXX -#define _INTRO_HXX -#define _SFXMSGDESCR_HXX -#define _SFXMSGPOOL_HXX -#define _SFXFILEDLG_HXX -#define _PASSWD_HXX -#define _SFXTBXCTRL_HXX -#define _SFXSTBITEM_HXX -#define _SFXMNUITEM_HXX -#define _SFXIMGMGR_HXX -#define _SFXTBXMGR_HXX -#define _SFXSTBMGR_HXX -#define _SFX_MINFITEM_HXX -#define _SFXEVENT_HXX - // INCLUDE --------------------------------------------------------------- #include <svx/svdundo.hxx> #include "undodraw.hxx" #include "docsh.hxx" +#include "tabvwsh.hxx" // ----------------------------------------------------------------------- @@ -233,12 +105,21 @@ sal_Bool __EXPORT ScUndoDraw::Merge( SfxUndoAction* pNextAction ) return sal_False; } +void ScUndoDraw::UpdateSubShell() +{ + // #i26822# remove the draw shell if the selected object has been removed + ScTabViewShell* pViewShell = pDocShell->GetBestViewShell(); + if (pViewShell) + pViewShell->UpdateDrawShell(); +} + void __EXPORT ScUndoDraw::Undo() { if (pDrawUndo) { pDrawUndo->Undo(); pDocShell->SetDrawModified(); + UpdateSubShell(); } } @@ -248,6 +129,7 @@ void __EXPORT ScUndoDraw::Redo() { pDrawUndo->Redo(); pDocShell->SetDrawModified(); + UpdateSubShell(); } } diff --git a/sc/source/ui/unoobj/addruno.cxx b/sc/source/ui/unoobj/addruno.cxx index e54c47b6bd64..0dde4fb9e880 100644 --- a/sc/source/ui/unoobj/addruno.cxx +++ b/sc/source/ui/unoobj/addruno.cxx @@ -195,7 +195,7 @@ void SAL_CALL ScAddressConversionObj::setPropertyValue( const rtl::OUString& aPr else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) || aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) ) { ::formula::FormulaGrammar::AddressConvention eConv = aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) ? - ::formula::FormulaGrammar::CONV_OOO : ::formula::FormulaGrammar::CONV_XL_A1; + ::formula::FormulaGrammar::CONV_XL_A1 : ::formula::FormulaGrammar::CONV_OOO; // parse the file format string rtl::OUString sRepresentation; @@ -273,7 +273,7 @@ uno::Any SAL_CALL ScAddressConversionObj::getPropertyValue( const rtl::OUString& else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) || aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) ) { ::formula::FormulaGrammar::AddressConvention eConv = aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) ? - ::formula::FormulaGrammar::CONV_OOO : ::formula::FormulaGrammar::CONV_XL_A1; + ::formula::FormulaGrammar::CONV_XL_A1 : ::formula::FormulaGrammar::CONV_OOO; // generate file format string - always include sheet String aFormatStr; diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index 3737e742b441..f5a94df0bfba 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -1110,35 +1110,60 @@ sal_Bool lcl_PutDataArray( ScDocShell& rDocShell, const ScRange& rRange, for (long nCol=0; nCol<nCols; nCol++) { const uno::Any& rElement = pColArr[nCol]; - uno::TypeClass eElemClass = rElement.getValueTypeClass(); - if ( eElemClass == uno::TypeClass_VOID ) - { - // void = "no value" - pDoc->SetError( nDocCol, nDocRow, nTab, NOTAVAILABLE ); - } - else if ( eElemClass == uno::TypeClass_BYTE || - eElemClass == uno::TypeClass_SHORT || - eElemClass == uno::TypeClass_UNSIGNED_SHORT || - eElemClass == uno::TypeClass_LONG || - eElemClass == uno::TypeClass_UNSIGNED_LONG || - eElemClass == uno::TypeClass_FLOAT || - eElemClass == uno::TypeClass_DOUBLE ) + switch( rElement.getValueTypeClass() ) { + case uno::TypeClass_VOID: + { + // void = "no value" + pDoc->SetError( nDocCol, nDocRow, nTab, NOTAVAILABLE ); + } + break; + // #87871# accept integer types because Basic passes a floating point // variable as byte, short or long if it's an integer number. - double fVal(0.0); - rElement >>= fVal; - pDoc->SetValue( nDocCol, nDocRow, nTab, fVal ); - } - else if ( eElemClass == uno::TypeClass_STRING ) - { - rtl::OUString aUStr; - rElement >>= aUStr; - if ( aUStr.getLength() ) - pDoc->PutCell( nDocCol, nDocRow, nTab, new ScStringCell( aUStr ) ); + case uno::TypeClass_BYTE: + case uno::TypeClass_SHORT: + case uno::TypeClass_UNSIGNED_SHORT: + case uno::TypeClass_LONG: + case uno::TypeClass_UNSIGNED_LONG: + case uno::TypeClass_FLOAT: + case uno::TypeClass_DOUBLE: + { + double fVal(0.0); + rElement >>= fVal; + pDoc->SetValue( nDocCol, nDocRow, nTab, fVal ); + } + break; + + case uno::TypeClass_STRING: + { + rtl::OUString aUStr; + rElement >>= aUStr; + if ( aUStr.getLength() ) + pDoc->PutCell( nDocCol, nDocRow, nTab, new ScStringCell( aUStr ) ); + } + break; + + // accept Sequence<FormulaToken> for formula cells + case uno::TypeClass_SEQUENCE: + { + uno::Sequence< sheet::FormulaToken > aTokens; + if ( rElement >>= aTokens ) + { + ScTokenArray aTokenArray; + ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, aTokens ); + ScAddress aPos( nDocCol, nDocRow, nTab ); + ScBaseCell* pNewCell = new ScFormulaCell( pDoc, aPos, &aTokenArray ); + pDoc->PutCell( aPos, pNewCell ); + } + else + bError = true; + } + break; + + default: + bError = true; // invalid type } - else - bError = sal_True; // invalid type ++nDocCol; } @@ -5907,12 +5932,11 @@ void SAL_CALL ScCellRangeObj::doImport( const uno::Sequence<beans::PropertyValue aParam.nRow2 = aRange.aEnd.Row(); //! TODO: could we get passed a valid result set by any means? - uno::Reference< sdbc::XResultSet > xResultSet; pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen ScDBDocFunc aFunc(*pDocSh); // Bereich muss angelegt sein - aFunc.DoImport( nTab, aParam, xResultSet, NULL, sal_True, sal_False ); //! Api-Flag als Parameter + aFunc.DoImport( nTab, aParam, NULL, sal_True ); //! Api-Flag as parameter } } diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx index 835959e68e3d..edc47f6c7a58 100644 --- a/sc/source/ui/unoobj/chart2uno.cxx +++ b/sc/source/ui/unoobj/chart2uno.cxx @@ -53,6 +53,7 @@ #include <com/sun/star/table/CellAddress.hpp> #include <com/sun/star/text/XText.hpp> #include <comphelper/extract.hxx> +#include <comphelper/processfactory.hxx> #include <vector> #include <list> @@ -62,8 +63,6 @@ SC_SIMPLE_SERVICE_INFO( ScChart2DataProvider, "ScChart2DataProvider", "com.sun.star.chart2.data.DataProvider") SC_SIMPLE_SERVICE_INFO( ScChart2DataSource, "ScChart2DataSource", "com.sun.star.chart2.data.DataSource") -SC_SIMPLE_SERVICE_INFO( ScChart2LabeledDataSequence, "ScChart2LabeledDataSequence", - "com.sun.star.chart2.data.LabeledDataSequence") SC_SIMPLE_SERVICE_INFO( ScChart2DataSequence, "ScChart2DataSequence", "com.sun.star.chart2.data.DataSequence") #if USE_CHART2_EMPTYDATASEQUENCE @@ -1051,27 +1050,40 @@ void ScChart2DataProvider::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint namespace { -ScChart2LabeledDataSequence* lcl_createScChart2DataSequenceFromTokens( auto_ptr< vector<ScSharedTokenRef> > pValueTokens, auto_ptr< vector<ScSharedTokenRef> > pLabelTokens, - ScDocument* pDoc, const uno::Reference < chart2::data::XDataProvider >& xDP, bool bIncludeHiddenCells ) +Reference< chart2::data::XLabeledDataSequence > lcl_createLabeledDataSequenceFromTokens( + auto_ptr< vector< ScSharedTokenRef > > pValueTokens, auto_ptr< vector< ScSharedTokenRef > > pLabelTokens, + ScDocument* pDoc, const Reference< chart2::data::XDataProvider >& xDP, bool bIncludeHiddenCells ) { - ScChart2LabeledDataSequence* pRet = 0; + Reference< chart2::data::XLabeledDataSequence > xResult; bool bHasValues = pValueTokens.get() && !pValueTokens->empty(); bool bHasLabel = pLabelTokens.get() && !pLabelTokens->empty(); if( bHasValues || bHasLabel ) { - pRet = new ScChart2LabeledDataSequence(pDoc); - if(bHasValues) + try { - uno::Reference < chart2::data::XDataSequence > xSeq(new ScChart2DataSequence(pDoc, xDP, pValueTokens.release(), bIncludeHiddenCells)); - pRet->setValues(xSeq); + Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); + if ( xContext.is() ) + { + xResult.set( xContext->getServiceManager()->createInstanceWithContext( + ::rtl::OUString::createFromAscii( "com.sun.star.chart2.data.LabeledDataSequence" ), + xContext ), uno::UNO_QUERY_THROW ); + } + if ( bHasValues ) + { + Reference< chart2::data::XDataSequence > xSeq( new ScChart2DataSequence( pDoc, xDP, pValueTokens.release(), bIncludeHiddenCells ) ); + xResult->setValues( xSeq ); + } + if ( bHasLabel ) + { + Reference< chart2::data::XDataSequence > xLabelSeq( new ScChart2DataSequence( pDoc, xDP, pLabelTokens.release(), bIncludeHiddenCells ) ); + xResult->setLabel( xLabelSeq ); + } } - if(bHasLabel) + catch( const uno::Exception& ) { - uno::Reference < chart2::data::XDataSequence > xLabelSeq(new ScChart2DataSequence(pDoc, xDP, pLabelTokens.release(), bIncludeHiddenCells)); - pRet->setLabel(xLabelSeq); } } - return pRet; + return xResult; } //---------------------------------------------------- @@ -1474,7 +1486,7 @@ ScChart2DataProvider::createDataSource( return xResult; ScChart2DataSource* pDS = NULL; - std::list < ScChart2LabeledDataSequence* > aSeqs; + ::std::list< Reference< chart2::data::XLabeledDataSequence > > aSeqs; // Fill Categories if( bCategories ) @@ -1488,9 +1500,12 @@ ScChart2DataProvider::createDataSource( auto_ptr< vector<ScSharedTokenRef> > pLabelTokens(NULL); pLabelTokens.reset(pChartMap->getLeftUpperCornerRanges()); - ScChart2LabeledDataSequence* pCategories = lcl_createScChart2DataSequenceFromTokens( pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells );//ownership of pointers is transfered! - if( pCategories ) - aSeqs.push_back(pCategories); + Reference< chart2::data::XLabeledDataSequence > xCategories = lcl_createLabeledDataSequenceFromTokens( + pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells ); //ownership of pointers is transfered! + if ( xCategories.is() ) + { + aSeqs.push_back( xCategories ); + } } // Fill Serieses (values and label) @@ -1509,42 +1524,47 @@ ScChart2DataProvider::createDataSource( pValueTokens.reset(pChartMap->getDataRowRanges(static_cast<SCROW>(i))); pLabelTokens.reset(pChartMap->getRowHeaderRanges(static_cast<SCROW>(i))); } - ScChart2LabeledDataSequence* pChartSeries = lcl_createScChart2DataSequenceFromTokens( pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells ); //ownership of pointers is transfered! - if( pChartSeries ) - aSeqs.push_back(pChartSeries); + Reference< chart2::data::XLabeledDataSequence > xChartSeries = lcl_createLabeledDataSequenceFromTokens( + pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells ); //ownership of pointers is transfered! + if ( xChartSeries.is() ) + { + aSeqs.push_back( xChartSeries ); + } } pDS = new ScChart2DataSource(m_pDocument); - std::list < ScChart2LabeledDataSequence* >::iterator aItr(aSeqs.begin()); - std::list < ScChart2LabeledDataSequence* >::iterator aEndItr(aSeqs.end()); + ::std::list< Reference< chart2::data::XLabeledDataSequence > >::iterator aItr( aSeqs.begin() ); + ::std::list< Reference< chart2::data::XLabeledDataSequence > >::iterator aEndItr( aSeqs.end() ); //reorder labeled sequences according to aSequenceMapping - std::vector< ScChart2LabeledDataSequence* > aSeqVector; + ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aSeqVector; while(aItr != aEndItr) { aSeqVector.push_back(*aItr); ++aItr; } - std::map< sal_Int32, ScChart2LabeledDataSequence* > aSequenceMap; + ::std::map< sal_Int32, Reference< chart2::data::XLabeledDataSequence > > aSequenceMap; for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ ) { // note: assuming that the values in the sequence mapping are always non-negative - std::vector< ScChart2LabeledDataSequence* >::size_type nOldIndex( static_cast< sal_uInt32 >( aSequenceMapping[nNewIndex] )); + ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::size_type nOldIndex( static_cast< sal_uInt32 >( aSequenceMapping[nNewIndex] ) ); if( nOldIndex < aSeqVector.size() ) { pDS->AddLabeledSequence( aSeqVector[nOldIndex] ); aSeqVector[nOldIndex] = 0; } - } - std::vector< ScChart2LabeledDataSequence* >::iterator aVectorItr(aSeqVector.begin()); - std::vector< ScChart2LabeledDataSequence* >::iterator aVectorEndItr(aSeqVector.end()); + ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aVectorItr( aSeqVector.begin() ); + ::std::vector< Reference< chart2::data::XLabeledDataSequence > >::iterator aVectorEndItr( aSeqVector.end() ); while(aVectorItr != aVectorEndItr) { - if(*aVectorItr) - pDS->AddLabeledSequence(*aVectorItr); + Reference< chart2::data::XLabeledDataSequence > xSeq( *aVectorItr ); + if ( xSeq.is() ) + { + pDS->AddLabeledSequence( xSeq ); + } ++aVectorItr; } @@ -2321,114 +2341,6 @@ void ScChart2DataSource::AddLabeledSequence(const uno::Reference < chart2::data: m_aLabeledSequences.push_back(xNew); } -// LabeledDataSequence ======================================================= - -ScChart2LabeledDataSequence::ScChart2LabeledDataSequence( - ScDocument* pDoc ) : - m_pDocument( pDoc ) -{ - if ( m_pDocument ) - m_pDocument->AddUnoObject( *this); -} - -ScChart2LabeledDataSequence::~ScChart2LabeledDataSequence() -{ - if ( m_pDocument ) - m_pDocument->RemoveUnoObject( *this); -} - -// SfxListener ----------------------------------------------------------- - -void ScChart2LabeledDataSequence::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint) -{ - if ( rHint.ISA( SfxSimpleHint ) && - ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) - { - ScUnoGuard aGuard; - m_pDocument = NULL; - } -} - -// XLabeledDataSequence -------------------------------------------------- - -uno::Reference< chart2::data::XDataSequence > SAL_CALL ScChart2LabeledDataSequence::getValues() - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - return m_aData; -} - -void SAL_CALL ScChart2LabeledDataSequence::setValues( - const uno::Reference< chart2::data::XDataSequence >& xSequence ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - m_aData = xSequence; -} - -uno::Reference< chart2::data::XDataSequence > SAL_CALL ScChart2LabeledDataSequence::getLabel() - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - return m_aLabel; -} - -void SAL_CALL ScChart2LabeledDataSequence::setLabel( - const uno::Reference< chart2::data::XDataSequence >& xSequence ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - m_aLabel = xSequence; -} - -// XCloneable ================================================================ - -uno::Reference< util::XCloneable > SAL_CALL ScChart2LabeledDataSequence::createClone() - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference< util::XCloneable > xToClone(m_aData, uno::UNO_QUERY); - if (xToClone.is()) - { - ScChart2LabeledDataSequence* pRet = new ScChart2LabeledDataSequence(m_pDocument); - uno::Reference< chart2::data::XDataSequence > xSequence(xToClone->createClone(), uno::UNO_QUERY); - pRet->setValues(xSequence); - xToClone.set(m_aLabel, uno::UNO_QUERY); - if(xToClone.is()) - { - xSequence.set(xToClone->createClone(), uno::UNO_QUERY); - pRet->setLabel(xSequence); - } - return pRet; - } - return NULL; -} - -// XModifyBroadcaster ======================================================== - -void SAL_CALL ScChart2LabeledDataSequence::addModifyListener( const uno::Reference< util::XModifyListener >& aListener ) - throw (uno::RuntimeException) -{ - // quick'n dirty: just add the listener to each DataSequence - - uno::Reference<util::XModifyBroadcaster> xDataBroadcaster( m_aData, uno::UNO_QUERY ); - if ( xDataBroadcaster.is() ) - xDataBroadcaster->addModifyListener( aListener ); - uno::Reference<util::XModifyBroadcaster> xLabelBroadcaster( m_aLabel, uno::UNO_QUERY ); - if ( xLabelBroadcaster.is() ) - xLabelBroadcaster->addModifyListener( aListener ); -} - -void SAL_CALL ScChart2LabeledDataSequence::removeModifyListener( const uno::Reference< util::XModifyListener >& aListener ) - throw (uno::RuntimeException) -{ - uno::Reference<util::XModifyBroadcaster> xDataBroadcaster( m_aData, uno::UNO_QUERY ); - if ( xDataBroadcaster.is() ) - xDataBroadcaster->removeModifyListener( aListener ); - uno::Reference<util::XModifyBroadcaster> xLabelBroadcaster( m_aLabel, uno::UNO_QUERY ); - if ( xLabelBroadcaster.is() ) - xLabelBroadcaster->removeModifyListener( aListener ); -} // DataSequence ============================================================== diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index f72141717159..42ed9179e6aa 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -108,6 +108,7 @@ const SfxItemPropertyMapEntry* lcl_GetDataPilotDescriptorBaseMap() { {MAP_CHAR_LEN(SC_UNO_COLGRAND), 0, &getBooleanCppuType(), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_DRILLDOWN), 0, &getBooleanCppuType(), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_GRANDTOTAL_NAME),0,&getCppuType((rtl::OUString*)0), beans::PropertyAttribute::MAYBEVOID, 0 }, {MAP_CHAR_LEN(SC_UNO_IGNEMPROWS), 0, &getBooleanCppuType(), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_IMPORTDESC), 0, &getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_RPTEMPTY), 0, &getBooleanCppuType(), 0, 0 }, @@ -343,8 +344,6 @@ ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nInd if ( pColl ) { // count tables on this sheet - // api only handles sheet data at this time - //! allow all data sources!!! sal_Int32 nFound = 0; sal_uInt16 nCount = pColl->GetCount(); for (sal_uInt16 i=0; i<nCount; i++) @@ -494,8 +493,6 @@ sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException) if ( pColl ) { // count tables on this sheet - // api only handles sheet data at this time - //! allow all data sources!!! sal_uInt16 nFound = 0; sal_uInt16 nCount = pColl->GetCount(); @@ -557,8 +554,6 @@ Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames() if ( pColl ) { // count tables on this sheet - // api only handles sheet data at this time - //! allow all data sources!!! sal_uInt16 nFound = 0; sal_uInt16 nCount = pColl->GetCount(); @@ -600,9 +595,6 @@ sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName ) sal_uInt16 nCount = pColl->GetCount(); for (sal_uInt16 i=0; i<nCount; i++) { - // api only handles sheet data at this time - //! allow all data sources!!! - ScDPObject* pDPObj = (*pColl)[i]; if ( pDPObj->GetOutRange().aStart.Tab() == nTab && pDPObj->GetName() == aNamStr ) @@ -824,6 +816,12 @@ void SAL_CALL ScDataPilotDescriptorBase::setPropertyValue( const OUString& aProp { aNewData.SetDrillDown(::cppu::any2bool( aValue )); } + else if ( aNameString.EqualsAscii( SC_UNO_GRANDTOTAL_NAME ) ) + { + rtl::OUString aStrVal; + if ( aValue >>= aStrVal ) + aNewData.SetGrandTotalName(aStrVal); + } else if ( aNameString.EqualsAscii( SC_UNO_IMPORTDESC ) ) { uno::Sequence<beans::PropertyValue> aArgSeq; @@ -967,6 +965,12 @@ Any SAL_CALL ScDataPilotDescriptorBase::getPropertyValue( const OUString& aPrope { aRet = ::cppu::bool2any( aNewData.GetDrillDown() ); } + else if ( aNameString.EqualsAscii( SC_UNO_GRANDTOTAL_NAME ) ) + { + const rtl::OUString* pGrandTotalName = aNewData.GetGrandTotalName(); + if (pGrandTotalName) + aRet <<= *pGrandTotalName; // same behavior as in ScDPSource + } else if ( aNameString.EqualsAscii( SC_UNO_IMPORTDESC ) ) { const ScImportSourceDesc* pImportDesc = pDPObject->GetImportSourceDesc(); diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx index 31ef83ee91db..10edb4f9d1aa 100644 --- a/sc/source/ui/unoobj/datauno.cxx +++ b/sc/source/ui/unoobj/datauno.cxx @@ -1893,8 +1893,7 @@ void SAL_CALL ScDatabaseRangeObj::refresh() throw(uno::RuntimeException) SCCOL nDummyCol; SCROW nDummyRow; pData->GetArea( nTab, nDummyCol,nDummyRow,nDummyCol,nDummyRow ); - uno::Reference< sdbc::XResultSet > xResultSet; - bContinue = aFunc.DoImport( nTab, aImportParam, xResultSet, NULL, sal_True, sal_False ); //! Api-Flag als Parameter + bContinue = aFunc.DoImport( nTab, aImportParam, NULL, sal_True ); //! Api-Flag as parameter } // interne Operationen (sort, query, subtotal) nur, wenn kein Fehler diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 23eb1abd2d82..daed78e09e82 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -87,6 +87,7 @@ #include "rangeutl.hxx" #include "markdata.hxx" #include "docoptio.hxx" +#include "scextopt.hxx" #include "unoguard.hxx" #include "unonames.hxx" #include "shapeuno.hxx" @@ -103,6 +104,9 @@ using namespace com::sun::star; +// #i111553# provides the name of the VBA constant for this document type (e.g. 'ThisExcelDoc' for Calc) +#define SC_UNO_VBAGLOBNAME "VBAGlobalConstantName" + //------------------------------------------------------------------------ // alles ohne Which-ID, Map nur fuer PropertySetInfo @@ -117,6 +121,7 @@ const SfxItemPropertyMapEntry* lcl_GetDocOptPropertyMap() {MAP_CHAR_LEN(SC_UNO_AUTOCONTFOC), 0, &getBooleanCppuType(), 0, 0}, {MAP_CHAR_LEN(SC_UNO_BASICLIBRARIES), 0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0}, {MAP_CHAR_LEN(SC_UNO_DIALOGLIBRARIES), 0, &getCppuType((uno::Reference< script::XLibraryContainer >*)0), beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(SC_UNO_VBAGLOBNAME), 0, &getCppuType(static_cast< const rtl::OUString * >(0)), beans::PropertyAttribute::READONLY, 0}, {MAP_CHAR_LEN(SC_UNO_CALCASSHOWN), PROP_UNO_CALCASSHOWN, &getBooleanCppuType(), 0, 0}, {MAP_CHAR_LEN(SC_UNONAME_CLOCAL), 0, &getCppuType((lang::Locale*)0), 0, 0}, {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL), 0, &getCppuType((lang::Locale*)0), 0, 0}, @@ -411,10 +416,14 @@ SfxObjectShell* ScModelObj::GetEmbeddedObject() const return pDocShell; } -void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark) +void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark, bool bCalcOutputFactor) { if (pDocShell) + { + if (bCalcOutputFactor) + pDocShell->CalcOutputFactor(); pDocShell->UpdateAllRowHeights(pTabMark); + } } void ScModelObj::BeforeXMLLoading() @@ -903,6 +912,16 @@ sal_Bool ScModelObj::FillRenderMarkData( const uno::Any& aSelection, ScTabViewShell* pViewSh = pViewObj->GetViewShell(); if (pViewSh) { + // #i95280# when printing from the shell, the view is never activated, + // so Excel view settings must also be evaluated here. + ScExtDocOptions* pExtOpt = pDocShell->GetDocument()->GetExtDocOptions(); + if ( pExtOpt && pExtOpt->IsChanged() ) + { + pViewSh->GetViewData()->ReadExtOptions(*pExtOpt); // Excel view settings + pViewSh->SetTabNo( pViewSh->GetViewData()->GetTabNo(), sal_True ); + pExtOpt->SetChanged( false ); + } + const ScMarkData& rViewMark = pViewSh->GetViewData()->GetMarkData(); SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount(); for (SCTAB nTab = 0; nTab < nTabCount; nTab++) @@ -1052,7 +1071,7 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab ); long nTabStart = pPrintFuncCache->GetTabStart( nTab ); - (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, NULL, NULL ); + (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, NULL ); ScRange aCellRange; sal_Bool bWasCellRange = aFunc.GetLastSourceRange( aCellRange ); @@ -1076,11 +1095,6 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 pArray[2].Value <<= aRangeAddress; } - #if 0 - const ScPrintOptions& rPrintOpt = - #endif - // FIXME: is this for side effects ? - SC_MOD()->GetPrintOptions(); if( ! pPrinterOptions ) pPrinterOptions = new ScPrintUIOptions; else @@ -1186,7 +1200,7 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec //<---i56629 } - (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_True, NULL, NULL ); + (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_True, NULL ); // resolve the hyperlinks for PDF export @@ -1268,7 +1282,12 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec } if ( nPage >= 0 ) - pPDFData->SetLinkDest( aIter->nLinkId, pPDFData->CreateDest( aArea, nPage ) ); + { + if ( aIter->nLinkId != -1 ) + pPDFData->SetLinkDest( aIter->nLinkId, pPDFData->CreateDest( aArea, nPage ) ); + else + pPDFData->DescribeRegisteredDest( aIter->nDestId, aArea, nPage ); + } } } else @@ -1893,6 +1912,15 @@ uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyNa { aRet <<= pDocShell->GetDialogContainer(); } + else if ( aString.EqualsAscii( SC_UNO_VBAGLOBNAME ) ) + { + /* #i111553# This property provides the name of the constant that + will be used to store this model in the global Basic manager. + That constant will be equivelant to 'ThisComponent' but for + each application, so e.g. a 'ThisExcelDoc' and a 'ThisWordDoc' + constant can co-exist, as required by VBA. */ + aRet <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ThisExcelDoc" ) ); + } else if ( aString.EqualsAscii( SC_UNO_RUNTIMEUID ) ) { aRet <<= getRuntimeUID(); diff --git a/sc/source/ui/unoobj/linkuno.cxx b/sc/source/ui/unoobj/linkuno.cxx index ee6c3ff1988a..8b9e1039f085 100644 --- a/sc/source/ui/unoobj/linkuno.cxx +++ b/sc/source/ui/unoobj/linkuno.cxx @@ -1641,10 +1641,17 @@ Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames() ScUnoGuard aGuard; vector<String> aTabNames; mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames); - size_t n = aTabNames.size(); + + // #i116940# be consistent with getByName: include only table names which have a cache already + vector<String> aValidNames; + for (vector<String>::const_iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter) + if (mpRefMgr->getCacheTable(mnFileId, *aIter, false)) + aValidNames.push_back(*aIter); + + size_t n = aValidNames.size(); Sequence<OUString> aSeq(n); for (size_t i = 0; i < n; ++i) - aSeq[i] = aTabNames[i]; + aSeq[i] = aValidNames[i]; return aSeq; } @@ -1652,25 +1659,35 @@ sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName) throw (RuntimeException) { ScUnoGuard aGuard; - return static_cast<sal_Bool>(mpRefMgr->hasCacheTable(mnFileId, aName)); + + // #i116940# be consistent with getByName: allow only table names which have a cache already + ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false); + return (pTable.get() != NULL); } sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount() throw (RuntimeException) { ScUnoGuard aGuard; - return static_cast<sal_Int32>(mpRefMgr->getCacheTableCount(mnFileId)); + + // #i116940# be consistent with getByName: count only table names which have a cache already + return getElementNames().getLength(); } -Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nIndex) +Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException) { ScUnoGuard aGuard; - size_t nTabCount = mpRefMgr->getCacheTableCount(mnFileId); - if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(nTabCount)) + + // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only + // the entries which have a cache already. Quick solution: Use getElementNames. + + Sequence< OUString > aNames( getElementNames() ); + if (nApiIndex < 0 || nApiIndex >= aNames.getLength()) throw lang::IndexOutOfBoundsException(); - ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, static_cast<size_t>(nIndex)); + size_t nIndex = 0; + ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex); if (!pTable) throw lang::IndexOutOfBoundsException(); @@ -1702,7 +1719,9 @@ sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements() throw (RuntimeException) { ScUnoGuard aGuard; - return static_cast<sal_Bool>(mpRefMgr->getCacheTableCount(mnFileId) > 0); + + // #i116940# be consistent with getByName: count only table names which have a cache already + return ( getElementNames().getLength() > 0 ); } sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex() diff --git a/sc/source/ui/unoobj/notesuno.cxx b/sc/source/ui/unoobj/notesuno.cxx index c5dd11977478..eac95f94d779 100644 --- a/sc/source/ui/unoobj/notesuno.cxx +++ b/sc/source/ui/unoobj/notesuno.cxx @@ -27,35 +27,24 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" -#include <svl/smplhint.hxx> +#include "notesuno.hxx" -#include "rangelst.hxx" +#include <svl/smplhint.hxx> #include <editeng/unotext.hxx> #include <svx/svdpool.hxx> #include <svx/svdobj.hxx> -#include "notesuno.hxx" -#include "textuno.hxx" -#include "cellsuno.hxx" // getParent +#include <svx/unoshape.hxx> +#include <svx/svdocapt.hxx> + +#include "postit.hxx" +#include "cellsuno.hxx" #include "docsh.hxx" #include "docfunc.hxx" #include "hints.hxx" #include "editsrc.hxx" #include "miscuno.hxx" - -// setVisible: -#include <svx/svdundo.hxx> -#include "drwlayer.hxx" -#include "detfunc.hxx" -#include "undocell.hxx" #include "unoguard.hxx" -#include "userdat.hxx" -#include <editeng/outlobj.hxx> -#include <svx/unoshape.hxx> -#include <svx/svdocapt.hxx> -#include <svx/svditer.hxx> -#include <svx/svdpage.hxx> -#include <com/sun/star/drawing/XShapeDescriptor.hpp> using namespace com::sun::star; @@ -75,7 +64,7 @@ const SvxItemPropertySet* lcl_GetAnnotationPropertySet() //------------------------------------------------------------------------ SC_SIMPLE_SERVICE_INFO( ScAnnotationObj, "ScAnnotationObj", "com.sun.star.sheet.CellAnnotation" ) -SC_SIMPLE_SERVICE_INFO( ScAnnotationShapeObj, "ScAnnotationShapeObj", "com.sun.star.sheet.CellAnnotationShape" ) +//SC_SIMPLE_SERVICE_INFO( ScAnnotationShapeObj, "ScAnnotationShapeObj", "com.sun.star.sheet.CellAnnotationShape" ) //------------------------------------------------------------------------ @@ -248,7 +237,11 @@ uno::Reference < drawing::XShape > SAL_CALL ScAnnotationObj::getAnnotationShape( throw(::com::sun::star::uno::RuntimeException) { ScUnoGuard aGuard; - return new ScAnnotationShapeObj(pDocShell, aCellPos); + uno::Reference < drawing::XShape > xShape; + if( const ScPostIt* pNote = ImplGetNote() ) + if( SdrObject* pCaption = pNote->GetOrCreateCaption( aCellPos ) ) + xShape.set( pCaption->getUnoShape(), uno::UNO_QUERY ); + return xShape; } SvxUnoText& ScAnnotationObj::GetUnoText() @@ -267,463 +260,5 @@ const ScPostIt* ScAnnotationObj::ImplGetNote() const { return pDocShell ? pDocShell->GetDocument()->GetNote( aCellPos ) : 0; } -//------------------------------------------------------------------------ - -ScAnnotationShapeObj::ScAnnotationShapeObj(ScDocShell* pDocSh, const ScAddress& rPos) : - pDocShell( pDocSh ), - aCellPos( rPos ), - pUnoText( NULL ) -{ - pDocShell->GetDocument()->AddUnoObject(*this); - - // pUnoText is allocated on demand (GetUnoText) - // can't be aggregated because getString/setString is handled here -} - -SvxUnoText& ScAnnotationShapeObj::GetUnoText() -{ - if (!pUnoText) - { - ScAnnotationEditSource aEditSource( pDocShell, aCellPos ); - pUnoText = new SvxUnoText( &aEditSource, lcl_GetAnnotationPropertySet(), - uno::Reference<text::XText>() ); - pUnoText->acquire(); - } - return *pUnoText; -} - -uno::Reference < drawing::XShape > ScAnnotationShapeObj::GetXShape() -{ - if (!xShape.is()) - if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote( aCellPos ) ) - if( SdrObject* pCaption = pNote->GetOrCreateCaption( aCellPos ) ) - xShape.set( pCaption->getUnoShape(), uno::UNO_QUERY ); - return xShape; -} - -ScAnnotationShapeObj::~ScAnnotationShapeObj() -{ - if (pDocShell) - pDocShell->GetDocument()->RemoveUnoObject(*this); - if (pUnoText) - pUnoText->release(); -} - -void ScAnnotationShapeObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) -{ - if ( rHint.ISA( ScUpdateRefHint ) ) - { -// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint; - - //! Ref-Update - } - else if ( rHint.ISA( SfxSimpleHint ) && - ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) - { - pDocShell = NULL; // ungueltig geworden - } -} - - -// XChild - -uno::Reference<uno::XInterface> SAL_CALL ScAnnotationShapeObj::getParent() throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - - // Parent der Notiz ist die zugehoerige Zelle - //! existierendes Objekt finden und zurueckgeben ??? - - if (pDocShell) - return (cppu::OWeakObject*)new ScCellObj( pDocShell, aCellPos ); - - return NULL; -} - -void SAL_CALL ScAnnotationShapeObj::setParent( const uno::Reference<uno::XInterface>& /* Parent */ ) - throw(lang::NoSupportException, uno::RuntimeException) -{ - // hamma nich - //! Exception oder so ??! -} - -// XElementAccess -uno::Type SAL_CALL ScAnnotationShapeObj::getElementType( ) throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - - return GetUnoText().getElementType(); -} - -sal_Bool SAL_CALL ScAnnotationShapeObj::hasElements( ) throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - - return GetUnoText().hasElements(); -} - -// XEnumerationAccess -uno::Reference< container::XEnumeration > SAL_CALL ScAnnotationShapeObj::createEnumeration( ) throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - - return GetUnoText().createEnumeration(); -} - -// XTextRangeMover -void SAL_CALL ScAnnotationShapeObj::moveTextRange( const uno::Reference< text::XTextRange >& xRange, sal_Int16 nParagraphs ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - - GetUnoText().moveTextRange( xRange, nParagraphs ); -} - -// XText -void SAL_CALL ScAnnotationShapeObj::insertTextContent( const uno::Reference< text::XTextRange >& xRange, - const uno::Reference< text::XTextContent >& xContent, sal_Bool bAbsorb ) - throw (lang::IllegalArgumentException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - - GetUnoText().insertTextContent( xRange, xContent, bAbsorb ); -} - -void SAL_CALL ScAnnotationShapeObj::removeTextContent( const uno::Reference< text::XTextContent >& xContent ) - throw (container::NoSuchElementException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - - GetUnoText().removeTextContent( xContent ); -} - -// XSimpleText - -uno::Reference<text::XTextCursor> SAL_CALL ScAnnotationShapeObj::createTextCursor() - throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - // Notizen brauchen keine Extrawurst - return GetUnoText().createTextCursor(); -} - -uno::Reference<text::XTextCursor> SAL_CALL ScAnnotationShapeObj::createTextCursorByRange( - const uno::Reference<text::XTextRange>& aTextPosition ) - throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - // Notizen brauchen keine Extrawurst - return GetUnoText().createTextCursorByRange(aTextPosition); -} - -rtl::OUString SAL_CALL ScAnnotationShapeObj::getString() throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - return GetUnoText().getString(); -} - -void SAL_CALL ScAnnotationShapeObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - GetUnoText().setString(aText); -} - -void SAL_CALL ScAnnotationShapeObj::insertString( const uno::Reference<text::XTextRange>& xRange, - const rtl::OUString& aString, sal_Bool bAbsorb ) - throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - GetUnoText().insertString( xRange, aString, bAbsorb ); -} - -void SAL_CALL ScAnnotationShapeObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange, - sal_Int16 nControlCharacter, sal_Bool bAbsorb ) - throw(lang::IllegalArgumentException, uno::RuntimeException) -{ - ScUnoGuard aGuard; - GetUnoText().insertControlCharacter( xRange, nControlCharacter, bAbsorb ); -} - -uno::Reference<text::XText> SAL_CALL ScAnnotationShapeObj::getText() throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - return GetUnoText().getText(); -} - -uno::Reference<text::XTextRange> SAL_CALL ScAnnotationShapeObj::getStart() throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - return GetUnoText().getStart(); -} - -uno::Reference<text::XTextRange> SAL_CALL ScAnnotationShapeObj::getEnd() throw(uno::RuntimeException) -{ - ScUnoGuard aGuard; - return GetUnoText().getEnd(); -} - -// XShapeDescriptor -::rtl::OUString SAL_CALL ScAnnotationShapeObj::getShapeType( ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < drawing::XShapeDescriptor > xDesc(GetXShape(), uno::UNO_QUERY); - if (xDesc.is()) - return xDesc->getShapeType(); - return rtl::OUString(); -} - -// XShape -awt::Point SAL_CALL ScAnnotationShapeObj::getPosition( ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - GetXShape(); - return xShape.is() ? xShape->getPosition() : awt::Point(); -} - -void SAL_CALL ScAnnotationShapeObj::setPosition( const awt::Point& aPosition ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - GetXShape(); - if( xShape.is() ) - xShape->setPosition(aPosition); -} - -awt::Size SAL_CALL ScAnnotationShapeObj::getSize( ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - GetXShape(); - return xShape.is() ? xShape->getSize() : awt::Size(); -} - -void SAL_CALL ScAnnotationShapeObj::setSize( const awt::Size& aSize ) - throw (beans::PropertyVetoException, uno::RuntimeException) -{ - ScUnoGuard aGuard; - GetXShape(); - if( xShape.is() ) - xShape->setSize(aSize); -} - -// XPropertyState -beans::PropertyState SAL_CALL ScAnnotationShapeObj::getPropertyState( const rtl::OUString& PropertyName ) - throw (beans::UnknownPropertyException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertyState > xState (GetXShape(), uno::UNO_QUERY); - if (xState.is()) - return xState->getPropertyState( PropertyName ); - return beans::PropertyState(); -} - -uno::Sequence< beans::PropertyState > SAL_CALL ScAnnotationShapeObj::getPropertyStates( - const uno::Sequence< rtl::OUString >& aPropertyName ) - throw (beans::UnknownPropertyException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertyState > xState (GetXShape(), uno::UNO_QUERY); - if (xState.is()) - return xState->getPropertyStates( aPropertyName ); - return uno::Sequence< beans::PropertyState >(); -} - -void SAL_CALL ScAnnotationShapeObj::setPropertyToDefault( const ::rtl::OUString& PropertyName ) - throw (::com::sun::star::beans::UnknownPropertyException, - ::com::sun::star::uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertyState > xState (GetXShape(), uno::UNO_QUERY); - if (xState.is()) - xState->setPropertyToDefault( PropertyName ); -} - -uno::Any SAL_CALL ScAnnotationShapeObj::getPropertyDefault( const rtl::OUString& aPropertyName ) - throw (beans::UnknownPropertyException, - lang::WrappedTargetException, uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertyState > xState (GetXShape(), uno::UNO_QUERY); - if (xState.is()) - return xState->getPropertyDefault( aPropertyName ); - return uno::Any(); -} - -// XPropertySet -uno::Reference< beans::XPropertySetInfo > SAL_CALL ScAnnotationShapeObj::getPropertySetInfo( ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - return xProp->getPropertySetInfo(); - return uno::Reference< beans::XPropertySetInfo >(); -} - -void SAL_CALL ScAnnotationShapeObj::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue ) - throw (beans::UnknownPropertyException, - beans::PropertyVetoException, - lang::IllegalArgumentException, - lang::WrappedTargetException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - xProp->setPropertyValue( aPropertyName, aValue ); -} - -uno::Any SAL_CALL ScAnnotationShapeObj::getPropertyValue( const rtl::OUString& PropertyName ) - throw (beans::UnknownPropertyException, - lang::WrappedTargetException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - return xProp->getPropertyValue( PropertyName ); - return uno::Any(); -} - -void SAL_CALL ScAnnotationShapeObj::addPropertyChangeListener( const rtl::OUString& aPropertyName, - const uno::Reference< beans::XPropertyChangeListener >& xListener ) - throw (beans::UnknownPropertyException, - lang::WrappedTargetException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - return xProp->addPropertyChangeListener( aPropertyName, xListener ); -} - -void SAL_CALL ScAnnotationShapeObj::removePropertyChangeListener( const rtl::OUString& aPropertyName, - const uno::Reference< beans::XPropertyChangeListener >& aListener ) - throw (beans::UnknownPropertyException, - lang::WrappedTargetException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - return xProp->removePropertyChangeListener( aPropertyName, aListener ); -} - -void SAL_CALL ScAnnotationShapeObj::addVetoableChangeListener( const rtl::OUString& PropertyName, - const uno::Reference< beans::XVetoableChangeListener >& aListener ) - throw (beans::UnknownPropertyException, - lang::WrappedTargetException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - return xProp->addVetoableChangeListener( PropertyName, aListener ); -} - -void SAL_CALL ScAnnotationShapeObj::removeVetoableChangeListener( const rtl::OUString& PropertyName, - const uno::Reference< beans::XVetoableChangeListener >& aListener ) - throw (beans::UnknownPropertyException, - lang::WrappedTargetException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - return xProp->removeVetoableChangeListener( PropertyName, aListener ); -} - - // XMultiPropertySet -void SAL_CALL ScAnnotationShapeObj::setPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames, - const uno::Sequence< uno::Any >& aValues ) - throw (beans::PropertyVetoException, - lang::IllegalArgumentException, - lang::WrappedTargetException, - uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - xProp->setPropertyValues( aPropertyNames, aValues ); -} - -uno::Sequence< uno::Any > SAL_CALL ScAnnotationShapeObj::getPropertyValues( - const uno::Sequence< rtl::OUString >& aPropertyNames ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - return xProp->getPropertyValues( aPropertyNames ); - return uno::Sequence< uno::Any >(); -} - -void SAL_CALL ScAnnotationShapeObj::addPropertiesChangeListener( const uno::Sequence< rtl::OUString >& aPropertyNames, - const uno::Reference< beans::XPropertiesChangeListener >& xListener ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - xProp->addPropertiesChangeListener( aPropertyNames, xListener ); -} - -void SAL_CALL ScAnnotationShapeObj::removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& xListener ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - xProp->removePropertiesChangeListener( xListener ); -} - -void SAL_CALL ScAnnotationShapeObj::firePropertiesChangeEvent( const uno::Sequence< rtl::OUString >& aPropertyNames, - const uno::Reference< beans::XPropertiesChangeListener >& xListener ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < beans::XMultiPropertySet > xProp (GetXShape(), uno::UNO_QUERY); - if (xProp.is()) - xProp->firePropertiesChangeEvent( aPropertyNames, xListener ); -} - - // XComponent -void SAL_CALL ScAnnotationShapeObj::dispose( ) throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < lang::XComponent > xComp (GetXShape(), uno::UNO_QUERY); - if (xComp.is()) - xComp->dispose(); - if (xShape.is()) - xShape.clear(); -} - -void SAL_CALL ScAnnotationShapeObj::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < lang::XComponent > xComp (GetXShape(), uno::UNO_QUERY); - if (xComp.is()) - xComp->addEventListener( xListener ); -} - -void SAL_CALL ScAnnotationShapeObj::removeEventListener( const uno::Reference< lang::XEventListener >& aListener ) - throw (uno::RuntimeException) -{ - ScUnoGuard aGuard; - uno::Reference < lang::XComponent > xComp (GetXShape(), uno::UNO_QUERY); - if (xComp.is()) - xComp->removeEventListener( aListener ); -} //------------------------------------------------------------------------ - - - - diff --git a/sc/source/ui/unoobj/shapeuno.cxx b/sc/source/ui/unoobj/shapeuno.cxx index fd31c233dc19..fe77e5ef32e6 100644 --- a/sc/source/ui/unoobj/shapeuno.cxx +++ b/sc/source/ui/unoobj/shapeuno.cxx @@ -102,7 +102,8 @@ ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) : pShapePropertySet(NULL), pShapePropertyState(NULL), pImplementationId(NULL), - bIsTextShape(sal_False), + bIsTextShape(false), + bIsNoteCaption(false), bInitializedNotifier(false) { comphelper::increment( m_refCount ); @@ -127,6 +128,7 @@ ScShapeObj::ScShapeObj( uno::Reference<drawing::XShape>& xShape ) : SdrObject* pObj = GetSdrObject(); if ( pObj ) { + bIsNoteCaption = ScDrawLayer::IsNoteCaption( pObj ); lcl_initializeNotifier( *pObj, *this ); bInitializedNotifier = true; } @@ -151,6 +153,9 @@ uno::Any SAL_CALL ScShapeObj::queryInterface( const uno::Type& rType ) if ( !aRet.hasValue() && bIsTextShape ) aRet = ScShapeObj_TextBase::queryInterface( rType ); + if ( !aRet.hasValue() && bIsNoteCaption ) + aRet = ScShapeObj_ChildBase::queryInterface( rType ); + if ( !aRet.hasValue() && mxShapeAgg.is() ) aRet = mxShapeAgg->queryAggregation( rType ); @@ -1261,6 +1266,48 @@ void SAL_CALL ScShapeObj::setString( const rtl::OUString& aText ) throw(uno::Run throw uno::RuntimeException(); } +// XChild + +uno::Reference< uno::XInterface > SAL_CALL ScShapeObj::getParent() throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + + // receive cell position from caption object (parent of a note caption is the note cell) + SdrObject* pObj = GetSdrObject(); + if( pObj ) + { + ScDrawLayer* pModel = (ScDrawLayer*)pObj->GetModel(); + SdrPage* pPage = pObj->GetPage(); + if ( pModel ) + { + ScDocument* pDoc = pModel->GetDocument(); + if ( pDoc ) + { + SfxObjectShell* pObjSh = pDoc->GetDocumentShell(); + if ( pObjSh && pObjSh->ISA(ScDocShell) ) + { + ScDocShell* pDocSh = (ScDocShell*)pObjSh; + + SCTAB nTab = 0; + if ( lcl_GetPageNum( pPage, *pModel, nTab ) ) + { + const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, nTab ); + if( pCaptData ) + return static_cast< ::cppu::OWeakObject* >( new ScCellObj( pDocSh, pCaptData->maStart ) ); + } + } + } + } + } + + return 0; +} + +void SAL_CALL ScShapeObj::setParent( const uno::Reference< uno::XInterface >& ) throw (lang::NoSupportException, uno::RuntimeException) +{ + throw lang::NoSupportException(); +} + // XTypeProvider uno::Sequence<uno::Type> SAL_CALL ScShapeObj::getTypes() throw(uno::RuntimeException) @@ -1517,5 +1564,12 @@ uno::Sequence< ::rtl::OUString > SAL_CALL ScShapeObj::getSupportedServiceNames( aSupported.realloc( aSupported.getLength() + 1 ); aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) ); + + if( bIsNoteCaption ) + { + aSupported.realloc( aSupported.getLength() + 1 ); + aSupported[ aSupported.getLength() - 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.CellAnnotationShape" ) ); + } + return aSupported; } diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index 04d88935acfc..50623610b5b3 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -247,7 +247,7 @@ getViewFrame( const uno::Reference< frame::XModel >& xModel ) return NULL; } -uno::Reference< vba::XHelperInterface > +uno::Reference< XHelperInterface > getUnoSheetModuleObj( const uno::Reference< sheet::XSpreadsheet >& xSheet ) throw ( uno::RuntimeException ) { uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW ); @@ -258,8 +258,7 @@ getUnoSheetModuleObj( const uno::Reference< sheet::XSpreadsheet >& xSheet ) thro // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at // the document in the future could fix this, especially IF the switching of the vba mode takes care to // create the special document module objects if they don't exist. - uno::Reference< XHelperInterface > xParent( ov::getUnoDocModule( sCodeName, GetDocShellFromRange( xSheet ) ), uno::UNO_QUERY ); - return xParent; + return getUnoDocModule( sCodeName, GetDocShellFromRange( xSheet ) ); } uno::Reference< XHelperInterface > diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx index 290b34a949ca..fa278e527d91 100644 --- a/sc/source/ui/vba/vbaapplication.cxx +++ b/sc/source/ui/vba/vbaapplication.cxx @@ -40,6 +40,7 @@ #include <ooo/vba/excel/XlMousePointer.hpp> #include <com/sun/star/sheet/XNamedRanges.hpp> #include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <ooo/vba/XExecutableDialog.hpp> #include "vbaapplication.hxx" #include "vbaworkbooks.hxx" @@ -98,17 +99,6 @@ using namespace ::com::sun::star; uno::Any sbxToUnoValue( SbxVariable* pVar ); -class ActiveWorkbook : public ScVbaWorkbook -{ -protected: - virtual uno::Reference< frame::XModel > getModel() - { - return getCurrentExcelDoc(mxContext); - } -public: - ActiveWorkbook( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) : ScVbaWorkbook( xParent, xContext ){} -}; - // ============================================================================ /** Global application settings shared by all open workbooks. */ @@ -215,47 +205,15 @@ ScVbaApplication::hasProperty( const ::rtl::OUString& Name ) throw(uno::RuntimeE uno::Reference< excel::XWorkbook > ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException) { - uno::Reference< excel::XWorkbook > xWrkbk; - ScDocShell* pShell = excel::getDocShell( getCurrentExcelDoc( mxContext ) ); - if ( pShell ) - { - String aName; - if ( pShell->GetDocument() ) - { - aName = pShell->GetDocument()->GetCodeName(); - xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY ); - // fallback ( e.g. it's possible a new document was created via the api ) - // in that case the document will not have the appropriate Document Modules - // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document - // vba mode etc. ) - if ( !xWrkbk.is() ) - return new ActiveWorkbook( this, mxContext ); - } - } - return xWrkbk; + // will throw if active document is not in VBA compatibility mode (no object for codename) + return uno::Reference< excel::XWorkbook >( getVBADocument( getCurrentExcelDoc( mxContext ) ), uno::UNO_QUERY_THROW ); } uno::Reference< excel::XWorkbook > SAL_CALL ScVbaApplication::getThisWorkbook() throw (uno::RuntimeException) { - uno::Reference< excel::XWorkbook > xWrkbk; - ScDocShell* pShell = excel::getDocShell( getThisExcelDoc( mxContext ) ); - if ( pShell ) - { - String aName; - if ( pShell->GetDocument() ) - { - aName = pShell->GetDocument()->GetCodeName(); - xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY ); - // fallback ( e.g. it's possible a new document was created via the api ) - // in that case the document will not have the appropriate Document Modules - // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document - // vba mode etc. ) - if ( !xWrkbk.is() ) - return new ActiveWorkbook( this, mxContext ); - } - } - return xWrkbk; + // should never throw as this model is in VBA compatibility mode + return uno::Reference< excel::XWorkbook >( getVBADocument( getThisExcelDoc( mxContext ) ), uno::UNO_QUERY_THROW ); } uno::Reference< XAssistant > SAL_CALL @@ -343,17 +301,8 @@ ScVbaApplication::Workbooks( const uno::Any& aIndex ) throw (uno::RuntimeExcepti uno::Any SAL_CALL ScVbaApplication::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeException) { - uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_QUERY ); - uno::Any result; - if ( xWorkbook.is() ) - result = xWorkbook->Worksheets( aIndex ); - - else - // Fixme - check if this is reasonable/desired behavior - throw uno::RuntimeException( rtl::OUString::createFromAscii( - "No ActiveWorkBook available" ), uno::Reference< uno::XInterface >() ); - - return result; + uno::Reference< excel::XWorkbook > xWorkbook( getActiveWorkbook(), uno::UNO_SET_THROW ); + return xWorkbook->Worksheets( aIndex ); } uno::Any SAL_CALL @@ -384,10 +333,10 @@ ScVbaApplication::Dialogs( const uno::Any &aIndex ) throw (uno::RuntimeException uno::Reference< excel::XWindow > SAL_CALL ScVbaApplication::getActiveWindow() throw (uno::RuntimeException) { - // #FIXME sofar can't determine Parent uno::Reference< frame::XModel > xModel = getCurrentDocument(); - ScVbaWindow* pWin = new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel ); - uno::Reference< excel::XWindow > xWin( pWin ); + uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); + uno::Reference< XHelperInterface > xParent( getActiveWorkbook(), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XWindow > xWin( new ScVbaWindow( xParent, mxContext, xModel, xController ) ); return xWin; } @@ -792,37 +741,36 @@ rtl::OUString ScVbaApplication::getOfficePath( const rtl::OUString& _sPathType ) } return sRetPath; } + void SAL_CALL -ScVbaApplication::setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (script::BasicErrorException, uno::RuntimeException) +ScVbaApplication::setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (uno::RuntimeException) { uno::Reference< beans::XPropertySet > xProps = lcl_getPathSettingsService( mxContext ); rtl::OUString aURL; osl::FileBase::getFileURLFromSystemPath( DefaultFilePath, aURL ); - xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Work")), uno::makeAny( aURL ) ); - - + xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Work")), uno::Any( aURL ) ); } ::rtl::OUString SAL_CALL -ScVbaApplication::getDefaultFilePath( ) throw (script::BasicErrorException, uno::RuntimeException) +ScVbaApplication::getDefaultFilePath() throw (uno::RuntimeException) { return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Work"))); } ::rtl::OUString SAL_CALL -ScVbaApplication::LibraryPath( ) throw (script::BasicErrorException, uno::RuntimeException) +ScVbaApplication::getLibraryPath() throw (uno::RuntimeException) { return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Basic"))); } ::rtl::OUString SAL_CALL -ScVbaApplication::TemplatesPath( ) throw (script::BasicErrorException, uno::RuntimeException) +ScVbaApplication::getTemplatesPath() throw (uno::RuntimeException) { return getOfficePath( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Template"))); } ::rtl::OUString SAL_CALL -ScVbaApplication::PathSeparator( ) throw (script::BasicErrorException, uno::RuntimeException) +ScVbaApplication::getPathSeparator() throw (uno::RuntimeException) { static rtl::OUString sPathSep( RTL_CONSTASCII_USTRINGPARAM( FILE_PATH_SEPERATOR ) ); return sPathSep; @@ -1174,6 +1122,40 @@ ScVbaApplication::Caller( const uno::Any& /*aIndex*/ ) throw ( uno::RuntimeExcep return aRet; } +uno::Any SAL_CALL ScVbaApplication::GetOpenFilename( + const uno::Any& rFileFilter, const uno::Any& rFilterIndex, const uno::Any& rTitle, + const uno::Any& rButtonText, const uno::Any& rMultiSelect ) throw (uno::RuntimeException) +{ + uno::Sequence< uno::Any > aArgs( 6 ); + aArgs[ 0 ] <<= getThisExcelDoc( mxContext ); + aArgs[ 1 ] = rFileFilter; + aArgs[ 2 ] = rFilterIndex; + aArgs[ 3 ] = rTitle; + aArgs[ 4 ] = rButtonText; + aArgs[ 5 ] = rMultiSelect; + uno::Reference< lang::XMultiComponentFactory > xFactory( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< XExecutableDialog > xFilePicker( xFactory->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.OpenFilePicker" ) ), aArgs, mxContext ), uno::UNO_QUERY_THROW ); + return xFilePicker->execute(); +} + +uno::Any SAL_CALL ScVbaApplication::GetSaveAsFilename( + const uno::Any& rInitialFileName, const uno::Any& rFileFilter, const uno::Any& rFilterIndex, + const uno::Any& rTitle, const uno::Any& rButtonText ) throw (uno::RuntimeException) +{ + uno::Sequence< uno::Any > aArgs( 6 ); + aArgs[ 0 ] <<= getThisExcelDoc( mxContext ); + aArgs[ 1 ] = rInitialFileName; + aArgs[ 2 ] = rFileFilter; + aArgs[ 3 ] = rFilterIndex; + aArgs[ 4 ] = rTitle; + aArgs[ 5 ] = rButtonText; + uno::Reference< lang::XMultiComponentFactory > xFactory( mxContext->getServiceManager(), uno::UNO_SET_THROW ); + uno::Reference< XExecutableDialog > xFilePicker( xFactory->createInstanceWithArgumentsAndContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.SaveAsFilePicker" ) ), aArgs, mxContext ), uno::UNO_QUERY_THROW ); + return xFilePicker->execute(); +} + uno::Reference< frame::XModel > ScVbaApplication::getCurrentDocument() throw (css::uno::RuntimeException) { diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx index bb696c967a37..b09fb66a8f91 100644 --- a/sc/source/ui/vba/vbaapplication.hxx +++ b/sc/source/ui/vba/vbaapplication.hxx @@ -73,11 +73,11 @@ public: virtual sal_Bool SAL_CALL hasProperty(const rtl::OUString& Name) throw(css::uno::RuntimeException); // XApplication - virtual ::rtl::OUString SAL_CALL PathSeparator( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual ::rtl::OUString SAL_CALL getDefaultFilePath( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual ::rtl::OUString SAL_CALL LibraryPath( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual ::rtl::OUString SAL_CALL TemplatesPath( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual void SAL_CALL setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDefaultFilePath() throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getPathSeparator() throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getLibraryPath() throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getTemplatesPath() throw (css::uno::RuntimeException); virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); virtual sal_Bool SAL_CALL getDisplayAlerts() throw (css::uno::RuntimeException); @@ -120,6 +120,8 @@ public: virtual void SAL_CALL Volatile( const css::uno::Any& Volatile ) throw (css::uno::RuntimeException ); virtual void SAL_CALL DoEvents() throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Caller( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL GetOpenFilename( const css::uno::Any& rFileFilter, const css::uno::Any& rFilterIndex, const css::uno::Any& rTitle, const css::uno::Any& rButtonText, const css::uno::Any& rMultiSelect ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL GetSaveAsFilename( const css::uno::Any& rInitialFileName, const css::uno::Any& rFileFilter, const css::uno::Any& rFilterIndex, const css::uno::Any& rTitle, const css::uno::Any& rButtonText ) throw (css::uno::RuntimeException); // XHelperInterface virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); diff --git a/sc/source/ui/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx index 6ea807a16eae..e96b2d001e75 100755 --- a/sc/source/ui/vba/vbaeventshelper.cxx +++ b/sc/source/ui/vba/vbaeventshelper.cxx @@ -27,21 +27,22 @@ #include "vbaeventshelper.hxx" +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/XTopWindowListener.hpp> #include <com/sun/star/awt/XWindowListener.hpp> #include <com/sun/star/frame/XBorderResizeListener.hpp> #include <com/sun/star/frame/XControllerBorder.hpp> +#include <com/sun/star/script/ModuleType.hpp> #include <com/sun/star/script/vba/VBAEventId.hpp> #include <com/sun/star/sheet/XCellRangeAddressable.hpp> #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp> #include <com/sun/star/table/XCellRange.hpp> #include <com/sun/star/util/XChangesListener.hpp> #include <com/sun/star/util/XChangesNotifier.hpp> -#include <com/sun/star/util/XCloseListener.hpp> - -#include <ooo/vba/excel/XApplication.hpp> #include <cppuhelper/implbase4.hxx> #include <toolkit/unohlp.hxx> +#include <unotools/eventcfg.hxx> #include <vbahelper/helperdecl.hxx> #include <vcl/svapp.hxx> #include <vcl/window.hxx> @@ -54,6 +55,8 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::script::vba::VBAEventId; using namespace ::ooo::vba; +using ::rtl::OUString; + // ============================================================================ namespace { @@ -65,9 +68,13 @@ SCTAB lclGetTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nInde VbaEventsHelperBase::checkArgument( rArgs, nIndex ); // first try to extract a sheet index - SCTAB nTab = -1; + sal_Int32 nTab = -1; if( rArgs[ nIndex ] >>= nTab ) - return nTab; + { + if( (nTab < 0) || (nTab > MAXTAB) ) + throw lang::IllegalArgumentException(); + return static_cast< SCTAB >( nTab ); + } // try VBA Range object uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex ); @@ -97,231 +104,271 @@ SCTAB lclGetTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nInde throw lang::IllegalArgumentException(); } +/** Returns the AWT container window of the passed controller. */ +uno::Reference< awt::XWindow > lclGetWindowForController( const uno::Reference< frame::XController >& rxController ) +{ + if( rxController.is() ) try + { + uno::Reference< frame::XFrame > xFrame( rxController->getFrame(), uno::UNO_SET_THROW ); + return xFrame->getContainerWindow(); + } + catch( uno::Exception& ) + { + } + return 0; +} + } // namespace // ============================================================================ -typedef ::cppu::WeakImplHelper4< - awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventsListener_BASE; +typedef ::cppu::WeakImplHelper4< awt::XTopWindowListener, awt::XWindowListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventListener_BASE; // This class is to process Workbook window related event -class ScVbaEventsListener : public ScVbaEventsListener_BASE +class ScVbaEventListener : public ScVbaEventListener_BASE { public : - ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ); - virtual ~ScVbaEventsListener(); - - void startListening(); - void stopListening(); + ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ); + virtual ~ScVbaEventListener(); + + /** Starts listening to the passed document controller. */ + void startControllerListening( const uno::Reference< frame::XController >& rxController ); + /** Stops listening to the passed document controller. */ + void stopControllerListening( const uno::Reference< frame::XController >& rxController ); + + // XTopWindowListener + virtual void SAL_CALL windowOpened( const lang::EventObject& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowClosing( const lang::EventObject& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowClosed( const lang::EventObject& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowMinimized( const lang::EventObject& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowNormalized( const lang::EventObject& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowActivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowDeactivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException); // XWindowListener - virtual void SAL_CALL windowResized( const awt::WindowEvent& aEvent ) throw (uno::RuntimeException); - virtual void SAL_CALL windowMoved( const awt::WindowEvent& aEvent ) throw (uno::RuntimeException); - virtual void SAL_CALL windowShown( const lang::EventObject& aEvent ) throw (uno::RuntimeException); - virtual void SAL_CALL windowHidden( const lang::EventObject& aEvent ) throw (uno::RuntimeException); - virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw (uno::RuntimeException); - - // XCloseListener - virtual void SAL_CALL queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException); - virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException); + virtual void SAL_CALL windowResized( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowMoved( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowShown( const lang::EventObject& rEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowHidden( const lang::EventObject& rEvent ) throw (uno::RuntimeException); // XBorderResizeListener - virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject, const frame::BorderWidths& aNewSize ) throw (uno::RuntimeException); + virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& aNewSize ) throw (uno::RuntimeException); // XChangesListener - virtual void SAL_CALL changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL changesOccurred( const util::ChangesEvent& rEvent ) throw (uno::RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException); private: - uno::Reference< frame::XFrame > getFrame(); - uno::Reference< awt::XWindow > getContainerWindow(); - bool isMouseReleased(); - DECL_LINK( fireResizeMacro, void* ); + /** Starts listening to the document model. */ + void startModelListening(); + /** Stops listening to the document model. */ + void stopModelListening(); + + /** Returns the controller for the passed VCL window. */ + uno::Reference< frame::XController > getControllerForWindow( Window* pWindow ) const; + + /** Calls the Workbook_Window[Activate|Deactivate] event handler. */ + void processWindowActivateEvent( Window* pWindow, bool bActivate ); + /** Posts a Workbook_WindowResize user event. */ + void postWindowResizeEvent( Window* pWindow ); + /** Callback link for Application::PostUserEvent(). */ + DECL_LINK( processWindowResizeEvent, Window* ); private: - ::osl::Mutex maMutex; - ScVbaEventsHelper& mrVbaEvents; + typedef ::std::map< Window*, uno::Reference< frame::XController > > WindowControllerMap; + + ::osl::Mutex maMutex; + ScVbaEventsHelper& mrVbaEvents; uno::Reference< frame::XModel > mxModel; - ScDocShell* mpDocShell; - bool mbWindowResized; - bool mbBorderChanged; - bool mbDisposed; + ScDocShell* mpDocShell; + WindowControllerMap maControllers; /// Maps VCL top windows to their controllers. + Window* mpActiveWindow; /// Currently activated window, to prevent multiple (de)activation. + bool mbWindowResized; /// True = window resize system event processed. + bool mbBorderChanged; /// True = borders changed system event processed. + bool mbDisposed; }; // ---------------------------------------------------------------------------- -ScVbaEventsListener::ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) : +ScVbaEventListener::ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) : mrVbaEvents( rVbaEvents ), mxModel( rxModel ), mpDocShell( pDocShell ), + mpActiveWindow( 0 ), mbWindowResized( false ), mbBorderChanged( false ), mbDisposed( !rxModel.is() ) { - OSL_TRACE( "ScVbaEventsListener::ScVbaEventsListener( 0x%x ) - ctor ", this ); + if( !mxModel.is() ) + return; + + startModelListening(); + try + { + uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + startControllerListening( xController ); + } + catch( uno::Exception& ) + { + } } -ScVbaEventsListener::~ScVbaEventsListener() +ScVbaEventListener::~ScVbaEventListener() { - OSL_TRACE( "ScVbaEventsListener::~ScVbaEventsListener( 0x%x ) - dtor ", this ); - stopListening(); } -void ScVbaEventsListener::startListening() +void ScVbaEventListener::startControllerListening( const uno::Reference< frame::XController >& rxController ) { - if( !mbDisposed ) + ::osl::MutexGuard aGuard( maMutex ); + + uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController ); + if( xWindow.is() ) + try { xWindow->addWindowListener( this ); } catch( uno::Exception& ) {} + + uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY ); + if( xTopWindow.is() ) + try { xTopWindow->addTopWindowListener( this ); } catch( uno::Exception& ) {} + + uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY ); + if( xControllerBorder.is() ) + try { xControllerBorder->addBorderResizeListener( this ); } catch( uno::Exception& ) {} + + if( Window* pWindow = VCLUnoHelper::GetWindow( xWindow ) ) + maControllers[ pWindow ] = rxController; +} + +void ScVbaEventListener::stopControllerListening( const uno::Reference< frame::XController >& rxController ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController ); + if( xWindow.is() ) + try { xWindow->removeWindowListener( this ); } catch( uno::Exception& ) {} + + uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY ); + if( xTopWindow.is() ) + try { xTopWindow->removeTopWindowListener( this ); } catch( uno::Exception& ) {} + + uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY ); + if( xControllerBorder.is() ) + try { xControllerBorder->removeBorderResizeListener( this ); } catch( uno::Exception& ) {} + + if( Window* pWindow = VCLUnoHelper::GetWindow( xWindow ) ) { - // add window listener - try - { - uno::Reference< awt::XWindow > xWindow( getContainerWindow(), uno::UNO_QUERY_THROW ); - xWindow->addWindowListener( this ); - } - catch( uno::Exception& ) - { - } - // add close listener - try - { - uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( mxModel, uno::UNO_QUERY_THROW ); - xCloseBroadcaster->addCloseListener( this ); - } - catch( uno::Exception& ) - { - } - // add Border resize listener - try - { - uno::Reference< frame::XControllerBorder > xControllerBorder( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); - xControllerBorder->addBorderResizeListener( this ); - } - catch( uno::Exception& ) - { - } - // add content change listener - try - { - uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); - xChangesNotifier->addChangesListener( this ); - } - catch( uno::Exception& ) - { - } + maControllers.erase( pWindow ); + if( pWindow == mpActiveWindow ) + mpActiveWindow = 0; } } -void ScVbaEventsListener::stopListening() +void SAL_CALL ScVbaEventListener::windowOpened( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException) +{ +} + +void SAL_CALL ScVbaEventListener::windowClosing( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException) { +} + +void SAL_CALL ScVbaEventListener::windowClosed( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException) +{ +} + +void SAL_CALL ScVbaEventListener::windowMinimized( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException) +{ +} + +void SAL_CALL ScVbaEventListener::windowNormalized( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException) +{ +} + +void SAL_CALL ScVbaEventListener::windowActivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( maMutex ); + if( !mbDisposed ) { - try - { - uno::Reference< awt::XWindow > xWindow( getContainerWindow(), uno::UNO_QUERY_THROW ); - xWindow->removeWindowListener( this ); - } - catch( uno::Exception& ) - { - } - try - { - uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( mxModel, uno::UNO_QUERY_THROW ); - xCloseBroadcaster->removeCloseListener( this ); - } - catch( uno::Exception& ) - { - } - try - { - uno::Reference< frame::XControllerBorder > xControllerBorder( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); - xControllerBorder->removeBorderResizeListener( this ); - } - catch( uno::Exception& ) - { - } - try - { - uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); - xChangesNotifier->removeChangesListener( this ); - } - catch( uno::Exception& ) + uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + OSL_TRACE( "ScVbaEventListener::windowActivated - pWindow = 0x%x, mpActiveWindow = 0x%x", pWindow, mpActiveWindow ); + // do not fire activation event multiple time for the same window + if( pWindow && (pWindow != mpActiveWindow) ) { + // if another window is active, fire deactivation event first + if( mpActiveWindow ) + processWindowActivateEvent( mpActiveWindow, false ); + // fire activation event for the new window + processWindowActivateEvent( pWindow, true ); + mpActiveWindow = pWindow; } } - mbDisposed = true; } -void SAL_CALL ScVbaEventsListener::windowResized( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventListener::windowDeactivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException) { ::osl::MutexGuard aGuard( maMutex ); - // Workbook_window_resize event - mbWindowResized = true; - if( !mbDisposed && mbBorderChanged ) + + if( !mbDisposed ) { - if( /*Window* pWindow =*/ VCLUnoHelper::GetWindow( getContainerWindow() ) ) - { - mbBorderChanged = mbWindowResized = false; - acquire(); // ensure we don't get deleted before the event is handled - Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 ); - } + uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + OSL_TRACE( "ScVbaEventListener::windowDeactivated - pWindow = 0x%x, mpActiveWindow = 0x%x", pWindow, mpActiveWindow ); + // do not fire the deactivation event, if the window is not active (prevent multiple deactivation) + if( pWindow && (pWindow == mpActiveWindow) ) + processWindowActivateEvent( pWindow, false ); + // forget pointer to the active window + mpActiveWindow = 0; } } -void SAL_CALL ScVbaEventsListener::windowMoved( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventListener::windowResized( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException) { - // not interest this time -} + ::osl::MutexGuard aGuard( maMutex ); -void SAL_CALL ScVbaEventsListener::windowShown( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) -{ - // not interest this time + mbWindowResized = true; + if( !mbDisposed && mbBorderChanged ) + { + uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY ); + postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) ); + } } -void SAL_CALL ScVbaEventsListener::windowHidden( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventListener::windowMoved( const awt::WindowEvent& /*rEvent*/ ) throw (uno::RuntimeException) { - // not interest this time } -void SAL_CALL ScVbaEventsListener::disposing( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventListener::windowShown( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException) { - ::osl::MutexGuard aGuard( maMutex ); - OSL_TRACE( "ScVbaEventsListener::disposing( 0x%x )", this ); - mbDisposed = true; } -void SAL_CALL ScVbaEventsListener::queryClosing( const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ ) throw (util::CloseVetoException, uno::RuntimeException) +void SAL_CALL ScVbaEventListener::windowHidden( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException) { - // it can cancel the close, but need to throw a CloseVetoException, and it will be transmit to caller. } -void SAL_CALL ScVbaEventsListener::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) +void SAL_CALL ScVbaEventListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException) { ::osl::MutexGuard aGuard( maMutex ); - stopListening(); -} -void SAL_CALL ScVbaEventsListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& /*aObject*/, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException) -{ - ::osl::MutexGuard aGuard( maMutex ); - // work with WindowResized event to guard Window Resize event. mbBorderChanged = true; if( !mbDisposed && mbWindowResized ) { - if( /*Window* pWindow =*/ VCLUnoHelper::GetWindow( getContainerWindow() ) ) - { - mbWindowResized = mbBorderChanged = false; - acquire(); // ensure we don't get deleted before the timer fires. - Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 ); - } + uno::Reference< frame::XController > xController( rSource, uno::UNO_QUERY ); + uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( xController ); + postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) ); } } -void SAL_CALL ScVbaEventsListener::changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException) +void SAL_CALL ScVbaEventListener::changesOccurred( const util::ChangesEvent& rEvent ) throw (uno::RuntimeException) { - sal_Int32 nCount = aEvent.Changes.getLength(); - if( nCount == 0 ) + ::osl::MutexGuard aGuard( maMutex ); + + sal_Int32 nCount = rEvent.Changes.getLength(); + if( mbDisposed || !mpDocShell || (nCount == 0) ) return; - util::ElementChange aChange = aEvent.Changes[ 0 ]; - rtl::OUString sOperation; + util::ElementChange aChange = rEvent.Changes[ 0 ]; + OUString sOperation; aChange.Accessor >>= sOperation; if( !sOperation.equalsIgnoreAsciiCaseAscii("cell-change") ) return; @@ -334,7 +381,7 @@ void SAL_CALL ScVbaEventsListener::changesOccurred( const util::ChangesEvent& aE { uno::Sequence< uno::Any > aArgs( 1 ); aArgs[0] <<= xRangeObj; - mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs ); + mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs ); } return; } @@ -342,7 +389,7 @@ void SAL_CALL ScVbaEventsListener::changesOccurred( const util::ChangesEvent& aE ScRangeList aRangeList; for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) { - aChange = aEvent.Changes[ nIndex ]; + aChange = rEvent.Changes[ nIndex ]; aChange.Accessor >>= sOperation; uno::Reference< table::XCellRange > xRangeObj; aChange.ReplacedElement >>= xRangeObj; @@ -358,62 +405,117 @@ void SAL_CALL ScVbaEventsListener::changesOccurred( const util::ChangesEvent& aE } } - if( (aRangeList.Count() > 0) && mpDocShell ) + if( aRangeList.Count() > 0 ) { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( mpDocShell, aRangeList ) ); uno::Sequence< uno::Any > aArgs(1); aArgs[0] <<= xRanges; - mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs ); + mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs ); } } -// ---------------------------------------------------------------------------- +void SAL_CALL ScVbaEventListener::disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( maMutex ); + + uno::Reference< frame::XModel > xModel( rEvent.Source, uno::UNO_QUERY ); + if( xModel.is() ) + { + OSL_ENSURE( xModel.get() == mxModel.get(), "ScVbaEventListener::disposing - disposing from unknown model" ); + stopModelListening(); + mbDisposed = true; + return; + } + + uno::Reference< frame::XController > xController( rEvent.Source, uno::UNO_QUERY ); + if( xController.is() ) + { + stopControllerListening( xController ); + return; + } +} -uno::Reference< frame::XFrame > ScVbaEventsListener::getFrame() +// private -------------------------------------------------------------------- + +void ScVbaEventListener::startModelListening() { - if( !mbDisposed && mxModel.is() ) try + try { - uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); - return xController->getFrame(); + uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); + xChangesNotifier->addChangesListener( this ); } catch( uno::Exception& ) { } - return uno::Reference< frame::XFrame >(); } -uno::Reference< awt::XWindow > ScVbaEventsListener::getContainerWindow() +void ScVbaEventListener::stopModelListening() { try { - uno::Reference< frame::XFrame > xFrame( getFrame(), uno::UNO_SET_THROW ); - return xFrame->getContainerWindow(); + uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); + xChangesNotifier->removeChangesListener( this ); } catch( uno::Exception& ) { } - return uno::Reference< awt::XWindow >(); } -bool ScVbaEventsListener::isMouseReleased() +uno::Reference< frame::XController > ScVbaEventListener::getControllerForWindow( Window* pWindow ) const { - if( Window* pWindow = VCLUnoHelper::GetWindow( getContainerWindow() ) ) + WindowControllerMap::const_iterator aIt = maControllers.find( pWindow ); + return (aIt == maControllers.end()) ? uno::Reference< frame::XController >() : aIt->second; +} + +void ScVbaEventListener::processWindowActivateEvent( Window* pWindow, bool bActivate ) +{ + uno::Reference< frame::XController > xController = getControllerForWindow( pWindow ); + if( xController.is() ) { - Window::PointerState aPointerState = pWindow->GetPointerState(); - return (aPointerState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT )) == 0; + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= xController; + mrVbaEvents.processVbaEventNoThrow( bActivate ? WORKBOOK_WINDOWACTIVATE : WORKBOOK_WINDOWDEACTIVATE, aArgs ); } - return false; } -IMPL_LINK( ScVbaEventsListener, fireResizeMacro, void*, EMPTYARG ) +void ScVbaEventListener::postWindowResizeEvent( Window* pWindow ) { - if( !mbDisposed && isMouseReleased() ) try + // check that the passed window is still alive (it must be registered in maControllers) + if( pWindow && (maControllers.count( pWindow ) > 0) ) { - mrVbaEvents.processVbaEvent( WORKBOOK_WINDOWRESIZE, uno::Sequence< uno::Any >() ); + mbWindowResized = mbBorderChanged = false; + acquire(); // ensure we don't get deleted before the timer fires + Application::PostUserEvent( LINK( this, ScVbaEventListener, processWindowResizeEvent ), pWindow ); } - catch( uno::Exception& ) +} + +IMPL_LINK( ScVbaEventListener, processWindowResizeEvent, Window*, EMPTYARG pWindow ) +{ + ::osl::MutexGuard aGuard( maMutex ); + + /* Check that the passed window is still alive (it must be registered in + maControllers). While closing a document, postWindowResizeEvent() may + be called on the last window which posts a user event via + Application::PostUserEvent to call this event handler. VCL will trigger + the handler some time later. Sometimes, the window gets deleted before. + This is handled via the disposing() function which removes the window + pointer from the member maControllers. Thus, checking whether + maControllers contains pWindow ensures that the window is still alive. */ + if( !mbDisposed && pWindow && (maControllers.count( pWindow ) > 0) ) { - // #163419# do not throw exceptions into application core + // do not fire event unless all mouse buttons have been released + Window::PointerState aPointerState = pWindow->GetPointerState(); + if( (aPointerState.mnState & (MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT)) == 0 ) + { + uno::Reference< frame::XController > xController = getControllerForWindow( pWindow ); + if( xController.is() ) + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= xController; + // #163419# do not throw exceptions into application core + mrVbaEvents.processVbaEventNoThrow( WORKBOOK_WINDOWRESIZE, aArgs ); + } + } } release(); return 0; @@ -431,19 +533,19 @@ ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, co if( !mxModel.is() || !mpDocShell || !mpDoc ) return; -#define REGISTER_EVENT( eventid, eventname, type, cancelindex, worksheet ) \ - registerEventHandler( eventid, eventname, type, cancelindex, uno::Any( worksheet ) ) - +#define REGISTER_EVENT( eventid, moduletype, classname, eventname, cancelindex, worksheet ) \ + registerEventHandler( eventid, moduletype, classname "_" eventname, cancelindex, uno::Any( worksheet ) ) +#define REGISTER_AUTO_EVENT( eventid, eventname ) \ + REGISTER_EVENT( AUTO_##eventid, script::ModuleType::NORMAL, "Auto", eventname, -1, false ) #define REGISTER_WORKBOOK_EVENT( eventid, eventname, cancelindex ) \ - REGISTER_EVENT( WORKBOOK_##eventid, "Workbook_" eventname, EVENTHANDLER_DOCUMENT, cancelindex, false ) - + REGISTER_EVENT( WORKBOOK_##eventid, script::ModuleType::DOCUMENT, "Workbook", eventname, cancelindex, false ) #define REGISTER_WORKSHEET_EVENT( eventid, eventname, cancelindex ) \ - REGISTER_EVENT( WORKSHEET_##eventid, "Worksheet_" eventname, EVENTHANDLER_DOCUMENT, cancelindex, true ); \ - REGISTER_EVENT( (USERDEFINED_START + WORKSHEET_##eventid), "Workbook_Sheet" eventname, EVENTHANDLER_DOCUMENT, (((cancelindex) >= 0) ? ((cancelindex) + 1) : -1), false ) + REGISTER_EVENT( WORKSHEET_##eventid, script::ModuleType::DOCUMENT, "Worksheet", eventname, cancelindex, true ); \ + REGISTER_EVENT( (USERDEFINED_START + WORKSHEET_##eventid), script::ModuleType::DOCUMENT, "Workbook", "Sheet" eventname, (((cancelindex) >= 0) ? ((cancelindex) + 1) : -1), false ) // global - REGISTER_EVENT( AUTO_OPEN, "Auto_Open", EVENTHANDLER_GLOBAL, -1, false ); - REGISTER_EVENT( AUTO_CLOSE, "Auto_Close", EVENTHANDLER_GLOBAL, -1, false ); + REGISTER_AUTO_EVENT( OPEN, "Open" ); + REGISTER_AUTO_EVENT( CLOSE, "Close" ); // Workbook REGISTER_WORKBOOK_EVENT( ACTIVATE, "Activate", -1 ); @@ -468,19 +570,68 @@ ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, co REGISTER_WORKSHEET_EVENT( SELECTIONCHANGE, "SelectionChange", -1 ); REGISTER_WORKSHEET_EVENT( FOLLOWHYPERLINK, "FollowHyperlink", -1 ); -#undef REGISTER_EVENT -#undef REGISTER_WORKBOOK_EVENT #undef REGISTER_WORKSHEET_EVENT +#undef REGISTER_WORKBOOK_EVENT +#undef REGISTER_AUTO_EVENT +#undef REGISTER_EVENT } ScVbaEventsHelper::~ScVbaEventsHelper() { } -void SAL_CALL ScVbaEventsHelper::disposing( const lang::EventObject& rSource ) throw (uno::RuntimeException) +void SAL_CALL ScVbaEventsHelper::notifyEvent( const css::document::EventObject& rEvent ) throw (css::uno::RuntimeException) { - mxListener.clear(); - VbaEventsHelperBase::disposing( rSource ); + static const uno::Sequence< uno::Any > saEmptyArgs; + if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_OPENDOC )) || + (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CREATEDOC )) ) // CREATEDOC triggered e.g. during VBA Workbooks.Add + { + processVbaEventNoThrow( WORKBOOK_OPEN, saEmptyArgs ); + } + else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_ACTIVATEDOC ) ) + { + processVbaEventNoThrow( WORKBOOK_ACTIVATE, saEmptyArgs ); + } + else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_DEACTIVATEDOC ) ) + { + processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs ); + } + else if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEDOCDONE )) || + (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEASDOCDONE )) || + (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVETODOCDONE )) ) + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= true; + processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs ); + } + else if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEDOCFAILED )) || + (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEASDOCFAILED )) || + (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVETODOCFAILED )) ) + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= false; + processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs ); + } + else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ) ) + { + /* Trigger the WORKBOOK_WINDOWDEACTIVATE and WORKBOOK_DEACTIVATE + events and stop listening to the model (done in base class). */ + uno::Reference< frame::XController > xController( mxModel->getCurrentController() ); + if( xController.is() ) + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= xController; + processVbaEventNoThrow( WORKBOOK_WINDOWDEACTIVATE, aArgs ); + } + processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs ); + } + else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_VIEWCREATED ) ) + { + uno::Reference< frame::XController > xController( mxModel->getCurrentController() ); + if( mxListener.get() && xController.is() ) + mxListener->startControllerListening( xController ); + } + VbaEventsHelperBase::notifyEvent( rEvent ); } // protected ------------------------------------------------------------------ @@ -492,25 +643,35 @@ bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue, if( !mpShell || !mpDoc ) throw uno::RuntimeException(); - // framework and Calc fire a few events before 'opened', ignore them - bool bExecuteEvent = mbOpened; + /* For document events: check if events are enabled via the + Application.EnableEvents symbol (this is an Excel-only attribute). + Check this again for every event, as the event handler may change the + state of the EnableEvents symbol. Global events such as AUTO_OPEN and + AUTO_CLOSE are always enabled. */ + bool bExecuteEvent = (rInfo.mnModuleType != script::ModuleType::DOCUMENT) || ScVbaApplication::getDocumentEventsEnabled(); + + // framework and Calc fire a few events before 'OnLoad', ignore them + if( bExecuteEvent ) + bExecuteEvent = (rInfo.mnEventId == WORKBOOK_OPEN) ? !mbOpened : mbOpened; // special handling for some events - switch( rInfo.mnEventId ) + if( bExecuteEvent ) switch( rInfo.mnEventId ) { case WORKBOOK_OPEN: - bExecuteEvent = !mbOpened; - if( bExecuteEvent ) - { - // execute delayed Activate event too (see above) - rEventQueue.push_back( WORKBOOK_ACTIVATE ); - rEventQueue.push_back( WORKBOOK_WINDOWACTIVATE ); - rEventQueue.push_back( AUTO_OPEN ); - } + { + // execute delayed Activate event too (see above) + rEventQueue.push_back( WORKBOOK_ACTIVATE ); + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= mxModel->getCurrentController(); + rEventQueue.push_back( EventQueueEntry( WORKBOOK_WINDOWACTIVATE, aArgs ) ); + rEventQueue.push_back( AUTO_OPEN ); + // remember initial selection + maOldSelection <<= mxModel->getCurrentSelection(); + } break; case WORKSHEET_SELECTIONCHANGE: // if selection is not changed, then do not fire the event - bExecuteEvent = bExecuteEvent && isSelectionChanged( rArgs, 0 ); + bExecuteEvent = isSelectionChanged( rArgs, 0 ); break; } @@ -520,14 +681,6 @@ bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue, bool bSheetEvent = false; if( (rInfo.maUserData >>= bSheetEvent) && bSheetEvent ) rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) ); - - /* For document events: check if events are enabled via the - Application.EnableEvents symbol (this is an Excel-only attribute). - Check this again for every event, as the event handler may change - the state of the EnableEvents symbol. Global events such as - AUTO_OPEN and AUTO_CLOSE are always enabled. */ - if( rInfo.meType == EVENTHANDLER_DOCUMENT ) - bExecuteEvent = ScVbaApplication::getDocumentEventsEnabled(); } return bExecuteEvent; @@ -574,7 +727,7 @@ uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventH case WORKBOOK_WINDOWDEACTIVATE: case WORKBOOK_WINDOWRESIZE: aVbaArgs.realloc( 1 ); - aVbaArgs[ 0 ] = createWindow(); + aVbaArgs[ 0 ] = createWindow( rArgs, 0 ); break; // 1 arg: worksheet case WORKBOOK_NEWSHEET: @@ -625,7 +778,7 @@ uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventH } void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue, - const EventHandlerInfo& rInfo, bool /*bSuccess*/, bool bCancel ) throw (uno::RuntimeException) + const EventHandlerInfo& rInfo, bool bCancel ) throw (uno::RuntimeException) { switch( rInfo.mnEventId ) { @@ -633,10 +786,7 @@ void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue, mbOpened = true; // register the listeners if( !mxListener.is() ) - { - mxListener = new ScVbaEventsListener( *this, mxModel, mpDocShell ); - mxListener->startListening(); - } + mxListener = new ScVbaEventListener( *this, mxModel, mpDocShell ); break; case WORKBOOK_BEFORECLOSE: /* Execute Auto_Close only if not cancelled by event handler, but @@ -647,7 +797,7 @@ void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue, } } -::rtl::OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo, +OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) const throw (lang::IllegalArgumentException) { bool bSheetEvent = false; @@ -746,11 +896,13 @@ uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rA return uno::Any( xHyperlink ); } -uno::Any ScVbaEventsHelper::createWindow() const throw (uno::RuntimeException) +uno::Any ScVbaEventsHelper::createWindow( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const + throw (lang::IllegalArgumentException, uno::RuntimeException) { - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[ 0 ] <<= createVBAUnoAPIService( mpShell, "ooo.vba.Application" ); + uno::Sequence< uno::Any > aArgs( 3 ); + aArgs[ 0 ] <<= getVBADocument( mxModel ); aArgs[ 1 ] <<= mxModel; + aArgs[ 2 ] <<= getXSomethingFromArgs< frame::XController >( rArgs, nIndex, false ); uno::Reference< uno::XInterface > xWindow( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Window", aArgs ), uno::UNO_SET_THROW ); return uno::Any( xWindow ); } diff --git a/sc/source/ui/vba/vbaeventshelper.hxx b/sc/source/ui/vba/vbaeventshelper.hxx index f1e8a4fb712d..4e7e3b52f610 100755 --- a/sc/source/ui/vba/vbaeventshelper.hxx +++ b/sc/source/ui/vba/vbaeventshelper.hxx @@ -25,15 +25,15 @@ * ************************************************************************/ -#ifndef SC_VBAEVENTS_HXX -#define SC_VBAEVENTS_HXX +#ifndef SC_VBAEVENTSHELPER_HXX +#define SC_VBAEVENTSHELPER_HXX #include <rtl/ref.hxx> #include <vbahelper/vbaeventshelperbase.hxx> #include "excelvbahelper.hxx" #include "rangelst.hxx" -class ScVbaEventsListener; +class ScVbaEventListener; // ============================================================================ @@ -45,13 +45,12 @@ public: const css::uno::Reference< css::uno::XComponentContext >& rxContext ); virtual ~ScVbaEventsHelper(); - // XEventListener - virtual void SAL_CALL disposing( const css::lang::EventObject& rSource ) throw (css::uno::RuntimeException); + virtual void SAL_CALL notifyEvent( const css::document::EventObject& rEvent ) throw (css::uno::RuntimeException); protected: virtual bool implPrepareEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::uno::RuntimeException); virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException); - virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bSuccess, bool bCancel ) throw (css::uno::RuntimeException); + virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bCancel ) throw (css::uno::RuntimeException); virtual ::rtl::OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException); private: @@ -65,11 +64,11 @@ private: css::uno::Any createRange( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); /** Creates a VBA Hyperlink object (the argument must contain a UNO cell). */ css::uno::Any createHyperlink( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); - /** Creates a VBA Window object. */ - css::uno::Any createWindow() const throw (css::uno::RuntimeException); + /** Creates a VBA Window object (the argument must contain a model controller). */ + css::uno::Any createWindow( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); private: - ::rtl::Reference< ScVbaEventsListener > mxListener; + ::rtl::Reference< ScVbaEventListener > mxListener; css::uno::Any maOldSelection; ScDocShell* mpDocShell; ScDocument* mpDoc; diff --git a/sc/source/ui/vba/vbaformat.cxx b/sc/source/ui/vba/vbaformat.cxx index 3b0ba2367c1a..0186b5a78645 100644 --- a/sc/source/ui/vba/vbaformat.cxx +++ b/sc/source/ui/vba/vbaformat.cxx @@ -62,10 +62,10 @@ ScVbaFormat< Ifc1 >::ScVbaFormat( const uno::Reference< XHelperInterface >& xPar { try { - mxServiceInfo.set( mxPropertySet, uno::UNO_QUERY_THROW ); if ( !mxModel.is() ) DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XModel Interface could not be retrieved") ) ); - mxNumberFormatsSupplier.set( mxModel, uno::UNO_QUERY_THROW ); + // mxServiceInfo is unused, + // mxNumberFormatsSupplier is initialized when needed in initializeNumberFormats. } catch (uno::Exception& ) { diff --git a/sc/source/ui/vba/vbaformat.hxx b/sc/source/ui/vba/vbaformat.hxx index bfa88d6c7cb8..b875f84c69cd 100644 --- a/sc/source/ui/vba/vbaformat.hxx +++ b/sc/source/ui/vba/vbaformat.hxx @@ -52,7 +52,6 @@ protected: css::uno::Reference< css::util::XNumberFormats > xNumberFormats; css::uno::Reference< css::util::XNumberFormatTypes > xNumberFormatTypes; css::uno::Reference< css::frame::XModel > mxModel; - css::uno::Reference< css::lang::XServiceInfo > mxServiceInfo; css::uno::Reference< css::beans::XPropertyState > xPropertyState; sal_Bool mbCheckAmbiguoity; sal_Bool mbAddIndent; @@ -69,7 +68,6 @@ public: ScVbaFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, const css::uno::Reference< css::frame::XModel >& xModel, bool bCheckAmbiguoity ) throw ( css::script::BasicErrorException ); virtual ~ScVbaFormat() {} virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() = 0; - css::uno::Reference< css::lang::XServiceInfo > getXServiceInfo() { return mxServiceInfo; } void SAL_CALL setAddIndent( const css::uno::Any& _BAddIndent) throw( css::uno::RuntimeException ) { _BAddIndent >>= mbAddIndent; } css::uno::Any SAL_CALL getAddIndent() throw( css::uno::RuntimeException ) { return css::uno::makeAny( mbAddIndent ); } // Interface Methods diff --git a/sc/source/ui/vba/vbaglobals.cxx b/sc/source/ui/vba/vbaglobals.cxx index c70a7f83726d..f9ab063937cf 100644 --- a/sc/source/ui/vba/vbaglobals.cxx +++ b/sc/source/ui/vba/vbaglobals.cxx @@ -234,11 +234,9 @@ ScVbaGlobals::getDebug() throw (uno::RuntimeException) { try // return empty object on error { - uno::Sequence< uno::Any > aArgs( 1 ); - aArgs[ 0 ] <<= uno::Reference< XHelperInterface >( this ); uno::Reference< lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_SET_THROW ); - uno::Reference< uno::XInterface > xVBADebug = xServiceManager->createInstanceWithArgumentsAndContext( - ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.Debug" ) ), aArgs, mxContext ); + uno::Reference< uno::XInterface > xVBADebug = xServiceManager->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.Debug" ) ), mxContext ); return uno::Any( xVBADebug ); } catch( uno::Exception& ) diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index 5cb6d44fc902..72f300d6463a 100755 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -406,7 +406,7 @@ ScDocShell* getDocShellFromRange( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) { // need the ScCellRangesBase to get docshell - uno::Reference< uno::XInterface > xIf( xRange, uno::UNO_QUERY_THROW ); + uno::Reference< uno::XInterface > xIf( xRange ); return getDocShellFromIf(xIf ); } @@ -414,7 +414,7 @@ ScDocShell* getDocShellFromRanges( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException ) { // need the ScCellRangesBase to get docshell - uno::Reference< uno::XInterface > xIf( xRanges, uno::UNO_QUERY_THROW ); + uno::Reference< uno::XInterface > xIf( xRanges ); return getDocShellFromIf(xIf ); } @@ -426,7 +426,8 @@ uno::Reference< frame::XModel > getModelFromXIf( const uno::Reference< uno::XInt uno::Reference< frame::XModel > getModelFromRange( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) { - uno::Reference< uno::XInterface > xIf( xRange, uno::UNO_QUERY_THROW ); + // the XInterface for getImplementation can be any derived interface, no need for queryInterface + uno::Reference< uno::XInterface > xIf( xRange ); return getModelFromXIf( xIf ); } @@ -1469,9 +1470,9 @@ uno::Reference< XCollection >& ScVbaRange::getBorders() void ScVbaRange::visitArray( ArrayVisitor& visitor ) { - uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY_THROW ); - sal_Int32 nRowCount = xColumnRowRange->getRows()->getCount(); - sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount(); + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( mxRange ); + sal_Int32 nRowCount = aRangeAddr.EndRow - aRangeAddr.StartRow + 1; + sal_Int32 nColCount = aRangeAddr.EndColumn - aRangeAddr.StartColumn + 1; for ( sal_Int32 i=0; i<nRowCount; ++i ) { for ( sal_Int32 j=0; j<nColCount; ++j ) @@ -3572,9 +3573,12 @@ ScVbaRange::End( ::sal_Int32 Direction ) throw (uno::RuntimeException) bool ScVbaRange::isSingleCellRange() { - uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, uno::UNO_QUERY); - if ( xColumnRowRange.is() && xColumnRowRange->getRows()->getCount() == 1 && xColumnRowRange->getColumns()->getCount() == 1 ) - return true; + uno::Reference< sheet::XCellRangeAddressable > xAddressable( mxRange, uno::UNO_QUERY ); + if ( xAddressable.is() ) + { + table::CellRangeAddress aRangeAddr = xAddressable->getRangeAddress(); + return ( aRangeAddr.EndColumn == aRangeAddr.StartColumn && aRangeAddr.EndRow == aRangeAddr.StartRow ); + } return false; } diff --git a/sc/source/ui/vba/vbawindow.cxx b/sc/source/ui/vba/vbawindow.cxx index 5964fe98317c..ed10e52cca7a 100644 --- a/sc/source/ui/vba/vbawindow.cxx +++ b/sc/source/ui/vba/vbawindow.cxx @@ -59,11 +59,9 @@ typedef std::hash_map< rtl::OUString, SCTAB, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > NameIndexHash; -typedef std::vector < uno::Reference< sheet::XSpreadsheet > > Sheets; +typedef std::vector< uno::Reference< sheet::XSpreadsheet > > Sheets; -typedef ::cppu::WeakImplHelper1< container::XEnumeration - -> Enumeration_BASE; +typedef ::cppu::WeakImplHelper1< container::XEnumeration > Enumeration_BASE; typedef ::cppu::WeakImplHelper3< container::XEnumerationAccess , com::sun::star::container::XIndexAccess @@ -200,13 +198,20 @@ public: }; -ScVbaWindow::ScVbaWindow( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : WindowImpl_BASE( xParent, xContext, xModel ) +ScVbaWindow::ScVbaWindow( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< frame::XController >& xController ) throw (uno::RuntimeException) : + WindowImpl_BASE( xParent, xContext, xModel, xController ) { init(); } -ScVbaWindow::ScVbaWindow( uno::Sequence< uno::Any > const & args, uno::Reference< uno::XComponentContext > const & xContext ) - : WindowImpl_BASE( args, xContext ) +ScVbaWindow::ScVbaWindow( + const uno::Sequence< uno::Any >& args, + const uno::Reference< uno::XComponentContext >& xContext ) throw (uno::RuntimeException) : + WindowImpl_BASE( args, xContext ) { init(); } @@ -218,20 +223,42 @@ ScVbaWindow::init() still zero. The implementation of ActivePane() uses a UNO reference of this (to set this window as parent of the pane obejct). This requires the own refcount to be non-zero, otherwise this instance will be - desctructed immediately! */ + desctructed immediately! Guard the call to ActivePane() in try/catch to + not miss the decrementation of the reference count on exception. */ osl_incrementInterlockedCount( &m_refCount ); - uno::Reference< frame::XController > xController( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); - m_xViewPane.set( xController, uno::UNO_QUERY_THROW ); - m_xViewFreezable.set( xController, uno::UNO_QUERY_THROW ); - m_xViewSplitable.set( xController, uno::UNO_QUERY_THROW ); - m_xPane.set( ActivePane(), uno::UNO_QUERY_THROW ); - m_xDevice.set( xController->getFrame()->getComponentWindow(), uno::UNO_QUERY_THROW ); + try + { + m_xPane = ActivePane(); + } + catch( uno::Exception& ) + { + } osl_decrementInterlockedCount( &m_refCount ); } +uno::Reference< beans::XPropertySet > +ScVbaWindow::getControllerProps() throw (uno::RuntimeException) +{ + return uno::Reference< beans::XPropertySet >( getController(), uno::UNO_QUERY_THROW ); +} + +uno::Reference< beans::XPropertySet > +ScVbaWindow::getFrameProps() throw (uno::RuntimeException) +{ + return uno::Reference< beans::XPropertySet >( getController()->getFrame(), uno::UNO_QUERY_THROW ); +} + +uno::Reference< awt::XDevice > +ScVbaWindow::getDevice() throw (uno::RuntimeException) +{ + return uno::Reference< awt::XDevice >( getWindow(), uno::UNO_QUERY_THROW ); +} + void ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft, bool bLargeScroll ) throw (uno::RuntimeException) { + if( !m_xPane.is() ) + throw uno::RuntimeException(); if( bLargeScroll ) m_xPane->LargeScroll( Down, Up, ToRight, ToLeft ); else @@ -253,7 +280,7 @@ ScVbaWindow::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::A uno::Any SAL_CALL ScVbaWindow::SelectedSheets( const uno::Any& aIndex ) throw (uno::RuntimeException) { - uno::Reference< container::XEnumerationAccess > xEnumAccess( new SelectedSheetsEnumAccess( mxContext, m_xModel ) ); + uno::Reference< container::XEnumerationAccess > xEnumAccess( new SelectedSheetsEnumAccess( mxContext, m_xModel ) ); // #FIXME needs a workbook as a parent uno::Reference< excel::XWorksheets > xSheets( new ScVbaWorksheets( uno::Reference< XHelperInterface >(), mxContext, xEnumAccess, m_xModel ) ); if ( aIndex.hasValue() ) @@ -283,16 +310,6 @@ ScVbaWindow::ScrollWorkbookTabs( const uno::Any& /*Sheets*/, const uno::Any& /*P */ } -uno::Reference< beans::XPropertySet > -getPropsFromModel( const uno::Reference< frame::XModel >& xModel ) -{ - uno::Reference< frame::XController > xController = xModel->getCurrentController(); - if ( !xController.is() ) - throw uno::RuntimeException( rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM ("No controller for model") ), uno::Reference< uno::XInterface >() ); - return uno::Reference< beans::XPropertySet >( xController->getFrame(), uno::UNO_QUERY ); -} - uno::Any SAL_CALL ScVbaWindow::getCaption() throw (uno::RuntimeException) @@ -300,9 +317,8 @@ ScVbaWindow::getCaption() throw (uno::RuntimeException) static rtl::OUString sCrud(RTL_CONSTASCII_USTRINGPARAM(" - OpenOffice.org Calc" ) ); static sal_Int32 nCrudLen = sCrud.getLength(); - uno::Reference< beans::XPropertySet > xProps = getPropsFromModel( m_xModel ); rtl::OUString sTitle; - xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SC_UNONAME_TITLE ) ) ) >>= sTitle; + getFrameProps()->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SC_UNONAME_TITLE ) ) ) >>= sTitle; sal_Int32 nCrudIndex = sTitle.indexOf( sCrud ); // adjust title ( by removing crud ) // sCrud string present @@ -338,16 +354,14 @@ ScVbaWindow::getCaption() throw (uno::RuntimeException) void SAL_CALL ScVbaWindow::setCaption( const uno::Any& _caption ) throw (uno::RuntimeException) { - - uno::Reference< beans::XPropertySet > xProps = getPropsFromModel( m_xModel ); - xProps->setPropertyValue( rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM ( SC_UNONAME_TITLE ) ) , _caption ); + getFrameProps()->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_TITLE ) ), _caption ); } uno::Any SAL_CALL ScVbaWindow::getScrollRow() throw (uno::RuntimeException) { sal_Int32 nValue = 0; + // !! TODO !! get view shell from controller ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); if ( pViewShell ) { @@ -361,6 +375,7 @@ ScVbaWindow::getScrollRow() throw (uno::RuntimeException) void SAL_CALL ScVbaWindow::setScrollRow( const uno::Any& _scrollrow ) throw (uno::RuntimeException) { + // !! TODO !! get view shell from controller ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); if ( pViewShell ) { @@ -376,6 +391,7 @@ uno::Any SAL_CALL ScVbaWindow::getScrollColumn() throw (uno::RuntimeException) { sal_Int32 nValue = 0; + // !! TODO !! get view shell from controller ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); if ( pViewShell ) { @@ -389,6 +405,7 @@ ScVbaWindow::getScrollColumn() throw (uno::RuntimeException) void SAL_CALL ScVbaWindow::setScrollColumn( const uno::Any& _scrollcolumn ) throw (uno::RuntimeException) { + // !! TODO !! get view shell from controller ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); if ( pViewShell ) { @@ -404,6 +421,7 @@ uno::Any SAL_CALL ScVbaWindow::getWindowState() throw (uno::RuntimeException) { sal_Int32 nwindowState = xlNormal; + // !! TODO !! get view shell from controller ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame(); WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow(); @@ -422,6 +440,7 @@ ScVbaWindow::setWindowState( const uno::Any& _windowstate ) throw (uno::RuntimeE { sal_Int32 nwindowState = xlMaximized; _windowstate >>= nwindowState; + // !! TODO !! get view shell from controller ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame(); WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow(); @@ -456,7 +475,8 @@ ScVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& FileName, const uno::Reference< excel::XPane > SAL_CALL ScVbaWindow::ActivePane() throw (script::BasicErrorException, uno::RuntimeException) { - return new ScVbaPane( this, mxContext, m_xModel, m_xViewPane ); + uno::Reference< sheet::XViewPane > xViewPane( getController(), uno::UNO_QUERY_THROW ); + return new ScVbaPane( this, mxContext, m_xModel, xViewPane ); } uno::Reference< excel::XRange > SAL_CALL @@ -484,10 +504,9 @@ ScVbaWindow::RangeSelection() throw (script::BasicErrorException, uno::RuntimeEx ::sal_Bool SAL_CALL ScVbaWindow::getDisplayGridlines() throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWGRID ) ); sal_Bool bGrid = sal_True; - xProps->getPropertyValue( sName ) >>= bGrid; + getControllerProps()->getPropertyValue( sName ) >>= bGrid; return bGrid; } @@ -495,131 +514,125 @@ ScVbaWindow::getDisplayGridlines() throw (uno::RuntimeException) void SAL_CALL ScVbaWindow::setDisplayGridlines( ::sal_Bool _displaygridlines ) throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWGRID ) ); - xProps->setPropertyValue( sName, uno::makeAny( _displaygridlines )); + getControllerProps()->setPropertyValue( sName, uno::makeAny( _displaygridlines )); } ::sal_Bool SAL_CALL ScVbaWindow::getDisplayHeadings() throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLROWHDR ) ); sal_Bool bHeading = sal_True; - xProps->getPropertyValue( sName ) >>= bHeading; + getControllerProps()->getPropertyValue( sName ) >>= bHeading; return bHeading; } void SAL_CALL ScVbaWindow::setDisplayHeadings( ::sal_Bool _bDisplayHeadings ) throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_COLROWHDR ) ); - xProps->setPropertyValue( sName, uno::makeAny( _bDisplayHeadings )); + getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayHeadings )); } ::sal_Bool SAL_CALL ScVbaWindow::getDisplayHorizontalScrollBar() throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_HORSCROLL ) ); sal_Bool bHorizontalScrollBar = sal_True; - xProps->getPropertyValue( sName ) >>= bHorizontalScrollBar; + getControllerProps()->getPropertyValue( sName ) >>= bHorizontalScrollBar; return bHorizontalScrollBar; } void SAL_CALL ScVbaWindow::setDisplayHorizontalScrollBar( ::sal_Bool _bDisplayHorizontalScrollBar ) throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_HORSCROLL ) ); - xProps->setPropertyValue( sName, uno::makeAny( _bDisplayHorizontalScrollBar )); + getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayHorizontalScrollBar )); } ::sal_Bool SAL_CALL ScVbaWindow::getDisplayOutline() throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_OUTLSYMB ) ); sal_Bool bOutline = sal_True; - xProps->getPropertyValue( sName ) >>= bOutline; + getControllerProps()->getPropertyValue( sName ) >>= bOutline; return bOutline; } void SAL_CALL ScVbaWindow::setDisplayOutline( ::sal_Bool _bDisplayOutline ) throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_OUTLSYMB ) ); - xProps->setPropertyValue( sName, uno::makeAny( _bDisplayOutline )); + getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayOutline )); } ::sal_Bool SAL_CALL ScVbaWindow::getDisplayVerticalScrollBar() throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_VERTSCROLL ) ); sal_Bool bVerticalScrollBar = sal_True; - xProps->getPropertyValue( sName ) >>= bVerticalScrollBar; + getControllerProps()->getPropertyValue( sName ) >>= bVerticalScrollBar; return bVerticalScrollBar; } void SAL_CALL ScVbaWindow::setDisplayVerticalScrollBar( ::sal_Bool _bDisplayVerticalScrollBar ) throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_VERTSCROLL ) ); - xProps->setPropertyValue( sName, uno::makeAny( _bDisplayVerticalScrollBar )); + getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayVerticalScrollBar )); } ::sal_Bool SAL_CALL ScVbaWindow::getDisplayWorkbookTabs() throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHEETTABS ) ); sal_Bool bWorkbookTabs = sal_True; - xProps->getPropertyValue( sName ) >>= bWorkbookTabs; + getControllerProps()->getPropertyValue( sName ) >>= bWorkbookTabs; return bWorkbookTabs; } void SAL_CALL ScVbaWindow::setDisplayWorkbookTabs( ::sal_Bool _bDisplayWorkbookTabs ) throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHEETTABS ) ); - xProps->setPropertyValue( sName, uno::makeAny( _bDisplayWorkbookTabs )); + getControllerProps()->setPropertyValue( sName, uno::makeAny( _bDisplayWorkbookTabs )); } ::sal_Bool SAL_CALL ScVbaWindow::getFreezePanes() throw (uno::RuntimeException) { - return m_xViewFreezable->hasFrozenPanes(); + uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW ); + return xViewFreezable->hasFrozenPanes(); } void SAL_CALL ScVbaWindow::setFreezePanes( ::sal_Bool /*_bFreezePanes*/ ) throw (uno::RuntimeException) { - if( m_xViewSplitable->getIsWindowSplit() ) + uno::Reference< sheet::XViewPane > xViewPane( getController(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XViewSplitable > xViewSplitable( xViewPane, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XViewFreezable > xViewFreezable( xViewPane, uno::UNO_QUERY_THROW ); + if( xViewSplitable->getIsWindowSplit() ) { // if there is a split we freeze at the split sal_Int32 nColumn = getSplitColumn(); sal_Int32 nRow = getSplitRow(); - m_xViewFreezable->freezeAtPosition( nColumn, nRow ); + xViewFreezable->freezeAtPosition( nColumn, nRow ); } else { // otherwise we freeze in the center of the visible sheet - table::CellRangeAddress aCellRangeAddress = m_xViewPane->getVisibleRange(); + table::CellRangeAddress aCellRangeAddress = xViewPane->getVisibleRange(); sal_Int32 nColumn = aCellRangeAddress.StartColumn + (( aCellRangeAddress.EndColumn - aCellRangeAddress.StartColumn )/2 ); sal_Int32 nRow = aCellRangeAddress.StartRow + (( aCellRangeAddress.EndRow - aCellRangeAddress.StartRow )/2 ); - m_xViewFreezable->freezeAtPosition( nColumn, nRow ); + xViewFreezable->freezeAtPosition( nColumn, nRow ); } } ::sal_Bool SAL_CALL ScVbaWindow::getSplit() throw (uno::RuntimeException) { - return m_xViewSplitable->getIsWindowSplit(); + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + return xViewSplitable->getIsWindowSplit(); } void SAL_CALL @@ -627,14 +640,16 @@ ScVbaWindow::setSplit( ::sal_Bool _bSplit ) throw (uno::RuntimeException) { if( !_bSplit ) { - m_xViewSplitable->splitAtPosition(0,0); + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + xViewSplitable->splitAtPosition(0,0); } else { + uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW ); uno::Reference< excel::XRange > xRange = ActiveCell(); sal_Int32 nRow = xRange->getRow(); sal_Int32 nColumn = xRange->getColumn(); - m_xViewFreezable->freezeAtPosition( nColumn-1, nRow-1 ); + xViewFreezable->freezeAtPosition( nColumn-1, nRow-1 ); SplitAtDefinedPosition( sal_True ); } } @@ -642,7 +657,8 @@ ScVbaWindow::setSplit( ::sal_Bool _bSplit ) throw (uno::RuntimeException) sal_Int32 SAL_CALL ScVbaWindow::getSplitColumn() throw (uno::RuntimeException) { - return m_xViewSplitable->getSplitColumn(); + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + return xViewSplitable->getSplitColumn(); } void SAL_CALL @@ -650,9 +666,10 @@ ScVbaWindow::setSplitColumn( sal_Int32 _splitcolumn ) throw (uno::RuntimeExcepti { if( getSplitColumn() != _splitcolumn ) { + uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW ); sal_Bool bFrozen = getFreezePanes(); sal_Int32 nRow = getSplitRow(); - m_xViewFreezable->freezeAtPosition( _splitcolumn, nRow ); + xViewFreezable->freezeAtPosition( _splitcolumn, nRow ); SplitAtDefinedPosition( !bFrozen ); } } @@ -660,22 +677,23 @@ ScVbaWindow::setSplitColumn( sal_Int32 _splitcolumn ) throw (uno::RuntimeExcepti double SAL_CALL ScVbaWindow::getSplitHorizontal() throw (uno::RuntimeException) { - double fSplitHorizontal = m_xViewSplitable->getSplitHorizontal(); - double fHoriPoints = PixelsToPoints( m_xDevice, fSplitHorizontal, sal_True ); - return fHoriPoints; + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + return PixelsToPoints( getDevice(), xViewSplitable->getSplitHorizontal(), sal_True ); } void SAL_CALL ScVbaWindow::setSplitHorizontal( double _splithorizontal ) throw (uno::RuntimeException) { - double fHoriPixels = PointsToPixels( m_xDevice, _splithorizontal, sal_True ); - m_xViewSplitable->splitAtPosition( static_cast<sal_Int32>( fHoriPixels ), 0 ); + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + double fHoriPixels = PointsToPixels( getDevice(), _splithorizontal, sal_True ); + xViewSplitable->splitAtPosition( static_cast< sal_Int32 >( fHoriPixels ), 0 ); } sal_Int32 SAL_CALL ScVbaWindow::getSplitRow() throw (uno::RuntimeException) { - sal_Int32 nValue = m_xViewSplitable->getSplitRow(); + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + sal_Int32 nValue = xViewSplitable->getSplitRow(); return nValue ? nValue - 1 : nValue; } @@ -684,9 +702,10 @@ ScVbaWindow::setSplitRow( sal_Int32 _splitrow ) throw (uno::RuntimeException) { if( getSplitRow() != _splitrow ) { + uno::Reference< sheet::XViewFreezable > xViewFreezable( getController(), uno::UNO_QUERY_THROW ); sal_Bool bFrozen = getFreezePanes(); sal_Int32 nColumn = getSplitColumn(); - m_xViewFreezable->freezeAtPosition( nColumn , _splitrow ); + xViewFreezable->freezeAtPosition( nColumn , _splitrow ); SplitAtDefinedPosition( !bFrozen ); } } @@ -694,33 +713,33 @@ ScVbaWindow::setSplitRow( sal_Int32 _splitrow ) throw (uno::RuntimeException) double SAL_CALL ScVbaWindow::getSplitVertical() throw (uno::RuntimeException) { - double fSplitVertical = m_xViewSplitable->getSplitVertical(); - double fVertiPoints = PixelsToPoints( m_xDevice, fSplitVertical, sal_False ); - return fVertiPoints; + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + return PixelsToPoints( getDevice(), xViewSplitable->getSplitVertical(), sal_False ); } void SAL_CALL ScVbaWindow::setSplitVertical(double _splitvertical ) throw (uno::RuntimeException) { - double fVertiPixels = PointsToPixels( m_xDevice, _splitvertical, sal_False ); - m_xViewSplitable->splitAtPosition( 0, static_cast<sal_Int32>( fVertiPixels ) ); + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + double fVertiPixels = PointsToPixels( getDevice(), _splitvertical, sal_False ); + xViewSplitable->splitAtPosition( 0, static_cast<sal_Int32>( fVertiPixels ) ); } void ScVbaWindow::SplitAtDefinedPosition(sal_Bool _bUnFreezePane) { - sal_Int32 nVertSplit = m_xViewSplitable->getSplitVertical(); - sal_Int32 nHoriSplit = m_xViewSplitable->getSplitHorizontal(); + uno::Reference< sheet::XViewSplitable > xViewSplitable( getController(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XViewFreezable > xViewFreezable( xViewSplitable, uno::UNO_QUERY_THROW ); + sal_Int32 nVertSplit = xViewSplitable->getSplitVertical(); + sal_Int32 nHoriSplit = xViewSplitable->getSplitHorizontal(); if( _bUnFreezePane ) - { - m_xViewFreezable->freezeAtPosition(0,0); - } - m_xViewSplitable->splitAtPosition(nHoriSplit, nVertSplit); + xViewFreezable->freezeAtPosition(0,0); + xViewSplitable->splitAtPosition(nHoriSplit, nVertSplit); } uno::Any SAL_CALL ScVbaWindow::getZoom() throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProps = getControllerProps(); rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ZOOMTYPE ) ); sal_Int16 nZoomType = view::DocumentZoomType::PAGE_WIDTH; xProps->getPropertyValue( sName ) >>= nZoomType; @@ -785,6 +804,7 @@ ScVbaWindow::setView( const uno::Any& _view) throw (uno::RuntimeException) default: DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() ); } + // !! TODO !! get view shell from controller ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); if ( pViewShell ) dispatchExecute( pViewShell, nSlot ); @@ -793,7 +813,7 @@ ScVbaWindow::setView( const uno::Any& _view) throw (uno::RuntimeException) uno::Reference< excel::XRange > SAL_CALL ScVbaWindow::getVisibleRange() throw (uno::RuntimeException) { - uno::Reference< container::XIndexAccess > xPanesIA( m_xViewPane, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xPanesIA( getController(), uno::UNO_QUERY_THROW ); uno::Reference< sheet::XViewPane > xTopLeftPane( xPanesIA->getByIndex( 0 ), uno::UNO_QUERY_THROW ); uno::Reference< excel::XPane > xPane( new ScVbaPane( this, mxContext, m_xModel, xTopLeftPane ) ); return xPane->getVisibleRange(); @@ -803,7 +823,7 @@ sal_Int32 SAL_CALL ScVbaWindow::PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException) { sal_Int32 nHundredthsofOneMillimeters = Millimeter::getInHundredthsOfOneMillimeter( _points ); - double fConvertFactor = (m_xDevice->getInfo().PixelPerMeterX/100000); + double fConvertFactor = (getDevice()->getInfo().PixelPerMeterX/100000); return static_cast<sal_Int32>(fConvertFactor * nHundredthsofOneMillimeters ); } @@ -811,7 +831,7 @@ sal_Int32 SAL_CALL ScVbaWindow::PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException) { sal_Int32 nHundredthsofOneMillimeters = Millimeter::getInHundredthsOfOneMillimeter( _points ); - double fConvertFactor = (m_xDevice->getInfo().PixelPerMeterY/100000); + double fConvertFactor = (getDevice()->getInfo().PixelPerMeterY/100000); return static_cast<sal_Int32>(fConvertFactor * nHundredthsofOneMillimeters ); } @@ -819,6 +839,7 @@ void SAL_CALL ScVbaWindow::PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException) { // need test, print current active sheet + // !! TODO !! get view shell from controller PrintOutHelper( excel::getBestViewShell( m_xModel ), From, To, Copies, Preview, ActivePrinter, PrintToFile, Collate, PrToFileName, sal_True ); } @@ -826,6 +847,7 @@ void SAL_CALL ScVbaWindow::PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException) { // need test, print preview current active sheet + // !! TODO !! get view shell from controller PrintPreviewHelper( EnableChanges, excel::getBestViewShell( m_xModel ) ); } diff --git a/sc/source/ui/vba/vbawindow.hxx b/sc/source/ui/vba/vbawindow.hxx index d58d2a07cb4b..d183ee346185 100644 --- a/sc/source/ui/vba/vbawindow.hxx +++ b/sc/source/ui/vba/vbawindow.hxx @@ -27,7 +27,6 @@ #ifndef SC_VBA_WINDOW_HXX #define SC_VBA_WINDOW_HXX -#include <cppuhelper/implbase1.hxx> #include <ooo/vba/excel/XWindow.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/sheet/XViewPane.hpp> @@ -46,19 +45,30 @@ typedef cppu::ImplInheritanceHelper1< VbaWindowBase, ov::excel::XWindow > Window class ScVbaWindow : public WindowImpl_BASE { private: - css::uno::Reference< css::sheet::XViewPane > m_xViewPane; - css::uno::Reference< css::sheet::XViewFreezable > m_xViewFreezable; - css::uno::Reference< css::sheet::XViewSplitable > m_xViewSplitable; css::uno::Reference< ov::excel::XPane > m_xPane; - css::uno::Reference< css::awt::XDevice > m_xDevice; + void init(); + css::uno::Reference< css::beans::XPropertySet > getControllerProps() throw (css::uno::RuntimeException); + css::uno::Reference< css::beans::XPropertySet > getFrameProps() throw (css::uno::RuntimeException); + css::uno::Reference< css::awt::XDevice > getDevice() throw (css::uno::RuntimeException); + protected: void SplitAtDefinedPosition(sal_Bool _bUnFreezePane); + public: - void Scroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft, bool bLargeScroll = false ) throw (css::uno::RuntimeException); + void Scroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft, bool bLargeScroll = false ) throw (css::uno::RuntimeException); + public: - ScVbaWindow( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::frame::XModel >& xModel ); - ScVbaWindow( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext > const& xContext ); + ScVbaWindow( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::frame::XController >& xController ) + throw (css::uno::RuntimeException); + ScVbaWindow( + const css::uno::Sequence< css::uno::Any >& aArgs, + const css::uno::Reference< css::uno::XComponentContext >& xContext ) + throw (css::uno::RuntimeException); // XWindow virtual css::uno::Reference< ov::excel::XRange > SAL_CALL ActiveCell( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbawindows.cxx b/sc/source/ui/vba/vbawindows.cxx index 3ddc5f5b3b45..80f215629126 100644 --- a/sc/source/ui/vba/vbawindows.cxx +++ b/sc/source/ui/vba/vbawindows.cxx @@ -53,7 +53,9 @@ uno::Reference< XHelperInterface > lcl_createWorkbookHIParent( const uno::Refere uno::Any ComponentToWindow( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext, const uno::Any& aApplication ) { uno::Reference< frame::XModel > xModel( aSource, uno::UNO_QUERY_THROW ); - uno::Reference< excel::XWindow > xWin( new ScVbaWindow( lcl_createWorkbookHIParent( xModel, xContext, aApplication ), xContext,xModel ) ); + // !! TODO !! iterate over all controllers + uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); + uno::Reference< excel::XWindow > xWin( new ScVbaWindow( lcl_createWorkbookHIParent( xModel, xContext, aApplication ), xContext, xModel, xController ) ); return uno::makeAny( xWin ); } @@ -138,8 +140,10 @@ public: { m_windows.push_back( xNext ); uno::Reference< frame::XModel > xModel( xNext, uno::UNO_QUERY_THROW ); // that the spreadsheetdocument is a xmodel is a given + // !! TODO !! iterate over all controllers + uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); uno::Reference< XHelperInterface > xTemp; // temporary needed for g++ 3.3.5 - ScVbaWindow window( xTemp, m_xContext, xModel ); + ScVbaWindow window( xTemp, m_xContext, xModel, xController ); rtl::OUString sCaption; window.getCaption() >>= sCaption; namesToIndices[ sCaption ] = nIndex++; diff --git a/sc/source/ui/vba/vbaworkbook.cxx b/sc/source/ui/vba/vbaworkbook.cxx index 1e2acd6252b8..e0d50c592e6c 100644 --- a/sc/source/ui/vba/vbaworkbook.cxx +++ b/sc/source/ui/vba/vbaworkbook.cxx @@ -218,14 +218,9 @@ ScVbaWorkbook::getActiveSheet() throw (uno::RuntimeException) { uno::Reference< frame::XModel > xModel( getCurrentExcelDoc( mxContext ), uno::UNO_SET_THROW ); uno::Reference< sheet::XSpreadsheetView > xView( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); - uno::Reference< beans::XPropertySet > xSheetProps( xView->getActiveSheet(), uno::UNO_QUERY_THROW ); - // #162503# return the original document module wrapper object, instead of a new instance - ::rtl::OUString aCodeName; - xSheetProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_CODENAME ) ) ) >>= aCodeName; - ScDocShell* pShell = excel::getDocShell( xModel ); - if( !pShell ) - throw uno::RuntimeException(); - return uno::Reference< excel::XWorksheet >( getUnoDocModule( aCodeName, pShell ), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xView->getActiveSheet(), uno::UNO_SET_THROW ); + // #162503# return the original sheet module wrapper object, instead of a new instance + return uno::Reference< excel::XWorksheet >( excel::getUnoSheetModuleObj( xSheet ), uno::UNO_QUERY_THROW ); } uno::Any SAL_CALL diff --git a/sc/source/ui/vba/vbaworkbooks.cxx b/sc/source/ui/vba/vbaworkbooks.cxx index a9f1970be34e..9fec863f5463 100644 --- a/sc/source/ui/vba/vbaworkbooks.cxx +++ b/sc/source/ui/vba/vbaworkbooks.cxx @@ -134,18 +134,6 @@ void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& } } } - - /* Trigger the Workbook_Open event, event processor will register - itself as listener for specific events. */ - try - { - uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pShell->GetDocument()->GetVbaEventProcessor(), uno::UNO_SET_THROW ); - uno::Sequence< uno::Any > aArgs; - xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_OPEN, aArgs ); - } - catch( uno::Exception& ) - { - } } } @@ -157,19 +145,14 @@ getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Refe if( !xModel.is() ) return uno::Any(); - ScDocShell* pShell = excel::getDocShell( xModel ); - if ( pShell ) + uno::Reference< excel::XWorkbook > xWb( getVBADocument( xModel ), uno::UNO_QUERY ); + if ( xWb.is() ) { - String sCodeName = pShell->GetDocument()->GetCodeName(); - uno::Reference< uno::XInterface > xIf = getUnoDocModule( sCodeName, pShell ); - if ( xIf.is() ) - { - OSL_TRACE(" *** Returning Module uno Object *** "); - return uno::makeAny( xIf ); - } + OSL_TRACE(" *** Returning Module uno Object *** "); + return uno::Any( xWb ); } - ScVbaWorkbook *pWb = new ScVbaWorkbook( xParent, xContext, xModel ); + ScVbaWorkbook *pWb = new ScVbaWorkbook( xParent, xContext, xModel ); return uno::Any( uno::Reference< excel::XWorkbook > (pWb) ); } diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx index bd21cb396c66..cf74f90b5941 100644 --- a/sc/source/ui/vba/vbaworksheets.cxx +++ b/sc/source/ui/vba/vbaworksheets.cxx @@ -68,23 +68,6 @@ typedef std::vector< uno::Reference< sheet::XSpreadsheet > > SheetMap; // #FIXME #TODO the implementation of the Sheets collections sucks, // e.g. there is no support for tracking sheets added/removed from the collection -uno::Reference< uno::XInterface > -lcl_getModulAsUnoObject( const uno::Reference< sheet::XSpreadsheet >& xSheet, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) -{ - uno::Reference< uno::XInterface > xRet; - if ( !xSheet.is() ) - throw uno::RuntimeException(); - uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW ); - rtl::OUString sName; - xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_CODENAME ) ) ) >>= sName; - - ScDocShell* pShell = excel::getDocShell( xModel ); - - if ( pShell ) - xRet = getUnoDocModule( sName, pShell ); - return xRet; -} - class WorkSheetsEnumeration : public SheetEnumeration_BASE { SheetMap mSheetMap; @@ -173,16 +156,16 @@ public: virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { uno::Reference< sheet::XSpreadsheet > xSheet( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); - uno::Reference< uno::XInterface > xIf = lcl_getModulAsUnoObject( xSheet, m_xModel ); + uno::Reference< XHelperInterface > xIf = excel::getUnoSheetModuleObj( xSheet ); uno::Any aRet; if ( !xIf.is() ) - { + { // if the Sheet is in a document created by the api unfortunately ( at the // moment, it actually wont have the special Document modules uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) ); aRet <<= xNewSheet; - } - else + } + else aRet <<= xIf; return aRet; } @@ -220,7 +203,7 @@ uno::Any ScVbaWorksheets::createCollectionObject( const uno::Any& aSource ) { uno::Reference< sheet::XSpreadsheet > xSheet( aSource, uno::UNO_QUERY ); - uno::Reference< XInterface > xIf = lcl_getModulAsUnoObject( xSheet, mxModel ); + uno::Reference< XHelperInterface > xIf = excel::getUnoSheetModuleObj( xSheet ); uno::Any aRet; if ( !xIf.is() ) { diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx index 8db71ad9752f..4b6d14470063 100644 --- a/sc/source/ui/view/dbfunc.cxx +++ b/sc/source/ui/view/dbfunc.cxx @@ -504,8 +504,7 @@ sal_Bool ScDBFunc::ImportData( const ScImportParam& rParam, sal_Bool bRecord ) } ScDBDocFunc aDBDocFunc( *GetViewData()->GetDocShell() ); - ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > xResultSet; - return aDBDocFunc.DoImport( GetViewData()->GetTabNo(), rParam, xResultSet, NULL, bRecord ); + return aDBDocFunc.DoImport( GetViewData()->GetTabNo(), rParam, NULL, bRecord ); } diff --git a/sc/source/ui/view/drawutil.cxx b/sc/source/ui/view/drawutil.cxx index a5a4a7ee1c1d..89287a93e14b 100644 --- a/sc/source/ui/view/drawutil.cxx +++ b/sc/source/ui/view/drawutil.cxx @@ -81,6 +81,15 @@ void ScDrawUtil::CalcScale( ScDocument* pDoc, SCTAB nTab, nPixelY += ScViewData::ToPixel(nHeight, nPPTY); } + // #i116848# To get a large-enough number for PixelToLogic, multiply the integer values + // instead of using a larger number of rows + long nMultiply = 2000000 / nTwipsY; + if ( nMultiply > 1 ) + { + nTwipsY *= nMultiply; + nPixelY *= nMultiply; + } + MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY ); Point aPixelLog = pDev->PixelToLogic( Point( nPixelX,nPixelY ), aHMMMode ); diff --git a/sc/source/ui/view/drawvie4.cxx b/sc/source/ui/view/drawvie4.cxx index 1c0d38ee18e5..76984b813063 100644 --- a/sc/source/ui/view/drawvie4.cxx +++ b/sc/source/ui/view/drawvie4.cxx @@ -283,7 +283,7 @@ void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const if (nEndCol<20) nEndCol = 20; if (nEndRow<20) - nEndRow = 1000; + nEndRow = 20; Fraction aZoom(1,1); ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom, diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index cc63f9b97a62..57b365eb228b 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -377,7 +377,7 @@ void ScDrawView::RecalcScale() if (nEndCol<20) nEndCol = 20; if (nEndRow<20) - nEndRow = 1000; + nEndRow = 20; // #i116848# instead of a large row number for an empty sheet, heights are multiplied in CalcScale ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY, aScaleX,aScaleY ); diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx index e07e15267198..f75ebcbe770f 100644 --- a/sc/source/ui/view/editsh.cxx +++ b/sc/source/ui/view/editsh.cxx @@ -199,6 +199,7 @@ void ScEditShell::Execute( SfxRequest& rReq ) pHdl->DataChanging(); sal_Bool bSetSelIsRef = sal_False; + sal_Bool bSetModified = sal_True; switch ( nSlot ) { @@ -234,6 +235,7 @@ void ScEditShell::Execute( SfxRequest& rReq ) case SID_COPY: pTableView->Copy(); + bSetModified = sal_False; break; case SID_CUT: @@ -334,6 +336,7 @@ void ScEditShell::Execute( SfxRequest& rReq ) if (pTopView) pTopView->SetSelection(ESelection(0,0,nPar-1,nLen)); } + bSetModified = sal_False; } break; @@ -615,7 +618,7 @@ void ScEditShell::Execute( SfxRequest& rReq ) break; } - pHdl->DataChanged(); + pHdl->DataChanged(sal_False, bSetModified); if (bSetSelIsRef) pHdl->SetSelIsRef(sal_True); } diff --git a/sc/source/ui/view/formatsh.cxx b/sc/source/ui/view/formatsh.cxx index ecc6f19d43e5..c9ed04ce2db9 100644 --- a/sc/source/ui/view/formatsh.cxx +++ b/sc/source/ui/view/formatsh.cxx @@ -1222,13 +1222,22 @@ void ScFormatShell::ExecuteTextAttr( SfxRequest& rReq ) if( pSet ) { - const SvxUnderlineItem& rUnderline = (const SvxUnderlineItem&)pSet->Get( ATTR_FONT_UNDERLINE ); + const SfxPoolItem& rUnderline = pSet->Get( ATTR_FONT_UNDERLINE ); if( rUnderline.ISA(SvxUnderlineItem) ) { pTabViewShell->ApplyAttr( rUnderline ); pNewSet->Put( rUnderline,rUnderline.Which() ); } + else if ( rUnderline.ISA(SvxTextLineItem) ) + { + // #i106580# also allow SvxTextLineItem (base class of SvxUnderlineItem) + const SvxTextLineItem& rTextLineItem = static_cast<const SvxTextLineItem&>(rUnderline); + SvxUnderlineItem aNewItem( rTextLineItem.GetLineStyle(), rTextLineItem.Which() ); + aNewItem.SetColor( rTextLineItem.GetColor() ); + pTabViewShell->ApplyAttr( aNewItem ); + pNewSet->Put( aNewItem, aNewItem.Which() ); + } } else { diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index d350da754433..d58d2266618d 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -2,7 +2,7 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2000, 2011 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * @@ -1682,6 +1682,7 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt ) pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG ); if (pAttr->HasAutoFilter()) { + SC_MOD()->InputEnterHandler(); //Add for i85305 if (DoAutoFilterButton(nPosX, nPosY, rMEvt)) return; } @@ -5100,6 +5101,26 @@ sal_Bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScen return sal_False; } +void ScGridWindow::UpdateVisibleRange() +{ + // #163911# Update the visible range outside of paint (called when switching sheets). + // Use the same logic here as in ScGridWindow::Draw. + + SCCOL nPosX = pViewData->GetPosX( eHWhich ); + SCROW nPosY = pViewData->GetPosY( eVWhich ); + + SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich); + if (nXRight > MAXCOL) nXRight = MAXCOL; + SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); + if (nYBottom > MAXROW) nYBottom = MAXROW; + + // Store the current visible range. + maVisibleRange.mnCol1 = nPosX; + maVisibleRange.mnCol2 = nXRight; + maVisibleRange.mnRow1 = nPosY; + maVisibleRange.mnRow2 = nYBottom; +} + // #114409# void ScGridWindow::DrawLayerCreated() { diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 67cc1d318fdb..89fd1027877d 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -456,6 +456,18 @@ private: } +bool lcl_GetLabelIndex( size_t& rLabelIndex, long nDimension, const ScDPLabelDataVector& rLabelArray ) +{ + size_t n = rLabelArray.size(); + for (size_t i = 0; i < n; ++i) + if (static_cast<long>(rLabelArray[i].mnCol) == nDimension) + { + rLabelIndex = i; + return true; + } + return false; +} + void ScGridWindow::DPLaunchFieldPopupMenu( const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj) { @@ -467,11 +479,12 @@ void ScGridWindow::DPLaunchFieldPopupMenu( sal_uInt16 nOrient; pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient); - if (pDPData->maDPParam.maLabelArray.size() <= static_cast<size_t>(pDPData->mnDim)) - // out-of-bound dimension ID. This should never happen! + // #i116457# FillLabelData skips empty column names, so mnDim can't be used directly as index into maLabelArray. + size_t nLabelIndex = 0; + if (!lcl_GetLabelIndex( nLabelIndex, pDPData->mnDim, pDPData->maDPParam.maLabelArray )) return; - const ScDPLabelData& rLabelData = pDPData->maDPParam.maLabelArray[pDPData->mnDim]; + const ScDPLabelData& rLabelData = pDPData->maDPParam.maLabelArray[nLabelIndex]; mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument())); mpDPFieldPopup->setName(OUString::createFromAscii("Pivot table field member popup")); @@ -567,8 +580,11 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu() if (!pDim) return; + size_t nLabelIndex = 0; + lcl_GetLabelIndex( nLabelIndex, pDPData->mnDim, pDPData->maDPParam.maLabelArray ); + // Build a map of layout names to original names. - const ScDPLabelData& rLabelData = pDPData->maDPParam.maLabelArray[pDPData->mnDim]; + const ScDPLabelData& rLabelData = pDPData->maDPParam.maLabelArray[nLabelIndex]; MemNameMapType aMemNameMap; for (vector<ScDPLabelData::Member>::const_iterator itr = rLabelData.maMembers.begin(), itrEnd = rLabelData.maMembers.end(); itr != itrEnd; ++itr) diff --git a/sc/source/ui/view/gridwin3.cxx b/sc/source/ui/view/gridwin3.cxx index 295caae639af..e7d9e4e318b4 100644 --- a/sc/source/ui/view/gridwin3.cxx +++ b/sc/source/ui/view/gridwin3.cxx @@ -265,7 +265,7 @@ MapMode ScGridWindow::GetDrawMapMode( sal_Bool bForce ) SCROW nEndRow = 0; pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<20) nEndRow = 1000; + if (nEndRow<20) nEndRow = 20; ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, this, pViewData->GetZoomX(),pViewData->GetZoomY(), pViewData->GetPPTX(),pViewData->GetPPTY(), diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index b1d6787d3ce6..0b9a1c4084e4 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -75,8 +75,6 @@ #include "scmod.hxx" #include "fillinfo.hxx" -#include <boost/ptr_container/ptr_vector.hpp> - #include <math.h> //! Autofilter-Breite mit column.cxx zusammenfassen @@ -154,6 +152,8 @@ public: const Size& GetTextSize() const { return aTextSize; } long GetOriginalWidth() const { return nOriginalWidth; } + sal_uLong GetResultValueFormat( const ScBaseCell* pCell ) const; + sal_uLong GetValueFormat() const { return nValueFormat; } sal_Bool GetLineBreak() const { return bLineBreak; } sal_Bool IsRepeat() const { return bRepeat; } @@ -532,9 +532,9 @@ void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ) if (eType == CELLTYPE_FORMULA) { ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); - if (pFCell->GetErrCode() != 0) + if (pFCell->GetErrCode() != 0 || pOutput->bShowFormulas) { - SetHashText(); // If the error string doesn't fit, always use "###" + SetHashText(); // If the error string doesn't fit, always use "###". Also for "display formulas" (#i116691#) return; } // If it's formula, the result must be a value. @@ -542,7 +542,7 @@ void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ) return; } - sal_uLong nFormat = GetValueFormat(); + sal_uLong nFormat = GetResultValueFormat(pCell); if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0) { // Not 'General' number format. Set hash text and bail out. @@ -719,6 +719,17 @@ sal_Bool ScDrawStringsVars::HasEditCharacters() const return aString.SearchChar( pChars ) != STRING_NOTFOUND; } +sal_uLong ScDrawStringsVars::GetResultValueFormat( const ScBaseCell* pCell ) const +{ + // Get the effective number format, including formula result types. + // This assumes that a formula cell has already been calculated. + + if ( (nValueFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && pCell && pCell->GetCellType() == CELLTYPE_FORMULA ) + return static_cast<const ScFormulaCell*>(pCell)->GetStandardFormat(*pOutput->pDoc->GetFormatTable(), nValueFormat); + else + return nValueFormat; +} + //================================================================== double ScOutputData::GetStretch() @@ -1361,10 +1372,6 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic ) const SfxItemSet* pOldCondSet = NULL; sal_uInt8 nOldScript = 0; - // alternative pattern instances in case we need to modify the pattern - // before processing the cell value. - ::boost::ptr_vector<ScPatternAttr> aAltPatterns; - long nPosY = nScrY; for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++) { @@ -1501,18 +1508,6 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic ) pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab ); } - if (pCell->HasValueData() && - static_cast<const SfxBoolItem&>( - pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue()) - { - // Disable line break when the cell content is numeric. - aAltPatterns.push_back(new ScPatternAttr(*pPattern)); - ScPatternAttr* pAltPattern = &aAltPatterns.back(); - SfxBoolItem aLineBreak(ATTR_LINEBREAK, false); - pAltPattern->GetItemSet().Put(aLineBreak); - pPattern = pAltPattern; - } - sal_uInt8 nScript = GetScriptType( pDoc, pCell, pPattern, pCondSet ); if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType(); if ( pPattern != pOldPattern || pCondSet != pOldCondSet || @@ -1562,6 +1557,11 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic ) eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented sal_Bool bBreak = ( aVars.GetLineBreak() || aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK ); + + // #i111387# #o11817313# disable automatic line breaks only for "General" number format + if ( bBreak && bCellIsValue && ( aVars.GetResultValueFormat(pCell) % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 ) + bBreak = sal_False; + sal_Bool bRepeat = aVars.IsRepeat() && !bBreak; sal_Bool bShrink = aVars.IsShrink() && !bBreak && !bRepeat; @@ -1905,6 +1905,26 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic ) // ------------------------------------------------------------------------------- +ScFieldEditEngine* ScOutputData::CreateOutputEditEngine() +{ + ScFieldEditEngine* pEngine = new ScFieldEditEngine( pDoc->GetEnginePool() ); + pEngine->SetUpdateMode( sal_False ); + // a RefDevice always has to be set, otherwise EditEngine would create a VirtualDevice + pEngine->SetRefDevice( pFmtDevice ); + sal_uInt32 nCtrl = pEngine->GetControlWord(); + if ( bShowSpellErrors ) + nCtrl |= EE_CNTRL_ONLINESPELLING; + if ( eType == OUTTYPE_PRINTER ) + nCtrl &= ~EE_CNTRL_MARKFIELDS; + if ( eType == OUTTYPE_WINDOW && pRefDevice == pFmtDevice ) + nCtrl &= ~EE_CNTRL_FORMAT100; // use the actual MapMode + pEngine->SetControlWord( nCtrl ); + pDoc->ApplyAsianEditSettings( *pEngine ); + pEngine->EnableAutoColor( bUseStyleColor ); + pEngine->SetDefaultHorizontalTextDirection( (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) ); + return pEngine; +} + void lcl_ClearEdit( EditEngine& rEngine ) // Text und Attribute { rEngine.SetUpdateMode( sal_False ); @@ -2221,29 +2241,10 @@ void ScOutputData::DrawEdit(sal_Bool bPixelToLogic) // if (!pEngine) - { - // Ein RefDevice muss auf jeden Fall gesetzt werden, - // sonst legt sich die EditEngine ein VirtualDevice an! - pEngine = new ScFieldEditEngine( pDoc->GetEnginePool() ); - pEngine->SetUpdateMode( sal_False ); - pEngine->SetRefDevice( pFmtDevice ); // always set - sal_uLong nCtrl = pEngine->GetControlWord(); - if ( bShowSpellErrors ) - nCtrl |= EE_CNTRL_ONLINESPELLING; - if ( eType == OUTTYPE_PRINTER ) - nCtrl &= ~EE_CNTRL_MARKFIELDS; - pEngine->SetControlWord( nCtrl ); - pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() ); - pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() ); - pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() ); - pEngine->EnableAutoColor( bUseStyleColor ); - pEngine->SetDefaultHorizontalTextDirection( - (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) ); - } + pEngine = CreateOutputEditEngine(); else lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(sal_False) - sal_Bool bCellIsValue = lcl_SafeIsValue(pCell); SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&) @@ -2285,8 +2286,6 @@ void ScOutputData::DrawEdit(sal_Bool bPixelToLogic) eHorJust = SVX_HOR_JUSTIFY_RIGHT; } - - SvxCellHorJustify eOutHorJust = ( eHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? eHorJust : ( bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT ); @@ -3054,25 +3053,7 @@ void ScOutputData::DrawRotated(sal_Bool bPixelToLogic) if (!bHidden) { if (!pEngine) - { - // Ein RefDevice muss auf jeden Fall gesetzt werden, - // sonst legt sich die EditEngine ein VirtualDevice an! - pEngine = new ScFieldEditEngine( pDoc->GetEnginePool() ); - pEngine->SetUpdateMode( sal_False ); - pEngine->SetRefDevice( pFmtDevice ); // always set - sal_uLong nCtrl = pEngine->GetControlWord(); - if ( bShowSpellErrors ) - nCtrl |= EE_CNTRL_ONLINESPELLING; - if ( eType == OUTTYPE_PRINTER ) - nCtrl &= ~EE_CNTRL_MARKFIELDS; - pEngine->SetControlWord( nCtrl ); - pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() ); - pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() ); - pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() ); - pEngine->EnableAutoColor( bUseStyleColor ); - pEngine->SetDefaultHorizontalTextDirection( - (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) ); - } + pEngine = CreateOutputEditEngine(); else lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(sal_False) diff --git a/sc/source/ui/view/pfuncache.cxx b/sc/source/ui/view/pfuncache.cxx index 6bb14163b227..4105bfb98db5 100644 --- a/sc/source/ui/view/pfuncache.cxx +++ b/sc/source/ui/view/pfuncache.cxx @@ -64,6 +64,11 @@ ScPrintFuncCache::ScPrintFuncCache( ScDocShell* pD, const ScMarkData& rMark, ScDocument* pDoc = pDocSh->GetDocument(); SCTAB nTabCount = pDoc->GetTableCount(); + + // avoid repeated progress bars if row heights for all sheets are needed + if ( nTabCount > 1 && rMark.GetSelectCount() == nTabCount ) + pDocSh->UpdatePendingRowHeights( nTabCount-1, true ); + SCTAB nTab; for ( nTab=0; nTab<nTabCount; nTab++ ) { @@ -72,8 +77,6 @@ ScPrintFuncCache::ScPrintFuncCache( ScDocShell* pD, const ScMarkData& rMark, long nThisTab = 0; if ( rMark.GetTableSelect( nTab ) ) { - pDoc->InvalidatePageBreaks( nTab ); // user print area (selection) may be different - ScPrintFunc aFunc( pDocSh, pPrinter, nTab, nAttrPage, 0, pSelRange, &aSelection.GetOptions() ); nThisTab = aFunc.GetTotalPages(); nFirstAttr[nTab] = aFunc.GetFirstPageNo(); // from page style or previous sheet @@ -125,7 +128,7 @@ void ScPrintFuncCache::InitLocations( const ScMarkData& rMark, OutputDevice* pDe aPage.Select( aPageRange ); ScPreviewLocationData aLocData( pDoc, pDev ); - aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, NULL, &aLocData ); + aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, &aLocData ); ScRange aCellRange; Rectangle aPixRect; diff --git a/sc/source/ui/view/preview.cxx b/sc/source/ui/view/preview.cxx index 4f3f1d753f32..8fc9c6037cbf 100644 --- a/sc/source/ui/view/preview.cxx +++ b/sc/source/ui/view/preview.cxx @@ -109,7 +109,8 @@ ScPreview::ScPreview( Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pView bLocationValid( sal_False ), pLocationData( NULL ), pDrawView( NULL ), - bInPaint( sal_False ), + bInPaint( false ), + bInSetZoom( false ), bInGetState( sal_False ), pDocShell( pDocSh ), pViewShell( pViewSh ), @@ -139,6 +140,9 @@ ScPreview::ScPreview( Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pView SetUniqueId( HID_SC_WIN_PREVIEW ); SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() ); + + for (SCCOL i=0; i<=MAXCOL; i++) + nRight[i] = 0; // initialized with actual positions when markers are drawn } @@ -367,6 +371,16 @@ void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation ) DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() )); } + long nLeftMargin = 0; + long nRightMargin = 0; + long nTopMargin = 0; + long nBottomMargin = 0; + sal_Bool bHeaderOn = sal_False; + sal_Bool bFooterOn = sal_False; + + ScDocument* pDoc = pDocShell->GetDocument(); + sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); + Size aLocalPageSize; if ( bValidPage ) { @@ -392,17 +406,65 @@ void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation ) aPage.SetTotalRange( Range(0,RANGE_MAX) ); aPage.Select( aPageRange ); - long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, bDoPrint, NULL, pFillLocation ); + long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, bDoPrint, pFillLocation ); DBG_ASSERT(nPrinted<=1, "was'n nu los?"); SetMapMode(aMMMode); -// sal_uInt16 nPrintZoom = pPrintFunc->GetZoom(); + + //init nLeftMargin ... in the ScPrintFunc::InitParam!!! + nLeftMargin = pPrintFunc->GetLeftMargin(); + nRightMargin = pPrintFunc->GetRightMargin(); + nTopMargin = pPrintFunc->GetTopMargin(); + nBottomMargin = pPrintFunc->GetBottomMargin(); + nHeaderHeight = pPrintFunc->GetHeader().nHeight; + nFooterHeight = pPrintFunc->GetFooter().nHeight; + bHeaderOn = pPrintFunc->GetHeader().bEnable; + bFooterOn = pPrintFunc->GetFooter().bEnable; + mnScale = pPrintFunc->GetZoom(); + + if ( bDoPrint && bPageMargin && pLocationData ) // don't make use of pLocationData while filling it + { + Rectangle aPixRect; + Rectangle aRectCellPosition; + Rectangle aRectPosition; + pLocationData->GetMainCellRange( aPageArea, aPixRect ); + if( !bLayoutRTL ) + { + pLocationData->GetCellPosition( aPageArea.aStart, aRectPosition ); + nLeftPosition = aRectPosition.Left(); + for( SCCOL i = aPageArea.aStart.Col(); i <= aPageArea.aEnd.Col(); i++ ) + { + pLocationData->GetCellPosition( ScAddress( i,aPageArea.aStart.Row(),aPageArea.aStart.Tab()),aRectCellPosition ); + nRight[i] = aRectCellPosition.Right(); + } + } + else + { + pLocationData->GetCellPosition( aPageArea.aEnd, aRectPosition ); + nLeftPosition = aRectPosition.Right()+1; + + pLocationData->GetCellPosition( aPageArea.aStart,aRectCellPosition ); + nRight[ aPageArea.aEnd.Col() ] = aRectCellPosition.Left(); + for( SCCOL i = aPageArea.aEnd.Col(); i > aPageArea.aStart.Col(); i-- ) + { + pLocationData->GetCellPosition( ScAddress( i,aPageArea.aEnd.Row(),aPageArea.aEnd.Tab()),aRectCellPosition ); + nRight[ i-1 ] = nRight[ i ] + aRectCellPosition.Right() - aRectCellPosition.Left() + 1; + } + } + } if (nPrinted) // wenn nichts, alles grau zeichnen { aLocalPageSize = pPrintFunc->GetPageSize(); aLocalPageSize.Width() = (long) (aLocalPageSize.Width() * HMM_PER_TWIPS ); aLocalPageSize.Height() = (long) (aLocalPageSize.Height() * HMM_PER_TWIPS ); + + nLeftMargin = (long) ( nLeftMargin * HMM_PER_TWIPS ); + nRightMargin = (long) ( nRightMargin * HMM_PER_TWIPS ); + nTopMargin = (long) ( nTopMargin * HMM_PER_TWIPS ); + nBottomMargin = (long) ( nBottomMargin * HMM_PER_TWIPS ); + nHeaderHeight = (long) ( nHeaderHeight * HMM_PER_TWIPS * mnScale / 100 + nTopMargin ); + nFooterHeight = (long) ( nFooterHeight * HMM_PER_TWIPS * mnScale / 100 + nBottomMargin ); } if (!bStateValid) @@ -425,8 +487,39 @@ void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation ) Point aWinEnd( aWinSize.Width(), aWinSize.Height() ); sal_Bool bRight = nPageEndX <= aWinEnd.X(); sal_Bool bBottom = nPageEndY <= aWinEnd.Y(); + + if( bPageMargin && bValidPage ) + { + SetMapMode(aMMMode); + SetLineColor( COL_BLACK ); + DrawInvert( (long)( nTopMargin - aOffset.Y() ), POINTER_VSIZEBAR ); + DrawInvert( (long)(nPageEndY - nBottomMargin ), POINTER_VSIZEBAR ); + DrawInvert( (long)( nLeftMargin - aOffset.X() ), POINTER_HSIZEBAR ); + DrawInvert( (long)( nPageEndX - nRightMargin ) , POINTER_HSIZEBAR ); + if( bHeaderOn ) + { + DrawInvert( nHeaderHeight - aOffset.Y(), POINTER_VSIZEBAR ); + } + if( bFooterOn ) + { + DrawInvert( nPageEndY - nFooterHeight, POINTER_VSIZEBAR ); + } + + SetMapMode( MapMode( MAP_PIXEL ) ); + for( int i= aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ ) + { + Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode ); + SetLineColor( COL_BLACK ); + SetFillColor( COL_BLACK ); + DrawRect( Rectangle( Point( nRight[i] - 2, aColumnTop.Y() ),Point( nRight[i] + 2 , 4 + aColumnTop.Y()) )); + DrawLine( Point( nRight[i], aColumnTop.Y() ), Point( nRight[i], 10 + aColumnTop.Y()) ); + } + SetMapMode( aMMMode ); + } + if (bRight || bBottom) { + SetMapMode(aMMMode); SetLineColor(); SetFillColor(aBackColor); if (bRight) @@ -482,189 +575,15 @@ void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation ) //Issue51656 Add resizeable margin on page preview from maoyg void __EXPORT ScPreview::Paint( const Rectangle& /* rRect */ ) { - if (!bValid) - { - CalcPages(0); - RecalcPages(); - UpdateDrawView(); // Table possibly amended - } - - Fraction aPreviewZoom( nZoom, 100 ); - Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 ); - MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom ); - - ScModule* pScMod = SC_MOD(); - const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig(); - Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor ); - - if ( aOffset.X() < 0 || aOffset.Y() < 0 ) - { - SetMapMode( aMMMode ); - SetLineColor(); - SetFillColor(aBackColor); + bool bWasInPaint = bInPaint; // nested calls shouldn't be necessary, but allow for now + bInPaint = true; - Size aWinSize = GetOutputSize(); - if ( aOffset.X() < 0 ) - DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() )); - if ( aOffset.Y() < 0 ) - DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() )); - } - - long nLeftMargin = 0; - long nRightMargin = 0; - long nTopMargin = 0; - long nBottomMargin = 0; - sal_Bool bHeaderOn = sal_False; - sal_Bool bFooterOn = sal_False; - - ScDocument* pDoc = pDocShell->GetDocument(); - sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); - - Size aPaintPageSize; - if ( nPageNo < nTotalPages ) - { - ScPrintOptions aOptions = SC_MOD()->GetPrintOptions(); - - ScPrintFunc* pPrintFunc; - if ( bStateValid ) - pPrintFunc = new ScPrintFunc( pDocShell, this, aState, &aOptions ); - else - pPrintFunc = new ScPrintFunc( pDocShell, this, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions ); - - pPrintFunc->SetOffset(aOffset); - pPrintFunc->SetManualZoom(nZoom); - pPrintFunc->SetDateTime(aDate,aTime); - pPrintFunc->SetClearFlag(sal_True); - pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() ); - pPrintFunc->SetDrawView( pDrawView ); - - // Multi Selection for one side must be something umstaendlich generated ... - Range aPageRange( nPageNo+1, nPageNo+1 ); - MultiSelection aPage( aPageRange ); - aPage.SetTotalRange( Range(0,RANGE_MAX) ); - aPage.Select( aPageRange ); - - long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart ); - DBG_ASSERT(nPrinted<=1, "was'n nu los?"); - - SetMapMode(aMMMode); - - //init nLeftMargin ... in the ScPrintFunc::InitParam!!! - nLeftMargin = pPrintFunc->GetLeftMargin(); - nRightMargin = pPrintFunc->GetRightMargin(); - nTopMargin = pPrintFunc->GetTopMargin(); - nBottomMargin = pPrintFunc->GetBottomMargin(); - nHeaderHeight = pPrintFunc->GetHeader().nHeight; - nFooterHeight = pPrintFunc->GetFooter().nHeight; - bHeaderOn = pPrintFunc->GetHeader().bEnable; - bFooterOn = pPrintFunc->GetFooter().bEnable; - mnScale = pPrintFunc->GetZoom(); - - Rectangle aPixRect; - Rectangle aRectCellPosition; - Rectangle aRectPosition; - GetLocationData().GetMainCellRange( aPageArea, aPixRect ); - if( !bLayoutRTL ) - { - GetLocationData().GetCellPosition( aPageArea.aStart, aRectPosition ); - nLeftPosition = aRectPosition.Left(); - for( SCCOL i = aPageArea.aStart.Col(); i <= aPageArea.aEnd.Col(); i++ ) - { - GetLocationData().GetCellPosition( ScAddress( i,aPageArea.aStart.Row(),aPageArea.aStart.Tab()),aRectCellPosition ); - nRight[i] = aRectCellPosition.Right(); - } - } - else - { - GetLocationData().GetCellPosition( aPageArea.aEnd, aRectPosition ); - nLeftPosition = aRectPosition.Right()+1; - - GetLocationData().GetCellPosition( aPageArea.aStart,aRectCellPosition ); - nRight[ aPageArea.aEnd.Col() ] = aRectCellPosition.Left(); - for( SCCOL i = aPageArea.aEnd.Col(); i > aPageArea.aStart.Col(); i-- ) - { - GetLocationData().GetCellPosition( ScAddress( i,aPageArea.aEnd.Row(),aPageArea.aEnd.Tab()),aRectCellPosition ); - nRight[ i-1 ] = nRight[ i ] + aRectCellPosition.Right() - aRectCellPosition.Left() + 1; - } - } - - if ( nPrinted ) // If nothing, all gray draw - { - aPaintPageSize = pPrintFunc->GetPageSize(); - aPaintPageSize.Width() = (long) (aPaintPageSize.Width() * HMM_PER_TWIPS ); - aPaintPageSize.Height() = (long) (aPaintPageSize.Height() * HMM_PER_TWIPS ); - - nLeftMargin = (long) ( nLeftMargin * HMM_PER_TWIPS ); - nRightMargin = (long) ( nRightMargin * HMM_PER_TWIPS ); - nTopMargin = (long) ( nTopMargin * HMM_PER_TWIPS ); - nBottomMargin = (long) ( nBottomMargin * HMM_PER_TWIPS ); - nHeaderHeight = (long) ( nHeaderHeight * HMM_PER_TWIPS * mnScale / 100 + nTopMargin ); - nFooterHeight = (long) ( nFooterHeight * HMM_PER_TWIPS * mnScale / 100 + nBottomMargin ); - } - - if ( !bStateValid ) - { - pPrintFunc->GetPrintState( aState ); - aState.nDocPages = nTotalPages; - bStateValid = sal_True; - } - - delete pPrintFunc; - } - - - long nPageEndX = aPaintPageSize.Width() - aOffset.X(); - long nPageEndY = aPaintPageSize.Height() - aOffset.Y(); - Size aWinSize = GetOutputSize(); - Point aWinEnd( aWinSize.Width(), aWinSize.Height() ); - sal_Bool bRight = nPageEndX <= aWinEnd.X(); - sal_Bool bBottom = nPageEndY <= aWinEnd.Y(); - - if( bPageMargin ) - { - SetMapMode(aMMMode); - SetLineColor( COL_BLACK ); - DrawInvert( (long)( nTopMargin - aOffset.Y() ), POINTER_VSIZEBAR ); - DrawInvert( (long)(nPageEndY - nBottomMargin ), POINTER_VSIZEBAR ); - DrawInvert( (long)( nLeftMargin - aOffset.X() ), POINTER_HSIZEBAR ); - DrawInvert( (long)( nPageEndX - nRightMargin ) , POINTER_HSIZEBAR ); - if( bHeaderOn ) - { - DrawInvert( nHeaderHeight - aOffset.Y(), POINTER_VSIZEBAR ); - } - if( bFooterOn ) - { - DrawInvert( nPageEndY - nFooterHeight, POINTER_VSIZEBAR ); - } - - SetMapMode( MapMode( MAP_PIXEL ) ); - for( int i= aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ ) - { - Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode ); - SetLineColor( COL_BLACK ); - SetFillColor( COL_BLACK ); - DrawRect( Rectangle( Point( nRight[i] - 2, aColumnTop.Y() ),Point( nRight[i] + 2 , 4 + aColumnTop.Y()) )); - DrawLine( Point( nRight[i], aColumnTop.Y() ), Point( nRight[i], 10 + aColumnTop.Y()) ); - } - SetMapMode( aMMMode ); - } - - if (bRight || bBottom) - { - SetMapMode(aMMMode); - SetLineColor(); - SetFillColor(aBackColor); - if (bRight) - DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y())); - if (bBottom) - { - if (bRight) - DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y())); // Ecke nicht doppelt - else - DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y())); - } - } + if (bPageMargin) + GetLocationData(); // fill location data for column positions + DoPrint( NULL ); pViewShell->UpdateScrollBars(); + + bInPaint = bWasInPaint; } //Issue51656 Add resizeable margin on page preview from maoyg @@ -783,9 +702,9 @@ void ScPreview::SetZoom(sal_uInt16 nNewZoom) MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom ); SetMapMode( aMMMode ); - bInPaint = sal_True; // don't scroll during SetYOffset in UpdateScrollBars + bInSetZoom = true; // don't scroll during SetYOffset in UpdateScrollBars pViewShell->UpdateScrollBars(); - bInPaint = sal_False; + bInSetZoom = false; bStateValid = sal_False; InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED ); @@ -892,7 +811,7 @@ void ScPreview::SetXOffset( long nX ) { long nDif = LogicToPixel(aOffset).X() - LogicToPixel(Point(nX,0)).X(); aOffset.X() = nX; - if (nDif && !bInPaint) + if (nDif && !bInSetZoom) { MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL); Scroll( nDif, 0 ); @@ -902,7 +821,7 @@ void ScPreview::SetXOffset( long nX ) else { aOffset.X() = nX; - if (!bInPaint) + if (!bInSetZoom) Invalidate(); } InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED ); @@ -919,7 +838,7 @@ void ScPreview::SetYOffset( long nY ) { long nDif = LogicToPixel(aOffset).Y() - LogicToPixel(Point(0,nY)).Y(); aOffset.Y() = nY; - if (nDif && !bInPaint) + if (nDif && !bInSetZoom) { MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL); Scroll( 0, nDif ); @@ -929,7 +848,7 @@ void ScPreview::SetYOffset( long nY ) else { aOffset.Y() = nY; - if (!bInPaint) + if (!bInSetZoom) Invalidate(); } InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED ); @@ -993,15 +912,20 @@ void ScPreview::DataChanged( const DataChangedEvent& rDCEvt ) if ( rDCEvt.GetType() == DATACHANGED_FONTS ) pDocShell->UpdateFontList(); - if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && - (rDCEvt.GetFlags() & SETTINGS_STYLE) ) + // #i114518# Paint of form controls may modify the window's settings. + // Ignore the event if it is called from within Paint. + if ( !bInPaint ) { - // scroll bar size may have changed - pViewShell->InvalidateBorder(); // calls OuterResizePixel - } + if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && + (rDCEvt.GetFlags() & SETTINGS_STYLE) ) + { + // scroll bar size may have changed + pViewShell->InvalidateBorder(); // calls OuterResizePixel + } - Invalidate(); - InvalidateLocationData( SC_HINT_DATACHANGED ); + Invalidate(); + InvalidateLocationData( SC_HINT_DATACHANGED ); + } } } @@ -1144,6 +1068,7 @@ void __EXPORT ScPreview::MouseButtonUp( const MouseEvent& rMEvt ) } if( bMoveRulerAction ) { + ScDocShellModificator aModificator( *pDocShell ); if( bLeftRulerChange && bLeftRulerMove ) { aLRItem.SetLeft( (long)( aButtonUpPt.X() / HMM_PER_TWIPS + aOffset.X() / HMM_PER_TWIPS )); @@ -1166,12 +1091,13 @@ void __EXPORT ScPreview::MouseButtonUp( const MouseEvent& rMEvt ) if ( ValidTab( nTab ) ) { - ScPrintFunc aPrintFunc( pDocShell, this, nTab ); + ScPrintFunc aPrintFunc( this, pDocShell, nTab ); aPrintFunc.UpdatePages(); } Rectangle aRect(0,0,10000,10000); Paint( aRect ); + aModificator.SetDocumentModified(); bLeftRulerChange = sal_False; bRightRulerChange = sal_False; } @@ -1204,6 +1130,7 @@ void __EXPORT ScPreview::MouseButtonUp( const MouseEvent& rMEvt ) DBG_ASSERT( pStyleSheet, "PageStyle not found" ); if ( pStyleSheet ) { + ScDocShellModificator aModificator( *pDocShell ); ScStyleSaveData aOldData; if( bUndo ) aOldData.InitFromStyle( pStyleSheet ); @@ -1262,12 +1189,13 @@ void __EXPORT ScPreview::MouseButtonUp( const MouseEvent& rMEvt ) if ( ValidTab( nTab ) ) { - ScPrintFunc aPrintFunc( pDocShell, this, nTab ); + ScPrintFunc aPrintFunc( this, pDocShell, nTab ); aPrintFunc.UpdatePages(); } Rectangle aRect(0,0,10000,10000); Paint( aRect ); + aModificator.SetDocumentModified(); bTopRulerChange = sal_False; bBottomRulerChange = sal_False; bHeaderRulerChange = sal_False; @@ -1318,7 +1246,7 @@ void __EXPORT ScPreview::MouseButtonUp( const MouseEvent& rMEvt ) } if ( ValidTab( nTab ) ) { - ScPrintFunc aPrintFunc( pDocShell, this, nTab ); + ScPrintFunc aPrintFunc( this, pDocShell, nTab ); aPrintFunc.UpdatePages(); } Rectangle nRect(0,0,10000,10000); @@ -1352,9 +1280,9 @@ void __EXPORT ScPreview::MouseMove( const MouseEvent& rMEvt ) ScPrintFunc* pPrintFunc; if (bStateValid) - pPrintFunc = new ScPrintFunc( pDocShell, this, aState, &aOptions ); + pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions ); else - pPrintFunc = new ScPrintFunc( pDocShell, this, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions ); + pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions ); nLeftMargin = (long)( pPrintFunc->GetLeftMargin() * HMM_PER_TWIPS - aOffset.X() ); nRightMargin = (long)( pPrintFunc->GetRightMargin() * HMM_PER_TWIPS ); diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx index c7cc92246536..2c4a5f855112 100644 --- a/sc/source/ui/view/printfun.cxx +++ b/sc/source/ui/view/printfun.cxx @@ -52,7 +52,6 @@ #include <editeng/ulspitem.hxx> #include <sfx2/app.hxx> #include <sfx2/printer.hxx> -#include <sfx2/progress.hxx> #include <tools/multisel.hxx> #include <sfx2/docfile.hxx> #include <tools/urlobj.hxx> @@ -304,54 +303,6 @@ ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, Construct( pOptions ); } -ScPrintFunc::ScPrintFunc( ScDocShell* pShell, Window* pWindow, SCTAB nTab, - long nPage, long nDocP, const ScRange* pArea, - const ScPrintOptions* pOptions ) - : pDocShell ( pShell ), - pPrinter ( NULL ), - pDrawView ( NULL ), - nPrintTab ( nTab ), - nPageStart ( nPage ), - nDocPages ( nDocP ), - pUserArea ( pArea ), - bState ( sal_False ), - bPrintCurrentTable ( sal_False ), - bMultiArea ( sal_False ), - nTabPages ( 0 ), - nTotalPages ( 0 ), - pPageData ( NULL ) -{ - pDev = pWindow; - Construct( pOptions ); -} -ScPrintFunc::ScPrintFunc( ScDocShell* pShell, Window* pWindow, - const ScPrintState& rState, const ScPrintOptions* pOptions ) - : pDocShell ( pShell ), - pPrinter ( NULL ), - pDrawView ( NULL ), - pUserArea ( NULL ), - bPrintCurrentTable ( sal_False ), - bMultiArea ( sal_False ), - pPageData ( NULL ) -{ - pDev = pWindow; - - nPrintTab = rState.nPrintTab; - nStartCol = rState.nStartCol; - nStartRow = rState.nStartRow; - nEndCol = rState.nEndCol; - nEndRow = rState.nEndRow; - nZoom = rState.nZoom; - nPagesX = rState.nPagesX; - nPagesY = rState.nPagesY; - nTabPages = rState.nTabPages; - nTotalPages = rState.nTotalPages; - nPageStart = rState.nPageStart; - nDocPages = rState.nDocPages; - bState = sal_True; - - Construct( pOptions ); -} void ScPrintFunc::GetPrintState( ScPrintState& rState ) { @@ -1768,6 +1719,7 @@ void ScPrintFunc::MakeEditEngine() pEditEngine->SetWordDelimiters( ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) ); pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS ); + pDoc->ApplyAsianEditSettings( *pEditEngine ); pEditEngine->EnableAutoColor( bUseStyleColor ); // Default-Set fuer Ausrichtung @@ -2460,9 +2412,8 @@ void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects() aTableParam.bNotes = false; aTableParam.bGrid = false; aTableParam.bHeaders = false; - aTableParam.bFormulas = false;; - aTableParam.bNullVals = false;; - aTableParam.bNullVals = false;; + aTableParam.bFormulas = false; + aTableParam.bNullVals = false; } // @@ -2715,7 +2666,7 @@ void ScPrintFunc::ApplyPrintSettings() long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges, long nStartPage, long nDisplayStart, sal_Bool bDoPrint, - SfxProgress* pProgress, ScPreviewLocationData* pLocationData ) + ScPreviewLocationData* pLocationData ) { DBG_ASSERT(pDev,"Device == NULL"); if (!pParamSet) @@ -2735,9 +2686,6 @@ long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges, MakeTableString(); - if ( pProgress ) - pProgress->SetText( String( ScResId( SCSTR_STAT_PRINT ) ) ); - //-------------------------------------------------------------------- long nPageNo = 0; @@ -2778,12 +2726,6 @@ long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges, { PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2, bDoPrint, pLocationData ); - - if ( pProgress ) - { - pProgress->SetState( nPageNo+nStartPage+1, nEndPage ); - pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug? - } ++nPrinted; } ++nPageNo; @@ -2808,12 +2750,6 @@ long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges, { PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2, bDoPrint, pLocationData ); - - if ( pProgress ) - { - pProgress->SetState( nPageNo+nStartPage+1, nEndPage ); - pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug? - } ++nPrinted; } ++nPageNo; @@ -2838,11 +2774,6 @@ long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges, if ( nNoteAdd ) { nNoteNr += nNoteAdd; - if ( pProgress && bPageSelected ) - { - pProgress->SetState( nPageNo+nStartPage+1, nEndPage ); - pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug? - } if (bPageSelected) { ++nPrinted; diff --git a/sc/source/ui/view/tabcont.cxx b/sc/source/ui/view/tabcont.cxx index 6e41548dc31f..48de6a0ee731 100644 --- a/sc/source/ui/view/tabcont.cxx +++ b/sc/source/ui/view/tabcont.cxx @@ -458,12 +458,13 @@ void ScTabControl::DoDrag( const Region& /* rRegion */ ) ScDocument* pDoc = pDocSh->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); + ScRange aTabRange( 0, 0, nTab, MAXCOL, MAXROW, nTab ); ScMarkData aTabMark = pViewData->GetMarkData(); aTabMark.ResetMark(); // doesn't change marked table information - aTabMark.SetMarkArea( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) ); + aTabMark.SetMarkArea( aTabRange ); ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); - ScClipParam aClipParam(ScRange(0, 0, 0, MAXCOL, MAXROW, 0), false); + ScClipParam aClipParam(aTabRange, false); pDoc->CopyToClip(aClipParam, pClipDoc, &aTabMark, false); TransferableObjectDescriptor aObjDesc; diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index 19289e4cf703..6265d823001b 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -1548,6 +1548,12 @@ void ScTabView::SelectNextTab( short nDir, sal_Bool bExtendSelection ) PaintExtras(); } +void ScTabView::UpdateVisibleRange() +{ + for (sal_uInt16 i=0; i<4; i++) + if (pGridWin[i] && pGridWin[i]->IsVisible()) + pGridWin[i]->UpdateVisibleRange(); +} // SetTabNo - angezeigte Tabelle @@ -1736,6 +1742,9 @@ void ScTabView::SetTabNo( SCTAB nTab, sal_Bool bNew, sal_Bool bExtendSelection, RepeatResize(); InvalidateSplit(); + // #163911# Update the visible range in each GridWin directly, don't wait for the repaint event. + UpdateVisibleRange(); + if ( aViewData.IsPagebreakMode() ) UpdatePageBreakData(); //! asynchron ?? diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index 3710fca85e33..b93fe814a4a2 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -638,24 +638,15 @@ void ScTabViewShell::DoReadUserData( const String& rData ) //------------------------------------------------------------------ -//UNUSED2008-05 void ScTabViewShell::ExecuteShowNIY( SfxRequest& /* rReq */ ) -//UNUSED2008-05 { -//UNUSED2008-05 ErrorMessage(STR_BOX_YNI); -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 //------------------------------------------------------------------ -//UNUSED2008-05 -//UNUSED2008-05 void ScTabViewShell::StateDisabled( SfxItemSet& rSet ) -//UNUSED2008-05 { -//UNUSED2008-05 SfxWhichIter aIter( rSet ); -//UNUSED2008-05 sal_uInt16 nWhich = aIter.FirstWhich(); -//UNUSED2008-05 -//UNUSED2008-05 while ( nWhich ) -//UNUSED2008-05 { -//UNUSED2008-05 rSet.DisableItem( nWhich ); -//UNUSED2008-05 nWhich = aIter.NextWhich(); -//UNUSED2008-05 } -//UNUSED2008-05 } +void ScTabViewShell::UpdateDrawShell() +{ + // Called after user interaction that may delete the selected drawing object. + // Remove DrawShell if nothing is selected. + + SdrView* pDrView = GetSdrView(); + if ( pDrView && !pDrView->AreObjectsMarked() && !IsDrawSelMode() ) + SetDrawShell( sal_False ); +} void ScTabViewShell::SetDrawShellOrSub() { diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx index 2001ba165531..944e2b938de2 100644 --- a/sc/source/ui/view/tabvwshb.cxx +++ b/sc/source/ui/view/tabvwshb.cxx @@ -181,6 +181,8 @@ sal_Bool ScTabViewShell::ActivateObject( SdrOle2Obj* pObj, long nVerb ) bErrorShown = sal_True; // SfxViewShell::DoVerb zeigt seine Fehlermeldungen selber an + SetNewVisArea(); + // attach listener to selection changes in chart that affect cell // ranges, so those can be highlighted // note: do that after DoVerb, so that the chart controller exists diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index 0f4893cf3512..f25aa500cc72 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -1104,7 +1104,20 @@ sal_Bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc, if (nBlockAddX > nDestSizeX) nMarkAddX = nBlockAddX - nDestSizeX; // fuer Merge-Test else + { nEndCol = nStartCol + nDestSizeX; + if (nEndCol > aMarkRange.aEnd.Col()) + { + // #i113553# larger range has to be included in aFilteredMark (for undo), but extending columns can't changed the filtered status + aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ); + aFilteredMark.SetMarkArea( aMarkRange ); + if (bMarkIsFiltered) + { + ScViewUtil::UnmarkFiltered( aFilteredMark, pDoc ); + aFilteredMark.FillRangeListWithMarks( &aRangeList, sal_True ); + } + } + } if (nBlockAddY > nDestSizeY) nMarkAddY = nBlockAddY - nDestSizeY; // fuer Merge-Test diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx index 205a0532eb3a..1d2b636c4259 100644 --- a/sc/source/ui/view/viewfun5.cxx +++ b/sc/source/ui/view/viewfun5.cxx @@ -165,7 +165,7 @@ sal_Bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId, nFirstCol = nLastCol = 0; nFirstRow = nLastRow = 0; } - ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, 0, nLastCol, nLastRow, 0), false); + ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, nSrcTab, nLastCol, nLastRow, nSrcTab), false); pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSrcMark); ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) ); @@ -374,10 +374,15 @@ sal_Bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId, { // import of database data into table - String sDataDesc; - if ( aDataHelper.GetString( nFormatId, sDataDesc ) ) + const DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector(); + if ( svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) ) { - SfxStringItem aDataDesc(SID_SBA_IMPORT, sDataDesc); + // transport the whole ODataAccessDescriptor as slot parameter + svx::ODataAccessDescriptor aDesc = svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper); + uno::Any aDescAny; + uno::Sequence<beans::PropertyValue> aProperties = aDesc.createPropertyValueSequence(); + aDescAny <<= aProperties; + SfxUsrAnyItem aDataDesc(SID_SBA_IMPORT, aDescAny); ScDocShell* pDocSh = GetViewData()->GetDocShell(); SCTAB nTab = GetViewData()->GetTabNo(); @@ -401,20 +406,10 @@ sal_Bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId, sal_Bool bAreaIsNew = !pDBData; SfxBoolItem aAreaNew(FN_PARAM_2, bAreaIsNew); - ::svx::ODataAccessDescriptor aDesc; - DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector(); - ::std::auto_ptr<SfxUsrAnyItem> pCursorItem; - if ( ::svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) ) - { - aDesc = ::svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper); - if ( aDesc.has(::svx::daCursor) ) - pCursorItem.reset(new SfxUsrAnyItem(FN_PARAM_3, aDesc[::svx::daCursor])); - } - // asynchronous, to avoid doing the whole import in drop handler SfxDispatcher& rDisp = GetViewData()->GetDispatcher(); rDisp.Execute(SID_SBA_IMPORT, SFX_CALLMODE_ASYNCHRON, - &aDataDesc, &aTarget, &aAreaNew, pCursorItem.get(), (void*)0 ); + &aDataDesc, &aTarget, &aAreaNew, (void*)0 ); bRet = sal_True; } diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk index dd0a6043c8fd..a7ce2f9407dc 100644 --- a/sc/util/makefile.mk +++ b/sc/util/makefile.mk @@ -311,6 +311,7 @@ SHL9STDLIBS= \ $(VCLLIB) \ $(TKLIB) \ $(MSFILTERLIB) \ + $(UNOTOOLSLIB) \ $(FORLIB) SHL9DEPN=$(SHL1TARGETN) $(SHL8TARGETN) |