diff options
author | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2011-03-25 13:58:04 +0100 |
---|---|---|
committer | Daniel Rentz [dr] <daniel.rentz@oracle.com> | 2011-03-25 13:58:04 +0100 |
commit | fc6b149ea291a21960448e13c70c6a981924d417 (patch) | |
tree | f290f3ee7c72e2bde83502ee5d28d0c9b887720c /sc | |
parent | 6dc0aa8956f71823cd056b1b1b9a4c2f45ce142b (diff) | |
parent | 4aac1b1152ac1bcb0f253d098efff9acc82acd26 (diff) |
calcvba: rebase to DEV300_m104
Diffstat (limited to 'sc')
100 files changed, 2429 insertions, 2518 deletions
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/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..3786b6b850b0 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -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; @@ -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/dpobject.hxx b/sc/inc/dpobject.hxx index e69f8e8c3a3f..8cbc6aa8e16a 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 @@ -150,9 +149,6 @@ 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; diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index 8c4babc77da3..bd84e599d984 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -69,16 +69,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(); 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..b51cc084594d 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -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; 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/column2.cxx b/sc/source/core/data/column2.cxx index 0cffd3bef163..abc82c005408 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -427,12 +427,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 +456,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, @@ -564,6 +568,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 +1057,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..44f7e6722d69 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -531,7 +531,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 +544,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/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 084ccb7ba977..7d66ece8c570 100755 --- a/sc/source/core/data/documen9.cxx +++ b/sc/source/core/data/documen9.cxx @@ -818,3 +818,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..c4a256b48f54 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -171,7 +171,6 @@ ScDPObject::ScDPObject( ScDocument* pD ) : pOutput( NULL ), bSettingsChanged( sal_False ), bAlive( sal_False ), - mnAutoFormatIndex( 65535 ), bAllowMove( sal_False ), nHeaderRows( 0 ), mbHeaderLayout(false), @@ -194,7 +193,6 @@ 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 ), @@ -256,16 +254,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; diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx index f2cc8d2c1e5c..3cf40a7ab6dc 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" diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index e3b75436f72c..59abdcfd6b60 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -767,7 +767,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/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..0ab37d167b01 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(); 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..7e015e12d16e 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -1579,6 +1579,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() { 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/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 7a4ac7ecdac8..e3cd6239191e 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"); } @@ -3459,6 +3459,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; 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/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/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..ead8067ee23e 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) @@ -3470,14 +3470,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..d4133686d2c8 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -1347,6 +1347,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 +1912,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 +1920,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 +2638,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(); } 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/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..33f6a279a40c 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 ); 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/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index b43779ffa62b..a1a90731cf0f 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -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..6414119677bf 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -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 62e923fa9ec2..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" @@ -2578,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/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/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/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/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/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/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/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 b95b9f504b7d..37505e44dce7 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" @@ -907,6 +908,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++) @@ -1056,7 +1067,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 ); @@ -1080,11 +1091,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 @@ -1190,7 +1196,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 @@ -1272,7 +1278,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 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/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/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/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..2df47d16e195 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -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. @@ -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/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/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx index 205a0532eb3a..fff42faecb51 100644 --- a/sc/source/ui/view/viewfun5.cxx +++ b/sc/source/ui/view/viewfun5.cxx @@ -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; } |