diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2010-04-29 05:16:36 +0200 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2010-04-29 05:16:36 +0200 |
commit | 2f32b639a988cde82849a1da7641b0be7943d25b (patch) | |
tree | 791aba8c48d6de81e67d791eb0fca7b7bdf578e7 /sc | |
parent | b1caadf8d9f10884f59f18ec1dc42b4fd99236c4 (diff) | |
parent | 4f7a90a20425a4319a0a06ca5b6716cac5f9e0cd (diff) |
rebased to m77.
Diffstat (limited to 'sc')
231 files changed, 11641 insertions, 6210 deletions
diff --git a/sc/addin/datefunc/makefile.mk b/sc/addin/datefunc/makefile.mk index 4e4966720261..f781b3835833 100644 --- a/sc/addin/datefunc/makefile.mk +++ b/sc/addin/datefunc/makefile.mk @@ -86,11 +86,7 @@ $(MISC)$/$(TARGET).lst : \ $(INCCOM)$/xlang.h \ ..$/inc$/$(TARGET).hrc \ ..$/inc$/addin.h -.IF "$(GUI)"=="UNX" || "$(USE_SHELL)"!="4nt" echo $< > $@ -.ELSE - echo $(<:+"\n":s/ //) > $@ -.ENDIF # --- Def-File --- diff --git a/sc/addin/makefile.mk b/sc/addin/makefile.mk index c9505e29d4d4..e716a8d8477a 100644 --- a/sc/addin/makefile.mk +++ b/sc/addin/makefile.mk @@ -41,10 +41,5 @@ TARGET=addin ALLTAR: $(MISC)$/cl2c.pl $(MISC)$/cl2c.pl: util/cl2c.pl -.IF "$(GUI)"=="UNX" || "$(USE_SHELL)"!="4nt" tr -d "\015" < util$/cl2c.pl > $@ chmod +rw $@ -.ELSE - @$(COPY) util$/cl2c.pl $@ -.ENDIF - diff --git a/sc/addin/rot13/exports.map b/sc/addin/rot13/exports.map index fa447824beda..c662c9148aba 100644 --- a/sc/addin/rot13/exports.map +++ b/sc/addin/rot13/exports.map @@ -1,4 +1,4 @@ -SC_1_0 { +UDK_3_0_0 { global: GetFunctionCount; GetFunctionData; diff --git a/sc/addin/rot13/makefile.mk b/sc/addin/rot13/makefile.mk index 128d8f10b6f8..a33c50d2a725 100644 --- a/sc/addin/rot13/makefile.mk +++ b/sc/addin/rot13/makefile.mk @@ -85,9 +85,4 @@ $(MISC)$/rot.lst : \ $(INCCOM)$/xlang.h \ ..$/inc$/rot13.hrc \ ..$/inc$/addin.h -.IF "$(GUI)"=="UNX" || "$(USE_SHELL)"!="4nt" @echo $< > $@ -.ELSE - @echo $(<:+"\n":s/ //) > $@ -.ENDIF - diff --git a/sc/addin/util/makefile.mk b/sc/addin/util/makefile.mk index e415cf7631d7..2bd75148f80a 100644 --- a/sc/addin/util/makefile.mk +++ b/sc/addin/util/makefile.mk @@ -37,13 +37,9 @@ TARGET=autil $(BIN)$/addin.zip : \ $(MISC)$/rot.lst \ $(MISC)$/dfa.lst -.IF "$(GUI)"=="UNX" || "$(USE_SHELL)"!="4nt" $(TYPE) $(MISC)$/rot.lst | tr -s " " "\n" | zip -@ -u -j -ll $(BIN)$/addin.zip $(CHECKZIPRESULT) $(TYPE) $(MISC)$/dfa.lst | tr -s " " "\n" | zip -@ -u -j -ll $(BIN)$/addin.zip $(CHECKZIPRESULT) chmod +rw $(BIN)$/addin.zip -.ELSE - $(TYPE) $< | zip -@ -u -j $(BIN)$/addin.zip $(CHECKZIPRESULT) -.ENDIF .INCLUDE: target.mk diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index 6d7b7f48c2d7..c82d607577bf 100644 --- a/sc/inc/attarray.hxx +++ b/sc/inc/attarray.hxx @@ -148,7 +148,7 @@ public: BOOL HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes, BOOL bLeft, BOOL bRight ) const; - BOOL HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const; + bool HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const; BOOL ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow, SCCOL& rPaintCol, SCROW& rPaintRow, BOOL bRefresh, BOOL bAttrs ); diff --git a/sc/inc/chart2uno.hxx b/sc/inc/chart2uno.hxx index d63e47d642b9..44737e711090 100644 --- a/sc/inc/chart2uno.hxx +++ b/sc/inc/chart2uno.hxx @@ -188,24 +188,6 @@ public: getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException); - /** - * Check the current list of reference tokens, and add the upper left - * corner of the minimum range that encloses all ranges if certain - * conditions are met. - * - * @param rRefTokens list of reference tokens - * - * @return true if the corner was added, false otherwise. - */ - static bool addUpperLeftCornerIfMissing(::std::vector<ScSharedTokenRef>& rRefTokens); - -private: - - void detectRangesFromDataSource(::std::vector<ScSharedTokenRef>& rRefTokens, - ::com::sun::star::chart::ChartDataRowSource& rRowSource, - bool& rRowSourceDetected, - const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataSource >& xDataSource); - private: ScDocument* m_pDocument; diff --git a/sc/inc/charthelper.hxx b/sc/inc/charthelper.hxx index b4c677d7c3c6..50b8586bdace 100644 --- a/sc/inc/charthelper.hxx +++ b/sc/inc/charthelper.hxx @@ -29,9 +29,12 @@ #define SC_CHARTHELPER_HXX #include <tools/solar.h> +#include "address.hxx" +#include "global.hxx" -class ScDocument; -class ScAddress; +#include <com/sun/star/chart2/XChartDocument.hpp> + +class SdrObject; /** Use this to handle charts in a calc document */ @@ -40,6 +43,12 @@ class ScChartHelper public: static USHORT DoUpdateAllCharts( ScDocument* pDoc ); static USHORT DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc ); //use this to replace ScDBFunc::DoUpdateCharts in future + static void AdjustRangesOfChartsOnDestinationPage( ScDocument* pSrcDoc, ScDocument* pDestDoc, const SCTAB nSrcTab, const SCTAB nDestTab ); + static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > GetChartFromSdrObject( SdrObject* pObject ); + static void GetChartRanges( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& xChartDoc, + ::com::sun::star::uno::Sequence< rtl::OUString >& rRanges ); + static void SetChartRanges( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& xChartDoc, + const ::com::sun::star::uno::Sequence< rtl::OUString >& rRanges ); }; #endif diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx index ffe248bb3f65..6cf3d59314ef 100644 --- a/sc/inc/chgtrack.hxx +++ b/sc/inc/chgtrack.hxx @@ -308,7 +308,6 @@ protected: GetDeletedInAddress(), p ); } BOOL RemoveDeletedIn( const ScChangeAction* ); - void RemoveAllDeletedIn(); void SetDeletedIn( ScChangeAction* ); ScChangeActionLinkEntry* AddDeleted( ScChangeAction* p ) @@ -414,6 +413,7 @@ public: { return IsDeleteType() || IsDeletedIn(); } BOOL IsDeletedIn( const ScChangeAction* ) const; BOOL IsDeletedInDelType( ScChangeActionType ) const; + void RemoveAllDeletedIn(); const ScChangeActionLinkEntry* GetFirstDeletedEntry() const { return pLinkDeleted; } diff --git a/sc/inc/collect.hxx b/sc/inc/collect.hxx index e8b9bed60865..167ab5929c6a 100644 --- a/sc/inc/collect.hxx +++ b/sc/inc/collect.hxx @@ -184,20 +184,18 @@ private: BOOL bCaseSensitive; public: - TypedScStrCollection( USHORT nLim = 4, USHORT nDel = 4, BOOL bDup = FALSE ) - : ScSortedCollection( nLim, nDel, bDup ) { bCaseSensitive = FALSE; } + TypedScStrCollection( USHORT nLim = 4, USHORT nDel = 4, BOOL bDup = FALSE ); - TypedScStrCollection( const TypedScStrCollection& rCpy ) - : ScSortedCollection( rCpy ) { bCaseSensitive = rCpy.bCaseSensitive; } - ~TypedScStrCollection(); + TypedScStrCollection( const TypedScStrCollection& rCpy ) + : ScSortedCollection( rCpy ) { bCaseSensitive = rCpy.bCaseSensitive; } + ~TypedScStrCollection(); virtual ScDataObject* Clone() const; virtual short Compare( ScDataObject* pKey1, ScDataObject* pKey2 ) const; - TypedStrData* operator[]( const USHORT nIndex) const - { return (TypedStrData*)At(nIndex); } + TypedStrData* operator[]( const USHORT nIndex) const; - void SetCaseSensitive( BOOL bSet ) { bCaseSensitive = bSet; } + void SetCaseSensitive( BOOL bSet ); BOOL FindText( const String& rStart, String& rResult, USHORT& rPos, BOOL bBack ) const; BOOL GetExactMatch( String& rString ) const; diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 3386b3ebec67..7ad5c96f4dfb 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -142,7 +142,7 @@ public: //UNUSED2009-05 BOOL HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes, //UNUSED2009-05 BOOL bLeft, BOOL bRight ) const; - BOOL HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const; + bool HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const; BOOL HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const; BOOL ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow, SCCOL& rPaintCol, SCROW& rPaintRow, @@ -235,7 +235,9 @@ public: // TRUE = Zahlformat gesetzt BOOL SetString( SCROW nRow, SCTAB nTab, const String& rString, - formula::FormulaGrammar::AddressConvention conv = formula::FormulaGrammar::CONV_OOO ); + formula::FormulaGrammar::AddressConvention conv = formula::FormulaGrammar::CONV_OOO, + SvNumberFormatter* pFormatter = NULL, + bool bDetectNumberFormat = true ); void SetValue( SCROW nRow, const double& rVal); void SetError( SCROW nRow, const USHORT nError); diff --git a/sc/inc/dapiuno.hxx b/sc/inc/dapiuno.hxx index ba695d8784bc..c9a5305a05ca 100644 --- a/sc/inc/dapiuno.hxx +++ b/sc/inc/dapiuno.hxx @@ -31,6 +31,8 @@ #include "global.hxx" #include "dpobject.hxx" #include "rangeutl.hxx" // ScArea +#include "cellsuno.hxx" // for XModifyListenerArr_Impl + #include <svl/lstner.hxx> #include <svl/itemprop.hxx> @@ -39,6 +41,7 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/util/XModifyBroadcaster.hpp> #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp> #include <com/sun/star/sheet/DataPilotFieldGroupInfo.hpp> @@ -313,11 +316,15 @@ public: // ============================================================================ class ScDataPilotTableObj : public ScDataPilotDescriptorBase, - public com::sun::star::sheet::XDataPilotTable2 + public com::sun::star::sheet::XDataPilotTable2, + public com::sun::star::util::XModifyBroadcaster { private: SCTAB nTab; String aName; + XModifyListenerArr_Impl aModifyListeners; + + void Refreshed_Impl(); public: ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const String& rN); @@ -329,6 +336,8 @@ public: virtual void SAL_CALL acquire() throw(); virtual void SAL_CALL release() throw(); + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + virtual ScDPObject* GetDPObject() const; virtual void SetDPObject(ScDPObject* pDPObj); @@ -361,6 +370,14 @@ public: throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + // XModifyBroadcaster + virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< + ::com::sun::star::util::XModifyListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException); + // XTypeProvider (overloaded) 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/document.hxx b/sc/inc/document.hxx index 5e0435be1d3e..2c7158c4d1a9 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -45,6 +45,13 @@ #include <memory> #include <map> +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include <list> +#include "dpobject.hxx" +#include "dptabdat.hxx" +// End Comments + class KeyEvent; class OutputDevice; class SdrObject; @@ -256,6 +263,11 @@ private: ScRangeName* pRangeName; ScDBCollection* pDBCollection; 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; std::auto_ptr< ScTemporaryChartLock > apTemporaryChartLock; ScPatternAttr* pSelectionAttr; // Attribute eines Blocks @@ -492,6 +504,17 @@ public: SC_DLLPUBLIC ScDPCollection* GetDPCollection(); ScDPObject* GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const; ScDPObject* GetDPAtBlock( const ScRange& rBlock ) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + SC_DLLPUBLIC ScDPTableDataCache* GetDPObjectCache( long nID ); + SC_DLLPUBLIC ScDPTableDataCache* GetUsedDPObjectCache ( ScRange rRange ); + SC_DLLPUBLIC long AddDPObjectCache( ScDPTableDataCache* pData ); + SC_DLLPUBLIC void RemoveDPObjectCache( long nID ); + SC_DLLPUBLIC void RemoveUnusedDPObjectCaches(); + SC_DLLPUBLIC void GetUsedDPObjectCache( std::list<ScDPTableDataCache*>& usedlist ); + SC_DLLPUBLIC long GetNewDPObjectCacheId (); + // End Comments + SC_DLLPUBLIC ScChartCollection* GetChartCollection() const; void StopTemporaryChartLock(); @@ -727,7 +750,9 @@ public: SC_DLLPUBLIC void PutCell(SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell, ULONG nFormatIndex, BOOL bForceTab = FALSE); // return TRUE = Zahlformat gesetzt - SC_DLLPUBLIC BOOL SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString ); + SC_DLLPUBLIC BOOL SetString( + SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, + SvNumberFormatter* pFormatter = NULL, bool bDetectNumberFormat = true ); SC_DLLPUBLIC void SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal ); void SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const USHORT nError); @@ -822,9 +847,9 @@ public: BOOL IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const; BOOL IsVerOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const; - SC_DLLPUBLIC BOOL HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, - SCCOL nCol2, SCROW nRow2, SCTAB nTab2, USHORT nMask ); - SC_DLLPUBLIC BOOL HasAttrib( const ScRange& rRange, USHORT nMask ); + SC_DLLPUBLIC bool HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, + SCCOL nCol2, SCROW nRow2, SCTAB nTab2, USHORT nMask ); + SC_DLLPUBLIC bool HasAttrib( const ScRange& rRange, USHORT nMask ); void GetBorderLines( SCCOL nCol, SCROW nRow, SCTAB nTab, const SvxBorderLine** ppLeft, @@ -871,10 +896,17 @@ public: USHORT GetErrCode( const ScAddress& ) const; - bool ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const; + /** Shrink a range to only include data area. + This is not the actually used area within the + selection, but the bounds of the sheet's data area + instead. */ + bool ShrinkToDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow ) const; + + /** Shrink a range to only include used data area. */ + bool ShrinkToUsedDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const; void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, - SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld ) const; + SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ) const; SC_DLLPUBLIC BOOL GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const; SC_DLLPUBLIC BOOL GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const; SC_DLLPUBLIC BOOL GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow, @@ -1070,7 +1102,8 @@ public: void UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz, - ScDocument* pUndoDoc = NULL, BOOL bIncludeDraw = TRUE ); + ScDocument* pUndoDoc = NULL, BOOL bIncludeDraw = TRUE, + bool bUpdateNoteCaptionPos = true ); SC_DLLPUBLIC void UpdateTranspose( const ScAddress& rDestPos, ScDocument* pClipDoc, const ScMarkData& rMark, ScDocument* pUndoDoc = NULL ); @@ -1626,7 +1659,7 @@ public: BOOL IsExpandRefs() { return bExpandRefs; } SC_DLLPUBLIC void IncSizeRecalcLevel( SCTAB nTab ); - SC_DLLPUBLIC void DecSizeRecalcLevel( SCTAB nTab ); + SC_DLLPUBLIC void DecSizeRecalcLevel( SCTAB nTab, bool bUpdateNoteCaptionPos = true ); ULONG GetXMLImportedFormulaCount() const { return nXMLImportedFormulaCount; } void IncXMLImportedFormulaCount( ULONG nVal ) diff --git a/sc/inc/dpcachetable.hxx b/sc/inc/dpcachetable.hxx index 60dba0bc27db..eab01d078081 100644 --- a/sc/inc/dpcachetable.hxx +++ b/sc/inc/dpcachetable.hxx @@ -55,33 +55,38 @@ class ScRange; class ScDPDimension; class ScDPCollection; struct ScDPCacheCell; -struct ScDPItemData; struct ScQueryParam; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPItemData; +// End Comments class Date; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPTableDataCache; +struct ScDPValueData; +// End Comments // ---------------------------------------------------------------------------- -class ScDPCacheTable +class SC_DLLPUBLIC ScDPCacheTable { public: - - struct Cell - { - SCROW mnCategoryRef; - ScDPCacheCell* mpContent; - - Cell(); - ~Cell(); - }; - /** individual filter item used in SingleFilter and GroupFilter. */ struct FilterItem { - sal_Int32 mnMatchStrId; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + String maString; + // End Comments double mfValue; bool mbHasValue; FilterItem(); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + bool match( const ScDPItemData& rCellData ) const; +// End Comments }; /** interface class used for filtering of rows. */ @@ -90,19 +95,26 @@ public: public: /** returns true if the matching condition is met for a single cell value, or false otherwise. */ - virtual bool match(const ScDPCacheCell& rCell) const = 0; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + virtual bool match( const ScDPItemData& rCellData ) const = 0; +// End Comments }; /** ordinary single-item filter. */ class SingleFilter : public FilterBase { public: - explicit SingleFilter(ScSimpleSharedString& rSharedString, - sal_Int32 nMatchStrId, double fValue, bool bHasValue); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + explicit SingleFilter(String aString, double fValue, bool bHasValue); + // End Comments virtual ~SingleFilter(){} - virtual bool match(const ScDPCacheCell& rCell) const; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual bool match(const ScDPItemData& rCellData) const; + // End Comments const String getMatchString(); double getMatchValue() const; bool hasValue() const; @@ -111,25 +123,27 @@ public: explicit SingleFilter(); FilterItem maItem; - ScSimpleSharedString mrSharedString; }; /** multi-item (group) filter. */ class GroupFilter : public FilterBase { public: - GroupFilter(ScSimpleSharedString& rSharedString); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + GroupFilter(); + // End Comments virtual ~GroupFilter(){} - virtual bool match(const ScDPCacheCell& rCell) const; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual bool match( const ScDPItemData& rCellData ) const; + // End Comments void addMatchItem(const String& rStr, double fVal, bool bHasValue); size_t getMatchItemCount() const; private: - GroupFilter(); ::std::vector<FilterItem> maItems; - ScSimpleSharedString mrSharedString; }; /** single filtering criterion. */ @@ -140,22 +154,26 @@ public: Criterion(); }; - - ScDPCacheTable(ScDPCollection* pCollection); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPCacheTable( ScDocument* pDoc,long nId ); + // End Comments ~ScDPCacheTable(); sal_Int32 getRowSize() const; sal_Int32 getColSize() const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPTableDataCache* GetCache() const; /** Fill the internal table from the cell range provided. This function - assumes that the first row is the column header. */ - void fillTable(ScDocument* pDoc, const ScRange& rRange, const ScQueryParam& rQuery, BOOL* pSpecial, - bool bIgnoreEmptyRows); - + assumes that the first row is the column header. */ + void fillTable( const ScQueryParam& rQuery, BOOL* pSpecial, + bool bIgnoreEmptyRows, bool bRepeatIfEmpty ); /** Fill the internal table from database connection object. This function assumes that the first row is the column header. */ - void fillTable(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet >& xRowSet, - const Date& rNullDate); + void fillTable(); + // End Comments /** Check whether a specified row is active or not. When a row is active, it is used in calculation of the results data. A row becomes inactive @@ -169,15 +187,23 @@ public: /** Get the cell instance at specified location within the data grid. Note that the data grid doesn't include the header row. Don't delete the returned object! */ - const ScDPCacheCell* getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const; - - const String* getFieldName(sal_Int32 nIndex) const; - - /** Get the unique entries for a field specified by index. The caller must + const ScDPItemData* getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const; + void getValue( ScDPValueData& rVal, SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const; + String getFieldName( SCCOL nIndex) const; + //End Comments + + /** Get the field index (i.e. column ID in the original data source) based + on the string value that corresponds with the column title. It returns + -1 if no field matching the string value exists. */ + sal_Int32 getFieldIndex(const String& rStr) const; + + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + /** Get the unique entries for a field specified by index. The caller must make sure that the table is filled before calling function, or it will get an empty collection. */ - const TypedScStrCollection& getFieldEntries(sal_Int32 nIndex) const; - + const ::std::vector<SCROW>& getFieldEntries( sal_Int32 nColumn ) const; + // End Comments /** Filter the table based on the specified criteria, and copy the result to rTabData. This method is used, for example, to generate a drill-down data table. */ @@ -186,6 +212,7 @@ public: const ::std::hash_set<sal_Int32>& rRepeatIfEmptyDims); void clear(); + void swap(ScDPCacheTable& rOther); bool empty() const; private: @@ -200,26 +227,23 @@ private: */ bool isRowQualified(sal_Int32 nRow, const ::std::vector<Criterion>& rCriteria, const ::std::hash_set<sal_Int32>& rRepeatIfEmptyDims) const; void getValueData(ScDocument* pDoc, const ScAddress& rPos, ScDPCacheCell& rCell); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void InitNoneCache( ScDocument* pDoc ); + // End Comments private: - typedef ::boost::shared_ptr<TypedScStrCollection> TypedScStrCollectionPtr; - - /** main data table. */ - ::std::vector< ::std::vector< ::ScDPCacheTable::Cell > > maTable; - - /** header string IDs */ - ::std::vector<sal_Int32> maHeader; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance /** unique field entires for each field (column). */ - ::std::vector<TypedScStrCollectionPtr> maFieldEntries; - + ::std::vector< ::std::vector<SCROW> > maFieldEntries; + // End Comments /** used to track visibility of rows. The first row below the header row has the index of 0. */ ::std::vector<bool> maRowsVisible; - - ScSimpleSharedString& mrSharedString; - ScDPCollection* mpCollection; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPTableDataCache* mpCache; + ScDPTableDataCache* mpNoneCache; + // End Comments }; - - #endif diff --git a/sc/inc/dpglobal.hxx b/sc/inc/dpglobal.hxx new file mode 100755 index 000000000000..7de5947cc969 --- /dev/null +++ b/sc/inc/dpglobal.hxx @@ -0,0 +1,209 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dpglobal.hxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +// Wang Xu Ming - DataPilot migration +// Buffer&&Performance +// +#ifndef _SC_DPGLOBAL_HXX +#define _SC_DPGLOBAL_HXX + +#include <algorithm> +#include <list> +#include <tools/gen.hxx> +#include <tools/debug.hxx> +#include <global.hxx> + +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/sheet/XDimensionsSupplier.hpp> + +#include <com/sun/star/sheet/DataPilotFieldFilter.hpp> +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> +#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp> +#include <com/sun/star/sheet/DataPilotTablePositionData.hpp> +#include <com/sun/star/sheet/DataPilotTablePositionType.hpp> +#include <com/sun/star/sheet/DataPilotTableResultData.hpp> +#include <com/sun/star/sheet/DataResultFlags.hpp> +#include <com/sun/star/sheet/GeneralFunction.hpp> +#include <com/sun/star/sheet/MemberResultFlags.hpp> +#include <com/sun/star/sheet/TableFilterField.hpp> +#include <com/sun/star/sheet/XDataPilotMemberResults.hpp> +#include <com/sun/star/sheet/XDataPilotResults.hpp> +#include <com/sun/star/sheet/XHierarchiesSupplier.hpp> +#include <com/sun/star/sheet/XLevelsSupplier.hpp> + + +// moved from fieldwnd.hxx, see also SC_DAPI_MAXFIELDS +#define MAX_LABELS 256 + +#define MAX_PAGEFIELDS 10 // maximum count of fields for page area + +#define PIVOT_MAXFUNC 11 +#define PIVOT_FUNC_NONE 0x0000 +#define PIVOT_FUNC_SUM 0x0001 +#define PIVOT_FUNC_COUNT 0x0002 +#define PIVOT_FUNC_AVERAGE 0x0004 +#define PIVOT_FUNC_MAX 0x0008 +#define PIVOT_FUNC_MIN 0x0010 +#define PIVOT_FUNC_PRODUCT 0x0020 +#define PIVOT_FUNC_COUNT_NUM 0x0040 +#define PIVOT_FUNC_STD_DEV 0x0080 +#define PIVOT_FUNC_STD_DEVP 0x0100 +#define PIVOT_FUNC_STD_VAR 0x0200 +#define PIVOT_FUNC_STD_VARP 0x0400 +#define PIVOT_FUNC_AUTO 0x1000 + +#define DATA_RENAME_SEPARATOR "_" +#define __MAX_NUM_LEN 64 +#define __DECIMALPLACE 18 + +#define DP_PROP_COLUMNGRAND "ColumnGrand" +#define DP_PROP_FUNCTION "Function" +#define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows" +#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension" +#define DP_PROP_ISVISIBLE "IsVisible" +#define DP_PROP_ORIENTATION "Orientation" +#define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty" +#define DP_PROP_ROWGRAND "RowGrand" +#define DP_PROP_SHOWDETAILS "ShowDetails" +#define DP_PROP_SHOWEMPTY "ShowEmpty" +#define DP_PROP_SUBTOTALS "SubTotals" +#define DP_PROP_USEDHIERARCHY "UsedHierarchy" +#define DP_PROP_FILTER "Filter" +#define DP_PROP_POSITION "Position" + +#define DBG_TRACESTR( x ) \ + {\ + ByteString aTemp( x , RTL_TEXTENCODING_UTF8 ); \ + DBG_TRACE( aTemp.GetBuffer() );\ + } + +class TypedStrData; +class ScDPObject; + +class SC_DLLPUBLIC ScDPItemData +{ +public: + enum { MK_VAL = 0x01, MK_DATA = MK_VAL<<1, MK_ERR = MK_DATA<<1, MK_DATE = MK_ERR<<1, MK_DATEPART = MK_DATE<<1 }; +private: + union + { + ULONG nNumFormat; + sal_Int32 mnDatePart; + }; + + String aString; + double fValue; + BYTE mbFlag; + //BOOL bHasValue: 1 ; + //BOOL bHasData: 1; + //BOOL bErr: 1; + + friend class ScDPTableDataCache; +public: + ScDPItemData() : nNumFormat( 0 ), fValue(0.0), mbFlag( 0 ){} + ScDPItemData( ULONG nNF, const String & rS, double fV, BYTE bF ):nNumFormat(nNF), aString(rS), fValue(fV), mbFlag( bF ){} + ScDPItemData( const String& rS, double fV = 0.0, BOOL bHV = FALSE, const ULONG nNumFormat = 0 , BOOL bData = TRUE) ; + ScDPItemData( ScDocument* pDoc, SCROW nRow, USHORT nCol, USHORT nDocTab ); + + void SetString( const String& rS ) { aString = rS; mbFlag &= ~(MK_VAL|MK_DATE); nNumFormat = 0; mbFlag |= MK_DATA; } +// void SetValue ( double value , ULONG nNumFormat = 0 ) { bHasValue = TRUE; nNumFormat = 0;bHasData = TRUE; bDate = FALSE; fValue = value ;} + BOOL IsCaseInsEqual( const ScDPItemData& r ) const; + + size_t Hash() const; + + // exact equality + BOOL operator==( const ScDPItemData& r ) const; + // case insensitive equality + static sal_Int32 Compare( const ScDPItemData& rA, const ScDPItemData& rB ); + +#ifdef DEBUG + void dump() const; +#endif + +public: + BOOL IsHasData() const ; + BOOL IsHasErr() const ; + BOOL IsValue() const; + String GetString() const ; + double GetValue() const ; + ULONG GetNumFormat() const ; + BOOL HasStringData() const ; + BOOL IsDate() const; + BOOL HasDatePart() const; + void SetDate( BOOL b ) ; + + TypedStrData* CreateTypeString( ); + sal_uInt8 GetType() const; + BYTE & GetFlag() throw() { return mbFlag; } + const BYTE & GetFlag() const throw() { return const_cast<ScDPItemData*>(this)->GetFlag(); } +}; + +class SC_DLLPUBLIC ScDPItemDataPool +{ +public: + // construct + ScDPItemDataPool(void); + ScDPItemDataPool(const ScDPItemDataPool& r); + + virtual ~ScDPItemDataPool(void); + virtual const ScDPItemData* getData( sal_Int32 nId ); + virtual sal_Int32 getDataId( const ScDPItemData& aData ); + virtual sal_Int32 insertData( const ScDPItemData& aData ); +protected: + struct DataHashFunc : public std::unary_function< const ScDPItemData &, size_t > + { + size_t operator() (const ScDPItemData &rData) const { return rData.Hash(); } + }; + + typedef ::std::hash_multimap< ScDPItemData, sal_Int32, DataHashFunc > DataHash; + + ::std::vector< ScDPItemData > maItems; + DataHash maItemIds; +}; + +class ScDPInfoWnd; +class ScDocShell; +class ScTabViewShell; +namespace ScDPGlobal +{ +// used for core data + String GetFieldFuncString( const String& rSourceName, USHORT &rFuncMask, BOOL bIsValue ); + String GetFuncString( const String &rString, const USHORT nIndex ); + com::sun::star::uno::Reference<com::sun::star::container::XNameAccess> DP_GetMembers( const com::sun::star::uno::Reference< + com::sun::star::sheet::XDimensionsSupplier>&rSrc, long nField ); +// common operation + String operator + ( const String & rL, const String &rR ); + Rectangle operator *( const Rectangle &rLeft, const std::pair<double,double> & rRight ); +// used for DataPilot Panel + ScDPInfoWnd* GetDPInfoWnd( ScTabViewShell *pViewShell ); + bool ChkDPTableOverlap( ScDocument *pDestDoc, std::list<ScDPObject> & rClipboard, SCCOL nClipStartCol, SCROW nClipStartRow, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, USHORT nEndTab, BOOL bExcludeClip = FALSE ); + +} +#endif diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx index 39770d2adffd..2a66f8b45555 100644 --- a/sc/inc/dpgroup.hxx +++ b/sc/inc/dpgroup.hxx @@ -34,7 +34,10 @@ #include "dptabdat.hxx" #include "scdllapi.h" - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpglobal.hxx" +// End Comments class ScDocument; class SvNumberFormatter; @@ -73,8 +76,11 @@ public: sal_Int32 GetDatePart() const { return nDatePart; } const ScDPNumGroupInfo& GetNumInfo() const { return aNumInfo; } - void FillColumnEntries( TypedScStrCollection& rEntries, const TypedScStrCollection& rOriginal, - SvNumberFormatter* pFormatter ) const; + // Wang Xu Ming -- 2009-9-8 + // DataPilot Migration - Cache&&Performance + void FillColumnEntries( SCCOL nSourceDim, ScDPTableDataCache* pCahe , std::vector< SCROW >& rEntries, + const std::vector< SCROW >& rOriginal ) const; + // End Comments }; // -------------------------------------------------------------------- @@ -108,8 +114,10 @@ class ScDPGroupDimension String aGroupName; ScDPDateGroupHelper* pDateHelper; ScDPGroupItemVec aItems; - mutable TypedScStrCollection* pCollection; // collection of item names (cached) - + // Wang Xu Ming -- 2009-9-4 + // DataPilot Migration - Cache&&Performance + mutable ::std::vector< SCROW > maMemberEntries; + // End Comments public: ScDPGroupDimension( long nSource, const String& rNewName ); ScDPGroupDimension( const ScDPGroupDimension& rOther ); @@ -122,9 +130,12 @@ public: long GetSourceDim() const { return nSourceDim; } long GetGroupDim() const { return nGroupDim; } - const String& GetName() const { return aGroupName; } + const String& GetName() const { return aGroupName; } - const TypedScStrCollection& GetColumnEntries( const TypedScStrCollection& rOriginal, ScDocument* pDoc ) const; +// Wang Xu Ming -- 2009-9-2 +// DataPilot Migration - Cache&&Performance + const std::vector< SCROW >& GetColumnEntries( const ScDPCacheTable& rCacheTable, const std::vector< SCROW >& rOriginal ) const; +// End Comments const ScDPGroupItem* GetGroupForData( const ScDPItemData& rData ) const; // rData = entry in original dim. const ScDPGroupItem* GetGroupForName( const ScDPItemData& rName ) const; // rName = entry in group dim. const ScDPGroupItem* GetGroupByIndex( size_t nIndex ) const; @@ -146,7 +157,10 @@ class SC_DLLPUBLIC ScDPNumGroupDimension { ScDPNumGroupInfo aGroupInfo; // settings ScDPDateGroupHelper* pDateHelper; - mutable TypedScStrCollection* pCollection; // collection of item names (cached) +// Wang Xu Ming -- 2009-9-4 +// DataPilot Migration - Cache&&Performance + mutable ::std::vector< SCROW > maMemberEntries; +// End Comments mutable bool bHasNonInteger; // initialized in GetNumEntries mutable sal_Unicode cDecSeparator; // initialized in GetNumEntries @@ -158,14 +172,15 @@ public: ScDPNumGroupDimension& operator=( const ScDPNumGroupDimension& rOther ); - const TypedScStrCollection& GetNumEntries( const TypedScStrCollection& rOriginal, ScDocument* pDoc ) const; - const ScDPNumGroupInfo& GetInfo() const { return aGroupInfo; } bool HasNonInteger() const { return bHasNonInteger; } sal_Unicode GetDecSeparator() const { return cDecSeparator; } const ScDPDateGroupHelper* GetDateHelper() const { return pDateHelper; } + const std::vector< SCROW >& GetNumEntries( SCCOL nSourceDim, ScDPTableDataCache* pCache, + const std::vector< SCROW >& rOriginal ) const; + void MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ); void DisposeData(); @@ -187,7 +202,11 @@ class ScDPGroupTableData : public ScDPTableData ScDocument* pDoc; StringHashSet aGroupNames; - void FillGroupValues( ScDPItemData* pItemData, long nCount, const long* pDims ); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + void FillGroupValues( SCROW* pItemDataIndex, long nCount, const long* pDims ); + virtual long GetSourceDim( long nDim ); +// End Comments void CopyFields(const ::std::vector<long>& rFieldDims, ::std::vector<long>& rNewFieldDims); bool IsNumGroupDimension( long nDimension ) const; @@ -208,11 +227,18 @@ public: ScDocument* GetDocument() { return pDoc; } virtual long GetColumnCount(); - virtual const TypedScStrCollection& GetColumnEntries(long nColumn); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + virtual long GetMembersCount( long nDim ); + virtual const std::vector< SCROW >& GetColumnEntries( long nColumn ) ; + virtual const ScDPItemData* GetMemberById( long nDim, long nId); + virtual long Compare( long nDim, long nDataId1, long nDataId2); + +// End Comments virtual String getDimensionName(long nColumn); virtual BOOL getIsDataLayoutDimension(long nColumn); virtual BOOL IsDateDimension(long nDim); - virtual UINT32 GetNumberFormat(long nDim); + virtual ULONG GetNumberFormat(long nDim); virtual void DisposeData(); virtual void SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ); diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 917d62f38bfe..65e89ec75d41 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -115,8 +115,18 @@ private: SC_DLLPRIVATE ScDPTableData* GetTableData(); SC_DLLPRIVATE void CreateObjects(); SC_DLLPRIVATE void CreateOutput(); + BOOL bRefresh; + long mnCacheId; public: + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + inline void SetRefresh() { bRefresh = TRUE; } + const ScDPTableDataCache* GetCache() const; + long GetCacheId() const; + void SetCacheId( long nCacheId ); + ULONG RefreshCache(); + // End Comments ScDPObject( ScDocument* pD ); ScDPObject(const ScDPObject& r); virtual ~ScDPObject(); @@ -251,19 +261,6 @@ public: PivotField* pRefPageFields = NULL, SCSIZE nRefPageCount = 0 ); }; -// ============================================================================ - -struct ScDPCacheCell -{ - sal_Int32 mnStrId; - sal_uInt8 mnType; - double mfValue; - bool mbNumeric; - - ScDPCacheCell(); - ScDPCacheCell(const ScDPCacheCell& r); - ~ScDPCacheCell(); -}; // ============================================================================ @@ -271,20 +268,6 @@ class ScDPCollection : public ScCollection { private: ScDocument* pDoc; - ScSimpleSharedString maSharedString; - - struct CacheCellHash - { - size_t operator()(const ScDPCacheCell* pCell) const; - }; - struct CacheCellEqual - { - bool operator()(const ScDPCacheCell* p1, const ScDPCacheCell* p2) const; - }; - typedef ::std::hash_set<ScDPCacheCell*, CacheCellHash, CacheCellEqual> CacheCellPoolType; - - CacheCellPoolType maCacheCellPool; - public: ScDPCollection(ScDocument* pDocument); ScDPCollection(const ScDPCollection& r); @@ -303,15 +286,10 @@ public: String CreateNewName( USHORT nMin = 1 ) const; - ScSimpleSharedString& GetSharedString(); - void FreeTable(ScDPObject* pDPObj); SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj); bool HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const; - - ScDPCacheCell* getCacheCellFromPool(const ScDPCacheCell& rCell); - void clearCacheCellPool(); }; diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index 587e23d8109b..bfff0b97a168 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -88,6 +88,9 @@ public: }; +bool operator == (const ::com::sun::star::sheet::DataPilotFieldSortInfo &l, const ::com::sun::star::sheet::DataPilotFieldSortInfo &r ); +bool operator == (const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &l, const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &r ); +bool operator == (const ::com::sun::star::sheet::DataPilotFieldReference &l, const ::com::sun::star::sheet::DataPilotFieldReference &r ); class SC_DLLPUBLIC ScDPSaveDimension { private: @@ -175,6 +178,9 @@ public: void WriteToSource( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface>& xDim ); + void Refresh( const com::sun::star::uno::Reference< + com::sun::star::sheet::XDimensionsSupplier>& xSource , + const std::list<String> & deletedDims); void UpdateMemberVisibility(const ::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rData); @@ -193,6 +199,10 @@ private: USHORT nRepeatEmptyMode; BOOL bFilterButton; // not passed to DataPilotSource BOOL bDrillDown; // not passed to DataPilotSource + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + long mnCacheId; + // End Comments /** if true, all dimensions already have all of their member instances * created. */ @@ -248,10 +258,15 @@ public: BOOL GetDrillDown() const { return bDrillDown; } void WriteToSource( const com::sun::star::uno::Reference< + com::sun::star::sheet::XDimensionsSupplier>& xSource ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void Refresh( const com::sun::star::uno::Reference< com::sun::star::sheet::XDimensionsSupplier>& xSource ); - BOOL IsEmpty() const; - + inline long GetCacheId() const{ return mnCacheId; } + inline void SetCacheId( long nCacheId ){ mnCacheId = nCacheId; } + // End Comments const ScDPDimensionSaveData* GetExistingDimensionData() const { return pDimensionData; } SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied diff --git a/sc/inc/dpsdbtab.hxx b/sc/inc/dpsdbtab.hxx index 1f980bdec3bf..732e3d30e8df 100644 --- a/sc/inc/dpsdbtab.hxx +++ b/sc/inc/dpsdbtab.hxx @@ -50,28 +50,32 @@ struct ScImportSourceDesc USHORT nType; // enum DataImportMode BOOL bNative; + ScImportSourceDesc() : nType(0), bNative(FALSE) {} + BOOL operator== ( const ScImportSourceDesc& rOther ) const { return aDBName == rOther.aDBName && aObject == rOther.aObject && nType == rOther.nType && bNative == rOther.bNative; } -}; -class ScDatabaseDPData_Impl; + // Wang Xu Ming -- 2009-9-15 + // DataPilot Migration - Cache&&Performance + ScDPTableDataCache* GetExistDPObjectCache( ScDocument* pDoc ) const; + ScDPTableDataCache* CreateCache( ScDocument* pDoc , long nID ) const; + ScDPTableDataCache* GetCache( ScDocument* pDoc, long nID ) const; + long GetCacheId( ScDocument* pDoc, long nID ) const; + // End Comments +}; class ScDatabaseDPData : public ScDPTableData { private: - ScDatabaseDPData_Impl* pImpl; - - BOOL OpenDatabase(); - + ScDPCacheTable aCacheTable; public: - ScDatabaseDPData(ScDocument* pDoc, const ScImportSourceDesc& rImport); + ScDatabaseDPData(ScDocument* pDoc, const ScImportSourceDesc& rImport, long nCacheId = -1); virtual ~ScDatabaseDPData(); virtual long GetColumnCount(); - virtual const TypedScStrCollection& GetColumnEntries(long nColumn); virtual String getDimensionName(long nColumn); virtual BOOL getIsDataLayoutDimension(long nColumn); virtual BOOL IsDateDimension(long nDim); diff --git a/sc/inc/dpshttab.hxx b/sc/inc/dpshttab.hxx index a0e67371eff1..a8d80072c68a 100644 --- a/sc/inc/dpshttab.hxx +++ b/sc/inc/dpshttab.hxx @@ -41,8 +41,10 @@ namespace com { namespace sun { namespace star { namespace sheet { }}}} class ScDPDimension; -struct ScDPItemData; - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPItemData; +// End Comments // -------------------------------------------------------------------- // // implementation of ScDPTableData with sheet data @@ -56,25 +58,38 @@ struct ScSheetSourceDesc BOOL operator== ( const ScSheetSourceDesc& rOther ) const { return aSourceRange == rOther.aSourceRange && aQueryParam == rOther.aQueryParam; } +// Wang Xu Ming - DataPilot migration +// Buffer&&Performance + ScDPTableDataCache* CreateCache( ScDocument* pDoc, long nID = -1) const; + ULONG CheckValidate( ScDocument* pDoc ) const; + ScDPTableDataCache* GetCache( ScDocument* pDoc, long nID ) const; + ScDPTableDataCache* GetExistDPObjectCache ( ScDocument* pDoc ) const; + long GetCacheId( ScDocument* pDoc, long nID ) const; + +// End Comments }; -class ScSheetDPData_Impl; - class SC_DLLPUBLIC ScSheetDPData : public ScDPTableData { private: - ScSheetDPData_Impl* pImpl; + ScQueryParam aQuery; + BOOL* pSpecial; + BOOL bIgnoreEmptyRows; + BOOL bRepeatIfEmpty; + + ScDPCacheTable aCacheTable; public: - ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc, long nCacheId = -1 ); virtual ~ScSheetDPData(); - + // End Comments virtual long GetColumnCount(); - virtual const TypedScStrCollection& GetColumnEntries(long nColumn); virtual String getDimensionName(long nColumn); virtual BOOL getIsDataLayoutDimension(long nColumn); virtual BOOL IsDateDimension(long nDim); - virtual UINT32 GetNumberFormat(long nDim); + virtual ULONG GetNumberFormat(long nDim); virtual void DisposeData(); virtual void SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ); diff --git a/sc/inc/dptabdat.hxx b/sc/inc/dptabdat.hxx index 43c719e9ee16..6323434ca4ad 100644 --- a/sc/inc/dptabdat.hxx +++ b/sc/inc/dptabdat.hxx @@ -31,7 +31,10 @@ #include "address.hxx" #include "dpoutput.hxx" #include "dpcachetable.hxx" - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dptablecache.hxx" +// End Comments #include <tools/string.hxx> #include <vector> @@ -43,8 +46,6 @@ namespace com { namespace sun { namespace star { namespace sheet { struct DataPilotFieldFilter; }}}} -class TypedScStrCollection; -class ScSimpleSharedString; // ----------------------------------------------------------------------- @@ -71,28 +72,6 @@ class ScSimpleSharedString; // base class ScDPTableData to allow implementation with tabular data // by deriving only of this // - -struct ScDPItemData -{ - String aString; - double fValue; - BOOL bHasValue; - - ScDPItemData() : fValue(0.0), bHasValue(FALSE) {} - ScDPItemData( const String& rS, double fV = 0.0, BOOL bHV = FALSE ) : - aString(rS), fValue(fV), bHasValue( bHV ) {} - - void SetString( const String& rS ) { aString = rS; bHasValue = FALSE; } - BOOL IsCaseInsEqual( const ScDPItemData& r ) const; - - size_t Hash() const; - - // exact equality - BOOL operator==( const ScDPItemData& r ) const; - // case insensitive equality - static sal_Int32 Compare( const ScDPItemData& rA, const ScDPItemData& rB ); -}; - #define SC_VALTYPE_EMPTY 0 #define SC_VALTYPE_VALUE 1 #define SC_VALTYPE_STRING 2 @@ -113,15 +92,18 @@ class ScDPInitState; class ScDPResultMember; class ScDocument; -class ScDPTableData + class SC_DLLPUBLIC ScDPTableData { // cached data for GetDatePart long nLastDateVal; long nLastHier; long nLastLevel; long nLastRet; - ScSimpleSharedString& mrSharedString; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + long mnCacheId; + const ScDocument* mpDoc; + // End Comments public: /** This structure stores dimension information used when calculating @@ -147,7 +129,10 @@ public: CalcInfo(); }; - ScDPTableData(ScDocument* pDoc); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPTableData(ScDocument* pDoc, long nCacheId ); + // End Comments virtual ~ScDPTableData(); long GetDatePart( long nDateVal, long nHierarchy, long nLevel ); @@ -156,11 +141,16 @@ public: //! or separate Str and ValueCollection virtual long GetColumnCount() = 0; - virtual const TypedScStrCollection& GetColumnEntries(long nColumn) = 0; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual const std::vector< SCROW >& GetColumnEntries( long nColumn ) ; + long GetCacheId() const; + // End Comments virtual String getDimensionName(long nColumn) = 0; virtual BOOL getIsDataLayoutDimension(long nColumn) = 0; virtual BOOL IsDateDimension(long nDim) = 0; - virtual UINT32 GetNumberFormat(long nDim); + virtual ULONG GetNumberFormat(long nDim); + virtual UINT32 GetNumberFormatByIdx( NfIndexTableOffset ); virtual void DisposeData() = 0; virtual void SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ) = 0; @@ -176,23 +166,33 @@ public: // overloaded in ScDPGroupTableData: virtual BOOL IsBaseForGroup(long nDim) const; - virtual long GetGroupBase(long nGroupDim) const; + virtual long GetGroupBase(long nGroupDim) const; virtual BOOL IsNumOrDateGroup(long nDim) const; virtual BOOL IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex, const ScDPItemData& rBaseData, long nBaseIndex ) const; virtual BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex, const ScDPItemData& rSecondData, long nSecondIndex ) const; - ScSimpleSharedString& GetSharedString(); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual long GetMembersCount( long nDim ); + virtual const ScDPItemData* GetMemberByIndex( long nDim, long nIndex ); + virtual const ScDPItemData* GetMemberById( long nDim, long nId); + virtual SCROW GetIdOfItemData( long nDim, const ScDPItemData& rData ); + virtual long GetSourceDim( long nDim ); + virtual long Compare( long nDim, long nDataId1, long nDataId2); + // End Comments protected: /** This structure stores vector arrays that hold intermediate data for each row during cache table iteration. */ struct CalcRowData { - ::std::vector<ScDPItemData> aColData; - ::std::vector<ScDPItemData> aRowData; - ::std::vector<ScDPItemData> aPageData; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ::std::vector< SCROW > aColData; + ::std::vector< SCROW > aRowData; + ::std::vector< SCROW > aPageData; + // End Comments ::std::vector<ScDPValueData> aValues; }; @@ -201,10 +201,11 @@ protected: void CalcResultsFromCacheTable(const ScDPCacheTable& rCacheTable, CalcInfo& rInfo, bool bAutoShow); private: + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance void GetItemData(const ScDPCacheTable& rCacheTable, sal_Int32 nRow, - const ::std::vector<long>& rDims, ::std::vector<ScDPItemData>& rItemData); + const ::std::vector<long>& rDims, ::std::vector< SCROW >& rItemData); + // End Comments }; - - #endif diff --git a/sc/inc/dptablecache.hxx b/sc/inc/dptablecache.hxx new file mode 100644 index 000000000000..953c793093be --- /dev/null +++ b/sc/inc/dptablecache.hxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dptablecache.hxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef DPTABLECACHE_HXX +#define DPTABLECACHE_HXX +// Wang Xu Ming -- 12/21/2008 +// Add Data Cache Support. +#ifndef SC_SCGLOB_HXX +#include "global.hxx" +#endif +//Added by PengYunQuan for SODC_16015 +#include <svl/zforlist.hxx> +//end +#include <vector> +#include "dpglobal.hxx" + +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> + +class ScDPTableDataCache; +class TypedStrData; +struct ScQueryParam; + +// -------------------------------------------------------------------- +// +// base class ScDPTableData to allow implementation with tabular data +// by deriving only of this +// + +class SC_DLLPUBLIC ScDPTableDataCache +{ + long mnID; + ScDocument* mpDoc; + + long mnColumnCount; // Column count + + std::vector<ScDPItemData*>* mpTableDataValues; //Data Pilot Table's index - value map + std::vector<SCROW>* mpSourceData; //Data Pilot Table's Source data + std::vector<SCROW>* mpGlobalOrder; //Sorted members index + std::vector<SCROW>* mpIndexOrder; //Index the sorted number + std::vector<ScDPItemData*> mrLabelNames; //Source Label data + std::vector<BOOL> mbEmptyRow; //If empty row? + mutable ScDPItemDataPool maAdditionalDatas; +public: + SCROW GetOrder( long nDim, SCROW nIndex ) const; + SCROW GetIdByItemData( long nDim, String sItemData ) const; + SCROW GetIdByItemData( long nDim, const ScDPItemData& rData ) const; + + SCROW GetAdditionalItemID ( String sItemData ); + SCROW GetAdditionalItemID( const ScDPItemData& rData ); + + SCCOL GetDimensionIndex( String sName) const; + const ScDPItemData* GetSortedItemData( SCCOL nDim, SCROW nOrder ) const; + ULONG GetNumType ( ULONG nFormat ) const; + ULONG GetNumberFormat( long nDim ) const; + BOOL IsDateDimension( long nDim ) const ; + ULONG GetDimNumType( SCCOL nDim) const; + SCROW GetDimMemberCount( SCCOL nDim ) const; + + SCROW GetSortedItemDataId( SCCOL nDim, SCROW nOrder ) const; + const std::vector<ScDPItemData*>& GetDimMemberValues( SCCOL nDim )const; + void SetId( long nId ){ mnID = nId;} + void AddRow( ScDPItemData* pRow, USHORT nCount ); + bool InitFromDoc( ScDocument* pDoc, const ScRange& rRange ); + bool InitFromDataBase (const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& xRowSet, const Date& rNullDate); + + SCROW GetRowCount() const; + SCROW GetItemDataId( USHORT nDim, SCROW nRow, BOOL bRepeatIfEmpty ) const; + String GetDimensionName( USHORT nColumn ) const; + bool IsEmptyMember( SCROW nRow, USHORT nColumn ) const; + bool IsRowEmpty( SCROW nRow ) const; + bool IsValid() const; + bool ValidQuery( SCROW nRow, const ScQueryParam& rQueryParam, BOOL* pSpecial ); + + ScDocument* GetDoc() const;//ms-cache-core + long GetColumnCount() const; + long GetId() const; + + const ScDPItemData* GetItemDataById( long nDim, SCROW nId ) const; + + BOOL operator== ( const ScDPTableDataCache& r ) const; + +//construction + ScDPTableDataCache( ScDocument* pDoc ); +//deconstruction + virtual ~ScDPTableDataCache(); + +protected: +private: + void AddLabel( ScDPItemData* pData); + BOOL AddData( long nDim, ScDPItemData* itemData ); +}; + +#endif //DPTABLECACHE_HXX diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx index d4e8807d4a3b..e35975ab170f 100644 --- a/sc/inc/dptabres.hxx +++ b/sc/inc/dptabres.hxx @@ -57,8 +57,10 @@ class ScDPResultMember; class ScDPResultVisibilityData; struct ScDPValueData; -struct ScDPItemData; - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPItemData; +// End Comments // // Member names that are being processed for InitFrom/LateInitFrom // (needed for initialization of grouped items) @@ -67,21 +69,26 @@ struct ScDPItemData; class ScDPInitState { long* pIndex; // array - ScDPItemData* pData; // array +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + SCROW* pData; // array + // End Comments long nCount; public: ScDPInitState(); ~ScDPInitState(); - void AddMember( long nSourceIndex, const ScDPItemData& rName ); + void AddMember( long nSourceIndex,SCROW nMember); void RemoveMember(); long GetCount() const { return nCount; } const long* GetSource() const { return pIndex; } - const ScDPItemData* GetNames() const { return pData; } - - const ScDPItemData* GetNameForIndex( long nIndexValue ) const; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + const SCROW* GetNameIds() const { return pData; } + const SCROW GetNameIdForIndex( long nIndexValue ) const; +// End Comments }; typedef ::std::vector<sal_Int32> ScMemberSortOrder; @@ -230,6 +237,68 @@ class ScDPDataMember; #define SC_DPMEASURE_ALL -1 #define SC_DPMEASURE_ANY -2 +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + +struct MemberHashIndexFunc : public std::unary_function< const SCROW &, size_t > +{ + size_t operator() (const SCROW &rDataIndex) const { return rDataIndex; } +}; + +class ScDPParentDimData +{ +public: + const SCROW mnOrder; //! Ref + const ScDPDimension* mpParentDim; //! Ref + const ScDPLevel* mpParentLevel; //! Ref + const ScDPMember* mpMemberDesc; //! Ref + + ScDPParentDimData():mnOrder(-1), mpParentDim( NULL), mpParentLevel( NULL ), mpMemberDesc( NULL ){} + ScDPParentDimData( const SCROW nIndex, ScDPDimension* pDim, const ScDPLevel* pLev, const ScDPMember* pMember ): mnOrder( nIndex ), mpParentDim( pDim), mpParentLevel( pLev ), mpMemberDesc( pMember ){} +}; + +typedef std::vector <ScDPParentDimData *> DimMemberArray; +typedef std::hash_map < SCROW, ScDPParentDimData *, MemberHashIndexFunc> DimMemberHash; + +class ResultMembers +{ + DimMemberHash maMemberHash; + BOOL mbHasHideDetailsMember; +public: + ScDPParentDimData* FindMember( const SCROW& nIndex ) const; + void InsertMember( ScDPParentDimData* pNew ); + BOOL IsHasHideDetailsMembers() const { return mbHasHideDetailsMember; } + void SetHasHideDetailsMembers( BOOL b ) { mbHasHideDetailsMember=b; } + ResultMembers(); + virtual ~ResultMembers(); +}; + +class LateInitParams +{ +private: + const ::std::vector<ScDPDimension*>& mppDim; + const ::std::vector<ScDPLevel*>& mppLev; + + BOOL mbRow; + BOOL mbInitChild; + BOOL mbAllChildren; +public: + LateInitParams( const ::std::vector<ScDPDimension*>& ppDim, const ::std::vector<ScDPLevel*>& ppLev, + BOOL bRow, BOOL bInitChild = TRUE , BOOL bAllChildren = FALSE); + ~LateInitParams(); + + void SetInitChild( BOOL b ) { mbInitChild = b; } + void SetInitAllChildren( BOOL b ) { mbAllChildren = b; } + + inline ScDPDimension* GetDim( size_t nPos ) const { return mppDim[nPos];} + inline ScDPLevel* GetLevel( size_t nPos ) const { return mppLev[nPos];} + + inline BOOL GetInitChild() const {return mbInitChild; } + inline BOOL GetInitAllChild() const { return mbAllChildren; } + inline BOOL IsRow() const { return mbRow; } + BOOL IsEnd( size_t nPos ) const ; +}; +// End Comments class ScDPResultData { @@ -247,7 +316,7 @@ private: BOOL bDataAtRow; //! add "displayed values" settings - + mutable std::vector< ResultMembers* > mpDimMembers; public: ScDPResultData( ScDPSource* pSrc ); //! Ref ~ScDPResultData(); @@ -278,11 +347,18 @@ public: BOOL IsBaseForGroup( long nDim ) const; // any group long GetGroupBase( long nGroupDim ) const; BOOL IsNumOrDateGroup( long nDim ) const; + // Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance BOOL IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex, - const ScDPItemData& rBaseData, long nBaseIndex ) const; - BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex, + long nBaseDataId, long nBaseIndex ) const; + BOOL IsInGroup( SCROW nGroupDataId, long nGroupIndex, + const ScDPItemData& rBaseData, long nBaseIndex ) const; + BOOL HasCommonElement( SCROW nFirstDataId, long nFirstIndex, const ScDPItemData& rSecondData, long nSecondIndex ) const; + ResultMembers* GetDimResultMembers( long nDim , ScDPDimension* pDim , ScDPLevel* pLevel) const ; + +// End Comments const ScDPSource* GetSource() const; }; @@ -291,9 +367,10 @@ class ScDPResultMember { private: const ScDPResultData* pResultData; - const ScDPDimension* pParentDim; //! Ref - const ScDPLevel* pParentLevel; //! Ref - const ScDPMember* pMemberDesc; //! Ref + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPParentDimData aParentDimData; + // End Comments ScDPResultDimension* pChildDimension; ScDPDataMember* pDataRoot; BOOL bHasElements; @@ -303,21 +380,30 @@ private: BOOL bAutoHidden; ScDPAggData aColTotal; // to store column totals + USHORT nMemberStep; // step to show details public: - ScDPResultMember( const ScDPResultData* pData, const ScDPDimension* pDim, - const ScDPLevel* pLev, const ScDPMember* pDesc, - BOOL bForceSub ); //! Ref - ~ScDPResultMember(); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData, + BOOL bForceSub ); //! Ref + ScDPResultMember( const ScDPResultData* pData, BOOL bForceSub ); + // End Comments + ~ScDPResultMember(); + + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance void InitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - size_t nPos, - ScDPInitState& rInitState ); - void LateInitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - const ::std::vector<ScDPItemData>& pItemData, - size_t nPos, - ScDPInitState& rInitState ); + const ::std::vector<ScDPLevel*>& ppLev, + size_t nPos, + ScDPInitState& rInitState, + BOOL bInitChild = TRUE ); + void LateInitFrom( + LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState); + void CheckShowEmpty( BOOL bShow = FALSE ); + // End Comments String GetName() const; void FillItemData( ScDPItemData& rData ) const; BOOL IsValid() const; @@ -329,17 +415,22 @@ public: // BOOL SubTotalEnabled() const; long GetSubTotalCount( long* pUserSubStart = NULL ) const; - BOOL IsNamedItem( const ScDPItemData& r ) const; - bool IsValidEntry( const ::std::vector<ScDPItemData>& aMembers ) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + BOOL IsNamedItem( SCROW nIndex ) const; + bool IsValidEntry( const ::std::vector< SCROW >& aMembers ) const; + // End Comments void SetHasElements() { bHasElements = TRUE; } void SetAutoHidden() { bAutoHidden = TRUE; } - void ProcessData( const ::std::vector<ScDPItemData>& aChildMembers, - const ScDPResultDimension* pDataDim, - const ::std::vector<ScDPItemData>& aDataMembers, - const ::std::vector<ScDPValueData>& aValues ); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void ProcessData( const ::std::vector<SCROW>& aChildMembers, + const ScDPResultDimension* pDataDim, + const ::std::vector<SCROW>& aDataMembers, + const ::std::vector<ScDPValueData>& aValues ); + // End Comments void FillMemberResults( com::sun::star::uno::Sequence< com::sun::star::sheet::MemberResult>* pSequences, long& rPos, long nMeasure, BOOL bRoot, @@ -369,9 +460,15 @@ public: ScDPDataMember* GetDataRoot() const { return pDataRoot; } - const ScDPDimension* GetParentDim() const { return pParentDim; } //! Ref - const ScDPLevel* GetParentLevel() const { return pParentLevel; } //! Ref - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + const ScDPDimension* GetParentDim() const { return aParentDimData.mpParentDim; } //! Ref + const ScDPLevel* GetParentLevel() const { return aParentDimData.mpParentLevel; } //! Ref + const ScDPMember* GetDPMember()const { return aParentDimData.mpMemberDesc; } //! Ref + inline SCROW GetOrder() const { return aParentDimData.mnOrder; } //! Ref + inline BOOL IsRoot() const { return GetParentLevel() == NULL; } + SCROW GetDataId( ) const ; + // End Comments ScDPAggData* GetColTotal( long nMeasure ) const; void FillVisibilityData(ScDPResultVisibilityData& rData) const; @@ -397,13 +494,17 @@ public: BOOL IsVisible() const; BOOL HasData( long nMeasure, const ScDPSubTotalState& rSubState ) const; - BOOL IsNamedItem( const ScDPItemData& r ) const; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + BOOL IsNamedItem( SCROW r ) const; + // End Comments BOOL HasHiddenDetails() const; - void ProcessData( const ::std::vector<ScDPItemData>& aChildMembers, const ::std::vector<ScDPValueData>& aValues, - const ScDPSubTotalState& rSubState ); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void ProcessData( const ::std::vector< SCROW >& aChildMembers, const ::std::vector<ScDPValueData>& aValues, + const ScDPSubTotalState& rSubState ); + // End Comments BOOL HasError( long nMeasure, const ScDPSubTotalState& rSubState ) const; double GetAggregate( long nMeasure, const ScDPSubTotalState& rSubState ) const; const ScDPAggData* GetConstAggData( long nMeasure, const ScDPSubTotalState& rSubState ) const; @@ -443,15 +544,13 @@ SV_DECL_PTRARR_DEL(ScDPDataMembers, ScDPDataMemberPtr, SC_DP_RES_GROW, SC_DP_RES class ScDPResultDimension { public : - struct MemberHashFunc : public std::unary_function< const ScDPItemData &, size_t > - { - size_t operator() (const ScDPItemData &rData) const { return rData.Hash(); } - }; - typedef std::vector <ScDPResultMember *> MemberArray; - typedef std::hash_map <ScDPItemData, ScDPResultMember *, MemberHashFunc> MemberHash; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + typedef std::vector <ScDPResultMember *> MemberArray; + typedef std::map < SCROW , ScDPResultMember *> MemberHash; + // End Comments private: - const ScDPResultData* pResultData; + const ScDPResultData* pResultData; MemberArray maMemberArray; MemberHash maMemberHash; BOOL bInitialized; @@ -466,31 +565,47 @@ private: long nAutoMeasure; long nAutoCount; - ScDPResultMember* FindMember( const ScDPItemData& rData ) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPResultMember* FindMember( SCROW iData ) const; + ScDPResultMember* AddMember( const ScDPParentDimData& aData ); + ScDPResultMember* InsertMember( ScDPParentDimData* pMemberData ); + ResultMembers* GetResultMember( ScDPDimension* pDim, ScDPLevel* pLevel ); + void InitWithMembers( LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState ); + // End Comments public: - ScDPResultDimension( const ScDPResultData* pData ); - ~ScDPResultDimension(); + ScDPResultDimension( const ScDPResultData* pData ); + ~ScDPResultDimension(); // allocates new members + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance void InitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - size_t nPos, - ScDPInitState& rInitState ); - void LateInitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - const ::std::vector<ScDPItemData>& pItemData, - size_t nPos, - ScDPInitState& rInitState ); - + const ::std::vector<ScDPLevel*>& ppLev, + size_t nPos, + ScDPInitState& rInitState , BOOL bInitChild = TRUE ); + void LateInitFrom( LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState ); + void CheckShowEmpty( BOOL bShow = FALSE ); + + // End Comments long GetSize(long nMeasure) const; - bool IsValidEntry( const ::std::vector<ScDPItemData>& aMembers ) const; - // modifies existing members, allocates data dimensions - void ProcessData( const ::std::vector<ScDPItemData>& aMembers, + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + bool IsValidEntry( const ::std::vector<SCROW>& aMembers ) const; + + // modifies existing members, allocates data dimensions + void ProcessData( const ::std::vector<SCROW>& aMembers, const ScDPResultDimension* pDataDim, - const ::std::vector<ScDPItemData>& aDataMembers, + const ::std::vector<SCROW>& aDataMembers, const ::std::vector<ScDPValueData>& aValues ) const; //! Test - + // End Comments void FillMemberResults( com::sun::star::uno::Sequence< com::sun::star::sheet::MemberResult>* pSequences, long nStart, long nMeasure ); @@ -560,9 +675,11 @@ public: ~ScDPDataDimension(); void InitFrom( const ScDPResultDimension* pDim ); // recursive - void ProcessData( const ::std::vector<ScDPItemData>& aDataMembers, const ::std::vector<ScDPValueData>& aValues, - const ScDPSubTotalState& rSubState ); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void ProcessData( const ::std::vector< SCROW >& aDataMembers, const ::std::vector<ScDPValueData>& aValues, + const ScDPSubTotalState& rSubState ); + // End Comments void FillDataRow( const ScDPResultDimension* pRefDim, com::sun::star::uno::Sequence<com::sun::star::sheet::DataResult>& rSequence, long nCol, long nMeasure, BOOL bIsSubTotalRow, @@ -596,7 +713,10 @@ public: class ScDPResultVisibilityData { public: - ScDPResultVisibilityData(ScSimpleSharedString& rSharedString, ScDPSource* pSource); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPResultVisibilityData( ScDPSource* pSource); + // End Comments ~ScDPResultVisibilityData(); void addVisibleMember(const String& rDimName, const ScDPItemData& rMemberItem); @@ -611,7 +731,6 @@ private: typedef ::std::hash_map<String, VisibleMemberType, ScStringHashCode> DimMemberType; DimMemberType maDimensions; - ScSimpleSharedString& mrSharedString; ScDPSource* mpSource; }; diff --git a/sc/inc/dptabsrc.hxx b/sc/inc/dptabsrc.hxx index d2884281e1b8..18210f38e80e 100644 --- a/sc/inc/dptabsrc.hxx +++ b/sc/inc/dptabsrc.hxx @@ -30,6 +30,10 @@ #include <vector> #include <hash_map> +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include <list> +// End Comments #include <memory> #include <tools/string.hxx> #include <tools/list.hxx> @@ -57,7 +61,10 @@ #include <cppuhelper/implbase3.hxx> #include <cppuhelper/implbase5.hxx> #include <cppuhelper/implbase6.hxx> - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpglobal.hxx" +// End Comments #include "dptabdat.hxx" namespace com { namespace sun { namespace star { @@ -71,7 +78,10 @@ namespace com { namespace sun { namespace star { class ScDPResultMember; class ScDPResultData; -struct ScDPItemData; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPItemData; +// End Comments class ScDPTableData; // ------------------------------------------------------------------------ @@ -172,10 +182,18 @@ public: long GetDataDimensionCount(); ScDPDimension* GetDataDimension(long nIndex); String GetDataDimName(long nIndex); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPTableDataCache* GetCache(); + const ScDPItemData* GetItemDataById( long nDim, long nId ); + long GetDataLayoutDim(){ return pData->GetColumnCount(); } + SCROW GetMemberId( long nDim, const ScDPItemData& rData ); + // End Comments BOOL IsDataLayoutDimension(long nDim); USHORT GetDataLayoutOrientation(); BOOL IsDateDimension(long nDim); + UINT32 GetNumberFormat(long nDim); BOOL SubTotalAllowed(long nColumn); //! move to ScDPResultData @@ -439,6 +457,10 @@ public: const ::com::sun::star::sheet::DataPilotFieldReference& GetReferenceValue() const; //UNUSED2009-05 BOOL IsValidPage( const ScDPItemData& rData ); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + BOOL IsVisible( const ScDPItemData& rData ); +// End Comments }; class ScDPHierarchies : public cppu::WeakImplHelper2< @@ -732,6 +754,12 @@ public: long getMinMembers() const; sal_Int32 GetIndexFromName( const ::rtl::OUString& rName ) const; // <0 if not found + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + const std::vector<sal_Int32>& GetGlobalOrder(); + const ScDPItemData* GetSrcItemDataByIndex( SCROW nIndex); + SCROW GetSrcItemsCount(); + // End Comments }; class ScDPMember : public cppu::WeakImplHelper3< @@ -745,7 +773,11 @@ private: long nHier; long nLev; - ScDPItemData maData; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + SCROW mnDataId; + // End Comments +// String aCaption; // visible name (changeable by user) ::std::auto_ptr<rtl::OUString> mpLayoutName; sal_Int32 nPosition; // manual sorting @@ -753,13 +785,24 @@ private: BOOL bShowDet; public: - ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL, - const String& rN, double fV, BOOL bHV ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL, + SCROW nIndex /*const String& rN, double fV, BOOL bHV */); + // End Comments virtual ~ScDPMember(); BOOL IsNamedItem( const ScDPItemData& r ) const; String GetNameStr() const; void FillItemData( ScDPItemData& rData ) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + // const ScDPItemData& GetItemData() const{ return maData; } + const ScDPItemData& GetItemData() const; + inline SCROW GetItemDataId() const { return mnDataId; } + BOOL IsNamedItem( SCROW nIndex ) const; + // End Comments + SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const; sal_Int32 Compare( const ScDPMember& rOther ) const; // visible order diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx index 563cf768b5ae..7dd9903f82a1 100644 --- a/sc/inc/drwlayer.hxx +++ b/sc/inc/drwlayer.hxx @@ -110,9 +110,9 @@ private: void MoveAreaTwips( SCTAB nTab, const Rectangle& rArea, const Point& rMove, const Point& rTopLeft ); void MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2, - SCsCOL nDx,SCsROW nDy ); + SCsCOL nDx,SCsROW nDy, bool bUpdateNoteCaptionPos ); - void RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage ); + void RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos ); public: ScDrawLayer( ScDocument* pDocument, const String& rName ); @@ -155,7 +155,7 @@ public: void AddCalcUndo( SdrUndoAction* pUndo ); void MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2, - SCsCOL nDx,SCsROW nDy, BOOL bInsDel ); + SCsCOL nDx,SCsROW nDy, BOOL bInsDel, bool bUpdateNoteCaptionPos = true ); void WidthChanged( SCTAB nTab, SCCOL nCol, long nDifTwips ); void HeightChanged( SCTAB nTab, SCROW nRow, long nDifTwips ); @@ -173,7 +173,7 @@ public: SCTAB nSourceTab, const Rectangle& rSourceRange, const ScAddress& rDestPos, const Rectangle& rDestRange ); - void SetPageSize( USHORT nPageNo, const Size& rSize ); + void SetPageSize( USHORT nPageNo, const Size& rSize, bool bUpdateNoteCaptionPos = true ); // mirror or move between positive and negative positions for RTL void MirrorRTL( SdrObject* pObj ); diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index 06704942a8aa..818920885493 100644 --- a/sc/inc/externalrefmgr.hxx +++ b/sc/inc/externalrefmgr.hxx @@ -160,7 +160,7 @@ public: * values, for performance reasons. */ SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0, bool bSetCacheRange = true); - TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = NULL) const; + SC_DLLPUBLIC TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = NULL) const; bool hasRow( SCROW nRow ) const; /** Set/clear referenced status flag only if current status is not REFERENCED_PERMANENT. */ @@ -171,8 +171,12 @@ public: bool isReferenced() const; /// Obtain a sorted vector of rows. void getAllRows(::std::vector<SCROW>& rRows, SCROW nLow = 0, SCROW nHigh = MAXROW) const; + /// Returns the half-open range of used rows in this table. Returns [0,0) if table is empty. + SC_DLLPUBLIC ::std::pair< SCROW, SCROW > getRowRange() const; /// Obtain a sorted vector of columns. void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow = 0, SCCOL nHigh = MAXCOL) const; + /// Returns the half-open range of used columns in the specified row. Returns [0,0) if row is empty. + SC_DLLPUBLIC ::std::pair< SCCOL, SCCOL > getColRange( SCROW nRow ) const; void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const; const ScRangeList& getCachedRanges() const; bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; @@ -470,6 +474,13 @@ public: * @return shared_ptr to the cache table instance */ ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex = 0); + + /** Returns a vector containing all (real) table names and cache tables of + the specified file. + + The index in the returned vector corresponds to the table index used to + access the cache table, e.g. in getCacheTable(). + */ void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector<String>& rTabNames) const; /** diff --git a/sc/inc/filter.hxx b/sc/inc/filter.hxx index 8e3e540c9038..ae0fd92f6858 100644 --- a/sc/inc/filter.hxx +++ b/sc/inc/filter.hxx @@ -39,6 +39,7 @@ class SvStream; class ScAddress; class ScDocument; class ScRange; +class SvNumberFormatter; // Return-Werte Im-/Exportfilter (ULONG) @@ -89,7 +90,9 @@ class ScEEAbsImport { virtual ~ScEEAbsImport() {} virtual ULONG Read( SvStream& rStream, const String& rBaseURL ) = 0; virtual ScRange GetRange() = 0; - virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0 ) = 0; + virtual void WriteToDocument( + BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0, + SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true ) = 0; }; class ScFormatFilterPlugin { @@ -106,7 +109,8 @@ class ScFormatFilterPlugin { virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress& rInsPos, const CharSet eSrc = RTL_TEXTENCODING_DONTKNOW, UINT32 nDifOption = SC_DIFOPT_EXCEL ) = 0; virtual FltError ScImportRTF( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange ) = 0; - virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange, double nOutputFactor = 1.0, BOOL bCalcWidthHeight = TRUE ) = 0; + virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange, double nOutputFactor = 1.0, + BOOL bCalcWidthHeight = TRUE, SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true ) = 0; // various import helpers virtual ScEEAbsImport *CreateRTFImport( ScDocument* pDoc, const ScRange& rRange ) = 0; diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 8bcbd50b0f3c..b85205741334 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -414,6 +414,29 @@ enum ScGetDBMode SC_DB_OLD // nicht neu anlegen }; +/// For ScDBFunc::GetDBData() +enum ScGetDBSelection +{ + /** Keep selection as is, expand to used data area if no selection. */ + SC_DBSEL_KEEP, + + /** Shrink selection to sheet's data area. */ + SC_DBSEL_SHRINK_TO_SHEET_DATA, + + /** Shrink selection to actually used data area within the selection. */ + SC_DBSEL_SHRINK_TO_USED_DATA, + + /** If only one row or portion thereof is selected, shrink row to used data + columns and select further rows down until end of data. If an area is + selected, shrink rows to actually used columns. Else, no selection, + expand to used data area. */ + SC_DBSEL_ROW_DOWN, + + /** Behave as if the range corresponding to a ScDBData area was selected, + for API use. */ + SC_DBSEL_FORCE_MARK +}; + enum ScLkUpdMode { //Verknuepfungen LM_ALWAYS, //immer aktualisieren @@ -758,21 +781,6 @@ enum ScSubTotalFunc }; -#define PIVOT_MAXFUNC 11 -#define PIVOT_FUNC_NONE 0x0000 -#define PIVOT_FUNC_SUM 0x0001 -#define PIVOT_FUNC_COUNT 0x0002 -#define PIVOT_FUNC_AVERAGE 0x0004 -#define PIVOT_FUNC_MAX 0x0008 -#define PIVOT_FUNC_MIN 0x0010 -#define PIVOT_FUNC_PRODUCT 0x0020 -#define PIVOT_FUNC_COUNT_NUM 0x0040 -#define PIVOT_FUNC_STD_DEV 0x0080 -#define PIVOT_FUNC_STD_DEVP 0x0100 -#define PIVOT_FUNC_STD_VAR 0x0200 -#define PIVOT_FUNC_STD_VARP 0x0400 -#define PIVOT_FUNC_AUTO 0x1000 - // ----------------------------------------------------------------------- /* @@ -876,46 +884,6 @@ struct ScConsolidateParam }; // ----------------------------------------------------------------------- - -class ScSimpleSharedString -{ -public: - static const sal_Int32 EMPTY = 0; - - ScSimpleSharedString(); - ScSimpleSharedString(const ScSimpleSharedString& r); - ~ScSimpleSharedString(); - - const String* getString(sal_Int32 nId); - sal_Int32 getStringId(const String& aStr); - sal_Int32 insertString(const String& aStr); - -private: - - /** internal shared string table implementation */ - class StringTable - { - public: - sal_Int32 insertString(const String& aStr); - sal_Int32 getStringId(const String& aStr); - const String* getString(sal_Int32 nId) const; - - StringTable(); - StringTable(const StringTable& r); - ~StringTable(); - - private: - typedef ::std::hash_map< String, sal_Int32, ScStringHashCode, ::std::equal_to< String > > SharedStrMap; - - ::std::vector<String> maSharedStrings; - SharedStrMap maSharedStringIds; - sal_Int32 mnStrCount; - }; - - StringTable maStringTable; -}; - -// ----------------------------------------------------------------------- extern ::utl::TransliterationWrapper* GetScGlobalpTransliteration();//CHINA001 extern const LocaleDataWrapper* GetScGlobalpLocaleData(); diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc index c635877e2ea2..bca93e7aa441 100644 --- a/sc/inc/globstr.hrc +++ b/sc/inc/globstr.hrc @@ -570,7 +570,10 @@ #define STR_STYLE_FAMILY_CELL 433 #define STR_STYLE_FAMILY_PAGE 434 -#define STR_COUNT 435 +#define STR_ERR_DATAPILOTSOURCE 435 +#define STR_PIVOT_FIRSTROWEMPTYERR 436 +#define STR_PIVOT_ONLYONEROWERR 437 +#define STR_COUNT 438 #endif diff --git a/sc/inc/hints.hxx b/sc/inc/hints.hxx index 00791921527d..fca3d184a4a2 100644 --- a/sc/inc/hints.hxx +++ b/sc/inc/hints.hxx @@ -170,4 +170,16 @@ public: const ScImportParam& GetImportParam() const { return aParam; } }; +class ScDataPilotModifiedHint : public SfxHint +{ + String maName; + +public: + TYPEINFO(); + ScDataPilotModifiedHint( const String& rName ); + ~ScDataPilotModifiedHint(); + + const String& GetName() const { return maName; } +}; + #endif diff --git a/sc/inc/optutil.hxx b/sc/inc/optutil.hxx index c197076ee642..83b23a3c9ef9 100644 --- a/sc/inc/optutil.hxx +++ b/sc/inc/optutil.hxx @@ -30,6 +30,7 @@ #include <unotools/configitem.hxx> #include <tools/link.hxx> +#include "scdllapi.h" class ScOptionsUtil @@ -41,13 +42,13 @@ public: // ConfigItem for classes that use items from several sub trees -class ScLinkConfigItem : public utl::ConfigItem +class SC_DLLPUBLIC ScLinkConfigItem : public utl::ConfigItem { Link aCommitLink; public: - ScLinkConfigItem( const rtl::OUString rSubTree ); - ScLinkConfigItem( const rtl::OUString rSubTree, sal_Int16 nMode ); + ScLinkConfigItem( const rtl::OUString& rSubTree ); + ScLinkConfigItem( const rtl::OUString& rSubTree, sal_Int16 nMode ); void SetCommitLink( const Link& rLink ); virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames ); diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index 2a1f17846afd..915a311411c4 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -48,6 +48,7 @@ #include "global.hxx" #include "address.hxx" +#include "dpglobal.hxx" #include <vector> #include <boost/shared_ptr.hpp> diff --git a/sc/inc/rangelst.hxx b/sc/inc/rangelst.hxx index 2350cea085f0..e00fce10da1c 100644 --- a/sc/inc/rangelst.hxx +++ b/sc/inc/rangelst.hxx @@ -40,6 +40,7 @@ class SC_DLLPUBLIC ScRangeList : public ScRangeListBase, public SvRefBase { private: using ScRangeListBase::operator==; + using ScRangeListBase::operator!=; public: ScRangeList() {} @@ -55,16 +56,17 @@ public: USHORT Parse( const String&, ScDocument* = NULL, USHORT nMask = SCA_VALID, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO, - char cDelimiter = 0 ); + sal_Unicode cDelimiter = 0 ); void Format( String&, USHORT nFlags = 0, ScDocument* = NULL, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO, - char cDelimiter = 0 ) const; + sal_Unicode cDelimiter = 0 ) const; void Join( const ScRange&, BOOL bIsInList = FALSE ); BOOL UpdateReference( UpdateRefMode, ScDocument*, const ScRange& rWhere, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ); ScRange* Find( const ScAddress& ) const; BOOL operator==( const ScRangeList& ) const; + BOOL operator!=( const ScRangeList& r ) const; BOOL Intersects( const ScRange& ) const; BOOL In( const ScRange& ) const; ULONG GetCellCount() const; diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index d9bce97f1bc8..a7d05925957a 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -262,6 +262,8 @@ #define HID_SC_RENAME_OBJECT ( HID_SC_TOOLBOX_START + 9 ) +#define HID_SC_REN_AFMT_DLG ( HID_SC_TOOLBOX_START + 10 ) + // Hilfe IDs fuer Submenus (max.50) ------------------------------------------ #define HID_SCMENU_EDIT ( HID_SC_MENU_START ) #define HID_SCMENU_FILL ( HID_SC_MENU_START + 1 ) @@ -1631,9 +1633,10 @@ #define RID_SCDLG_DOCPROTECTION (SC_DIALOGS_START + 149) #define RID_SCDLG_RETYPEPASS (SC_DIALOGS_START + 150) #define RID_SCDLG_RETYPEPASS_INPUT (SC_DIALOGS_START + 151) -#define RID_POPUP_FILTER (SC_DIALOGS_START + 152) +#define RID_SCDLG_TEXT_IMPORT_OPTIONS (SC_DIALOGS_START + 152) +#define RID_POPUP_FILTER (SC_DIALOGS_START + 153) -#define SC_DIALOGS_END (SC_DIALOGS_START + 153) +#define SC_DIALOGS_END (SC_DIALOGS_START + 154) #ifndef STD_MASKCOLOR #define STD_MASKCOLOR Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; } diff --git a/sc/inc/scabstdlg.hxx b/sc/inc/scabstdlg.hxx index f33077b3e090..d3c19bb539d5 100644 --- a/sc/inc/scabstdlg.hxx +++ b/sc/inc/scabstdlg.hxx @@ -38,6 +38,7 @@ #include "sc.hrc" #include "global.hxx" #include "pivot.hxx" +#include "i18npool/lang.h" class ScAsciiOptions; class ScAutoFormat; @@ -65,6 +66,7 @@ class AbstractScImportAsciiDlg : public VclAbstractDialog //add for ScImportAsc public: virtual void GetOptions( ScAsciiOptions& rOpt ) = 0; virtual void SetTextToColumnsMode() = 0; + virtual void SaveParameters() = 0; }; @@ -289,6 +291,14 @@ class AbstractScImportOptionsDlg : public VclAbstractDialog //add for ScImportO public: virtual void GetImportOptions( ScImportOptions& rOptions ) const = 0; }; + +class AbstractScTextImportOptionsDlg : public VclAbstractDialog //add for ScLangChooserDlg +{ +public: + virtual LanguageType GetLanguageType() const = 0; + virtual bool IsDateConversionSet() const = 0; +}; + //-------Scabstract fractory --------------------------- class ScAbstractDialogFactory { @@ -299,6 +309,8 @@ public: SvStream* pInStream, int nId, sal_Unicode cSep = '\t') = 0; + virtual AbstractScTextImportOptionsDlg * CreateScTextImportOptionsDlg( Window* pParent, int nId ) = 0; + virtual AbstractScAutoFormatDlg * CreateScAutoFormatDlg( Window* pParent, //add for ScAutoFormatDlg ScAutoFormat* pAutoFormat, const ScAutoFormatData* pSelFormatData, diff --git a/sc/inc/scimpexpmsg.hxx b/sc/inc/scimpexpmsg.hxx deleted file mode 100644 index 5574edd12083..000000000000 --- a/sc/inc/scimpexpmsg.hxx +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef SC_SCIMPEXPMSG_HXX -#define SC_SCIMPEXPMSG_HXX - - -#include <tools/string.hxx> -#include <tools/solar.h> - -//UNUSED2008-05 enum ScImpExpMsg -//UNUSED2008-05 { -//UNUSED2008-05 SC_IMPEXPMSG_UNKNOWN -//UNUSED2008-05 }; -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 class String; -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 class ScImpExpLogMsg -//UNUSED2008-05 { -//UNUSED2008-05 private: -//UNUSED2008-05 ScImpExpMsg eId; -//UNUSED2008-05 String* pPos; -//UNUSED2008-05 String* pHint; -//UNUSED2008-05 protected: -//UNUSED2008-05 public: -//UNUSED2008-05 ScImpExpLogMsg( ScImpExpMsg eId ); -//UNUSED2008-05 ScImpExpLogMsg( ScImpExpMsg eId, const String& rPosition ); -//UNUSED2008-05 ScImpExpLogMsg( ScImpExpMsg eId, const String& rPosition, const String& rAdditionalHint ); -//UNUSED2008-05 ScImpExpLogMsg( const ScImpExpLogMsg& rCpy ); -//UNUSED2008-05 virtual ~ScImpExpLogMsg(); -//UNUSED2008-05 -//UNUSED2008-05 ScImpExpLogMsg& operator =( const ScImpExpLogMsg& rCpy ); -//UNUSED2008-05 -//UNUSED2008-05 void Set( ScImpExpMsg eId, const String* pPos = NULL, const String* pHint = NULL ); -//UNUSED2008-05 -//UNUSED2008-05 inline ScImpExpMsg GetId( void ) const; -//UNUSED2008-05 inline const String* GetPos( void ) const; -//UNUSED2008-05 inline const String* GetHint( void ) const; -//UNUSED2008-05 -//UNUSED2008-05 static String GetMsg( ScImpExpMsg eId ); -//UNUSED2008-05 inline String GetMsg( void ) const; -//UNUSED2008-05 }; -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 inline ScImpExpLogMsg& ScImpExpLogMsg::operator =( const ScImpExpLogMsg& r ) -//UNUSED2008-05 { -//UNUSED2008-05 Set( r.eId, r.pPos, r.pHint ); -//UNUSED2008-05 return *this; -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 inline ScImpExpMsg ScImpExpLogMsg::GetId( void ) const -//UNUSED2008-05 { -//UNUSED2008-05 return eId; -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 inline const String* ScImpExpLogMsg::GetPos( void ) const -//UNUSED2008-05 { -//UNUSED2008-05 return pPos; -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 inline const String* ScImpExpLogMsg::GetHint( void ) const -//UNUSED2008-05 { -//UNUSED2008-05 return pHint; -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 inline String ScImpExpLogMsg::GetMsg( void ) const -//UNUSED2008-05 { -//UNUSED2008-05 return GetMsg( eId ); -//UNUSED2008-05 } - -#endif - - diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 494ab86b0c74..9857d675b7ab 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -103,6 +103,7 @@ class SC_DLLPUBLIC ScMatrix void ResetIsString(); void DeleteIsString(); void CreateMatrix( SCSIZE nC, SCSIZE nR); + void Clear(); // pStr may be NULL, bFlag MUST NOT be 0 void PutStringEntry( const String* pStr, BYTE bFlag, SCSIZE nIndex ); @@ -175,6 +176,12 @@ public: /** Clone the matrix. */ ScMatrix* Clone() const; + /** + * Resize the matrix to specified new dimension. Note that this operation + * clears all stored values. + */ + void Resize( SCSIZE nC, SCSIZE nR); + /** Clone the matrix and extend it to the new size. nNewCols and nNewRows MUST be at least of the size of the original matrix. */ ScMatrix* CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows ) const; diff --git a/sc/source/core/data/pivot.cxx b/sc/inc/stringutil.hxx index e63b228de703..c50c0d8cf156 100644 --- a/sc/source/core/data/pivot.cxx +++ b/sc/inc/stringutil.hxx @@ -2,10 +2,13 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * + * $RCSfile: table.hxx,v $ + * $Revision: 1.35 $ + * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -25,10 +28,29 @@ * ************************************************************************/ -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_sc.hxx" +#ifndef SC_STRINGUTIL_HXX +#define SC_STRINGUTIL_HXX +#include "rtl/ustring.hxx" +class ScStringUtil +{ +public: + /** + * Check if a given string is a simple decimal number (e.g. 12.345). We + * don't do any elaborate parsing here; we only check for the simplest + * case of decimal number format. + * + * @param rStr string to parse + * @param dsep decimal separator + * @param gsep group separator (aka thousands separator) + * @param rVal value of successfully parsed number + * + * @return true if the string is a valid number, false otherwise. + */ + static bool parseSimpleNumber( + const ::rtl::OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal); +}; -// ----------------------------------------------------------------------- +#endif diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 46e8f133c274..2e2d3c772486 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -265,7 +265,8 @@ public: void PutCell( SCCOL nCol, SCROW nRow, ScBaseCell* pCell ); void PutCell(SCCOL nCol, SCROW nRow, ULONG nFormatIndex, ScBaseCell* pCell); // TRUE = Zahlformat gesetzt - BOOL SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString ); + BOOL SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, + SvNumberFormatter* pFormatter = NULL, bool bDetectNumberFormat = true ); void SetValue( SCCOL nCol, SCROW nRow, const double& rVal ); void SetError( SCCOL nCol, SCROW nRow, USHORT nError); @@ -379,7 +380,9 @@ public: SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow ); void GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, - BOOL bIncludeOld ) const; + BOOL bIncludeOld, bool bOnlyDown ) const; + + bool ShrinkToUsedDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const; SCSIZE GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ); @@ -420,11 +423,11 @@ public: void UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz, - ScDocument* pUndoDoc = NULL, BOOL bIncludeDraw = TRUE ); + ScDocument* pUndoDoc = NULL, BOOL bIncludeDraw = TRUE, bool bUpdateNoteCaptionPos = true ); void UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, - SCsCOL nDx, SCsROW nDy, SCsTAB nDz ); + SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bUpdateNoteCaptionPos = true ); void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest, ScDocument* pUndoDoc ); @@ -467,7 +470,7 @@ public: const SvxBorderLine** ppRight, const SvxBorderLine** ppBottom ) const; //UNUSED2009-05 BOOL HasLines( const ScRange& rRange, Rectangle& rSizes ) const; - BOOL HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const; + bool HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const; BOOL HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const; BOOL ExtendMerge( SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW& rEndRow, @@ -658,8 +661,8 @@ public: void FindConditionalFormat( ULONG nKey, ScRangeList& rRanges ); - void IncRecalcLevel() { ++nRecalcLvl; } - void DecRecalcLevel() { if (!--nRecalcLvl) SetDrawPageSize(); } + void IncRecalcLevel() { ++nRecalcLvl; } + void DecRecalcLevel( bool bUpdateNoteCaptionPos = true ) { if (!--nRecalcLvl) SetDrawPageSize(true, bUpdateNoteCaptionPos); } BOOL IsSortCollatorGlobal() const; void InitSortCollator( const ScSortParam& rPar ); @@ -733,7 +736,7 @@ private: BOOL GetNextSpellingCell(SCCOL& rCol, SCROW& rRow, BOOL bInSel, const ScMarkData& rMark) const; BOOL GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ); - void SetDrawPageSize(bool bResetStreamValid = true); + void SetDrawPageSize( bool bResetStreamValid = true, bool bUpdateNoteCaptionPos = true ); BOOL TestTabRefAbs(SCTAB nTable); void CompileDBFormula(); void CompileDBFormula( BOOL bCreateFormulaString ); diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index 84e5c4b11cb1..f5de35c9d033 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -574,6 +574,15 @@ #define SC_UNO_RPTEMPTY "RepeatIfEmpty" #define SC_UNO_DRILLDOWN "DrillDownOnDoubleClick" #define SC_UNO_SHOWFILT "ShowFilterButton" +#define SC_UNO_IMPORTDESC "ImportDescriptor" +#define SC_UNO_SOURCESERV "SourceServiceName" +#define SC_UNO_SERVICEARG "ServiceArguments" + +// properties in data pilot descriptor ServiceArguments +#define SC_UNO_SOURCENAME "SourceName" +#define SC_UNO_OBJECTNAME "ObjectName" +#define SC_UNO_USERNAME "UserName" +#define SC_UNO_PASSWORD "Password" // range selection #define SC_UNONAME_INITVAL "InitialValue" diff --git a/sc/prj/build.lst b/sc/prj/build.lst index 115e92990f3c..e32d8938afc4 100755 --- a/sc/prj/build.lst +++ b/sc/prj/build.lst @@ -48,3 +48,4 @@ sc sc\addin\datefunc nmake - all sc_addfu sc_add sc_sdi sc_inc NULL sc sc\addin\rot13 nmake - all sc_adrot sc_add sc_sdi sc_inc NULL sc sc\addin\util nmake - all sc_adutil sc_addfu sc_adrot sc_sdi sc_inc NULL sc sc\util nmake - all sc_util sc_addfu sc_adrot sc_adutil sc_app sc_attr sc_cctrl sc_cosrc sc_data sc_dbgui sc_dif sc_docsh sc_drfnc sc_excel sc_form sc_html sc_lotus sc_qpro sc_misc sc_name sc_nvipi sc_opt sc_page sc_rtf sc_scalc sc_style sc_tool sc_uisrc sc_undo sc_unobj sc_view sc_xcl97 sc_xml sc_acc sc_ftools sc_inc sc_vba NULL +sc sc\qa\unoapi nmake - all sc_qa_unoapi NULL diff --git a/sc/qa/unoapi/Test.java b/sc/qa/unoapi/Test.java new file mode 100644 index 000000000000..27d048b8bf51 --- /dev/null +++ b/sc/qa/unoapi/Test.java @@ -0,0 +1,51 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +package org.openoffice.sc.qa.unoapi; + +import org.openoffice.Runner; +import org.openoffice.test.OfficeConnection; +import static org.junit.Assert.*; + +public final class Test { + @org.junit.Before public void setUp() throws Exception { + connection.setUp(); + } + + @org.junit.After public void tearDown() + throws InterruptedException, com.sun.star.uno.Exception + { + connection.tearDown(); + } + + @org.junit.Test public void test() { + assertTrue( + Runner.run( + "-sce", "sc.sce", "-xcl", "knownissues.xcl", "-tdoc", + "testdocuments", "-cs", connection.getDescription())); + } + + private final OfficeConnection connection = new OfficeConnection(); +} diff --git a/sc/qa/unoapi/knownissues.xcl b/sc/qa/unoapi/knownissues.xcl index d84379c1ac5b..e6863cd75cab 100644 --- a/sc/qa/unoapi/knownissues.xcl +++ b/sc/qa/unoapi/knownissues.xcl @@ -164,4 +164,30 @@ sc.ScAccessibleCsvGrid ### i91045 ### sc.ScAccessibleDocumentPagePreview -#-> disabled in sc.sce
\ No newline at end of file +#-> disabled in sc.sce + +### i109517 ### +sc.AccessibleEditableTextPara_PreviewCell::com::sun::star::accessibility::XAccessibleComponent +sc.ScAccessiblePageHeaderArea::com::sun::star::accessibility::XAccessibleEventBroadcaster +sc.ScAnnotationObj::com::sun::star::sheet::XSheetAnnotation +sc.ScAnnotationObj::com::sun::star::text::XSimpleText +sc.ScAnnotationObj::com::sun::star::text::XTextRange +sc.ScAnnotationShapeObj::com::sun::star::beans::XPropertySet +sc.ScAnnotationShapeObj::com::sun::star::drawing::CaptionShape +sc.ScAnnotationShapeObj::com::sun::star::drawing::LineProperties +sc.ScAnnotationShapeObj::com::sun::star::drawing::RotationDescriptor +sc.ScAnnotationShapeObj::com::sun::star::drawing::ShadowProperties +sc.ScAnnotationShapeObj::com::sun::star::drawing::Shape +sc.ScAnnotationShapeObj::com::sun::star::drawing::XShape +sc.ScAnnotationShapeObj::com::sun::star::drawing::XShapeDescriptor +sc.ScAnnotationShapeObj::com::sun::star::lang::XComponent +sc.ScAnnotationShapeObj::com::sun::star::style::CharacterProperties +sc.ScAnnotationShapeObj::com::sun::star::style::CharacterPropertiesAsian +sc.ScAnnotationShapeObj::com::sun::star::style::CharacterPropertiesComplex +sc.ScAnnotationShapeObj::com::sun::star::style::ParagraphPropertiesAsian +sc.ScAnnotationShapeObj::com::sun::star::style::ParagraphPropertiesComplex +sc.ScAnnotationShapeObj::com::sun::star::text::XSimpleText +sc.ScAnnotationShapeObj::com::sun::star::text::XTextRange +sc.ScAnnotationsObj::com::sun::star::container::XElementAccess +sc.ScCellObj::com::sun::star::sheet::XSheetAnnotationAnchor +sc.ScDataPilotFieldObj::com::sun::star::sheet::XDataPilotFieldGrouping diff --git a/sc/qa/unoapi/makefile.mk b/sc/qa/unoapi/makefile.mk index b5506881fb2a..a4781282a0b3 100644 --- a/sc/qa/unoapi/makefile.mk +++ b/sc/qa/unoapi/makefile.mk @@ -1,7 +1,6 @@ #************************************************************************* -# # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# +# # Copyright 2000, 2010 Oracle and/or its affiliates. # # OpenOffice.org - a multi-platform office productivity suite @@ -22,19 +21,28 @@ # version 3 along with OpenOffice.org. If not, see # <http://www.openoffice.org/license.html> # for a copy of the LGPLv3 License. -# -#************************************************************************* +#***********************************************************************/ -PRJ=..$/.. +.IF "$(OOO_SUBSEQUENT_TESTS)" == "" +nothing .PHONY: +.ELSE -PRJNAME=sc -TARGET=qa_unoapi +PRJ = ../.. +PRJNAME = sc +TARGET = qa_unoapi -.INCLUDE: settings.mk +.IF "$(OOO_JUNIT_JAR)" != "" +PACKAGE = org/openoffice/sc/qa/unoapi +JAVATESTFILES = Test.java +JAVAFILES = $(JAVATESTFILES) +JARFILES = OOoRunner.jar ridl.jar test.jar +EXTRAJARFILES = $(OOO_JUNIT_JAR) +.END +.INCLUDE: settings.mk .INCLUDE: target.mk +.INCLUDE: installationtest.mk -ALLTAR : UNOAPI_TEST +ALLTAR : javatest -UNOAPI_TEST: - +$(SOLARENV)$/bin$/checkapi -sce sc.sce -xcl knownissues.xcl -tdoc $(PWD)$/testdocuments +.END diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index 67be752fd8c8..53df13b4cd62 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -1228,13 +1228,13 @@ BOOL ScAttrArray::HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes, // Testen, ob Bereich bestimmtes Attribut enthaelt -BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const +bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const { SCSIZE nStartIndex; SCSIZE nEndIndex; Search( nRow1, nStartIndex ); Search( nRow2, nEndIndex ); - BOOL bFound = FALSE; + bool bFound = false; for (SCSIZE i=nStartIndex; i<=nEndIndex && !bFound; i++) { @@ -1244,46 +1244,46 @@ BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const const ScMergeAttr* pMerge = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE ); if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 ) - bFound = TRUE; + bFound = true; } if ( nMask & ( HASATTR_OVERLAPPED | HASATTR_NOTOVERLAPPED | HASATTR_AUTOFILTER ) ) { const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem( ATTR_MERGE_FLAG ); if ( (nMask & HASATTR_OVERLAPPED) && pMergeFlag->IsOverlapped() ) - bFound = TRUE; + bFound = true; if ( (nMask & HASATTR_NOTOVERLAPPED) && !pMergeFlag->IsOverlapped() ) - bFound = TRUE; + bFound = true; if ( (nMask & HASATTR_AUTOFILTER) && pMergeFlag->HasAutoFilter() ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_LINES ) { const SvxBoxItem* pBox = (const SvxBoxItem*) &pPattern->GetItem( ATTR_BORDER ); if ( pBox->GetLeft() || pBox->GetRight() || pBox->GetTop() || pBox->GetBottom() ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_SHADOW ) { const SvxShadowItem* pShadow = (const SvxShadowItem*) &pPattern->GetItem( ATTR_SHADOW ); if ( pShadow->GetLocation() != SVX_SHADOW_NONE ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_CONDITIONAL ) { const SfxUInt32Item* pConditional = (const SfxUInt32Item*) &pPattern->GetItem( ATTR_CONDITIONAL ); if ( pConditional->GetValue() != 0 ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_PROTECTED ) { const ScProtectionAttr* pProtect = (const ScProtectionAttr*) &pPattern->GetItem( ATTR_PROTECTION ); if ( pProtect->GetProtection() || pProtect->GetHideCell() ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_ROTATE ) { @@ -1293,21 +1293,21 @@ BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const // (see ScPatternAttr::GetCellOrientation) INT32 nAngle = pRotate->GetValue(); if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_NEEDHEIGHT ) { if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD) - bFound = TRUE; + bFound = true; else if (((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK )).GetValue()) - bFound = TRUE; + bFound = true; else if ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern-> GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK) - bFound = TRUE; + bFound = true; else if (((const SfxUInt32Item&)pPattern->GetItem( ATTR_CONDITIONAL )).GetValue()) - bFound = TRUE; + bFound = true; else if (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE )).GetValue()) - bFound = TRUE; + bFound = true; } if ( nMask & ( HASATTR_SHADOW_RIGHT | HASATTR_SHADOW_DOWN ) ) { @@ -1316,17 +1316,17 @@ BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const SvxShadowLocation eLoc = pShadow->GetLocation(); if ( nMask & HASATTR_SHADOW_RIGHT ) if ( eLoc == SVX_SHADOW_TOPRIGHT || eLoc == SVX_SHADOW_BOTTOMRIGHT ) - bFound = TRUE; + bFound = true; if ( nMask & HASATTR_SHADOW_DOWN ) if ( eLoc == SVX_SHADOW_BOTTOMLEFT || eLoc == SVX_SHADOW_BOTTOMRIGHT ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_RTL ) { const SvxFrameDirectionItem& rDirection = (const SvxFrameDirectionItem&) pPattern->GetItem( ATTR_WRITINGDIR ); if ( rDirection.GetValue() == FRMDIR_HORI_RIGHT_TOP ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_RIGHTORCENTER ) { @@ -1334,7 +1334,7 @@ BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const SvxCellHorJustify eHorJust = (SvxCellHorJustify) ((const SvxHorJustifyItem&) pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue(); if ( eHorJust == SVX_HOR_JUSTIFY_RIGHT || eHorJust == SVX_HOR_JUSTIFY_CENTER ) - bFound = TRUE; + bFound = true; } } diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index d68994354af4..6a5fe824197b 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -244,7 +244,7 @@ BOOL ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark) const //UNUSED2009-05 } -BOOL ScColumn::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const +bool ScColumn::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const { return pAttrArray->HasAttrib( nRow1, nRow2, nMask ); } diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 30081a6bf402..dc206950b3ea 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -51,6 +51,13 @@ #include "markdata.hxx" #include "detfunc.hxx" // fuer Notizen bei DeleteRange #include "postit.hxx" +#include "stringutil.hxx" + +#include <com/sun/star/i18n/LocaleDataItem.hpp> + +using ::com::sun::star::i18n::LocaleDataItem; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; // Err527 Workaround extern const ScFormulaCell* pLastFormulaTreeTop; // in cellform.cxx @@ -1241,7 +1248,8 @@ void ScColumn::StartListeningInArea( SCROW nRow1, SCROW nRow2 ) // TRUE = Zahlformat gesetzt BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, - formula::FormulaGrammar::AddressConvention eConv ) + formula::FormulaGrammar::AddressConvention eConv, + SvNumberFormatter* pFormatter, bool bDetectNumberFormat ) { BOOL bNumFmtSet = FALSE; if (VALIDROW(nRow)) @@ -1253,7 +1261,8 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, double nVal; sal_uInt32 nIndex, nOldIndex = 0; sal_Unicode cFirstChar; - SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); + if (!pFormatter) + pFormatter = pDocument->GetFormatTable(); SfxObjectShell* pDocSh = pDocument->GetDocumentShell(); if ( pDocSh ) bIsLoading = pDocSh->IsLoading(); @@ -1320,46 +1329,78 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, if ( !bIsText ) nIndex = nOldIndex = pFormatter->GetStandardIndex(); } - if ( !bIsText && - pFormatter->IsNumberFormat(rString, nIndex, nVal) ) - { // Zahl - pNewCell = new ScValueCell( nVal ); - if ( nIndex != nOldIndex) + + do + { + if (bIsText) + break; + + if (bDetectNumberFormat) { - // #i22345# New behavior: Apply the detected number format only if - // the old one was the default number, date, time or boolean format. - // Exception: If the new format is boolean, always apply it. + if (!pFormatter->IsNumberFormat(rString, nIndex, nVal)) + break; - BOOL bOverwrite = FALSE; - const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex ); - if ( pOldFormat ) + pNewCell = new ScValueCell( nVal ); + if ( nIndex != nOldIndex) { - short nOldType = pOldFormat->GetType() & ~NUMBERFORMAT_DEFINED; - if ( nOldType == NUMBERFORMAT_NUMBER || nOldType == NUMBERFORMAT_DATE || - nOldType == NUMBERFORMAT_TIME || nOldType == NUMBERFORMAT_LOGICAL ) + // #i22345# New behavior: Apply the detected number format only if + // the old one was the default number, date, time or boolean format. + // Exception: If the new format is boolean, always apply it. + + BOOL bOverwrite = FALSE; + const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex ); + if ( pOldFormat ) { - if ( nOldIndex == pFormatter->GetStandardFormat( - nOldType, pOldFormat->GetLanguage() ) ) + short nOldType = pOldFormat->GetType() & ~NUMBERFORMAT_DEFINED; + if ( nOldType == NUMBERFORMAT_NUMBER || nOldType == NUMBERFORMAT_DATE || + nOldType == NUMBERFORMAT_TIME || nOldType == NUMBERFORMAT_LOGICAL ) { - bOverwrite = TRUE; // default of these types can be overwritten + if ( nOldIndex == pFormatter->GetStandardFormat( + nOldType, pOldFormat->GetLanguage() ) ) + { + bOverwrite = TRUE; // default of these types can be overwritten + } } } - } - if ( !bOverwrite && pFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL ) - { - bOverwrite = TRUE; // overwrite anything if boolean was detected - } + if ( !bOverwrite && pFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL ) + { + bOverwrite = TRUE; // overwrite anything if boolean was detected + } - if ( bOverwrite ) - { - ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT, - (UINT32) nIndex) ); - bNumFmtSet = TRUE; + if ( bOverwrite ) + { + ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT, + (UINT32) nIndex) ); + bNumFmtSet = TRUE; + } } } + else + { + // Only check if the string is a regular number. + const LocaleDataWrapper* pLocale = pFormatter->GetLocaleData(); + if (!pLocale) + break; + + LocaleDataItem aLocaleItem = pLocale->getLocaleItem(); + const OUString& rDecSep = aLocaleItem.decimalSeparator; + const OUString& rGroupSep = aLocaleItem.thousandSeparator; + if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1) + break; + + sal_Unicode dsep = rDecSep.getStr()[0]; + sal_Unicode gsep = rGroupSep.getStr()[0]; + + if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, nVal)) + break; + + pNewCell = new ScValueCell(nVal); + } } - else // Text - pNewCell = new ScStringCell( rString ); + while (false); + + if (!pNewCell) + pNewCell = new ScStringCell(rString); } } diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index b68ad36364f3..706783579a24 100755..100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -591,7 +591,11 @@ bool ScDBQueryDataIterator::DataAccessInternal::getCurrent(Value& rValue) if (ScDBQueryDataIterator::IsQueryValid(*mpDoc, *mpParam, nTab, nRow, pCell)) { - switch (pCell->GetCellType()) + // #i109812# get cell here if it wasn't done above + if (nCol != static_cast<SCCOL>(nFirstQueryField)) + pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow); + + switch (pCell ? pCell->GetCellType() : CELLTYPE_NONE) { case CELLTYPE_VALUE: { diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 683f5ea55eb6..f04204c85aaf 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -75,6 +75,11 @@ #include "drwlayer.hxx" #include "unoreflist.hxx" #include "listenercalls.hxx" +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpshttab.hxx" +#include "dptablecache.hxx" +// End Comments #include "tabprotection.hxx" #include "formulaparserpool.hxx" #include "clipparam.hxx" @@ -777,7 +782,8 @@ void ScDocument::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz, - ScDocument* pUndoDoc, BOOL bIncludeDraw ) + ScDocument* pUndoDoc, BOOL bIncludeDraw, + bool bUpdateNoteCaptionPos ) { PutInOrder( nCol1, nCol2 ); PutInOrder( nRow1, nRow2 ); @@ -821,7 +827,7 @@ void ScDocument::UpdateReference( UpdateRefMode eUpdateRefMode, if (pTab[i]) pTab[i]->UpdateReference( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, - nDx, nDy, nDz, pUndoDoc, bIncludeDraw ); + nDx, nDy, nDz, pUndoDoc, bIncludeDraw, bUpdateNoteCaptionPos ); if ( bIsEmbedded ) { @@ -1892,12 +1898,125 @@ void ScDocument::IncSizeRecalcLevel( SCTAB nTab ) pTab[nTab]->IncRecalcLevel(); } -void ScDocument::DecSizeRecalcLevel( SCTAB nTab ) +void ScDocument::DecSizeRecalcLevel( SCTAB nTab, bool bUpdateNoteCaptionPos ) { if ( ValidTab(nTab) && pTab[nTab] ) - pTab[nTab]->DecRecalcLevel(); + pTab[nTab]->DecRecalcLevel( bUpdateNoteCaptionPos ); } +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +ScDPTableDataCache* ScDocument::GetDPObjectCache( long nID ) +{ + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { // + if ( nID == (*iter)->GetId() ) + return *iter; + } + return NULL; +} + +ScDPTableDataCache* ScDocument::GetUsedDPObjectCache ( ScRange rRange ) +{ + ScDPTableDataCache* pCache = NULL; + USHORT nCount = GetDPCollection()->GetCount(); + for ( short i=nCount-1; i>=0 ; i--) + { + if ( const ScSheetSourceDesc* pUsedSheetDesc = (*pDPCollection)[i]->GetSheetDesc() ) + if ( rRange == pUsedSheetDesc->aSourceRange ) + { + long nID = (*pDPCollection)[i]->GetCacheId(); + if ( nID >= 0 ) + pCache= GetDPObjectCache( nID ); + if ( pCache ) + return pCache; + } + } + return pCache; +} +long ScDocument::AddDPObjectCache( ScDPTableDataCache* pData ) +{ + if ( pData->GetId() < 0 ) + { //create a id for it + pData->SetId( GetNewDPObjectCacheId() ); + } + m_listDPObjectsCaches.push_back( pData ); + return pData->GetId(); +} +long ScDocument::GetNewDPObjectCacheId() +{ + long nID = 0; + bool bFound = false; + std::list<ScDPTableDataCache*>::iterator iter; + do { + for ( iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { //Get a new Id + if ( nID == (*iter)->GetId() ) + { + nID++; + bFound = true; + break; + } + } + if ( iter == m_listDPObjectsCaches.end() ) + bFound = false; + } while ( bFound ); + + return nID; +} + +void ScDocument::RemoveDPObjectCache( long nID ) +{ + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { + if ( nID == (*iter)->GetId() ) + { + ScDPTableDataCache* pCache = *iter; + m_listDPObjectsCaches.erase( iter ); + delete pCache; + break; + } + } + +} + +void ScDocument::RemoveUnusedDPObjectCaches() +{ + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { + long nID = (*iter)->GetId(); + USHORT nCount = GetDPCollection()->GetCount(); + USHORT i ; + for ( i=0; i<nCount; i++) + { + if ( nID == (*pDPCollection)[i]->GetCacheId() ) + break; + } + if ( i == nCount ) + { + ScDPTableDataCache* pCache = *iter; + m_listDPObjectsCaches.erase( iter ); + delete pCache; + continue; + } + } +} + +void ScDocument::GetUsedDPObjectCache( std::list<ScDPTableDataCache*>& usedlist ) +{ + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { + long nID = (*iter)->GetId(); + USHORT nCount = GetDPCollection()->GetCount(); + USHORT i=0; + for ( i=0; i<nCount; i++) + if ( nID == (*pDPCollection)[i]->GetCacheId() ) + break; + if ( i != nCount ) + usedlist.push_back( *iter ); + } +} +// End Comments diff --git a/sc/source/core/data/documen5.cxx b/sc/source/core/data/documen5.cxx index 643c0885a46f..d86d174ab414 100644 --- a/sc/source/core/data/documen5.cxx +++ b/sc/source/core/data/documen5.cxx @@ -64,107 +64,12 @@ #include "miscuno.hxx" #include "chart2uno.hxx" +#include "charthelper.hxx" using namespace ::com::sun::star; // ----------------------------------------------------------------------- -void lcl_GetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, - uno::Sequence< rtl::OUString >& rRanges ) -{ - rRanges.realloc(0); - uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); - if( !xDataSource.is() ) - return; - //uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); - - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); - rRanges.realloc(2*aLabeledDataSequences.getLength()); - sal_Int32 nRealCount=0; - for( sal_Int32 nN=0;nN<aLabeledDataSequences.getLength();nN++) - { - uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); - if(!xLabeledSequence.is()) - continue; - uno::Reference< chart2::data::XDataSequence > xLabel( xLabeledSequence->getLabel()); - uno::Reference< chart2::data::XDataSequence > xValues( xLabeledSequence->getValues()); - - if( xLabel.is()) - rRanges[nRealCount++] = xLabel->getSourceRangeRepresentation(); - if( xValues.is()) - rRanges[nRealCount++] = xValues->getSourceRangeRepresentation(); - } - rRanges.realloc(nRealCount); -} - -void lcl_SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, - const uno::Sequence< rtl::OUString >& rRanges ) -{ - uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); - if( !xDataSource.is() ) - return; - uno::Reference< chart2::data::XDataProvider > xDataProvider = xChartDoc->getDataProvider(); - if( !xDataProvider.is() ) - return; - - uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY ); - if( xModel.is() ) - xModel->lockControllers(); - - try - { - rtl::OUString aPropertyNameRole( ::rtl::OUString::createFromAscii("Role") ); - - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); - sal_Int32 nRange=0; - for( sal_Int32 nN=0; (nN<aLabeledDataSequences.getLength()) && (nRange<rRanges.getLength()); nN++ ) - { - uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); - if(!xLabeledSequence.is()) - continue; - uno::Reference< beans::XPropertySet > xLabel( xLabeledSequence->getLabel(), uno::UNO_QUERY ); - uno::Reference< beans::XPropertySet > xValues( xLabeledSequence->getValues(), uno::UNO_QUERY ); - - if( xLabel.is()) - { - // the range string must be in Calc A1 format. - uno::Reference< chart2::data::XDataSequence > xNewSeq( - xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); - - uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); - if( xNewProps.is() ) - xNewProps->setPropertyValue( aPropertyNameRole, xLabel->getPropertyValue( aPropertyNameRole ) ); - - xLabeledSequence->setLabel( xNewSeq ); - } - - if( !(nRange<rRanges.getLength()) ) - break; - - if( xValues.is()) - { - // the range string must be in Calc A1 format. - uno::Reference< chart2::data::XDataSequence > xNewSeq( - xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); - - uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); - if( xNewProps.is() ) - xNewProps->setPropertyValue( aPropertyNameRole, xValues->getPropertyValue( aPropertyNameRole ) ); - - xLabeledSequence->setValues( xNewSeq ); - } - } - } - catch ( uno::Exception& ex ) - { - (void)ex; - DBG_ERROR("Exception in lcl_SetChartRanges - invalid range string?"); - } - - if( xModel.is() ) - xModel->unlockControllers(); -} - void lcl_GetChartParameters( const uno::Reference< chart2::XChartDocument >& xChartDoc, rtl::OUString& rRanges, chart::ChartDataRowSource& rDataRowSource, bool& rHasCategories, bool& rFirstCellAsLabel ) @@ -363,14 +268,7 @@ uno::Reference< chart2::XChartDocument > ScDocument::GetChartByName( const Strin if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) - { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); - xReturn.set( uno::Reference< chart2::XChartDocument >( xComponent, uno::UNO_QUERY ) ); - } + xReturn.set( ScChartHelper::GetChartFromSdrObject( pObject ) ); return xReturn; } pObject = aIter.Next(); @@ -386,7 +284,7 @@ void ScDocument::GetChartRanges( const String& rChartName, ::std::vector< ScRang if ( xChartDoc.is() ) { uno::Sequence< rtl::OUString > aRangeStrings; - lcl_GetChartRanges( xChartDoc, aRangeStrings ); + ScChartHelper::GetChartRanges( xChartDoc, aRangeStrings ); for( sal_Int32 nN=0; nN<aRangeStrings.getLength(); nN++ ) { ScRangeList aRanges; @@ -410,7 +308,7 @@ void ScDocument::SetChartRanges( const String& rChartName, const ::std::vector< aScRangeList.Format( sRangeStr, SCR_ABS_3D, this ); aRangeStrings[nN]=sRangeStr; } - lcl_SetChartRanges( xChartDoc, aRangeStrings ); + ScChartHelper::SetChartRanges( xChartDoc, aRangeStrings ); } } @@ -435,32 +333,25 @@ void ScDocument::GetOldChartParameters( const String& rName, if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->GetPersistName() == rName ) { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) + uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) ); + if ( xChartDoc.is() ) { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); - uno::Reference< chart2::XChartDocument > xChartDoc( xComponent, uno::UNO_QUERY ); - if ( xChartDoc.is() ) + chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; + bool bHasCategories = false; + bool bFirstCellAsLabel = false; + rtl::OUString aRangesStr; + lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + + rRanges.Parse( aRangesStr, this ); + if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS ) { - chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; - bool bHasCategories = false; - bool bFirstCellAsLabel = false; - rtl::OUString aRangesStr; - lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - - rRanges.Parse( aRangesStr, this ); - if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS ) - { - rRowHeaders = bHasCategories; - rColHeaders = bFirstCellAsLabel; - } - else - { - rColHeaders = bHasCategories; - rRowHeaders = bFirstCellAsLabel; - } + rRowHeaders = bHasCategories; + rColHeaders = bFirstCellAsLabel; + } + else + { + rColHeaders = bHasCategories; + rRowHeaders = bFirstCellAsLabel; } } return; @@ -489,75 +380,68 @@ void ScDocument::UpdateChartArea( const String& rChartName, if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) + uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) ); + uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); + if ( xChartDoc.is() && xReceiver.is() ) { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); + ScRangeListRef aNewRanges; + chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; + bool bHasCategories = false; + bool bFirstCellAsLabel = false; + rtl::OUString aRangesStr; + lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); - uno::Reference< chart2::XChartDocument > xChartDoc( xComponent, uno::UNO_QUERY ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xComponent, uno::UNO_QUERY ); - if ( xChartDoc.is() && xReceiver.is() ) - { - ScRangeListRef aNewRanges; - chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; - bool bHasCategories = false; - bool bFirstCellAsLabel = false; - rtl::OUString aRangesStr; - lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + sal_Bool bInternalData = xChartDoc->hasInternalDataProvider(); - sal_Bool bInternalData = xChartDoc->hasInternalDataProvider(); + if ( bAdd && !bInternalData ) + { + // append to old ranges, keep other settings - if ( bAdd && !bInternalData ) - { - // append to old ranges, keep other settings + aNewRanges = new ScRangeList; + aNewRanges->Parse( aRangesStr, this ); - aNewRanges = new ScRangeList; - aNewRanges->Parse( aRangesStr, this ); + ULONG nAddCount = rNewList->Count(); + for ( ULONG nAdd=0; nAdd<nAddCount; nAdd++ ) + aNewRanges->Append( *rNewList->GetObject(nAdd) ); + } + else + { + // directly use new ranges (only eDataRowSource is used from old settings) - ULONG nAddCount = rNewList->Count(); - for ( ULONG nAdd=0; nAdd<nAddCount; nAdd++ ) - aNewRanges->Append( *rNewList->GetObject(nAdd) ); + if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS ) + { + bHasCategories = bRowHeaders; + bFirstCellAsLabel = bColHeaders; } else { - // directly use new ranges (only eDataRowSource is used from old settings) - - if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS ) - { - bHasCategories = bRowHeaders; - bFirstCellAsLabel = bColHeaders; - } - else - { - bHasCategories = bColHeaders; - bFirstCellAsLabel = bRowHeaders; - } - aNewRanges = rNewList; + bHasCategories = bColHeaders; + bFirstCellAsLabel = bRowHeaders; } + aNewRanges = rNewList; + } - if ( bInternalData && pShell ) - { - // Calc -> DataProvider - uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( this ); - xReceiver->attachDataProvider( xDataProvider ); - uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( - pShell->GetModel(), uno::UNO_QUERY ); - xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); - } + if ( bInternalData && pShell ) + { + // Calc -> DataProvider + uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( this ); + xReceiver->attachDataProvider( xDataProvider ); + uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( + pShell->GetModel(), uno::UNO_QUERY ); + xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); + } - String sRangeStr; - aNewRanges->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() ); + String sRangeStr; + aNewRanges->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() ); - lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - pChartListenerCollection->ChangeListening( rChartName, aNewRanges ); + pChartListenerCollection->ChangeListening( rChartName, aNewRanges ); - // ((SdrOle2Obj*)pObject)->GetNewReplacement(); - // pObject->ActionChanged(); + // ((SdrOle2Obj*)pObject)->GetNewReplacement(); + // pObject->ActionChanged(); - return; // nicht weitersuchen - } + return; // nicht weitersuchen } } pObject = aIter.Next(); @@ -569,124 +453,25 @@ void ScDocument::UpdateChart( const String& rChartName ) { if (!pDrawLayer || bInDtorClear) return; - - for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++) + uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) ); + if( xChartDoc.is() ) { - SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); - DBG_ASSERT(pPage,"Page ?"); - - SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); - SdrObject* pObject = aIter.Next(); - while (pObject) + try + { + uno::Reference< util::XModifiable > xModif( xChartDoc, uno::UNO_QUERY_THROW ); + if( apTemporaryChartLock.get() ) + apTemporaryChartLock->AlsoLockThisChart( uno::Reference< frame::XModel >( xModif, uno::UNO_QUERY ) ); + xModif->setModified( sal_True ); + } + catch ( uno::Exception& ) { - if ( pObject->GetObjIdentifier() == OBJ_OLE2 && - ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) - { - //@todo?: maybe we need a notification - //from the calc to the chart in future - //that calc content has changed - // ((SdrOle2Obj*)pObject)->GetNewReplacement(); - - // Load the object and set modified - - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) - { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - try - { - uno::Reference< util::XModifiable > xModif( xIPObj->getComponent(), uno::UNO_QUERY_THROW ); - if( apTemporaryChartLock.get() ) - apTemporaryChartLock->AlsoLockThisChart( uno::Reference< frame::XModel >( xModif, uno::UNO_QUERY ) ); - xModif->setModified( sal_True ); - } - catch ( uno::Exception& ) - { - } - } - - // repaint - - pObject->ActionChanged(); - - // After the update, chart keeps track of its own data source ranges, - // the listener doesn't need to listen anymore. - - pChartListenerCollection->ChangeListening( rChartName, new ScRangeList ); - - return; - - /* old chart: - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) - { - const SchMemChart* pChartData = SchDLL::GetChartData(xIPObj); - if ( pChartData ) - { - ScChartArray aArray( this, *pChartData ); - - SchMemChart* pMemChart = aArray.CreateMemChart(); - ScChartArray::CopySettings( *pMemChart, *pChartData ); - - // #57655# Chart-Update ohne geaenderte Einstellungen (MemChart) - // soll das Dokument nicht auf modified setzen (z.B. in frisch - // geladenem Dokument durch initiales Recalc) - - // #72576# disable SetModified for readonly documents only - - sal_Bool bEnabled = ( (pShell && pShell->IsReadOnly()) || IsImportingXML() ); - sal_Bool bModified = sal_False; - uno::Reference< util::XModifiable > xModif; - - if ( bEnabled ) - { - try - { - xModif = - uno::Reference< util::XModifiable >( xIPObj->getComponent(), uno::UNO_QUERY_THROW ); - bModified = xModif->isModified(); - } - catch( uno::Exception& ) - { - bEnabled = sal_False; - } - } - - SchDLL::Update( xIPObj, pMemChart, pWindow ); - ((SdrOle2Obj*)pObject)->GetNewReplacement(); - delete pMemChart; - - // Dies veranlaesst Chart zum sofortigen Update - //SvData aEmpty; - //aIPObj->SendDataChanged( aEmpty ); - - // the method below did nothing in SO7 -//REMOVE aIPObj->SendViewChanged(); - - // redraw only - pObject->ActionChanged(); - // pObject->SendRepaintBroadcast(); - - if ( bEnabled && xModif.is() ) - { - try - { - if ( xModif->isModified() != bModified ) - xModif->setModified( bModified ); - } - catch ( uno::Exception& ) - {} - } - - return; // nicht weitersuchen - } - } - */ - } - pObject = aIter.Next(); } } + + // After the update, chart keeps track of its own data source ranges, + // the listener doesn't need to listen anymore. + if(pChartListenerCollection) + pChartListenerCollection->ChangeListening( rChartName, new ScRangeList ); } void ScDocument::RestoreChartListener( const String& rName ) @@ -823,31 +608,24 @@ void ScDocument::SetChartRangeList( const String& rChartName, if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) + uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) ); + uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); + if ( xChartDoc.is() && xReceiver.is() ) { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); - uno::Reference< chart2::XChartDocument > xChartDoc( xComponent, uno::UNO_QUERY ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xComponent, uno::UNO_QUERY ); - if ( xChartDoc.is() && xReceiver.is() ) - { - ScRangeListRef aNewRanges; - chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; - bool bHasCategories = false; - bool bFirstCellAsLabel = false; - rtl::OUString aRangesStr; - lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + ScRangeListRef aNewRanges; + chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; + bool bHasCategories = false; + bool bFirstCellAsLabel = false; + rtl::OUString aRangesStr; + lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - String sRangeStr; - rNewRangeListRef->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() ); + String sRangeStr; + rNewRangeListRef->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() ); - lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - // don't modify pChartListenerCollection here, called from there - return; - } + // don't modify pChartListenerCollection here, called from there + return; } } pObject = aIter.Next(); diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx index b9abe0839279..9da788fca01c 100644 --- a/sc/source/core/data/documen9.cxx +++ b/sc/source/core/data/documen9.cxx @@ -28,10 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" -#include <com/sun/star/embed/XEmbeddedObject.hpp> -#include <com/sun/star/embed/XClassifiedObject.hpp> -#include <com/sun/star/chart2/data/XDataReceiver.hpp> - // INCLUDE --------------------------------------------------------------- #include "scitems.hxx" @@ -65,10 +61,10 @@ #include "rechead.hxx" #include "poolhelp.hxx" #include "docpool.hxx" -#include "chartarr.hxx" #include "detfunc.hxx" // for UpdateAllComments #include "editutil.hxx" #include "postit.hxx" +#include "charthelper.hxx" using namespace ::com::sun::star; @@ -102,37 +98,6 @@ XColorTable* ScDocument::GetColorTable() } } -BOOL lcl_AdjustRanges( ScRangeList& rRanges, SCTAB nSource, SCTAB nDest, SCTAB nTabCount ) -{ - //! if multiple sheets are copied, update references into the other copied sheets? - - BOOL bChanged = FALSE; - - ULONG nCount = rRanges.Count(); - for (ULONG i=0; i<nCount; i++) - { - ScRange* pRange = rRanges.GetObject(i); - if ( pRange->aStart.Tab() == nSource && pRange->aEnd.Tab() == nSource ) - { - pRange->aStart.SetTab( nDest ); - pRange->aEnd.SetTab( nDest ); - bChanged = TRUE; - } - if ( pRange->aStart.Tab() >= nTabCount ) - { - pRange->aStart.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); - bChanged = TRUE; - } - if ( pRange->aEnd.Tab() >= nTabCount ) - { - pRange->aEnd.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); - bChanged = TRUE; - } - } - - return bChanged; -} - void ScDocument::TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos) { if (pDrawLayer && pSrcDoc->pDrawLayer) @@ -158,53 +123,14 @@ void ScDocument::TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDes if (pDrawLayer->IsRecording()) pDrawLayer->AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); - // #71726# if it's a chart, make sure the data references are valid - // (this must be after InsertObject!) - - if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 ) - { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pNewObject)->GetObjRef(); - uno::Reference< embed::XClassifiedObject > xClassified( xIPObj, uno::UNO_QUERY ); - SvGlobalName aObjectClassName; - if ( xClassified.is() ) - { - try { - aObjectClassName = SvGlobalName( xClassified->getClassID() ); - } catch( uno::Exception& ) - { - // TODO: handle error? - } - } - - if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) ) - { - String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName(); - - uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( aChartName ) ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); - if( xChartDoc.is() && xReceiver.is() ) - { - if( !xChartDoc->hasInternalDataProvider() ) - { - ::std::vector< ScRangeList > aRangesVector; - GetChartRanges( aChartName, aRangesVector, pSrcDoc ); - - ::std::vector< ScRangeList >::iterator aIt( aRangesVector.begin() ); - for( ; aIt!=aRangesVector.end(); aIt++ ) - { - ScRangeList& rScRangeList( *aIt ); - lcl_AdjustRanges( rScRangeList, nSrcPos, nDestPos, GetTableCount() ); - } - SetChartRanges( aChartName, aRangesVector ); - } - } - } - } - pOldObject = aIter.Next(); } } } + + // #71726# make sure the data references of charts are adapted + // (this must be after InsertObject!) + ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pSrcDoc, this, nSrcPos, nDestPos ); } void ScDocument::InitDrawLayer( SfxObjectShell* pDocShell ) @@ -242,7 +168,7 @@ void ScDocument::InitDrawLayer( SfxObjectShell* pDocShell ) pTab[nTab]->GetName(aTabName); pDrawLayer->ScRenamePage( nTab, aTabName ); - pTab[nTab]->SetDrawPageSize(false); // #54782# set the right size immediately + pTab[nTab]->SetDrawPageSize(false,false); // #54782# set the right size immediately #if 0 ULONG nx = (ULONG) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS ); ULONG ny = (ULONG) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS ); diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index ade881b77671..9f118fe80917 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -691,13 +691,21 @@ bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow return true; // success! } +bool ScDocument::ShrinkToUsedDataArea( SCTAB nTab, SCCOL& rStartCol, + SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return false; + return pTab[nTab]->ShrinkToUsedDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bColumnsOnly); +} + // zusammenhaengender Bereich void ScDocument::GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, - SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld ) const + SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ) const { if (ValidTab(nTab) && pTab[nTab]) - pTab[nTab]->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld ); + pTab[nTab]->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld, bOnlyDown ); } @@ -947,7 +955,7 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab, { UpdateReference( URM_INSDEL, nStartCol, nStartRow+nSize, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd, - 0, -(static_cast<SCsROW>(nSize)), 0, pRefUndoDoc ); + 0, -(static_cast<SCsROW>(nSize)), 0, pRefUndoDoc, TRUE, false ); } while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); } @@ -1048,7 +1056,7 @@ BOOL ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab, { UpdateReference( URM_INSDEL, nStartCol, nStartRow, nTabRangeStart, MAXCOL, nEndRow, nTabRangeEnd, - static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc ); + static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc, TRUE, false ); } while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); @@ -1137,7 +1145,7 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA { UpdateReference( URM_INSDEL, sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart, MAXCOL, nEndRow, nTabRangeEnd, - -static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc ); + -static_cast<SCsCOL>(nSize), 0, 0, pRefUndoDoc, TRUE, false ); } while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark ) ); } @@ -2638,10 +2646,11 @@ void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell, BOOL bForceT } -BOOL ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString ) +BOOL ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, + SvNumberFormatter* pFormatter, bool bDetectNumberFormat ) { if ( ValidTab(nTab) && pTab[nTab] ) - return pTab[nTab]->SetString( nCol, nRow, nTab, rString ); + return pTab[nTab]->SetString( nCol, nRow, nTab, rString, pFormatter, bDetectNumberFormat ); else return FALSE; } @@ -3900,7 +3909,7 @@ void ScDocument::GetSelectionFrame( const ScMarkData& rMark, } -BOOL ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, +bool ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, USHORT nMask ) { if ( nMask & HASATTR_ROTATE ) @@ -3954,16 +3963,16 @@ BOOL ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, } if (!nMask) - return FALSE; + return false; - BOOL bFound = FALSE; + bool bFound = false; for (SCTAB i=nTab1; i<=nTab2 && !bFound; i++) if (pTab[i]) { if ( nMask & HASATTR_RTL ) { if ( GetEditTextDirection(i) == EE_HTEXTDIR_R2L ) // sheet default - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_RIGHTORCENTER ) { @@ -3972,7 +3981,7 @@ BOOL ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, // That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets. if ( IsLayoutRTL(i) ) - bFound = TRUE; + bFound = true; } if ( !bFound ) @@ -3982,7 +3991,7 @@ BOOL ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, return bFound; } -BOOL ScDocument::HasAttrib( const ScRange& rRange, USHORT nMask ) +bool ScDocument::HasAttrib( const ScRange& rRange, USHORT nMask ) { return HasAttrib( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx index 237d7ffd16db..ad5e921cb278 100644 --- a/sc/source/core/data/dpcachetable.cxx +++ b/sc/source/core/data/dpcachetable.cxx @@ -65,7 +65,6 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::sheet::DataPilotFieldFilter; -const double D_TIMEFACTOR = 86400.0; static BOOL lcl_HasQueryEntry( const ScQueryParam& rParam ) { @@ -75,56 +74,35 @@ static BOOL lcl_HasQueryEntry( const ScQueryParam& rParam ) // ---------------------------------------------------------------------------- -static ScDPCacheCell EmptyCellContent = ScDPCacheCell(); - -// ---------------------------------------------------------------------------- - -ScDPCacheTable::Cell::Cell() : - mnCategoryRef(0), - mpContent(NULL) -{ -} - -ScDPCacheTable::Cell::~Cell() -{ -} - -// ---------------------------------------------------------------------------- - ScDPCacheTable::FilterItem::FilterItem() : - mnMatchStrId(ScSimpleSharedString::EMPTY), mfValue(0.0), mbHasValue(false) { } - +bool ScDPCacheTable::FilterItem::match( const ScDPItemData& rCellData ) const +{ + if (rCellData.GetString()!= maString && + (!rCellData.IsValue()|| rCellData.GetValue()!= mfValue)) + return false; + return true; +} // ---------------------------------------------------------------------------- -ScDPCacheTable::SingleFilter::SingleFilter(ScSimpleSharedString& rSharedString, - sal_Int32 nMatchStrId, double fValue, bool bHasValue) : - mrSharedString(rSharedString) +ScDPCacheTable::SingleFilter::SingleFilter(String aString, double fValue, bool bHasValue) { - maItem.mnMatchStrId = nMatchStrId; + maItem.maString = aString; maItem.mfValue = fValue; maItem.mbHasValue = bHasValue; } -bool ScDPCacheTable::SingleFilter::match(const ScDPCacheCell& rCell) const +bool ScDPCacheTable::SingleFilter::match( const ScDPItemData& rCellData ) const { - if (rCell.mnStrId != maItem.mnMatchStrId && - (!rCell.mbNumeric || rCell.mfValue != maItem.mfValue)) - return false; - - return true; + return maItem.match(rCellData); } const String ScDPCacheTable::SingleFilter::getMatchString() { - const String* pStr = mrSharedString.getString(maItem.mnMatchStrId); - if (pStr) - return *pStr; - - return String(); + return maItem.maString; } double ScDPCacheTable::SingleFilter::getMatchValue() const @@ -139,33 +117,26 @@ bool ScDPCacheTable::SingleFilter::hasValue() const // ---------------------------------------------------------------------------- -ScDPCacheTable::GroupFilter::GroupFilter(ScSimpleSharedString& rSharedString) : - mrSharedString(rSharedString) +ScDPCacheTable::GroupFilter::GroupFilter() { } -bool ScDPCacheTable::GroupFilter::match(const ScDPCacheCell& rCell) const +bool ScDPCacheTable::GroupFilter::match( const ScDPItemData& rCellData ) const { vector<FilterItem>::const_iterator itrEnd = maItems.end(); - for (vector<FilterItem>::const_iterator itr = maItems.begin(); itr != itrEnd; ++itr) - { - bool bMatch = false; - if (rCell.mbNumeric) - bMatch = (itr->mfValue == rCell.mfValue); - else - bMatch = (itr->mnMatchStrId == rCell.mnStrId); - - if (bMatch) - return true; - } - return false; + for (vector<FilterItem>::const_iterator itr = maItems.begin(); itr != itrEnd; ++itr) + { + bool bMatch = itr->match( rCellData); + if (bMatch) + return true; + } + return false; } void ScDPCacheTable::GroupFilter::addMatchItem(const String& rStr, double fVal, bool bHasValue) { - sal_Int32 nStrId = mrSharedString.getStringId(rStr); FilterItem aItem; - aItem.mnMatchStrId = nStrId; + aItem.maString = rStr; aItem.mfValue = fVal; aItem.mbHasValue = bHasValue; maItems.push_back(aItem); @@ -186,10 +157,16 @@ ScDPCacheTable::Criterion::Criterion() : // ---------------------------------------------------------------------------- -ScDPCacheTable::ScDPCacheTable(ScDPCollection* pCollection) : - mrSharedString(pCollection->GetSharedString()), - mpCollection(pCollection) +ScDPCacheTable::ScDPCacheTable( ScDocument* pDoc,long nId ) : + mpCache( NULL ), + mpNoneCache( NULL ) { + if ( nId >= 0 ) + mpCache = pDoc->GetDPObjectCache( nId ); + else + { //create a temp cache object + InitNoneCache( NULL ); + } } ScDPCacheTable::~ScDPCacheTable() @@ -198,12 +175,12 @@ ScDPCacheTable::~ScDPCacheTable() sal_Int32 ScDPCacheTable::getRowSize() const { - return maTable.size(); + return GetCache()->GetRowCount(); } sal_Int32 ScDPCacheTable::getColSize() const { - return maTable.empty() ? 0 : maTable[0].size(); + return GetCache()->GetColumnCount(); } namespace { @@ -230,276 +207,114 @@ private: } -void ScDPCacheTable::fillTable(ScDocument* pDoc, const ScRange& rRange, const ScQueryParam& rQuery, BOOL* pSpecial, - bool bIgnoreEmptyRows) +void ScDPCacheTable::fillTable( const ScQueryParam& rQuery, BOOL* pSpecial, + bool bIgnoreEmptyRows, bool bRepeatIfEmpty ) { // Make sure the formula cells within the data range are interpreted // during this call, for this method may be called from the interpretation // of GETPIVOTDATA, which disables nested formula interpretation without // increasing the macro level. - MacroInterpretIncrementer aMacroInc(pDoc); - - SCTAB nTab = rRange.aStart.Tab(); - SCCOL nStartCol = rRange.aStart.Col(); - SCROW nStartRow = rRange.aStart.Row(); - SCCOL nColCount = rRange.aEnd.Col() - rRange.aStart.Col() + 1; - SCROW nRowCount = rRange.aEnd.Row() - rRange.aStart.Row() + 1; - - if (nRowCount <= 1 || nColCount <= 0) + MacroInterpretIncrementer aMacroInc(GetCache()->GetDoc()); + + if ( mpCache == NULL ) + InitNoneCache( NULL ); +//check cache + const SCROW nRowCount = getRowSize(); + const SCCOL nColCount = (SCCOL) getColSize(); + if ( nRowCount <= 0 || nColCount <= 0) return; - maTable.clear(); - maTable.reserve(nRowCount); - maHeader.clear(); - maHeader.reserve(nColCount); maRowsVisible.clear(); maRowsVisible.reserve(nRowCount); - // Header row - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) - { - String aStr; - pDoc->GetString(nCol + nStartCol, nStartRow, nTab, aStr); - sal_Int32 nStrId = mrSharedString.insertString(aStr); - maHeader.push_back(nStrId); - } // Initialize field entries container. maFieldEntries.clear(); maFieldEntries.reserve(nColCount); - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) - { - TypedScStrCollectionPtr p(new TypedScStrCollection); - maFieldEntries.push_back(p); - } - - vector<SCROW> aLastNonEmptyRows(nColCount, 0); // Data rows - for (SCROW nRow = 1; nRow < nRowCount; ++nRow) + for (SCCOL nCol = 0; nCol < nColCount; ++nCol) { - if ( lcl_HasQueryEntry(rQuery) && !pDoc->ValidQuery(nRow + nStartRow, nTab, rQuery, pSpecial) ) - // filtered out by standard filter. - continue; - - if ( bIgnoreEmptyRows && - pDoc->IsBlockEmpty(nTab, nStartCol, nRow + nStartRow, - nStartCol + nColCount - 1, nRow + nStartRow) ) - // skip an empty row. - continue; - - // Insert a new row into cache table. - maRowsVisible.push_back(true); - maTable.push_back( vector<Cell>() ); - maTable.back().reserve(nColCount); - - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) + SCROW nMemCount = GetCache()->GetDimMemberCount( nCol ); + if ( nMemCount ) { - maTable.back().push_back( ScDPCacheTable::Cell() ); - Cell& rCell = maTable.back().back(); - rCell.mnCategoryRef = maTable.size()-1; + std::vector< SCROW > pAdded( nMemCount, -1 ); - String aCellStr; - bool bReadCell = nRow == 0 || pDoc->HasData(nStartCol + nCol, nStartRow + nRow, nTab); - if (bReadCell) + for (SCROW nRow = 0; nRow < nRowCount; ++nRow ) { - aLastNonEmptyRows[nCol] = maTable.size()-1; - ScDPCacheCell aCell; - pDoc->GetString(nStartCol + nCol, nStartRow + nRow, nTab, aCellStr); - aCell.mnStrId = mrSharedString.insertString(aCellStr); - aCell.mnType = SC_VALTYPE_STRING; - aCell.mbNumeric = false; - ScAddress aPos(nStartCol + nCol, nStartRow + nRow, nTab); - getValueData(pDoc, aPos, aCell); - rCell.mpContent = mpCollection->getCacheCellFromPool(aCell); + SCROW nIndex = GetCache()->GetItemDataId( nCol, nRow, bRepeatIfEmpty ); + SCROW nOrder = GetCache()->GetOrder( nCol, nIndex ); + + if ( nCol == 0 ) + maRowsVisible.push_back(false); + + if ( lcl_HasQueryEntry(rQuery) && + !GetCache()->ValidQuery( nRow , rQuery, pSpecial ) ) + continue; + if ( bIgnoreEmptyRows && GetCache()->IsRowEmpty( nRow ) ) + continue; + // Insert a new row into cache table. + if ( nCol == 0 ) + maRowsVisible.back() = true; + + pAdded[nOrder] = nIndex; + } + maFieldEntries.push_back( vector<SCROW>() ); + for ( SCROW nRow = 0; nRow < nMemCount; nRow++ ) + { + if ( pAdded[nRow] != -1 ) + maFieldEntries.back().push_back( pAdded[nRow] ); } - else - rCell.mnCategoryRef = aLastNonEmptyRows[nCol]; - - TypedStrData* pNew; - if (rCell.mpContent && rCell.mpContent->mbNumeric) - pNew = new TypedStrData(aCellStr, rCell.mpContent->mfValue, SC_STRTYPE_VALUE); - else - pNew = new TypedStrData(aCellStr); - - if (!maFieldEntries[nCol]->Insert(pNew)) - delete pNew; } } } -void lcl_GetCellValue(const Reference<sdbc::XRow>& xRow, sal_Int32 nType, long nCol, - const Date& rNullDate, ScDPCacheCell& rCell, String& rStr, - ScSimpleSharedString& rSharedString) +void ScDPCacheTable::fillTable() { - short nNumType = NUMBERFORMAT_NUMBER; - BOOL bEmptyFlag = FALSE; - try - { - rStr = xRow->getString(nCol); - rCell.mnStrId = rSharedString.getStringId(rStr); - rCell.mnType = SC_VALTYPE_STRING; - - switch (nType) - { - case sdbc::DataType::BIT: - case sdbc::DataType::BOOLEAN: - { - nNumType = NUMBERFORMAT_LOGICAL; - rCell.mfValue = xRow->getBoolean(nCol) ? 1 : 0; - bEmptyFlag = (rCell.mfValue == 0.0 && xRow->wasNull()); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; - - case sdbc::DataType::TINYINT: - case sdbc::DataType::SMALLINT: - case sdbc::DataType::INTEGER: - case sdbc::DataType::BIGINT: - case sdbc::DataType::FLOAT: - case sdbc::DataType::REAL: - case sdbc::DataType::DOUBLE: - case sdbc::DataType::NUMERIC: - case sdbc::DataType::DECIMAL: - { - //! do the conversion here? - rCell.mfValue = xRow->getDouble(nCol); - bEmptyFlag = (rCell.mfValue == 0.0 && xRow->wasNull()); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; - - case sdbc::DataType::CHAR: - case sdbc::DataType::VARCHAR: - case sdbc::DataType::LONGVARCHAR: - bEmptyFlag = (rStr.Len() == 0 && xRow->wasNull()); - break; + if ( mpCache == NULL ) + InitNoneCache( NULL ); +//check cache + const SCROW nRowCount = getRowSize(); + const SCCOL nColCount = (SCCOL) getColSize(); + if ( nRowCount <= 0 || nColCount <= 0) + return; - case sdbc::DataType::DATE: - { - nNumType = NUMBERFORMAT_DATE; + maRowsVisible.clear(); + maRowsVisible.reserve(nRowCount); - util::Date aDate = xRow->getDate(nCol); - rCell.mfValue = Date(aDate.Day, aDate.Month, aDate.Year) - rNullDate; - bEmptyFlag = xRow->wasNull(); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; - case sdbc::DataType::TIME: - { - nNumType = NUMBERFORMAT_TIME; - - util::Time aTime = xRow->getTime(nCol); - rCell.mfValue = ( aTime.Hours * 3600 + aTime.Minutes * 60 + - aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; - bEmptyFlag = xRow->wasNull(); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; + // Initialize field entries container. + maFieldEntries.clear(); + maFieldEntries.reserve(nColCount); - case sdbc::DataType::TIMESTAMP: - { - nNumType = NUMBERFORMAT_DATETIME; - - util::DateTime aStamp = xRow->getTimestamp(nCol); - rCell.mfValue = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - rNullDate ) + - ( aStamp.Hours * 3600 + aStamp.Minutes * 60 + - aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; - bEmptyFlag = xRow->wasNull(); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; - - case sdbc::DataType::SQLNULL: - case sdbc::DataType::BINARY: - case sdbc::DataType::VARBINARY: - case sdbc::DataType::LONGVARBINARY: - default: - break; - } - } - catch (uno::Exception&) + // Data rows + for (SCCOL nCol = 0; nCol < nColCount; ++nCol) { - } -} + SCROW nMemCount = GetCache()->GetDimMemberCount( nCol ); + if ( nMemCount ) + { + std::vector< SCROW > pAdded( nMemCount, -1 ); -void ScDPCacheTable::fillTable(const Reference<sdbc::XRowSet>& xRowSet, const Date& rNullDate) -{ - if (!xRowSet.is()) - // Dont' even waste time to go any further. - return; + for (SCROW nRow = 0; nRow < nRowCount; ++nRow ) + { + SCROW nIndex = GetCache()->GetItemDataId( nCol, nRow, false ); + SCROW nOrder = GetCache()->GetOrder( nCol, nIndex ); - try - { - Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp(xRowSet, UNO_QUERY_THROW); - Reference<sdbc::XResultSetMetaData> xMeta = xMetaSupp->getMetaData(); - if (!xMeta.is()) - return; - - sal_Int32 nColCount = xMeta->getColumnCount(); - - // Get column titles and types. - vector<sal_Int32> aColTypes(nColCount); - maHeader.clear(); - maHeader.reserve(nColCount); - for (sal_Int32 nCol = 0; nCol < nColCount; ++nCol) - { - String aColTitle = xMeta->getColumnLabel(nCol+1); - aColTypes[nCol] = xMeta->getColumnType(nCol+1); - maHeader.push_back( mrSharedString.getStringId(aColTitle) ); - } + if ( nCol == 0 ) + maRowsVisible.push_back(true); - // Initialize field entries container. - maFieldEntries.clear(); - maFieldEntries.reserve(nColCount); - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) - { - TypedScStrCollectionPtr p(new TypedScStrCollection); - maFieldEntries.push_back(p); - } - // Now get the data rows. - Reference<sdbc::XRow> xRow(xRowSet, UNO_QUERY_THROW); - xRowSet->first(); - maTable.clear(); - maRowsVisible.clear(); - do - { - maRowsVisible.push_back(true); - maTable.push_back( vector<Cell>() ); - maTable.back().reserve(nColCount); - for (sal_Int32 nCol = 0; nCol < nColCount; ++nCol) + pAdded[nOrder] = nIndex; + } + maFieldEntries.push_back( vector<SCROW>() ); + for ( SCROW nRow = 0; nRow < nMemCount; nRow++ ) { - maTable.back().push_back( Cell() ); - Cell& rCell = maTable.back().back(); - ScDPCacheCell aCellContent; - String aStr; - lcl_GetCellValue(xRow, aColTypes[nCol], nCol+1, rNullDate, aCellContent, aStr, mrSharedString); - rCell.mpContent = mpCollection->getCacheCellFromPool(aCellContent); - - TypedStrData* pNew; - if (rCell.mpContent->mbNumeric) - pNew = new TypedStrData(aStr, rCell.mpContent->mfValue, SC_STRTYPE_VALUE); - else - pNew = new TypedStrData(aStr); - - if (!maFieldEntries[nCol]->Insert(pNew)) - delete pNew; + if ( pAdded[nRow] != -1 ) + maFieldEntries.back().push_back( pAdded[nRow] ); } } - while (xRowSet->next()); - - xRowSet->beforeFirst(); - } - catch (const Exception&) - { } + return; } bool ScDPCacheTable::isRowActive(sal_Int32 nRow) const @@ -524,41 +339,43 @@ void ScDPCacheTable::filterByPageDimension(const vector<Criterion>& rCriteria, c maRowsVisible[nRow] = isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims); } -const ScDPCacheCell* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const +const ScDPItemData* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const { - if ( nRow >= static_cast<SCROW>(maTable.size()) ) - return NULL; - - const vector<Cell>& rRow = maTable[nRow]; - if ( nCol < 0 || static_cast<size_t>(nCol) >= rRow.size() ) - return NULL; + SCROW nId= GetCache()->GetItemDataId(nCol, nRow, bRepeatIfEmpty); + return GetCache()->GetItemDataById( nCol, nId ); +} - const Cell& rCell = rRow[nCol]; - const ScDPCacheCell* pCell = rCell.mpContent; - if (bRepeatIfEmpty && !pCell) - pCell = getCell(nCol, rCell.mnCategoryRef, false); +void ScDPCacheTable::getValue( ScDPValueData& rVal, SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const +{ + const ScDPItemData* pData = getCell( nCol, nRow, bRepeatIfEmpty ); - return pCell ? pCell : &EmptyCellContent; + if (pData) + { + rVal.fValue = pData->IsValue() ? pData->GetValue() : 0.0; + rVal.nType = pData->GetType(); + } + else + rVal.Set(0.0, SC_VALTYPE_EMPTY); } - -const String* ScDPCacheTable::getFieldName(sal_Int32 nIndex) const +String ScDPCacheTable::getFieldName(SCCOL nIndex) const { - if (nIndex >= static_cast<sal_Int32>(maHeader.size())) - return NULL; + return (GetCache()->GetDimensionName( nIndex )); +} - return mrSharedString.getString(maHeader[nIndex]); +sal_Int32 ScDPCacheTable::getFieldIndex(const String& rStr) const +{ + return GetCache()->GetDimensionIndex( rStr ); } -const TypedScStrCollection& ScDPCacheTable::getFieldEntries(sal_Int32 nIndex) const +const ::std::vector<SCROW>& ScDPCacheTable::getFieldEntries( sal_Int32 nColumn ) const { - if (nIndex < 0 || static_cast<size_t>(nIndex) >= maFieldEntries.size()) + if (nColumn < 0 || static_cast<size_t>(nColumn) >= maFieldEntries.size()) { // index out of bound. Hopefully this code will never be reached. - static const TypedScStrCollection emptyCollection; - return emptyCollection; + static const ::std::vector<SCROW> emptyEntries; + return emptyEntries; } - - return *maFieldEntries[nIndex].get(); + return maFieldEntries[nColumn]; } void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< Sequence<Any> >& rTabData, @@ -577,13 +394,10 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S // Header first. Sequence<Any> headerRow(nColSize); - for (sal_Int32 nCol = 0; nCol < nColSize; ++nCol) + for (SCCOL nCol = 0; nCol < nColSize; ++nCol) { OUString str; - const String* pStr = mrSharedString.getString(maHeader[nCol]); - if (pStr) - str = *pStr; - + str = getFieldName( nCol); Any any; any <<= str; headerRow[nCol] = any; @@ -607,26 +421,14 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S { Any any; bool bRepeatIfEmpty = rRepeatIfEmptyDims.count(nCol) > 0; - const ScDPCacheCell* pCell = getCell(nCol, nRow, bRepeatIfEmpty); - if (!pCell) - { - // This should never happen, but in case this happens, just - // stick in an empty string. - OUString str; - any <<= str; - row[nCol] = any; - continue; - } - - if (pCell->mbNumeric) - any <<= pCell->mfValue; + // Wang Xu Ming - DataPilot migration + const ScDPItemData* pData= getCell(nCol, nRow, bRepeatIfEmpty); + if ( pData->IsValue() ) + any <<= pData->GetValue(); else { - OUString str; - const String* pStr = mrSharedString.getString(pCell->mnStrId); - if (pStr) - str = *pStr; - any <<= str; + OUString string (pData->GetString() ); + any <<= string; } row[nCol] = any; } @@ -642,15 +444,19 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S void ScDPCacheTable::clear() { - maTable.clear(); - maHeader.clear(); maFieldEntries.clear(); maRowsVisible.clear(); } +void ScDPCacheTable::swap(ScDPCacheTable& rOther) +{ + maFieldEntries.swap(rOther.maFieldEntries); + maRowsVisible.swap(rOther.maRowsVisible); +} + bool ScDPCacheTable::empty() const { - return maTable.empty(); + return ( mpCache == NULL&& mpNoneCache == NULL ) || maFieldEntries.size()==0; } bool ScDPCacheTable::isRowQualified(sal_Int32 nRow, const vector<Criterion>& rCriteria, @@ -667,52 +473,26 @@ bool ScDPCacheTable::isRowQualified(sal_Int32 nRow, const vector<Criterion>& rCr // Check if the 'repeat if empty' flag is set for this field. bool bRepeatIfEmpty = rRepeatIfEmptyDims.count(itr->mnFieldIndex) > 0; - const ScDPCacheCell* pCell = getCell(static_cast<SCCOL>(itr->mnFieldIndex), nRow, bRepeatIfEmpty); - if (!pCell) - // This should never happen, but just in case... - return false; - - if (!itr->mpFilter->match(*pCell)) + const ScDPItemData* pCellData = getCell(static_cast<SCCOL>(itr->mnFieldIndex), nRow, bRepeatIfEmpty); + if (!itr->mpFilter->match(*pCellData)) return false; } return true; } -void ScDPCacheTable::getValueData(ScDocument* pDoc, const ScAddress& rPos, ScDPCacheCell& rCell) -{ - ScBaseCell* pCell = pDoc->GetCell(rPos); - if (!pCell) - { - rCell.mnType = SC_VALTYPE_EMPTY; - return; - } - - CellType eType = pCell->GetCellType(); - if (eType == CELLTYPE_NOTE) - { - // note cell - rCell.mnType = SC_VALTYPE_EMPTY; - return; - } - if (eType == CELLTYPE_FORMULA && static_cast<ScFormulaCell*>(pCell)->GetErrCode()) - { - // formula cell with error - rCell.mnType = SC_VALTYPE_ERROR; - return; - } - - if ( pCell->HasValueData() ) - { - if (eType == CELLTYPE_VALUE) - // value cell - rCell.mfValue = static_cast<ScValueCell*>(pCell)->GetValue(); - else if (eType == CELLTYPE_FORMULA) - // formula cell - rCell.mfValue = static_cast<ScFormulaCell*>(pCell)->GetValue(); - - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } +void ScDPCacheTable::InitNoneCache( ScDocument* pDoc ) +{ + mpCache = NULL; + if ( mpNoneCache ) + delete mpNoneCache; + mpNoneCache = new ScDPTableDataCache( pDoc ); } +ScDPTableDataCache* ScDPCacheTable::GetCache() const +{ + if ( mpCache ) + return mpCache; + return mpNoneCache; +} +// End Comments diff --git a/sc/source/core/data/dpglobal.cxx b/sc/source/core/data/dpglobal.cxx new file mode 100755 index 000000000000..6b84d37d8d0f --- /dev/null +++ b/sc/source/core/data/dpglobal.cxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dpglobal.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include "dpglobal.hxx" +#include "document.hxx" + +#include <stdio.h> + +namespace ScDPGlobal +{ + Rectangle operator *( const Rectangle &rLeft, const std::pair<double,double> & rRight ) + { + Rectangle rcResult( rLeft ); + rcResult.Bottom() = rcResult.Top() + static_cast<long>( rcResult.GetHeight() * rRight.second ); + rcResult.Right() = rcResult.Left() + static_cast<long>( rcResult.GetWidth() * rRight.first); + return rcResult; + } + + String GetFuncString( const String &rString, const USHORT nIndex ) + { + if ( nIndex <= 1 ) return rString; + ULONG uch = rString.Len() ? rString.GetChar( rString.Len()-1 ) : (L'9'+1); + bool bEndWithDigital = ( L'0'<=uch && uch<=L'9'); + char szTemp[__MAX_NUM_LEN+1]; + int nLen = sprintf( szTemp, bEndWithDigital ? DATA_RENAME_SEPARATOR"%hu" : "%hu", nIndex ); + String strRet = rString; + strRet.Append( String::CreateFromAscii( szTemp, static_cast<USHORT>(nLen) )); + return strRet; + } + + bool ChkDPTableOverlap( ScDocument *pDestDoc, std::list<ScDPObject> & rClipboard, SCCOL nClipStartCol, SCROW nClipStartRow, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, USHORT nEndTab, BOOL bExcludeClip /*= FALSE*/ ) + { + if ( ScDPCollection* pDPCollection = pDestDoc->GetDPCollection() ) + { + USHORT nCount = pDPCollection->GetCount(); + SCsCOL nOffsetX = nStartCol - nClipStartCol; + SCsROW nOffsetY = nStartRow - nClipStartRow; + + for( std::list<ScDPObject>::iterator iter = rClipboard.begin(); iter!=rClipboard.end(); iter++ ) + { + ScRange aRange = iter->GetOutRange(); + + for( USHORT nCurrTab = nStartTab; nCurrTab<=nEndTab; nCurrTab++ ) + { + SCsTAB nOffsetZ = nCurrTab - aRange.aStart.Tab(); + aRange.Move( nOffsetX, nOffsetY, nOffsetZ ); + + for ( USHORT i = 0; i<nCount; i++) + { + if ( (*pDPCollection)[i] && aRange.Intersects( (*pDPCollection)[i]->GetOutRange())) + { + if ( bExcludeClip && iter->GetOutRange() == (*pDPCollection)[i]->GetOutRange() ) + { + continue; + } + return false; + } + } + } + } + } + return true; +} +//end + +} +// -------------------------------------------------------------------- +// ScDPItemDataPool +// Construct +ScDPItemDataPool::ScDPItemDataPool(void) +{ +} +// +ScDPItemDataPool::ScDPItemDataPool(const ScDPItemDataPool& r): + maItems(r.maItems), + maItemIds(r.maItemIds) +{ +} + +ScDPItemDataPool::~ScDPItemDataPool(void) +{ +} + + +const ScDPItemData* ScDPItemDataPool::getData( sal_Int32 nId ) +{ + if ( nId >= static_cast<sal_Int32>(maItems.size()) ) + return NULL; + else + return &(maItems[nId]); +} + +sal_Int32 ScDPItemDataPool::getDataId( const ScDPItemData& aData ) +{ + DataHash::const_iterator itr = maItemIds.find( aData), + itrEnd = maItemIds.end(); + if ( itr == itrEnd ) + // not exist + return -1; + + else //exist + return itr->second; + +} + +sal_Int32 ScDPItemDataPool::insertData( const ScDPItemData& aData ) +{ + sal_Int32 nResult = getDataId( aData ); + + if( nResult < 0 ) + { + maItemIds.insert( DataHash::value_type( aData, nResult = maItems.size() ) ); + maItems.push_back( aData ); + } + + return nResult; +} + + diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx index 1bc888100a9f..e71ec5c8b82c 100644 --- a/sc/source/core/data/dpgroup.cxx +++ b/sc/source/core/data/dpgroup.cxx @@ -47,6 +47,7 @@ #include "dptabsrc.hxx" #include "dptabres.hxx" #include "dpobject.hxx" +#include "dpglobal.hxx" #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> @@ -78,6 +79,202 @@ const sal_Int32 SC_DP_DATE_FIRST = -1; const sal_Int32 SC_DP_DATE_LAST = 10000; // ============================================================================ +namespace +{ + BOOL lcl_Search( SCCOL nSourceDim, ScDPTableDataCache* pCache , const std::vector< SCROW >& vIdx, SCROW nNew , SCROW& rIndex) + { + rIndex = vIdx.size(); + BOOL bFound = FALSE; + SCROW nLo = 0; + SCROW nHi = vIdx.size() - 1; + SCROW nIndex; + long nCompare; + while (nLo <= nHi) + { + nIndex = (nLo + nHi) / 2; + + const ScDPItemData* pData = pCache->GetItemDataById( nSourceDim, vIdx[nIndex] ); + const ScDPItemData* pDataInsert = pCache->GetItemDataById( nSourceDim, nNew ); + + nCompare = ScDPItemData::Compare( *pData, *pDataInsert ); + if (nCompare < 0) + nLo = nIndex + 1; + else + { + nHi = nIndex - 1; + if (nCompare == 0) + { + bFound = TRUE; + nLo = nIndex; + } + } + } + rIndex = nLo; + return bFound; + } + + void lcl_Insert( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, SCROW nNew ) + { + SCROW nIndex = 0; + if ( !lcl_Search( nSourceDim, pCache, vIdx, nNew ,nIndex ) ) + vIdx.insert( vIdx.begin()+nIndex, nNew ); + } + + template<bool bUpdateData> + SCROW lcl_InsertValue( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData ); + + template<> + SCROW lcl_InsertValue<false>( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData ) + { + SCROW nNewID = pCache->GetAdditionalItemID( rData ); + lcl_Insert( nSourceDim, pCache, vIdx, nNewID ); + return nNewID; + } + + template<> + SCROW lcl_InsertValue<true>( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData ) + { + SCROW nItemId = lcl_InsertValue<false>( nSourceDim, pCache, vIdx, rData ); + + if( const ScDPItemData *pData = pCache->GetItemDataById( nSourceDim, nItemId ) ) + const_cast<ScDPItemData&>(*pData) = rData; + + return nItemId; + } + + template<bool bUpdateData> + void lcl_InsertValue ( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const String& rString, const double& fValue ) + { + lcl_InsertValue<bUpdateData>( nSourceDim, pCache, vIdx, ScDPItemData( rString, fValue, TRUE ) ); + } + + template<bool bUpdateData> + void lcl_InsertValue ( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const String& rString, const double& fValue, sal_Int32 nDatePart ) + { + lcl_InsertValue<bUpdateData>( nSourceDim, pCache, vIdx, ScDPItemData( nDatePart, rString, fValue, ScDPItemData::MK_DATA|ScDPItemData::MK_VAL|ScDPItemData::MK_DATEPART ) ); + } + + void lcl_AppendDateStr( rtl::OUStringBuffer& rBuffer, double fValue, SvNumberFormatter* pFormatter ) + { + ULONG nFormat = pFormatter->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge ); + String aString; + pFormatter->GetInputLineString( fValue, nFormat, aString ); + rBuffer.append( aString ); + } + + String lcl_GetNumGroupName( double fStartValue, const ScDPNumGroupInfo& rInfo, + bool bHasNonInteger, sal_Unicode cDecSeparator, SvNumberFormatter* pFormatter ) + { + DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" ); + + double fStep = rInfo.Step; + double fEndValue = fStartValue + fStep; + if ( !bHasNonInteger && ( rInfo.DateValues || !rtl::math::approxEqual( fEndValue, rInfo.End ) ) ) + { + // The second number of the group label is + // (first number + size - 1) if there are only integer numbers, + // (first number + size) if any non-integer numbers are involved. + // Exception: The last group (containing the end value) is always + // shown as including the end value (but not for dates). + + fEndValue -= 1.0; + } + + if ( fEndValue > rInfo.End && !rInfo.AutoEnd ) + { + // limit the last group to the end value + + fEndValue = rInfo.End; + } + + rtl::OUStringBuffer aBuffer; + if ( rInfo.DateValues ) + { + lcl_AppendDateStr( aBuffer, fStartValue, pFormatter ); + aBuffer.appendAscii( " - " ); // with spaces + lcl_AppendDateStr( aBuffer, fEndValue, pFormatter ); + } + else + { + rtl::math::doubleToUStringBuffer( aBuffer, fStartValue, rtl_math_StringFormat_Automatic, + rtl_math_DecimalPlaces_Max, cDecSeparator, true ); + aBuffer.append( (sal_Unicode) '-' ); + rtl::math::doubleToUStringBuffer( aBuffer, fEndValue, rtl_math_StringFormat_Automatic, + rtl_math_DecimalPlaces_Max, cDecSeparator, true ); + } + + return aBuffer.makeStringAndClear(); + } + + String lcl_GetSpecialNumGroupName( double fValue, bool bFirst, sal_Unicode cDecSeparator, + bool bDateValues, SvNumberFormatter* pFormatter ) + { + DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" ); + + rtl::OUStringBuffer aBuffer; + aBuffer.append((sal_Unicode)( bFirst ? '<' : '>' )); + if ( bDateValues ) + lcl_AppendDateStr( aBuffer, fValue, pFormatter ); + else + rtl::math::doubleToUStringBuffer( aBuffer, fValue, rtl_math_StringFormat_Automatic, + rtl_math_DecimalPlaces_Max, cDecSeparator, true ); + return aBuffer.makeStringAndClear(); + } + + inline bool IsInteger( double fValue ) + { + return rtl::math::approxEqual( fValue, rtl::math::approxFloor(fValue) ); + } + + String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bool bHasNonInteger, + sal_Unicode cDecSeparator, double& rGroupValue, ScDocument* pDoc ) + { + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + + if ( fValue < rInfo.Start && !rtl::math::approxEqual( fValue, rInfo.Start ) ) + { + rGroupValue = rInfo.Start - rInfo.Step; + return lcl_GetSpecialNumGroupName( rInfo.Start, true, cDecSeparator, rInfo.DateValues, pFormatter ); + } + + if ( fValue > rInfo.End && !rtl::math::approxEqual( fValue, rInfo.End ) ) + { + rGroupValue = rInfo.End + rInfo.Step; + return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter ); + } + + double fDiff = fValue - rInfo.Start; + double fDiv = rtl::math::approxFloor( fDiff / rInfo.Step ); + double fGroupStart = rInfo.Start + fDiv * rInfo.Step; + + if ( rtl::math::approxEqual( fGroupStart, rInfo.End ) && + !rtl::math::approxEqual( fGroupStart, rInfo.Start ) ) + { + if ( !rInfo.DateValues ) + { + // A group that would consist only of the end value is not created, + // instead the value is included in the last group before. So the + // previous group is used if the calculated group start value is the + // selected end value. + + fDiv -= 1.0; + fGroupStart = rInfo.Start + fDiv * rInfo.Step; + } + else + { + // For date values, the end value is instead treated as above the limit + // if it would be a group of its own. + + rGroupValue = rInfo.End + rInfo.Step; + return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter ); + } + } + + rGroupValue = fGroupStart; + + return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter ); + } +} class ScDPGroupDateFilter : public ScDPCacheTable::FilterBase { @@ -85,7 +282,10 @@ public: ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart, const Date* pNullDate, const ScDPNumGroupInfo* pNumInfo); - virtual bool match(const ScDPCacheCell &rCell) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual bool match(const ScDPItemData & rCellData) const; + // End Comments private: ScDPGroupDateFilter(); // disabled @@ -108,26 +308,25 @@ ScDPGroupDateFilter::ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart // fprintf(stdout, "ScDPCacheTable:DateGroupFilter::DateGroupFilter: match value = %g; date part = %ld\n", // mfMatchValue, mnDatePart); } - -bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const +bool ScDPGroupDateFilter::match( const ScDPItemData & rCellData ) const { using namespace ::com::sun::star::sheet; using ::rtl::math::approxFloor; using ::rtl::math::approxEqual; - if (!rCell.mbNumeric) + if ( !rCellData.IsValue() ) return false; - +// ScDPCacheCell rCell( rCellData.fValue ); if (!mpNumInfo) return false; // Start and end dates are inclusive. (An end date without a time value // is included, while an end date with a time value is not.) - if ( rCell.mfValue < mpNumInfo->Start && !approxEqual(rCell.mfValue, mpNumInfo->Start) ) + if ( rCellData.GetValue() < mpNumInfo->Start && !approxEqual(rCellData.GetValue(), mpNumInfo->Start) ) return static_cast<sal_Int32>(mfMatchValue) == SC_DP_DATE_FIRST; - if ( rCell.mfValue > mpNumInfo->End && !approxEqual(rCell.mfValue, mpNumInfo->End) ) + if ( rCellData.GetValue() > mpNumInfo->End && !approxEqual(rCellData.GetValue(), mpNumInfo->End) ) return static_cast<sal_Int32>(mfMatchValue) == SC_DP_DATE_LAST; if (mnDatePart == DataPilotFieldGroupBy::HOURS || mnDatePart == DataPilotFieldGroupBy::MINUTES || @@ -136,7 +335,7 @@ bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const // handle time // (as in the cell functions, ScInterpreter::ScGetHour etc.: seconds are rounded) - double time = rCell.mfValue - approxFloor(rCell.mfValue); + double time = rCellData.GetValue() - approxFloor(rCellData.GetValue()); long seconds = static_cast<long>(approxFloor(time*D_TIMEFACTOR + 0.5)); switch (mnDatePart) @@ -165,7 +364,7 @@ bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const return false; } - Date date = *mpNullDate + static_cast<long>(approxFloor(rCell.mfValue)); + Date date = *mpNullDate + static_cast<long>(approxFloor(rCellData.GetValue())); switch (mnDatePart) { case DataPilotFieldGroupBy::YEARS: @@ -204,17 +403,6 @@ bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const return false; } - -// ============================================================================ - -void lcl_AppendDateStr( rtl::OUStringBuffer& rBuffer, double fValue, SvNumberFormatter* pFormatter ) -{ - ULONG nFormat = pFormatter->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge ); - String aString; - pFormatter->GetInputLineString( fValue, nFormat, aString ); - rBuffer.append( aString ); -} - // ----------------------------------------------------------------------- ScDPDateGroupHelper::ScDPDateGroupHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ) : @@ -354,15 +542,18 @@ sal_Int32 lcl_GetDatePartValue( double fValue, sal_Int32 nDatePart, SvNumberForm BOOL lcl_DateContained( sal_Int32 nGroupPart, const ScDPItemData& rGroupData, sal_Int32 nBasePart, const ScDPItemData& rBaseData ) { - if ( !rGroupData.bHasValue || !rBaseData.bHasValue ) + if ( !rGroupData.IsValue() || !rBaseData.IsValue() ) { // non-numeric entries involved: only match equal entries return rGroupData.IsCaseInsEqual( rBaseData ); } // no approxFloor needed, values were created from integers - sal_Int32 nGroupValue = (sal_Int32) rGroupData.fValue; - sal_Int32 nBaseValue = (sal_Int32) rBaseData.fValue; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + sal_Int32 nGroupValue = (sal_Int32) rGroupData.GetValue(); + sal_Int32 nBaseValue = (sal_Int32) rBaseData.GetValue(); +// End Comments if ( nBasePart > nGroupPart ) { // switch, so the base part is the smaller (inner) part @@ -417,28 +608,25 @@ String lcl_GetSpecialDateName( double fValue, bool bFirst, SvNumberFormatter* pF return aBuffer.makeStringAndClear(); } -void ScDPDateGroupHelper::FillColumnEntries( TypedScStrCollection& rEntries, const TypedScStrCollection& rOriginal, - SvNumberFormatter* pFormatter ) const +void ScDPDateGroupHelper::FillColumnEntries( SCCOL nSourceDim, ScDPTableDataCache* pCache, std::vector< SCROW >& rEntries, const std::vector< SCROW >& rOriginal ) const { // auto min/max is only used for "Years" part, but the loop is always needed double fSourceMin = 0.0; double fSourceMax = 0.0; bool bFirst = true; - USHORT nOriginalCount = rOriginal.GetCount(); - for (USHORT nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) + size_t nOriginalCount = rOriginal.size(); + for (size_t nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) { - const TypedStrData& rStrData = *rOriginal[nOriginalPos]; - if ( rStrData.IsStrData() ) + const ScDPItemData* pItemData = pCache->GetItemDataById( nSourceDim, rOriginal[nOriginalPos] ); + if ( pItemData->HasStringData() ) { // string data: just copy - TypedStrData* pNew = new TypedStrData( rStrData ); - if ( !rEntries.Insert( pNew ) ) - delete pNew; + lcl_Insert( nSourceDim, pCache , rEntries, rOriginal[nOriginalPos] ); } else { - double fSourceValue = rStrData.GetValue(); + double fSourceValue = pItemData->GetValue(); if ( bFirst ) { fSourceMin = fSourceMax = fSourceValue; @@ -462,6 +650,7 @@ void ScDPDateGroupHelper::FillColumnEntries( TypedScStrCollection& rEntries, con const_cast<ScDPDateGroupHelper*>(this)->aNumInfo.End = rtl::math::approxFloor( fSourceMax ) + 1; //! if not automatic, limit fSourceMin/fSourceMax for list of year values? + SvNumberFormatter* pFormatter = pCache->GetDoc()->GetFormatTable(); long nStart = 0; long nEnd = 0; // including @@ -485,22 +674,15 @@ void ScDPDateGroupHelper::FillColumnEntries( TypedScStrCollection& rEntries, con for ( sal_Int32 nValue = nStart; nValue <= nEnd; nValue++ ) { String aName = lcl_GetDateGroupName( nDatePart, nValue, pFormatter ); - TypedStrData* pNew = new TypedStrData( aName, nValue, SC_STRTYPE_VALUE ); - if ( !rEntries.Insert( pNew ) ) - delete pNew; + lcl_InsertValue<false>( nSourceDim, pCache, rEntries, aName, nValue, nDatePart ); } // add first/last entry (min/max) - String aFirstName = lcl_GetSpecialDateName( aNumInfo.Start, true, pFormatter ); - TypedStrData* pFirstEntry = new TypedStrData( aFirstName, SC_DP_DATE_FIRST, SC_STRTYPE_VALUE ); - if ( !rEntries.Insert( pFirstEntry ) ) - delete pFirstEntry; + lcl_InsertValue<true>( nSourceDim, pCache, rEntries, aFirstName, SC_DP_DATE_FIRST, nDatePart ); String aLastName = lcl_GetSpecialDateName( aNumInfo.End, false, pFormatter ); - TypedStrData* pLastEntry = new TypedStrData( aLastName, SC_DP_DATE_LAST, SC_STRTYPE_VALUE ); - if ( !rEntries.Insert( pLastEntry ) ) - delete pLastEntry; + lcl_InsertValue<true>( nSourceDim, pCache, rEntries, aLastName, SC_DP_DATE_LAST, nDatePart ); } // ----------------------------------------------------------------------- @@ -541,7 +723,10 @@ void ScDPGroupItem::FillGroupFilter( ScDPCacheTable::GroupFilter& rFilter ) cons { ScDPItemDataVec::const_iterator itrEnd = aElements.end(); for (ScDPItemDataVec::const_iterator itr = aElements.begin(); itr != itrEnd; ++itr) - rFilter.addMatchItem(itr->aString, itr->fValue, itr->bHasValue); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + rFilter.addMatchItem(itr->GetString(), itr->GetValue(), itr->IsValue()); +// End Comments } // ----------------------------------------------------------------------- @@ -550,15 +735,15 @@ ScDPGroupDimension::ScDPGroupDimension( long nSource, const String& rNewName ) : nSourceDim( nSource ), nGroupDim( -1 ), aGroupName( rNewName ), - pDateHelper( NULL ), - pCollection( NULL ) + pDateHelper( NULL )/*, + pCollection( NULL )*/ { } ScDPGroupDimension::~ScDPGroupDimension() { delete pDateHelper; - delete pCollection; + maMemberEntries.clear(); } ScDPGroupDimension::ScDPGroupDimension( const ScDPGroupDimension& rOther ) : @@ -566,8 +751,7 @@ ScDPGroupDimension::ScDPGroupDimension( const ScDPGroupDimension& rOther ) : nGroupDim( rOther.nGroupDim ), aGroupName( rOther.aGroupName ), pDateHelper( NULL ), - aItems( rOther.aItems ), - pCollection( NULL ) // collection isn't copied - allocated on demand + aItems( rOther.aItems ) { if ( rOther.pDateHelper ) pDateHelper = new ScDPDateGroupHelper( *rOther.pDateHelper ); @@ -586,8 +770,6 @@ ScDPGroupDimension& ScDPGroupDimension::operator=( const ScDPGroupDimension& rOt else pDateHelper = NULL; - delete pCollection; // collection isn't copied - allocated on demand - pCollection = NULL; return *this; } @@ -606,44 +788,42 @@ void ScDPGroupDimension::SetGroupDim( long nDim ) { nGroupDim = nDim; } - -const TypedScStrCollection& ScDPGroupDimension::GetColumnEntries( - const TypedScStrCollection& rOriginal, ScDocument* pDoc ) const +// Wang Xu Ming -- 2009-9-2 +// DataPilot Migration - Cache&&Performance +const std::vector< SCROW >& ScDPGroupDimension::GetColumnEntries( const ScDPCacheTable& rCacheTable, const std::vector< SCROW >& rOriginal ) const { - if ( !pCollection ) + if ( maMemberEntries.empty() ) { - pCollection = new TypedScStrCollection(); if ( pDateHelper ) - pDateHelper->FillColumnEntries( *pCollection, rOriginal, pDoc->GetFormatTable() ); + { + pDateHelper->FillColumnEntries( (SCCOL)GetSourceDim(), rCacheTable.GetCache(), maMemberEntries, rOriginal ); + } else { - long nCount = aItems.size(); - for (long i=0; i<nCount; i++) + for (size_t i =0; i < rOriginal.size( ); i ++) { - //! numeric entries? - TypedStrData* pNew = new TypedStrData( aItems[i].GetName().aString ); - if ( !pCollection->Insert( pNew ) ) - delete pNew; - } - - USHORT nOriginalCount = rOriginal.GetCount(); - for (USHORT nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) - { - const TypedStrData& rStrData = *rOriginal[nOriginalPos]; - ScDPItemData aItemData( rStrData.GetString(), rStrData.GetValue(), !rStrData.IsStrData() ); - if ( !GetGroupForData( aItemData ) ) + const ScDPItemData* pItemData = rCacheTable.GetCache()->GetItemDataById( (SCCOL)GetSourceDim(), rOriginal[i] ); + if ( !pItemData || !GetGroupForData( *pItemData ) ) { // not in any group -> add as its own group - TypedStrData* pNew = new TypedStrData( rStrData ); - if ( !pCollection->Insert( pNew ) ) - delete pNew; + maMemberEntries.push_back( rOriginal[i] ); } } + + long nCount = aItems.size(); + for (long i=0; i<nCount; i++) + { + SCROW nNew = rCacheTable.GetCache()->GetAdditionalItemID( aItems[i].GetName() ); + lcl_Insert ( (SCCOL)GetSourceDim(), rCacheTable.GetCache(), maMemberEntries, nNew ); + } } } - return *pCollection; + return maMemberEntries; } +// End Comments + + const ScDPGroupItem* ScDPGroupDimension::GetGroupForData( const ScDPItemData& rData ) const { for ( ScDPGroupItemVec::const_iterator aIter(aItems.begin()); aIter != aItems.end(); aIter++ ) @@ -672,15 +852,13 @@ const ScDPGroupItem* ScDPGroupDimension::GetGroupByIndex( size_t nIndex ) const void ScDPGroupDimension::DisposeData() { - delete pCollection; - pCollection = NULL; + maMemberEntries.clear(); } // ----------------------------------------------------------------------- ScDPNumGroupDimension::ScDPNumGroupDimension() : pDateHelper( NULL ), - pCollection( NULL ), bHasNonInteger( false ), cDecSeparator( 0 ) { @@ -689,7 +867,6 @@ ScDPNumGroupDimension::ScDPNumGroupDimension() : ScDPNumGroupDimension::ScDPNumGroupDimension( const ScDPNumGroupInfo& rInfo ) : aGroupInfo( rInfo ), pDateHelper( NULL ), - pCollection( NULL ), bHasNonInteger( false ), cDecSeparator( 0 ) { @@ -698,7 +875,6 @@ ScDPNumGroupDimension::ScDPNumGroupDimension( const ScDPNumGroupInfo& rInfo ) : ScDPNumGroupDimension::ScDPNumGroupDimension( const ScDPNumGroupDimension& rOther ) : aGroupInfo( rOther.aGroupInfo ), pDateHelper( NULL ), - pCollection( NULL ), // collection isn't copied - allocated on demand bHasNonInteger( false ), cDecSeparator( 0 ) { @@ -716,23 +892,19 @@ ScDPNumGroupDimension& ScDPNumGroupDimension::operator=( const ScDPNumGroupDimen else pDateHelper = NULL; - delete pCollection; // collection isn't copied - allocated on demand - pCollection = NULL; bHasNonInteger = false; return *this; } void ScDPNumGroupDimension::DisposeData() { - delete pCollection; - pCollection = NULL; bHasNonInteger = false; + maMemberEntries.clear(); } ScDPNumGroupDimension::~ScDPNumGroupDimension() { delete pDateHelper; - delete pCollection; } void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ) @@ -743,80 +915,15 @@ void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_I aGroupInfo.Enable = sal_True; //! or query both? } -String lcl_GetNumGroupName( double fStartValue, const ScDPNumGroupInfo& rInfo, - bool bHasNonInteger, sal_Unicode cDecSeparator, SvNumberFormatter* pFormatter ) -{ - DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" ); - - double fStep = rInfo.Step; - double fEndValue = fStartValue + fStep; - if ( !bHasNonInteger && ( rInfo.DateValues || !rtl::math::approxEqual( fEndValue, rInfo.End ) ) ) - { - // The second number of the group label is - // (first number + size - 1) if there are only integer numbers, - // (first number + size) if any non-integer numbers are involved. - // Exception: The last group (containing the end value) is always - // shown as including the end value (but not for dates). - - fEndValue -= 1.0; - } - - if ( fEndValue > rInfo.End && !rInfo.AutoEnd ) - { - // limit the last group to the end value - - fEndValue = rInfo.End; - } - - rtl::OUStringBuffer aBuffer; - if ( rInfo.DateValues ) - { - lcl_AppendDateStr( aBuffer, fStartValue, pFormatter ); - aBuffer.appendAscii( " - " ); // with spaces - lcl_AppendDateStr( aBuffer, fEndValue, pFormatter ); - } - else - { - rtl::math::doubleToUStringBuffer( aBuffer, fStartValue, rtl_math_StringFormat_Automatic, - rtl_math_DecimalPlaces_Max, cDecSeparator, true ); - aBuffer.append( (sal_Unicode) '-' ); - rtl::math::doubleToUStringBuffer( aBuffer, fEndValue, rtl_math_StringFormat_Automatic, - rtl_math_DecimalPlaces_Max, cDecSeparator, true ); - } - - return aBuffer.makeStringAndClear(); -} - -String lcl_GetSpecialNumGroupName( double fValue, bool bFirst, sal_Unicode cDecSeparator, - bool bDateValues, SvNumberFormatter* pFormatter ) +const std::vector< SCROW >& ScDPNumGroupDimension::GetNumEntries( SCCOL nSourceDim, ScDPTableDataCache* pCache, + const std::vector< SCROW >& rOriginal ) const { - DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" ); - - rtl::OUStringBuffer aBuffer; - aBuffer.append((sal_Unicode)( bFirst ? '<' : '>' )); - if ( bDateValues ) - lcl_AppendDateStr( aBuffer, fValue, pFormatter ); - else - rtl::math::doubleToUStringBuffer( aBuffer, fValue, rtl_math_StringFormat_Automatic, - rtl_math_DecimalPlaces_Max, cDecSeparator, true ); - return aBuffer.makeStringAndClear(); -} - -inline bool IsInteger( double fValue ) -{ - return rtl::math::approxEqual( fValue, rtl::math::approxFloor(fValue) ); -} - -const TypedScStrCollection& ScDPNumGroupDimension::GetNumEntries( - const TypedScStrCollection& rOriginal, ScDocument* pDoc ) const -{ - if ( !pCollection ) + if ( maMemberEntries.empty() ) { - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + SvNumberFormatter* pFormatter = pCache->GetDoc()->GetFormatTable(); - pCollection = new TypedScStrCollection(); if ( pDateHelper ) - pDateHelper->FillColumnEntries( *pCollection, rOriginal, pFormatter ); + pDateHelper->FillColumnEntries( nSourceDim, pCache, maMemberEntries,rOriginal ); else { // Copy textual entries. @@ -835,39 +942,37 @@ const TypedScStrCollection& ScDPNumGroupDimension::GetNumEntries( double fSourceMax = 0.0; bool bFirst = true; - USHORT nOriginalCount = rOriginal.GetCount(); - for (USHORT nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) + size_t nOriginalCount = rOriginal.size(); + for (size_t nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) { - const TypedStrData& rStrData = *rOriginal[nOriginalPos]; - if ( rStrData.IsStrData() ) - { - // string data: just copy - TypedStrData* pNew = new TypedStrData( rStrData ); - if ( !pCollection->Insert( pNew ) ) - delete pNew; - } - else - { - double fSourceValue = rStrData.GetValue(); - if ( bFirst ) - { - fSourceMin = fSourceMax = fSourceValue; - bFirst = false; - } - else - { - if ( fSourceValue < fSourceMin ) - fSourceMin = fSourceValue; - if ( fSourceValue > fSourceMax ) - fSourceMax = fSourceValue; - } - if ( !bHasNonInteger && !IsInteger( fSourceValue ) ) - { - // if any non-integer numbers are involved, the group labels are - // shown including their upper limit - bHasNonInteger = true; - } - } + const ScDPItemData* pItemData = pCache->GetItemDataById( nSourceDim , rOriginal[nOriginalPos] ); + + if ( pItemData && pItemData ->HasStringData() ) + { + lcl_Insert( nSourceDim, pCache, maMemberEntries, rOriginal[nOriginalPos] ); + } + else + { + double fSourceValue = pItemData->GetValue(); + if ( bFirst ) + { + fSourceMin = fSourceMax = fSourceValue; + bFirst = false; + } + else + { + if ( fSourceValue < fSourceMin ) + fSourceMin = fSourceValue; + if ( fSourceValue > fSourceMax ) + fSourceMax = fSourceValue; + } + if ( !bHasNonInteger && !IsInteger( fSourceValue ) ) + { + // if any non-integer numbers are involved, the group labels are + // shown including their upper limit + bHasNonInteger = true; + } + } } if ( aGroupInfo.DateValues ) @@ -899,10 +1004,7 @@ const TypedScStrCollection& ScDPNumGroupDimension::GetNumEntries( String aName = lcl_GetNumGroupName( fLoop, aGroupInfo, bHasNonInteger, cDecSeparator, pFormatter ); // create a numerical entry to ensure proper sorting // (in FillMemberResults this needs special handling) - TypedStrData* pNew = new TypedStrData( aName, fLoop, SC_STRTYPE_VALUE ); - if ( !pCollection->Insert( pNew ) ) - delete pNew; - + lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aName, fLoop ); ++nLoopCount; fLoop = aGroupInfo.Start + nLoopCount * aGroupInfo.Step; bFirstGroup = false; @@ -911,72 +1013,17 @@ const TypedScStrCollection& ScDPNumGroupDimension::GetNumEntries( } String aFirstName = lcl_GetSpecialNumGroupName( aGroupInfo.Start, true, cDecSeparator, aGroupInfo.DateValues, pFormatter ); - TypedStrData* pFirstEntry = new TypedStrData( aFirstName, aGroupInfo.Start - aGroupInfo.Step, SC_STRTYPE_VALUE ); - if ( !pCollection->Insert( pFirstEntry ) ) - delete pFirstEntry; + lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aFirstName, aGroupInfo.Start - aGroupInfo.Step ); String aLastName = lcl_GetSpecialNumGroupName( aGroupInfo.End, false, cDecSeparator, aGroupInfo.DateValues, pFormatter ); - TypedStrData* pLastEntry = new TypedStrData( aLastName, aGroupInfo.End + aGroupInfo.Step, SC_STRTYPE_VALUE ); - if ( !pCollection->Insert( pLastEntry ) ) - delete pLastEntry; - } - } - return *pCollection; -} - -// ----------------------------------------------------------------------- - -String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bool bHasNonInteger, - sal_Unicode cDecSeparator, double& rGroupValue, ScDocument* pDoc ) -{ - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); - - if ( fValue < rInfo.Start && !rtl::math::approxEqual( fValue, rInfo.Start ) ) - { - rGroupValue = rInfo.Start - rInfo.Step; - return lcl_GetSpecialNumGroupName( rInfo.Start, true, cDecSeparator, rInfo.DateValues, pFormatter ); - } - - if ( fValue > rInfo.End && !rtl::math::approxEqual( fValue, rInfo.End ) ) - { - rGroupValue = rInfo.End + rInfo.Step; - return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter ); - } - - double fDiff = fValue - rInfo.Start; - double fDiv = rtl::math::approxFloor( fDiff / rInfo.Step ); - double fGroupStart = rInfo.Start + fDiv * rInfo.Step; - - if ( rtl::math::approxEqual( fGroupStart, rInfo.End ) && - !rtl::math::approxEqual( fGroupStart, rInfo.Start ) ) - { - if ( !rInfo.DateValues ) - { - // A group that would consist only of the end value is not created, - // instead the value is included in the last group before. So the - // previous group is used if the calculated group start value is the - // selected end value. - - fDiv -= 1.0; - fGroupStart = rInfo.Start + fDiv * rInfo.Step; - } - else - { - // For date values, the end value is instead treated as above the limit - // if it would be a group of its own. - - rGroupValue = rInfo.End + rInfo.Step; - return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter ); + lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aLastName, aGroupInfo.End + aGroupInfo.Step ); } } - - rGroupValue = fGroupStart; - - return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter ); + return maMemberEntries; } ScDPGroupTableData::ScDPGroupTableData( const shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument ) : - ScDPTableData(pDocument), + ScDPTableData(pDocument, pSource->GetCacheId() ), pSourceData( pSource ), pDoc( pDocument ) { @@ -1015,7 +1062,6 @@ long ScDPGroupTableData::GetDimensionIndex( const String& rName ) for (long i=0; i<nSourceCount; i++) // nSourceCount excludes data layout if ( pSourceData->getDimensionName(i) == rName ) //! ignore case? return i; - return -1; // none } @@ -1039,36 +1085,53 @@ void ScDPGroupTableData::GetNumGroupInfo( long nDimension, ScDPNumGroupInfo& rIn rDecimal = pNumGroups[nDimension].GetDecSeparator(); } } - -const TypedScStrCollection& ScDPGroupTableData::GetColumnEntries(long nColumn) +// Wang Xu Ming - DataPilot migration +long ScDPGroupTableData::GetMembersCount( long nDim ) +{ + const std::vector< SCROW >& members = GetColumnEntries( nDim ); + return members.size(); +} +const std::vector< SCROW >& ScDPGroupTableData::GetColumnEntries( long nColumn ) { - // date handling is in ScDPGroupDimension::GetColumnEntries / ScDPNumGroupDimension::GetNumEntries - // (to use the pCollection members) - if ( nColumn >= nSourceCount ) { - if ( nColumn == sal::static_int_cast<long>( nSourceCount + aGroups.size() ) ) // data layout dimension? + if ( getIsDataLayoutDimension( nColumn) ) // data layout dimension? nColumn = nSourceCount; // index of data layout in source data else { const ScDPGroupDimension& rGroupDim = aGroups[nColumn - nSourceCount]; long nSourceDim = rGroupDim.GetSourceDim(); // collection is cached at pSourceData, GetColumnEntries can be called every time - const TypedScStrCollection& rOriginal = pSourceData->GetColumnEntries( nSourceDim ); - return rGroupDim.GetColumnEntries( rOriginal, pDoc ); + const std::vector< SCROW >& rOriginal = pSourceData->GetColumnEntries( nSourceDim ); + return rGroupDim.GetColumnEntries( GetCacheTable(), rOriginal ); } } if ( IsNumGroupDimension( nColumn ) ) { // dimension number is unchanged for numerical groups - const TypedScStrCollection& rOriginal = pSourceData->GetColumnEntries( nColumn ); - return pNumGroups[nColumn].GetNumEntries( rOriginal, pDoc ); + const std::vector< SCROW >& rOriginal = pSourceData->GetColumnEntries( nColumn ); + return pNumGroups[nColumn].GetNumEntries( (SCCOL)nColumn, GetCacheTable().GetCache(), rOriginal ); } return pSourceData->GetColumnEntries( nColumn ); } +const ScDPItemData* ScDPGroupTableData::GetMemberById( long nDim, long nId ) +{ + if ( nDim >= nSourceCount ) + { + if ( getIsDataLayoutDimension( nDim) ) + nDim = nSourceCount; + else + { + const ScDPGroupDimension& rGroupDim = aGroups[nDim - nSourceCount]; + nDim = rGroupDim.GetSourceDim(); + } + } + return pSourceData->GetMemberById( nDim, nId ); +} + String ScDPGroupTableData::getDimensionName(long nColumn) { if ( nColumn >= nSourceCount ) @@ -1101,7 +1164,7 @@ BOOL ScDPGroupTableData::IsDateDimension(long nDim) return pSourceData->IsDateDimension( nDim ); } -UINT32 ScDPGroupTableData::GetNumberFormat(long nDim) +ULONG ScDPGroupTableData::GetNumberFormat(long nDim) { if ( nDim >= nSourceCount ) { @@ -1220,16 +1283,19 @@ void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>& for (size_t i = 0; i < nGroupItemCount; ++i) { const ScDPGroupItem* pGrpItem = pGrpDim->GetGroupByIndex(i); - ScDPItemData aName; - aName.aString = pFilter->getMatchString(); + // Wang Xu Ming -- 2009-6-9 + // DataPilot Migration + ScDPItemData aName( pFilter->getMatchString(),pFilter->getMatchValue(),pFilter->hasValue()) ; + /*aName.aString = pFilter->getMatchString(); aName.fValue = pFilter->getMatchValue(); - aName.bHasValue = pFilter->hasValue(); - if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(aName)) + aName.bHasValue = pFilter->hasValue();*/ + // End Comments + if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(aName)) continue; ScDPCacheTable::Criterion aCri; aCri.mnFieldIndex = nSrcDim; - aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(GetSharedString())); + aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter()); ScDPCacheTable::GroupFilter* pGrpFilter = static_cast<ScDPCacheTable::GroupFilter*>(aCri.mpFilter.get()); @@ -1321,25 +1387,27 @@ void ScDPGroupTableData::CopyFields(const vector<long>& rFieldDims, vector<long> } } -void ScDPGroupTableData::FillGroupValues( ScDPItemData* pItemData, long nCount, const long* pDims ) +void ScDPGroupTableData::FillGroupValues( /*ScDPItemData* pItemData*/ SCROW* pItemDataIndex, long nCount, const long* pDims ) { long nGroupedColumns = aGroups.size(); + ScDPTableDataCache* pCache = GetCacheTable().GetCache(); for (long nDim=0; nDim<nCount; nDim++) { const ScDPDateGroupHelper* pDateHelper = NULL; long nColumn = pDims[nDim]; + long nSourceDim = nColumn; if ( nColumn >= nSourceCount && nColumn < nSourceCount + nGroupedColumns ) { const ScDPGroupDimension& rGroupDim = aGroups[nColumn - nSourceCount]; + nSourceDim= rGroupDim.GetSourceDim(); pDateHelper = rGroupDim.GetDateHelper(); if ( !pDateHelper ) // date is handled below { - const ScDPGroupItem* pGroupItem = rGroupDim.GetGroupForData( pItemData[nDim] ); - if ( pGroupItem ) - pItemData[nDim] = pGroupItem->GetName(); - // if no group is found, keep the original name + const ScDPGroupItem* pGroupItem = rGroupDim.GetGroupForData( *GetMemberById( nSourceDim, pItemDataIndex[nDim] )); + if ( pGroupItem ) + pItemDataIndex[nDim] = pCache->GetAdditionalItemID( pGroupItem->GetName() ); } } else if ( IsNumGroupDimension( nColumn ) ) @@ -1347,18 +1415,18 @@ void ScDPGroupTableData::FillGroupValues( ScDPItemData* pItemData, long nCount, pDateHelper = pNumGroups[nColumn].GetDateHelper(); if ( !pDateHelper ) // date is handled below { - if ( pItemData[nDim].bHasValue ) + const ScDPItemData* pData = pCache->GetItemDataById( (SCCOL)nSourceDim, pItemDataIndex[nDim]); + if ( pData ->IsValue() ) { ScDPNumGroupInfo aNumInfo; bool bHasNonInteger = false; sal_Unicode cDecSeparator = 0; GetNumGroupInfo( nColumn, aNumInfo, bHasNonInteger, cDecSeparator ); double fGroupValue; - String aGroupName = lcl_GetNumGroupForValue( pItemData[nDim].fValue, - aNumInfo, bHasNonInteger, cDecSeparator, fGroupValue, pDoc ); - - // consistent with TypedStrData in GetNumEntries - pItemData[nDim] = ScDPItemData( aGroupName, fGroupValue, TRUE ); + String aGroupName = lcl_GetNumGroupForValue( pData->GetValue(), + aNumInfo, bHasNonInteger, cDecSeparator, fGroupValue, pDoc ); + ScDPItemData aItemData ( aGroupName, fGroupValue, TRUE ) ; + pItemDataIndex[nDim] = pCache->GetAdditionalItemID( aItemData ); } // else (textual) keep original value } @@ -1366,12 +1434,18 @@ void ScDPGroupTableData::FillGroupValues( ScDPItemData* pItemData, long nCount, if ( pDateHelper ) { - if ( pItemData[nDim].bHasValue ) + const ScDPItemData* pData = GetCacheTable().GetCache()->GetItemDataById( (SCCOL)nSourceDim, pItemDataIndex[nDim]); + if ( pData ->IsValue() ) { sal_Int32 nPartValue = lcl_GetDatePartValue( - pItemData[nDim].fValue, pDateHelper->GetDatePart(), pDoc->GetFormatTable(), - &pDateHelper->GetNumInfo() ); - pItemData[nDim] = ScDPItemData( String(), nPartValue, TRUE ); + pData->GetValue(), pDateHelper->GetDatePart(), pDoc->GetFormatTable(), + &pDateHelper->GetNumInfo() ); +// Wang Xu Ming -- 2009-9-7 +// DataPilot Migration - Cache&&Performance + //String aName = lcl_GetDateGroupName( pDateHelper, nPartValue, pDoc->GetFormatTable() ); + ScDPItemData aItemData( pDateHelper->GetDatePart(), String(), nPartValue, ScDPItemData::MK_DATA|ScDPItemData::MK_VAL|ScDPItemData::MK_DATEPART ); + pItemDataIndex[nDim] = GetCacheTable().GetCache()->GetAdditionalItemID( aItemData ); +// End Comments } } } @@ -1527,5 +1601,22 @@ BOOL ScDPGroupTableData::HasCommonElement( const ScDPItemData& rFirstData, long return TRUE; } +long ScDPGroupTableData::GetSourceDim( long nDim ) +{ + if ( getIsDataLayoutDimension( nDim ) ) + return nSourceCount; + if ( nDim >= nSourceCount && nDim < nSourceCount +(long) aGroups.size() ) + { + const ScDPGroupDimension& rGroupDim = aGroups[nDim - nSourceCount]; + return rGroupDim.GetSourceDim(); + } + return nDim; +} + long ScDPGroupTableData::Compare( long nDim, long nDataId1, long nDataId2) +{ + if ( getIsDataLayoutDimension(nDim) ) + return 0; + return ScDPItemData::Compare( *GetMemberById(nDim, nDataId1),*GetMemberById(nDim, nDataId2) ); +} // ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 66ac3a4bedbb..44c998fb4ede 100644..100755 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -52,7 +52,11 @@ #include "attrib.hxx" #include "scitems.hxx" #include "unonames.hxx" - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpglobal.hxx" +#include "globstr.hrc" +// End Comments #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/sheet/GeneralFunction.hpp> #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> @@ -86,9 +90,6 @@ using ::com::sun::star::sheet::DataPilotTablePositionData; using ::com::sun::star::beans::XPropertySet; using ::rtl::OUString; -// ----------------------------------------------------------------------- - -#define MAX_LABELS 256 //!!! from fieldwnd.hxx, must be moved to global.hxx // ----------------------------------------------------------------------- @@ -168,7 +169,9 @@ ScDPObject::ScDPObject( ScDocument* pD ) : mnAutoFormatIndex( 65535 ), bAllowMove( FALSE ), nHeaderRows( 0 ), - mbHeaderLayout(false) + mbHeaderLayout(false), + bRefresh( FALSE ), // Wang Xu Ming - DataPilot migration + mnCacheId( -1) // Wang Xu Ming - DataPilot migration { } @@ -189,7 +192,9 @@ ScDPObject::ScDPObject(const ScDPObject& r) : mnAutoFormatIndex( r.mnAutoFormatIndex ), bAllowMove( FALSE ), nHeaderRows( r.nHeaderRows ), - mbHeaderLayout( r.mbHeaderLayout ) + mbHeaderLayout( r.mbHeaderLayout ), + bRefresh( r.bRefresh ), // Wang Xu Ming - DataPilot migration + mnCacheId ( r.mnCacheId ) // Wang Xu Ming - DataPilot migration { if (r.pSaveData) pSaveData = new ScDPSaveData(*r.pSaveData); @@ -209,6 +214,7 @@ ScDPObject::~ScDPObject() delete pSheetDesc; delete pImpDesc; delete pServDesc; + mnCacheId = -1; // Wang Xu Ming - DataPilot migration } ScDataObject* ScDPObject::Clone() const @@ -232,6 +238,13 @@ void ScDPObject::SetSaveData(const ScDPSaveData& rData) { delete pSaveData; pSaveData = new ScDPSaveData( rData ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + if ( rData.GetCacheId() >= 0 ) + mnCacheId = rData.GetCacheId(); + else if ( mnCacheId >= 0 ) + pSaveData->SetCacheId( mnCacheId ); + // End Comments } InvalidateData(); // re-init source from SaveData @@ -411,10 +424,11 @@ ScDPTableData* ScDPObject::GetTableData() { if (!mpTableData) { + shared_ptr<ScDPTableData> pData; if ( pImpDesc ) { // database data - mpTableData.reset(new ScDatabaseDPData(pDoc, *pImpDesc)); + pData.reset(new ScDatabaseDPData(pDoc, *pImpDesc, GetCacheId())); } else { @@ -424,16 +438,27 @@ ScDPTableData* ScDPObject::GetTableData() DBG_ERROR("no source descriptor"); pSheetDesc = new ScSheetSourceDesc; // dummy defaults } - mpTableData.reset(new ScSheetDPData(pDoc, *pSheetDesc)); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + pData.reset(new ScSheetDPData(pDoc, *pSheetDesc, GetCacheId())); + // End Comments } // grouping (for cell or database data) if ( pSaveData && pSaveData->GetExistingDimensionData() ) { - shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(mpTableData, pDoc)); + shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(pData, pDoc)); pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData); - mpTableData = pGroupData; + pData = pGroupData; } + + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + if ( pData ) + SetCacheId( pData->GetCacheId()); // resets mpTableData + // End Comments + + mpTableData = pData; // after SetCacheId } return mpTableData.get(); @@ -462,11 +487,17 @@ void ScDPObject::CreateObjects() { DBG_ASSERT( !pServDesc, "DPSource could not be created" ); ScDPTableData* pData = GetTableData(); + ScDPSource* pSource = new ScDPSource( pData ); xSource = pSource; - } - if (pSaveData) + if ( pSaveData && bRefresh ) + { + pSaveData->Refresh( xSource ); + bRefresh = FALSE; + } + } + if (pSaveData ) pSaveData->WriteToSource( xSource ); } else if (bSettingsChanged) @@ -784,13 +815,10 @@ bool ScDPObject::IsDimNameInUse(const OUString& rName) const if (!xPropSet.is()) continue; - Any any = xPropSet->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME)); - OUString aLayoutName; - if (any >>= aLayoutName) - { - if (aLayoutName.equalsIgnoreAsciiCase(rName)) - return true; - } + OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty( + xPropSet, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString()); + if (aLayoutName.equalsIgnoreAsciiCase(rName)) + return true; } return false; } @@ -2301,48 +2329,6 @@ uno::Reference<sheet::XDimensionsSupplier> ScDPObject::CreateSource( const ScDPS return xRet; } -// ============================================================================ - -ScDPCacheCell::ScDPCacheCell() : - mnStrId(ScSimpleSharedString::EMPTY), - mnType(SC_VALTYPE_EMPTY), - mfValue(0.0), - mbNumeric(false) -{ -} - -ScDPCacheCell::ScDPCacheCell(const ScDPCacheCell& r) : - mnStrId(r.mnStrId), - mnType(r.mnType), - mfValue(r.mfValue), - mbNumeric(r.mbNumeric) -{ -} - -ScDPCacheCell::~ScDPCacheCell() -{ -} - -// ============================================================================ - -size_t ScDPCollection::CacheCellHash::operator()(const ScDPCacheCell* pCell) const -{ - return pCell->mnStrId + static_cast<size_t>(pCell->mnType) + - static_cast<size_t>(pCell->mfValue) + static_cast<size_t>(pCell->mbNumeric); -} - -bool ScDPCollection::CacheCellEqual::operator()(const ScDPCacheCell* p1, const ScDPCacheCell* p2) const -{ - if (!p1 && !p2) - return true; - - if ((!p1 && p2) || (p1 && !p2)) - return false; - - return p1->mnStrId == p2->mnStrId && p1->mfValue == p2->mfValue && - p1->mbNumeric == p2->mbNumeric && p1->mnType == p2->mnType; -} - // ---------------------------------------------------------------------------- ScDPCollection::ScDPCollection(ScDocument* pDocument) : @@ -2352,15 +2338,12 @@ ScDPCollection::ScDPCollection(ScDocument* pDocument) : ScDPCollection::ScDPCollection(const ScDPCollection& r) : ScCollection(r), - pDoc(r.pDoc), - maSharedString(r.maSharedString), - maCacheCellPool() // #i101725# don't copy hash_set with pointers from the other collection + pDoc(r.pDoc) { } ScDPCollection::~ScDPCollection() { - clearCacheCellPool(); } ScDataObject* ScDPCollection::Clone() const @@ -2465,10 +2448,83 @@ String ScDPCollection::CreateNewName( USHORT nMin ) const return String(); // should not happen } -ScSimpleSharedString& ScDPCollection::GetSharedString() + + +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +long ScDPObject::GetCacheId() const { - return maSharedString; + if ( GetSaveData() ) + return GetSaveData()->GetCacheId(); + else + return mnCacheId; } +ULONG ScDPObject::RefreshCache() +{ + if ( pServDesc ) + { + // cache table isn't used for external service - do nothing, no error + return 0; + } + + CreateObjects(); + ULONG nErrId = 0; + if ( pSheetDesc) + nErrId = pSheetDesc->CheckValidate( pDoc ); + if ( nErrId == 0 ) + { + long nOldId = GetCacheId(); + long nNewId = pDoc->GetNewDPObjectCacheId(); + if ( nOldId >= 0 ) + pDoc->RemoveDPObjectCache( nOldId ); + + ScDPTableDataCache* pCache = NULL; + if ( pSheetDesc ) + pCache = pSheetDesc->CreateCache( pDoc, nNewId ); + else if ( pImpDesc ) + pCache = pImpDesc->CreateCache( pDoc, nNewId ); + + if ( pCache == NULL ) + { + //cache failed + DBG_ASSERT( pCache , " pCache == NULL" ); + return STR_ERR_DATAPILOTSOURCE; + } + + nNewId = pCache->GetId(); + + bRefresh = TRUE; + ScDPCollection* pDPCollection = pDoc->GetDPCollection(); + USHORT nCount = pDPCollection->GetCount(); + for (USHORT i=0; i<nCount; i++) + { //set new cache id + if ( (*pDPCollection)[i]->GetCacheId() == nOldId ) + { + (*pDPCollection)[i]->SetCacheId( nNewId ); + (*pDPCollection)[i]->SetRefresh(); + + } + } + DBG_ASSERT( GetCacheId() >= 0, " GetCacheId() >= 0 " ); + } + return nErrId; +} +void ScDPObject::SetCacheId( long nCacheId ) +{ + if ( GetCacheId() != nCacheId ) + { + InvalidateSource(); + if ( GetSaveData() ) + GetSaveData()->SetCacheId( nCacheId ); + + mnCacheId = nCacheId; + } +} +const ScDPTableDataCache* ScDPObject::GetCache() const +{ + return pDoc->GetDPObjectCache( GetCacheId() ); +} +// End Comments void ScDPCollection::FreeTable(ScDPObject* pDPObj) { @@ -2503,54 +2559,4 @@ bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const return pMergeAttr->HasDPTable(); } -ScDPCacheCell* ScDPCollection::getCacheCellFromPool(const ScDPCacheCell& rCell) -{ - ScDPCacheCell aCell(rCell); - CacheCellPoolType::iterator itr = maCacheCellPool.find(&aCell); - if (itr == maCacheCellPool.end()) - { - // Insert a new instance. - ScDPCacheCell* p = new ScDPCacheCell(rCell); - ::std::pair<CacheCellPoolType::iterator, bool> r = - maCacheCellPool.insert(p); - if (!r.second) - delete p; - - ScDPCacheCell* p2 = r.second ? *r.first : NULL; - DBG_ASSERT(p == p2, "ScDPCollection::getCacheCellFromPool: pointer addresses differ"); - return p2; - } - return *itr; -} - -namespace { - -class DeleteCacheCells : public ::std::unary_function<ScDPCacheCell*, void> -{ -public: - void operator()(ScDPCacheCell* p) const - { - delete p; - } -}; - -} - -void ScDPCollection::clearCacheCellPool() -{ - // Transferring all stored pointers to a vector first. For some unknown - // reason, deleting cell content instances by directly iterating through - // the hash set causes the iteration to return an identical pointer - // value twice, causing a double-delete. I have no idea why this happens. - - using ::std::copy; - using ::std::back_inserter; - - vector<ScDPCacheCell*> ps; - ps.reserve(maCacheCellPool.size()); - copy(maCacheCellPool.begin(), maCacheCellPool.end(), back_inserter(ps)); - maCacheCellPool.clear(); - // for correctness' sake, delete the elements after clearing the hash_set - for_each(ps.begin(), ps.end(), DeleteCacheCells()); -} diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index 7ecdc3d34702..ec384874aa69 100644..100755 --- a/sc/source/core/data/dpoutput.cxx +++ b/sc/source/core/data/dpoutput.cxx @@ -56,22 +56,11 @@ #include "scresid.hxx" #include "unonames.hxx" #include "sc.hrc" - -#include <com/sun/star/container/XNamed.hpp> -#include <com/sun/star/sheet/DataPilotFieldFilter.hpp> -#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> -#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp> -#include <com/sun/star/sheet/DataPilotTablePositionData.hpp> -#include <com/sun/star/sheet/DataPilotTablePositionType.hpp> -#include <com/sun/star/sheet/DataPilotTableResultData.hpp> -#include <com/sun/star/sheet/DataResultFlags.hpp> -#include <com/sun/star/sheet/GeneralFunction.hpp> -#include <com/sun/star/sheet/MemberResultFlags.hpp> -#include <com/sun/star/sheet/TableFilterField.hpp> -#include <com/sun/star/sheet/XDataPilotMemberResults.hpp> -#include <com/sun/star/sheet/XDataPilotResults.hpp> -#include <com/sun/star/sheet/XHierarchiesSupplier.hpp> -#include <com/sun/star/sheet/XLevelsSupplier.hpp> +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "scdpoutputimpl.hxx" +#include "dpglobal.hxx" +// End Comments #include <com/sun/star/beans/XPropertySet.hpp> #include <vector> @@ -451,14 +440,12 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS if ( xLevNam.is() && xLevRes.is() ) { String aName = xLevNam->getName(); - OUString aCaption = aName; // Caption equals the field name by default. Reference<XPropertySet> xPropSet(xLevel, UNO_QUERY); - if (xPropSet.is()) - { - Any any = xPropSet->getPropertyValue( - OUString::createFromAscii(SC_UNO_LAYOUTNAME)); - any >>= aCaption; - } + // Caption equals the field name by default. + // #i108948# use ScUnoHelpFunctions::GetStringProperty, because + // LayoutName is new and may not be present in external implementation + OUString aCaption = ScUnoHelpFunctions::GetStringProperty( xPropSet, + OUString::createFromAscii(SC_UNO_LAYOUTNAME), aName ); bool bRowFieldHasMember = false; switch ( eDimOrient ) @@ -653,11 +640,21 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab, if ( nFlags & sheet::MemberResultFlags::SUBTOTAL ) { // SvxWeightItem aItem( WEIGHT_BOLD ); // weight is in the style - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + OutputImpl outputimp( pDoc, nTab, + nTabStartCol, nTabStartRow, nMemberStartCol, nMemberStartRow, + nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow ); + // End Comments //! limit frames to horizontal or vertical? if (bColHeader) { - lcl_SetFrame( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nTabEndRow, 20 ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + //lcl_SetFrame( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nTabEndRow, SC_DP_FRAME_INNER_BOLD ); + outputimp.OutputBlockFrame( nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1 ); + // End Comments + lcl_SetStyleById( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1, STR_PIVOT_STYLE_TITLE ); lcl_SetStyleById( pDoc,nTab, nCol,nDataStartRow, nCol,nTabEndRow, @@ -665,7 +662,11 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab, } else { - lcl_SetFrame( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nTabEndCol,nRow, 20 ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + //lcl_SetFrame( pDoc,nTab, nMemberStartCol+(USHORT)nLevel,nRow, nTabEndCol,nRow, SC_DP_FRAME_INNER_BOLD ); + outputimp.OutputBlockFrame( nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow ); + // End Comments lcl_SetStyleById( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow, STR_PIVOT_STYLE_TITLE ); lcl_SetStyleById( pDoc,nTab, nDataStartCol,nRow, nTabEndCol,nRow, @@ -814,6 +815,20 @@ void ScDPOutput::Output() if ( bDoFilter ) lcl_DoFilterButton( pDoc, aStartPos.Col(), aStartPos.Row(), nTab ); + // output data results: + + for (long nRow=0; nRow<nRowCount; nRow++) + { + SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow + const sheet::DataResult* pColAry = pRowAry[nRow].getConstArray(); + long nThisColCount = pRowAry[nRow].getLength(); + DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ??? + for (long nCol=0; nCol<nThisColCount; nCol++) + { + SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow + DataCell( nColPos, nRowPos, nTab, pColAry[nCol] ); + } + } // output page fields: for (nField=0; nField<nPageFieldCount; nField++) @@ -856,7 +871,12 @@ void ScDPOutput::Output() STR_PIVOT_STYLE_INNER ); // output column headers: - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + OutputImpl outputimp( pDoc, nTab, + nTabStartCol, nTabStartRow, nMemberStartCol, nMemberStartRow, + nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow ); + // End Comments for (nField=0; nField<nColFieldCount; nField++) { SCCOL nHdrCol = nDataStartCol + (SCCOL)nField; //! check for overflow @@ -871,28 +891,44 @@ void ScDPOutput::Output() { SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow HeaderCell( nColPos, nRowPos, nTab, pArray[nCol], TRUE, nField ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance if ( ( pArray[nCol].Flags & sheet::MemberResultFlags::HASMEMBER ) && !( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL ) ) { + long nEnd = nCol; + while ( nEnd+1 < nThisColCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) ) + ++nEnd; + SCCOL nEndColPos = nDataStartCol + (SCCOL)nEnd; //! check for overflow if ( nField+1 < nColFieldCount ) { - long nEnd = nCol; - while ( nEnd+1 < nThisColCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) ) - ++nEnd; - SCCOL nEndColPos = nDataStartCol + (SCCOL)nEnd; //! check for overflow - lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nRowPos, 20 ); - lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nTabEndRow, 20 ); + // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nRowPos, SC_DP_FRAME_INNER_BOLD ); + // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nTabEndRow, SC_DP_FRAME_INNER_BOLD ); + if ( nField == nColFieldCount - 2 ) + { + outputimp.AddCol( nColPos ); + if ( nColPos + 1 == nEndColPos ) + outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos+1, TRUE ); + } + else + outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos ); lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nEndColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY ); } else lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY ); } + else if ( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL ) + outputimp.AddCol( nColPos ); } + if ( nField== 0 && nColFieldCount == 1 ) + outputimp.OutputBlockFrame( nDataStartCol,nTabStartRow, nTabEndCol,nRowPos-1 ); + // End Comments } // output row headers: - + std::vector<BOOL> vbSetBorder; + vbSetBorder.resize( nTabEndRow - nDataStartRow + 1, FALSE ); for (nField=0; nField<nRowFieldCount; nField++) { bool bDataLayout = mbHasDataLayout && (nField == nRowFieldCount-1); @@ -920,41 +956,39 @@ void ScDPOutput::Output() while ( nEnd+1 < nThisRowCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) ) ++nEnd; SCROW nEndRowPos = nDataStartRow + (SCROW)nEnd; //! check for overflow - lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nColPos,nEndRowPos, 20 ); - lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nTabEndCol,nEndRowPos, 20 ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nColPos,nEndRowPos, SC_DP_FRAME_INNER_BOLD ); + //lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nTabEndCol,nEndRowPos, SC_DP_FRAME_INNER_BOLD ); + outputimp.AddRow( nRowPos ); + if ( vbSetBorder[ nRow ] == FALSE ) + { + outputimp.OutputBlockFrame( nColPos, nRowPos, nTabEndCol, nEndRowPos ); + vbSetBorder[ nRow ] = TRUE; + } + outputimp.OutputBlockFrame( nColPos, nRowPos, nColPos, nEndRowPos ); + + if ( nField == nRowFieldCount - 2 ) + outputimp.OutputBlockFrame( nColPos+1, nRowPos, nColPos+1, nEndRowPos ); + // End Comments lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nEndRowPos, STR_PIVOT_STYLE_CATEGORY ); } else lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nRowPos, STR_PIVOT_STYLE_CATEGORY ); } + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + else if ( pArray[nRow].Flags & sheet::MemberResultFlags::SUBTOTAL ) + outputimp.AddRow( nRowPos ); + // End Comments } } - // output data results: - - for (long nRow=0; nRow<nRowCount; nRow++) - { - SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow - const sheet::DataResult* pColAry = pRowAry[nRow].getConstArray(); - long nThisColCount = pRowAry[nRow].getLength(); - DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ??? - for (long nCol=0; nCol<nThisColCount; nCol++) - { - SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow - DataCell( nColPos, nRowPos, nTab, pColAry[nCol] ); - } - } - - // frame around the whole table - - lcl_SetFrame( pDoc,nTab, nDataStartCol,nDataStartRow, nTabEndCol,nTabEndRow, 20 ); - if ( nDataStartCol > nMemberStartCol ) - lcl_SetFrame( pDoc,nTab, nMemberStartCol,nDataStartRow, nDataStartCol-1,nTabEndRow, 20 ); - if ( nDataStartRow > nMemberStartRow ) - lcl_SetFrame( pDoc,nTab, nDataStartCol,nMemberStartRow, nTabEndCol,nDataStartRow-1, 20 ); - - lcl_SetFrame( pDoc,nTab, nTabStartCol,nTabStartRow, nTabEndCol,nTabEndRow, 40 ); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + outputimp.OutputDataArea(); +// End Comments } ScRange ScDPOutput::GetOutputRange( sal_Int32 nRegionType ) diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index 58a9e112ab7d..72cf15285310 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -54,6 +54,19 @@ #include <com/sun/star/sheet/XMembersSupplier.hpp> #include <com/sun/star/container/XNamed.hpp> #include <com/sun/star/util/XCloneable.hpp> +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dptabsrc.hxx" +#include "dpglobal.hxx" +using namespace ScDPGlobal; +#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDREFERENCETYPE_HPP_ +#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp> +#endif +#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDREFERENCEITEMTYPE_HPP_ +#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp> +#endif +using namespace com::sun::star::sheet; +// End Comments #include <hash_map> @@ -73,25 +86,6 @@ using ::std::auto_ptr; // ----------------------------------------------------------------------- -//! move to a header file -//! use names from unonames.hxx? -#define DP_PROP_COLUMNGRAND "ColumnGrand" -#define DP_PROP_FUNCTION "Function" -#define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows" -#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension" -#define DP_PROP_ISVISIBLE "IsVisible" -#define DP_PROP_ORIENTATION "Orientation" -#define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty" -#define DP_PROP_ROWGRAND "RowGrand" -#define DP_PROP_SHOWDETAILS "ShowDetails" -#define DP_PROP_SHOWEMPTY "ShowEmpty" -#define DP_PROP_SUBTOTALS "SubTotals" -#define DP_PROP_USEDHIERARCHY "UsedHierarchy" -#define DP_PROP_FILTER "Filter" -#define DP_PROP_POSITION "Position" - -// ----------------------------------------------------------------------- - void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp, const rtl::OUString& rName, sal_Bool bValue ) { @@ -320,6 +314,51 @@ BOOL ScDPSaveDimension::operator== ( const ScDPSaveDimension& r ) const if (!(**a == **b)) return FALSE; + if ( this->HasCurrentPage() && r.HasCurrentPage() ) + { + if ( this->GetCurrentPage() != r.GetCurrentPage() ) + { + return FALSE; + } + } + else if ( this->HasCurrentPage() || r.HasCurrentPage() ) + { + return FALSE; + } + if( pReferenceValue && r.pReferenceValue ) + { + if ( !(*pReferenceValue == *r.pReferenceValue) ) + { + return FALSE; + } + } + else if ( pReferenceValue || r.pReferenceValue ) + { + return FALSE; + } + if( this->pSortInfo && r.pSortInfo ) + { + if ( !(*this->pSortInfo == *r.pSortInfo) ) + { + return FALSE; + } + } + else if ( this->pSortInfo || r.pSortInfo ) + { + return FALSE; + } + if( this->pAutoShowInfo && r.pAutoShowInfo ) + { + if ( !(*this->pAutoShowInfo == *r.pAutoShowInfo) ) + { + return FALSE; + } + } + else if ( this->pAutoShowInfo || r.pAutoShowInfo ) + { + return FALSE; + } + return TRUE; } @@ -709,6 +748,10 @@ ScDPSaveData::ScDPSaveData() : nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ), bFilterButton( TRUE ), bDrillDown( TRUE ), + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + mnCacheId( -1), + // End Comments mbDimensionMembersBuilt(false), mpGrandTotalName(NULL) { @@ -721,6 +764,10 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) : nRepeatEmptyMode( r.nRepeatEmptyMode ), bFilterButton( r.bFilterButton ), bDrillDown( r.bDrillDown ), + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + mnCacheId( r.mnCacheId ), + // End Comments mbDimensionMembersBuilt(r.mbDimensionMembersBuilt), mpGrandTotalName(NULL) { @@ -744,40 +791,11 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r ) { if ( &r != this ) { - delete pDimensionData; - if ( r.pDimensionData ) - pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData ); - else - pDimensionData = NULL; - - nColumnGrandMode = r.nColumnGrandMode; - nRowGrandMode = r.nRowGrandMode; - nIgnoreEmptyMode = r.nIgnoreEmptyMode; - nRepeatEmptyMode = r.nRepeatEmptyMode; - bFilterButton = r.bFilterButton; - bDrillDown = r.bDrillDown; - mbDimensionMembersBuilt = r.mbDimensionMembersBuilt; - - // remove old dimensions - - long nCount = aDimList.Count(); - long i; - for (i=0; i<nCount; i++) - delete (ScDPSaveDimension*)aDimList.GetObject(i); - aDimList.Clear(); - - // copy new dimensions - - nCount = r.aDimList.Count(); - for (i=0; i<nCount; i++) - { - ScDPSaveDimension* pNew = - new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) ); - aDimList.Insert( pNew, LIST_APPEND ); - } - - if (r.mpGrandTotalName.get()) - mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName)); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + this->~ScDPSaveData(); + new( this ) ScDPSaveData ( r ); + // End Comments } return *this; } @@ -789,6 +807,7 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const nIgnoreEmptyMode != r.nIgnoreEmptyMode || nRepeatEmptyMode != r.nRepeatEmptyMode || bFilterButton != r.bFilterButton || + mnCacheId != r.mnCacheId ||/// Wang Xu Ming -- 2009-6-18 DataPilot Migration bDrillDown != r.bDrillDown || mbDimensionMembersBuilt != r.mbDimensionMembersBuilt) return FALSE; @@ -1089,6 +1108,7 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie // reset all orientations //! "forgetSettings" or similar at source ????? //! reset all duplicated dimensions, or reuse them below !!! + DBG_TRACE( "ScDPSaveData::WriteToSource" ); lcl_ResetOrient( xSource ); @@ -1097,6 +1117,9 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie { ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i); rtl::OUString aName = pDim->GetName(); + + DBG_TRACESTR(pDim->GetName()); + BOOL bData = pDim->IsDataLayout(); //! getByName for ScDPSource, including DataLayoutDimension !!!!!!!! @@ -1228,16 +1251,17 @@ void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData) continue; long nDimIndex = itr->second; - const TypedScStrCollection& rMembers = pData->GetColumnEntries(nDimIndex); - sal_uInt16 nMemberCount = rMembers.GetCount(); - for (sal_uInt16 j = 0; j < nMemberCount; ++j) + const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex); + size_t mMemberCount = rMembers.size(); + for (size_t j = 0; j < mMemberCount; ++j) { - const String& rMemName = rMembers[j]->GetString(); - if (pDim->GetExistingMemberByName(rMemName)) + const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] ); + String aMemName = pMemberData->GetString(); + if (pDim->GetExistingMemberByName(aMemName)) // this member instance already exists. nothing to do. continue; - auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(rMemName)); + auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName)); pNewMember->SetIsVisible(true); pDim->AddMember(pNewMember.release()); } @@ -1254,3 +1278,196 @@ bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const return pDim->HasInvisibleMember(); } + +void ScDPSaveData::Refresh( const uno::Reference<sheet::XDimensionsSupplier>& xSource ) +{ + try + { + long nCount = aDimList.Count(); + std::list<String> deletedDims; + for (long i=nCount-1; i >=0 ; i--) + { + ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i); + + rtl::OUString aName = pDim->GetName(); + if ( pDim->IsDataLayout() ) + continue; + + uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions(); + uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName ); + long nIntCount = xIntDims->getCount(); + BOOL bFound = FALSE; + for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++) + { + uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) ); + uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY ); + if ( xDimName.is() && xDimName->getName() == aName ) + bFound = TRUE; + } + if ( !bFound ) + { + deletedDims.push_back( aName ); + aDimList.Remove(i); + DBG_TRACE( "\n Remove dim: \t" ); + DBG_TRACESTR( String( aName ) ); + } + + } + + nCount = aDimList.Count(); + for (long i=nCount-1; i >=0 ; i--) //check every dimension ?? + { + ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i); + + rtl::OUString aName = pDim->GetName(); + if ( pDim->IsDataLayout() ) + continue; + pDim->Refresh( xSource, deletedDims ); + + } + } + catch(uno::Exception&) + { + DBG_ERROR("error in ScDPSaveData::Refresh"); + } + +} +void ScDPSaveDimension::Refresh( const com::sun::star::uno::Reference< + com::sun::star::sheet::XDimensionsSupplier>& xSource , + const std::list<String>& deletedDims) +{ + if ( xSource.is() ) + { + ScDPSource* pTabSource = static_cast<ScDPSource*>( xSource.get() ); + ScDPTableDataCache* pCache = pTabSource->GetCache(); + if ( pCache->GetId() == -1 ) + return; + + SCCOL nSrcDim = pCache->GetDimensionIndex( GetName() ); + + if ( nSrcDim == -1 ) + return; + if ( pSelectedPage ) + {//check pSelected page + DBG_TRACESTR( (*pSelectedPage) ); + if ( pCache->GetIdByItemData( nSrcDim, *pSelectedPage ) == -1 ) + { + delete pSelectedPage; + pSelectedPage = NULL; + } + + }; + + if ( pReferenceValue && pReferenceValue->ReferenceItemType == DataPilotFieldReferenceItemType::NAMED ) + {//check pReferenceValue +#ifdef DEBUG + switch( pReferenceValue->ReferenceType) + { + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE: //both + DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE \n" ); + break; + case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE: //both + DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE \n" ); + break; + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE: //both + DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE \n" ); + break; + case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL: + DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::RUNNING_TOTAL \n" ); //enable name + break; + } +#endif + switch( pReferenceValue->ReferenceType) + { + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE: + case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE: + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE: + case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL: + { + if( pReferenceValue->ReferenceItemType == DataPilotFieldReferenceItemType::NAMED ) + { + const String& sReferenceFieldName = pReferenceValue->ReferenceField; + DBG_TRACESTR( sReferenceFieldName ); + SCCOL nRefDim = pCache->GetDimensionIndex( sReferenceFieldName ); + bool bValid = true; + if ( nRefDim == -1 ) + bValid = false; + else if ( pReferenceValue->ReferenceType != sheet::DataPilotFieldReferenceType::RUNNING_TOTAL ) + { //running total has not reference item + const String& sReferenceItemName = pReferenceValue->ReferenceItemName; + DBG_TRACESTR( sReferenceItemName ); + if ( pCache->GetIdByItemData( nRefDim, sReferenceItemName ) == -1 ) + bValid = false; + } + if ( !bValid ) + { + delete pReferenceValue; + pReferenceValue = NULL; + } + } + } + break; + } + + }; + + if ( pSortInfo ) + { //check sortinfo + if ( pSortInfo->Mode == DataPilotFieldSortMode::DATA ) + { + DBG_TRACE( "\n DataPilotFieldSortMode::DATA \n" ); + const String& sFieldDimName = pSortInfo->Field; + std::list<String>::const_iterator iter = std::find( deletedDims.begin(), deletedDims.end(), sFieldDimName ); + if ( iter != deletedDims.end() && pCache->GetDimensionIndex( sFieldDimName ) == -1 ) + { + pSortInfo->Mode = DataPilotFieldSortMode::MANUAL; + pSortInfo->Field = GetName(); + } + } + + }; + + if ( pAutoShowInfo ) + { //check autoshow + const String& sFieldDimName = pAutoShowInfo->DataField; + std::list<String>::const_iterator iter = std::find( deletedDims.begin(), deletedDims.end(), sFieldDimName ); + if ( iter != deletedDims.end() && pCache->GetDimensionIndex( sFieldDimName ) == -1 ) + { + delete pAutoShowInfo; + pAutoShowInfo = NULL; + } + + }; + + //remove unused members + //SODC_19124 + for (MemberList::iterator i=maMemberList.begin(); i != maMemberList.end() ; ) + { + rtl::OUString aMemberName = (*i)->GetName(); + if ( pCache->GetIdByItemData( nSrcDim, aMemberName ) == -1 ) + i = maMemberList.erase( i ); + else + i++; + } + } +} +// End Comments +bool operator == (const ::com::sun::star::sheet::DataPilotFieldSortInfo &l, const ::com::sun::star::sheet::DataPilotFieldSortInfo &r ) +{ + return l.Field == r.Field && l.IsAscending == r.IsAscending && l.Mode == r.Mode; +} +bool operator == (const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &l, const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &r ) +{ + return l.IsEnabled == r.IsEnabled && + l.ShowItemsMode == r.ShowItemsMode && + l.ItemCount == r.ItemCount && + l.DataField == r.DataField; +} +bool operator == (const ::com::sun::star::sheet::DataPilotFieldReference &l, const ::com::sun::star::sheet::DataPilotFieldReference &r ) +{ + return l.ReferenceType == r.ReferenceType && + l.ReferenceField == r.ReferenceField && + l.ReferenceItemType == r.ReferenceItemType && + l.ReferenceItemName == r.ReferenceItemName; +} + diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx index be8eca58ce95..aae5797211b0 100644 --- a/sc/source/core/data/dpsdbtab.cxx +++ b/sc/source/core/data/dpsdbtab.cxx @@ -69,169 +69,181 @@ using ::com::sun::star::uno::Any; using ::com::sun::star::uno::UNO_QUERY; #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet" -#define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler" +#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler" //! move to a header file? #define SC_DBPROP_DATASOURCENAME "DataSourceName" #define SC_DBPROP_COMMAND "Command" #define SC_DBPROP_COMMANDTYPE "CommandType" - // ----------------------------------------------------------------------- - -class ScDatabaseDPData_Impl +// Wang Xu Ming -- 2009-9-15 +// DataPilot Migration - Cache&&Performance + ScDPTableDataCache* ScImportSourceDesc::GetExistDPObjectCache( ScDocument* pDoc ) const { -public: - ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager; - ScImportSourceDesc aDesc; - long nColCount; - uno::Reference<sdbc::XRowSet> xRowSet; - sal_Int32* pTypes; - SvNumberFormatter* pFormatter; - - ScDPCacheTable aCacheTable; - - ScDatabaseDPData_Impl(ScDPCollection* p) : - aCacheTable(p) + ScDPTableDataCache* pCache = NULL; + ScDPCollection* pDPCollection= pDoc->GetDPCollection(); + USHORT nCount = pDPCollection->GetCount(); + + for ( short i=nCount-1; i>=0 ; i--) { + if ( const ScImportSourceDesc* pUsedDesc = (*pDPCollection)[i]->GetImportSourceDesc() ) + if ( *this == *pUsedDesc ) + { + long nID = (*pDPCollection)[i]->GetCacheId(); + if ( nID >= 0 ) + pCache= pDoc->GetDPObjectCache( nID ); + if ( pCache ) + return pCache; + } } -}; - -// ----------------------------------------------------------------------- - -ScDatabaseDPData::ScDatabaseDPData( - ScDocument* pDoc, - const ScImportSourceDesc& rImport ) : - ScDPTableData(pDoc) -{ - pImpl = new ScDatabaseDPData_Impl(pDoc->GetDPCollection()); - pImpl->xServiceManager = pDoc->GetServiceManager(); - pImpl->aDesc = rImport; - pImpl->nColCount = 0; - pImpl->pTypes = NULL; - pImpl->pFormatter = NULL; // created on demand - - OpenDatabase(); - CreateCacheTable(); -} - -ScDatabaseDPData::~ScDatabaseDPData() -{ - ::comphelper::disposeComponent( pImpl->xRowSet ); - - delete[] pImpl->pTypes; - delete pImpl->pFormatter; // NumberFormatter is local for this object - delete pImpl; + return NULL; } -void ScDatabaseDPData::DisposeData() +ScDPTableDataCache* ScImportSourceDesc::CreateCache( ScDocument* pDoc , long nID ) const { - //! use OpenDatabase here? - pImpl->aCacheTable.clear(); -} + if ( !pDoc ) + return NULL; -BOOL ScDatabaseDPData::OpenDatabase() -{ sal_Int32 nSdbType = -1; - switch ( pImpl->aDesc.nType ) + + switch ( nType ) { - case sheet::DataImportMode_SQL: nSdbType = sdb::CommandType::COMMAND; break; - case sheet::DataImportMode_TABLE: nSdbType = sdb::CommandType::TABLE; break; - case sheet::DataImportMode_QUERY: nSdbType = sdb::CommandType::QUERY; break; - default: - return FALSE; + case sheet::DataImportMode_SQL: nSdbType = sdb::CommandType::COMMAND; break; + case sheet::DataImportMode_TABLE: nSdbType = sdb::CommandType::TABLE; break; + case sheet::DataImportMode_QUERY: nSdbType = sdb::CommandType::QUERY; break; + default: + return NULL; } - BOOL bSuccess = FALSE; + + ScDPTableDataCache* pCache = GetExistDPObjectCache( pDoc ); + + if ( pCache && ( nID < 0 || nID == pCache->GetId() ) ) + return pCache; + + if ( pCache == NULL ) + pCache = new ScDPTableDataCache( pDoc ); + + uno::Reference<sdbc::XRowSet> xRowSet ; try { - pImpl->xRowSet = uno::Reference<sdbc::XRowSet>( - comphelper::getProcessServiceFactory()->createInstance( - rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), - uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xRowProp( pImpl->xRowSet, uno::UNO_QUERY ); + xRowSet = uno::Reference<sdbc::XRowSet>( + comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY ); DBG_ASSERT( xRowProp.is(), "can't get RowSet" ); if ( xRowProp.is() ) { // // set source parameters // - uno::Any aAny; - - aAny <<= rtl::OUString( pImpl->aDesc.aDBName ); + aAny <<= rtl::OUString( aDBName ); xRowProp->setPropertyValue( - rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny ); + rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny ); - aAny <<= rtl::OUString( pImpl->aDesc.aObject ); + aAny <<= rtl::OUString( aObject ); xRowProp->setPropertyValue( - rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny ); + rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny ); aAny <<= nSdbType; xRowProp->setPropertyValue( - rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny ); + rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny ); - uno::Reference<sdb::XCompletedExecution> xExecute( pImpl->xRowSet, uno::UNO_QUERY ); + uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY ); if ( xExecute.is() ) { uno::Reference<task::XInteractionHandler> xHandler( - comphelper::getProcessServiceFactory()->createInstance( - rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ), - uno::UNO_QUERY); + comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ), + uno::UNO_QUERY); xExecute->executeWithCompletion( xHandler ); } else - pImpl->xRowSet->execute(); - - // - // get column descriptions - // - - pImpl->nColCount = 0; - uno::Reference<sdbc::XResultSetMetaData> xMeta; - uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( pImpl->xRowSet, uno::UNO_QUERY ); - if ( xMetaSupp.is() ) - xMeta = xMetaSupp->getMetaData(); - if ( xMeta.is() ) - pImpl->nColCount = xMeta->getColumnCount(); // this is the number of real columns - - uno::Reference<sdbc::XResultSet> xResSet( pImpl->xRowSet, uno::UNO_QUERY ); - if ( pImpl->nColCount > 0 && xResSet.is() ) - { - pImpl->pTypes = new sal_Int32[pImpl->nColCount]; - for (long nCol=0; nCol<pImpl->nColCount; nCol++) - pImpl->pTypes[nCol] = xMeta->getColumnType( nCol+1 ); - - bSuccess = TRUE; - } + xRowSet->execute(); + SvNumberFormatter aFormat( pDoc->GetServiceManager(), ScGlobal::eLnge); + pCache->InitFromDataBase( xRowSet, *aFormat.GetNullDate() ); + pCache->SetId( nID ); + pDoc->AddDPObjectCache( pCache ); + DBG_TRACE1("Create a cache id = %d \n", pCache->GetId() ); } } catch ( sdbc::SQLException& rError ) { //! store error message + delete pCache; + pCache = NULL; InfoBox aInfoBox( 0, String(rError.Message) ); aInfoBox.Execute(); } catch ( uno::Exception& ) { + delete pCache; + pCache = NULL; DBG_ERROR("Unexpected exception in database"); } - if (!bSuccess) - ::comphelper::disposeComponent( pImpl->xRowSet ); + ::comphelper::disposeComponent( xRowSet ); + return pCache; +} - return bSuccess; +ScDPTableDataCache* ScImportSourceDesc::GetCache( ScDocument* pDoc, long nID ) const +{ + ScDPTableDataCache* pCache = pDoc->GetDPObjectCache( nID ); + if ( NULL == pCache && pDoc ) + pCache = GetExistDPObjectCache( pDoc); + if ( NULL == pCache ) + pCache = CreateCache( pDoc , nID ); + return pCache; } -long ScDatabaseDPData::GetColumnCount() +long ScImportSourceDesc:: GetCacheId( ScDocument* pDoc, long nID ) const +{ + ScDPTableDataCache* pCache = GetCache( pDoc, nID); + if ( NULL == pCache ) + return -1; + else + return pCache->GetId(); +} + +// ----------------------------------------------------------------------- + +ScDatabaseDPData::ScDatabaseDPData( + ScDocument* pDoc, + const ScImportSourceDesc& rImport, long nCacheId /*=-1 */ ) : + ScDPTableData(pDoc, rImport.GetCacheId( pDoc, nCacheId) ), + aCacheTable( pDoc, rImport.GetCacheId( pDoc, nCacheId)) +{ + +} + +ScDatabaseDPData::~ScDatabaseDPData() +{ +} + +void ScDatabaseDPData::DisposeData() { - return pImpl->nColCount; + //! use OpenDatabase here? + aCacheTable.clear(); } -const TypedScStrCollection& ScDatabaseDPData::GetColumnEntries(long nColumn) +long ScDatabaseDPData::GetColumnCount() { CreateCacheTable(); - return pImpl->aCacheTable.getFieldEntries(nColumn); + return GetCacheTable().getColSize(); +} + +// End Comments + +void lcl_Reset( const uno::Reference<sdbc::XRowSet>& xRowSet ) + throw(sdbc::SQLException, uno::RuntimeException) +{ + // isBeforeFirst / beforeFirst is not always available + //! query if it is allowed + + xRowSet->execute(); // restart } String ScDatabaseDPData::getDimensionName(long nColumn) @@ -244,17 +256,12 @@ String ScDatabaseDPData::getDimensionName(long nColumn) } CreateCacheTable(); - const String* pStr = pImpl->aCacheTable.getFieldName(nColumn); - if (pStr) - return *pStr; - - DBG_ERROR("getDimensionName: invalid dimension"); - return String(); + return aCacheTable.getFieldName((SCCOL)nColumn); } BOOL ScDatabaseDPData::getIsDataLayoutDimension(long nColumn) { - return ( nColumn == pImpl->nColCount ); + return ( nColumn == GetCacheTable().getColSize()); } BOOL ScDatabaseDPData::IsDateDimension(long /* nDim */) @@ -271,43 +278,39 @@ void ScDatabaseDPData::SetEmptyFlags( BOOL /* bIgnoreEmptyRows */, BOOL /* bRepe void ScDatabaseDPData::CreateCacheTable() { - if (!pImpl->aCacheTable.empty()) + if (!aCacheTable.empty()) return; - // Get null date. - if (!pImpl->pFormatter) - pImpl->pFormatter = new SvNumberFormatter(pImpl->xServiceManager, ScGlobal::eLnge); - - pImpl->aCacheTable.fillTable(pImpl->xRowSet, *pImpl->pFormatter->GetNullDate()); + aCacheTable.fillTable(); } void ScDatabaseDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims) { CreateCacheTable(); - pImpl->aCacheTable.filterByPageDimension( + aCacheTable.filterByPageDimension( rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>())); } void ScDatabaseDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData) { CreateCacheTable(); - sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize(); + sal_Int32 nRowSize = aCacheTable.getRowSize(); if (!nRowSize) return; - pImpl->aCacheTable.filterTable( + aCacheTable.filterTable( rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()); } void ScDatabaseDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow) { CreateCacheTable(); - CalcResultsFromCacheTable(pImpl->aCacheTable, rInfo, bAutoShow); + CalcResultsFromCacheTable( aCacheTable, rInfo, bAutoShow); } const ScDPCacheTable& ScDatabaseDPData::GetCacheTable() const { - return pImpl->aCacheTable; + return aCacheTable; } // ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx index c7e75f438ce1..6254e3861db5 100644..100755 --- a/sc/source/core/data/dpshttab.cxx +++ b/sc/source/core/data/dpshttab.cxx @@ -43,7 +43,10 @@ #include "dpcachetable.hxx" #include "dpobject.hxx" #include "globstr.hrc" - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpglobal.hxx" +// End Comments #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> #include <vector> @@ -58,55 +61,27 @@ using ::std::hash_set; // ----------------------------------------------------------------------- -class ScSheetDPData_Impl -{ -public: - ScDocument* pDoc; - ScRange aRange; - ScQueryParam aQuery; - BOOL* pSpecial; // to flag special handling of query parameters in ValidQuery. - BOOL bIgnoreEmptyRows; - BOOL bRepeatIfEmpty; - BOOL* pDateDim; - SCROW nNextRow; // for iterator, within range - - ScDPCacheTable aCacheTable; - - ScSheetDPData_Impl(ScDPCollection* p) : - pSpecial(NULL), - aCacheTable(p) - { - } -}; - -// ----------------------------------------------------------------------- - -ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ) : - ScDPTableData(pD) +ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc , long nCacheId) : + ScDPTableData(pD, rDesc.GetCacheId( pD, nCacheId) ), // DataPilot Migration - Cache&&Performance + aQuery ( rDesc.aQueryParam ), + pSpecial(NULL), + bIgnoreEmptyRows( FALSE ), + bRepeatIfEmpty(FALSE), + aCacheTable( pD, rDesc.GetCacheId( pD, nCacheId)) { - pImpl = new ScSheetDPData_Impl(pD->GetDPCollection()); - pImpl->pDoc = pD; - pImpl->aRange = rDesc.aSourceRange; - pImpl->aQuery = rDesc.aQueryParam; - pImpl->bIgnoreEmptyRows = FALSE; - pImpl->bRepeatIfEmpty = FALSE; - pImpl->pDateDim = NULL; - - pImpl->nNextRow = pImpl->aRange.aStart.Row() + 1; - - SCSIZE nEntryCount(pImpl->aQuery.GetEntryCount()); - pImpl->pSpecial = new BOOL[nEntryCount]; + SCSIZE nEntryCount( aQuery.GetEntryCount()); + pSpecial = new BOOL[nEntryCount]; for (SCSIZE j = 0; j < nEntryCount; ++j ) { - ScQueryEntry& rEntry = pImpl->aQuery.GetEntry(j); + ScQueryEntry& rEntry = aQuery.GetEntry(j); if (rEntry.bDoQuery) { - pImpl->pSpecial[j] = false; + pSpecial[j] = false; if (!rEntry.bQueryByString) { if (*rEntry.pStr == EMPTY_STRING && ((rEntry.nVal == SC_EMPTYFIELDS) || (rEntry.nVal == SC_NONEMPTYFIELDS))) - pImpl->pSpecial[j] = true; + pSpecial[j] = true; } else { @@ -121,27 +96,24 @@ ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ) : ScSheetDPData::~ScSheetDPData() { - delete[] pImpl->pDateDim; - delete[] pImpl->pSpecial; - delete pImpl; + delete[] pSpecial; } void ScSheetDPData::DisposeData() { - pImpl->aCacheTable.clear(); + aCacheTable.clear(); } long ScSheetDPData::GetColumnCount() { CreateCacheTable(); - return pImpl->aCacheTable.getColSize(); + return aCacheTable.getColSize(); } -const TypedScStrCollection& ScSheetDPData::GetColumnEntries(long nColumn) +BOOL lcl_HasQuery( const ScQueryParam& rParam ) { - DBG_ASSERT(nColumn>=0 && nColumn < pImpl->aCacheTable.getColSize(), "ScSheetDPData: wrong column"); - CreateCacheTable(); - return pImpl->aCacheTable.getFieldEntries(nColumn); + return rParam.GetEntryCount() > 0 && + rParam.GetEntry(0).bDoQuery; } String ScSheetDPData::getDimensionName(long nColumn) @@ -153,35 +125,21 @@ String ScSheetDPData::getDimensionName(long nColumn) //return "Data"; return ScGlobal::GetRscString(STR_PIVOT_DATA); } - else if (nColumn >= pImpl->aCacheTable.getColSize()) + else if (nColumn >= aCacheTable.getColSize()) { DBG_ERROR("getDimensionName: invalid dimension"); return String(); } else { - const String* pStr = pImpl->aCacheTable.getFieldName(nColumn); - if (pStr) - return *pStr; - else return String(); + return aCacheTable.getFieldName((SCCOL)nColumn); } } -BOOL lcl_HasDateFormat( ScDocument* pDoc, const ScRange& rRange ) -{ - //! iterate formats in range? - - ScAddress aPos = rRange.aStart; - aPos.SetRow( aPos.Row() + 1 ); // below title - ULONG nFormat = pDoc->GetNumberFormat( aPos ); - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); - return ( pFormatter->GetType(nFormat) & NUMBERFORMAT_DATE ) != 0; -} - BOOL ScSheetDPData::IsDateDimension(long nDim) { CreateCacheTable(); - long nColCount = pImpl->aCacheTable.getColSize(); + long nColCount = aCacheTable.getColSize(); if (getIsDataLayoutDimension(nDim)) { return FALSE; @@ -193,101 +151,165 @@ BOOL ScSheetDPData::IsDateDimension(long nDim) } else { - if (!pImpl->pDateDim) - { - pImpl->pDateDim = new BOOL[nColCount]; - ScRange aTestRange = pImpl->aRange; - for (long i = 0; i < nColCount; ++i) - { - SCCOL nCol = (SCCOL)( pImpl->aRange.aStart.Col() + i ); - aTestRange.aStart.SetCol(nCol); - aTestRange.aEnd.SetCol(nCol); - pImpl->pDateDim[i] = lcl_HasDateFormat( pImpl->pDoc, aTestRange ); - } - } - return pImpl->pDateDim[nDim]; + return aCacheTable.GetCache()->IsDateDimension( nDim); } } -UINT32 ScSheetDPData::GetNumberFormat(long nDim) +ULONG ScSheetDPData::GetNumberFormat(long nDim) { CreateCacheTable(); if (getIsDataLayoutDimension(nDim)) { return 0; } - else if (nDim >= pImpl->aCacheTable.getColSize()) + else if (nDim >= GetCacheTable().getColSize()) { DBG_ERROR("GetNumberFormat: invalid dimension"); return 0; } else { - // is queried only once per dimension from ScDPOutput -> no need to cache - - ScAddress aPos = pImpl->aRange.aStart; - aPos.SetCol( sal::static_int_cast<SCCOL>( aPos.Col() + nDim ) ); - aPos.SetRow( aPos.Row() + 1 ); // below title - return pImpl->pDoc->GetNumberFormat( aPos ); + return GetCacheTable().GetCache()->GetNumberFormat( nDim ); } } +UINT32 ScDPTableData::GetNumberFormatByIdx( NfIndexTableOffset eIdx ) +{ + if( !mpDoc ) + return 0; + + if ( SvNumberFormatter* pFormatter = mpDoc->GetFormatTable() ) + return pFormatter->GetFormatIndex( eIdx, LANGUAGE_SYSTEM ); + + return 0; +} BOOL ScSheetDPData::getIsDataLayoutDimension(long nColumn) { CreateCacheTable(); - return (nColumn == pImpl->aCacheTable.getColSize()); + return (nColumn ==(long)( aCacheTable.getColSize())); } -void ScSheetDPData::SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ) +void ScSheetDPData::SetEmptyFlags( BOOL bIgnoreEmptyRowsP, BOOL bRepeatIfEmptyP ) { - pImpl->bIgnoreEmptyRows = bIgnoreEmptyRows; - pImpl->bRepeatIfEmpty = bRepeatIfEmpty; + bIgnoreEmptyRows = bIgnoreEmptyRowsP; + bRepeatIfEmpty = bRepeatIfEmptyP; } bool ScSheetDPData::IsRepeatIfEmpty() { - return pImpl->bRepeatIfEmpty; + return bRepeatIfEmpty; } void ScSheetDPData::CreateCacheTable() { // Scan and store the data from the source range. - if (!pImpl->aCacheTable.empty()) + if (!aCacheTable.empty()) // already cached. return; - pImpl->aCacheTable.fillTable(pImpl->pDoc, pImpl->aRange, pImpl->aQuery, pImpl->pSpecial, - pImpl->bIgnoreEmptyRows); + aCacheTable.fillTable( aQuery, pSpecial, + bIgnoreEmptyRows, bRepeatIfEmpty ); } void ScSheetDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims) { CreateCacheTable(); - pImpl->aCacheTable.filterByPageDimension( + aCacheTable.filterByPageDimension( rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>())); } void ScSheetDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData) { CreateCacheTable(); - sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize(); + sal_Int32 nRowSize = aCacheTable.getRowSize(); if (!nRowSize) return; - pImpl->aCacheTable.filterTable( + aCacheTable.filterTable( rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()); } void ScSheetDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow) { CreateCacheTable(); - CalcResultsFromCacheTable(pImpl->aCacheTable, rInfo, bAutoShow); + CalcResultsFromCacheTable(aCacheTable, rInfo, bAutoShow); } const ScDPCacheTable& ScSheetDPData::GetCacheTable() const { - return pImpl->aCacheTable; + return aCacheTable; +} + + +// Wang Xu Ming -- 2009-8-5 +// DataPilot Migration - Cache&&Performance +ScDPTableDataCache* ScSheetSourceDesc::CreateCache( ScDocument* pDoc , long nID ) const +{ + if ( pDoc ) + { + ScDPTableDataCache* pCache = GetExistDPObjectCache( pDoc ); + if ( pCache && ( nID < 0 || nID == pCache->GetId() ) ) + return pCache; + + ULONG nErrId = CheckValidate( pDoc ); + if ( !nErrId ) + { + pCache = new ScDPTableDataCache( pDoc ); + + pCache->InitFromDoc( pDoc, aSourceRange ); + pCache->SetId( nID ); + pDoc->AddDPObjectCache( pCache ); + + DBG_TRACE1("Create a cache id = %d \n", pCache->GetId() ); + } + else + DBG_ERROR( "\n Error Create Cache" ); + return pCache; + } + return NULL; +} + +ScDPTableDataCache* ScSheetSourceDesc::GetExistDPObjectCache ( ScDocument* pDoc ) const +{ + return pDoc->GetUsedDPObjectCache( aSourceRange ); +} +ScDPTableDataCache* ScSheetSourceDesc::GetCache( ScDocument* pDoc, long nID ) const +{ + ScDPTableDataCache* pCache = pDoc->GetDPObjectCache( nID ); + if ( NULL == pCache && pDoc ) + pCache = GetExistDPObjectCache( pDoc ); + if ( NULL == pCache ) + pCache = CreateCache( pDoc ); + return pCache; +} + +long ScSheetSourceDesc:: GetCacheId( ScDocument* pDoc, long nID ) const +{ + ScDPTableDataCache* pCache = GetCache( pDoc, nID); + if ( NULL == pCache ) + return -1; + else + return pCache->GetId(); +} + +ULONG ScSheetSourceDesc::CheckValidate( ScDocument* pDoc ) const +{ + ScRange aSrcRange( aSourceRange); + if ( !pDoc ) + return STR_ERR_DATAPILOTSOURCE; + for(USHORT i= aSrcRange.aStart.Col();i <= aSrcRange.aEnd.Col();i++) + { + if ( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), + i, aSrcRange.aStart.Row(),i, aSrcRange.aStart.Row())) + return STR_PIVOT_FIRSTROWEMPTYERR; + } + if( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), aSrcRange.aStart.Col(), aSrcRange.aStart.Row()+1, aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row() ) ) + { + return STR_PIVOT_ONLYONEROWERR; + } + return 0; } +// End Comments // ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dptabdat.cxx b/sc/source/core/data/dptabdat.cxx index 530f1c44123f..cff18ef925d9 100644..100755 --- a/sc/source/core/data/dptabdat.cxx +++ b/sc/source/core/data/dptabdat.cxx @@ -52,69 +52,6 @@ using namespace ::com::sun::star; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Any; using ::std::vector; -using ::std::set; -using ::std::hash_map; - -// ----------------------------------------------------------------------- - -BOOL ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const -{ - //! pass Transliteration? - //! inline? - return bHasValue ? ( r.bHasValue && rtl::math::approxEqual( fValue, r.fValue ) ) : - ( !r.bHasValue && - ScGlobal::GetpTransliteration()->isEqual( aString, r.aString ) ); -} - -size_t ScDPItemData::Hash() const -{ - if ( bHasValue ) - return (size_t) rtl::math::approxFloor( fValue ); - else - // If we do unicode safe case insensitive hash we can drop - // ScDPItemData::operator== and use ::IsCasInsEqual - return rtl_ustr_hashCode_WithLength( aString.GetBuffer(), aString.Len() ); -} - -BOOL ScDPItemData::operator==( const ScDPItemData& r ) const -{ - if ( bHasValue ) - { - if ( r.bHasValue ) - return rtl::math::approxEqual( fValue, r.fValue ); - else - return FALSE; - } - else if ( r.bHasValue ) - return FALSE; - else - // need exact equality until we have a safe case insensitive string hash - return aString == r.aString; -} - -sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA, - const ScDPItemData& rB ) -{ - if ( rA.bHasValue ) - { - if ( rB.bHasValue ) - { - if ( rtl::math::approxEqual( rA.fValue, rB.fValue ) ) - return 0; - else if ( rA.fValue < rB.fValue ) - return -1; - else - return 1; - } - else - return -1; // values first - } - else if ( rB.bHasValue ) - return 1; // values first - else - return ScGlobal::GetCollator()->compareString( rA.aString, rB.aString ); -} - // --------------------------------------------------------------------------- ScDPTableData::CalcInfo::CalcInfo() : @@ -124,8 +61,9 @@ ScDPTableData::CalcInfo::CalcInfo() : // --------------------------------------------------------------------------- -ScDPTableData::ScDPTableData(ScDocument* pDoc) : - mrSharedString(pDoc->GetDPCollection()->GetSharedString()) +ScDPTableData::ScDPTableData(ScDocument* pDoc, long nCacheId ) : + mnCacheId( nCacheId ), + mpDoc ( pDoc ) { nLastDateVal = nLastHier = nLastLevel = nLastRet = -1; // invalid @@ -186,7 +124,7 @@ bool ScDPTableData::IsRepeatIfEmpty() return false; } -UINT32 ScDPTableData::GetNumberFormat(long) +ULONG ScDPTableData::GetNumberFormat(long) { return 0; // default format } @@ -219,12 +157,6 @@ BOOL ScDPTableData::HasCommonElement( const ScDPItemData&, long, DBG_ERROR("HasCommonElement shouldn't be called for non-group data"); return FALSE; } - -ScSimpleSharedString& ScDPTableData::GetSharedString() -{ - return mrSharedString; -} - void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTable& rCacheTable, const CalcInfo& rInfo, CalcRowData& rData) { @@ -243,25 +175,28 @@ void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTab long nDim = rInfo.aDataSrcCols[i]; rData.aValues.push_back( ScDPValueData() ); ScDPValueData& rVal = rData.aValues.back(); - const ScDPCacheCell* pCell = rCacheTable.getCell( - static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false); - if (pCell) - { - rVal.fValue = pCell->mbNumeric ? pCell->mfValue : 0.0; - rVal.nType = pCell->mnType; - } - else - rVal.Set(0.0, SC_VALTYPE_EMPTY); + rCacheTable.getValue( rVal, static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false); } } void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAutoShow) { + // Wang Xu Ming -- 2009-6-16 + // DataPilot Migration if (!bAutoShow) { - rInfo.pColRoot->LateInitFrom(rInfo.aColDims, rInfo.aColLevels, rData.aColData, 0, *rInfo.pInitState); - rInfo.pRowRoot->LateInitFrom(rInfo.aRowDims, rInfo.aRowLevels, rData.aRowData, 0, *rInfo.pInitState); + LateInitParams aColParams( rInfo.aColDims, rInfo.aColLevels, FALSE ); + LateInitParams aRowParams ( rInfo.aRowDims, rInfo.aRowLevels, TRUE ); + // root always init child + aColParams.SetInitChild( TRUE ); + aColParams.SetInitAllChildren( FALSE); + aRowParams.SetInitChild( TRUE ); + aRowParams.SetInitAllChildren( FALSE); + + rInfo.pColRoot->LateInitFrom( aColParams, rData.aColData,0, *rInfo.pInitState); + rInfo.pRowRoot->LateInitFrom( aRowParams, rData.aRowData, 0, *rInfo.pInitState); } + // End Comments if ( ( !rInfo.pColRoot->GetChildDimension() || rInfo.pColRoot->GetChildDimension()->IsValidEntry(rData.aColData) ) && ( !rInfo.pRowRoot->GetChildDimension() || rInfo.pRowRoot->GetChildDimension()->IsValidEntry(rData.aRowData) ) ) @@ -269,8 +204,11 @@ void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAu //! single process method with ColMembers, RowMembers and data !!! if (rInfo.pColRoot->GetChildDimension()) { - vector<ScDPItemData> aEmptyData; +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration + vector</*ScDPItemData*/ SCROW > aEmptyData; rInfo.pColRoot->GetChildDimension()->ProcessData(rData.aColData, NULL, aEmptyData, rData.aValues); +// End Comments } rInfo.pRowRoot->ProcessData(rData.aRowData, rInfo.pColRoot->GetChildDimension(), @@ -292,42 +230,94 @@ void ScDPTableData::CalcResultsFromCacheTable(const ScDPCacheTable& rCacheTable, } } +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration void ScDPTableData::GetItemData(const ScDPCacheTable& rCacheTable, sal_Int32 nRow, - const vector<long>& rDims, vector<ScDPItemData>& rItemData) + const vector<long>& rDims, vector< SCROW/*ScDPItemData*/>& rItemData) +// End Comments { sal_Int32 nDimSize = rDims.size(); for (sal_Int32 i = 0; i < nDimSize; ++i) { long nDim = rDims[i]; - rItemData.push_back( ScDPItemData() ); - ScDPItemData& rData = rItemData.back(); + if (getIsDataLayoutDimension(nDim)) { - rData.SetString(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("x"))); + rItemData.push_back( -1 ); continue; } - const ScDPCacheCell* pCell = rCacheTable.getCell( - static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty()); - if (!pCell || pCell->mnType == SC_VALTYPE_EMPTY) - continue; + nDim = GetSourceDim( nDim ); + if ( nDim >= rCacheTable.GetCache()->GetColumnCount() ) + continue; - const String* pString = GetSharedString().getString(pCell->mnStrId); - if (!pString) - continue; + SCROW nId= rCacheTable.GetCache()->GetItemDataId( static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty()); + rItemData.push_back( nId ); - rData.aString = *pString; - rData.bHasValue = false; - if (pCell->mbNumeric) - { - rData.bHasValue = true; - rData.fValue = pCell->mfValue; - } } } // ----------------------------------------------------------------------- +// Wang Xu Ming -- 2009-6-8 +// DataPilot Migration +long ScDPTableData::GetMembersCount( long nDim ) +{ + if ( nDim > MAXCOL ) + return 0; + return GetCacheTable().getFieldEntries( nDim ).size(); +} + +long ScDPTableData::GetCacheId() const +{ + return mnCacheId; +} + +const ScDPItemData* ScDPTableData::GetMemberByIndex( long nDim, long nIndex ) +{ + if ( nIndex >= GetMembersCount( nDim ) ) + return NULL; + + const ::std::vector<SCROW>& nMembers = GetCacheTable().getFieldEntries( nDim ); + + return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nMembers[nIndex] ); +} + +const ScDPItemData* ScDPTableData::GetMemberById( long nDim, long nId) +{ + + return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nId); +} +SCROW ScDPTableData::GetIdOfItemData( long nDim, const ScDPItemData& rData ) +{ + return GetCacheTable().GetCache()->GetIdByItemData((SCCOL) nDim, rData ); + } +const std::vector< SCROW >& ScDPTableData::GetColumnEntries( long nColumn ) +{ + return GetCacheTable().getFieldEntries( nColumn ); +} +long ScDPTableData::GetSourceDim( long nDim ) +{ + return nDim; + +} + + long ScDPTableData::Compare( long nDim, long nDataId1, long nDataId2) +{ + if ( getIsDataLayoutDimension(nDim) ) + return 0; + + long n1 = GetCacheTable().GetCache()->GetOrder( nDim, nDataId1); + long n2 = GetCacheTable().GetCache()->GetOrder( nDim, nDataId2); + if ( n1 > n2 ) + return 1; + else if ( n1 == n2 ) + return 0; + else + return -1; +} +// End Comments +// ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx new file mode 100755 index 000000000000..42090e5203a2 --- /dev/null +++ b/sc/source/core/data/dptablecache.cxx @@ -0,0 +1,1093 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dptablecache.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + // MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" +// INCLUDE --------------------------------------------------------------- +#include "dptablecache.hxx" +#include "document.hxx" +#include "cell.hxx" +#include "globstr.hrc" + +#include <rtl/math.hxx> +#include "queryparam.hxx" +#include "dpglobal.hxx" + +#include "docoptio.hxx" //for ValidQuery +#include <unotools/textsearch.hxx> //for ValidQuery + +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> +#include <com/sun/star/sdbc/XResultSetMetaData.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +const double D_TIMEFACTOR = 86400.0; + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +// ----------------------------------------------------------------------- +namespace +{ + BOOL lcl_isDate( ULONG nNumType ) + { + return ( (nNumType & NUMBERFORMAT_DATE) != 0 )? 1:0 ; + } + + BOOL lcl_Search( const std::vector<ScDPItemData*>& list, const ::std::vector<SCROW>& rOrder, const ScDPItemData& item, SCROW& rIndex) + { + rIndex = list.size(); + BOOL bFound = FALSE; + SCROW nLo = 0; + SCROW nHi = list.size() - 1; + SCROW nIndex; + long nCompare; + while (nLo <= nHi) + { + nIndex = (nLo + nHi) / 2; + nCompare = ScDPItemData::Compare( *list[rOrder[nIndex]], item ); + if (nCompare < 0) + nLo = nIndex + 1; + else + { + nHi = nIndex - 1; + if (nCompare == 0) + { + bFound = TRUE; + nLo = nIndex; + } + } + } + rIndex = nLo; + return bFound; + } + + ScDPItemData* lcl_GetItemValue(const Reference<sdbc::XRow>& xRow, sal_Int32 nType, long nCol, + const Date& rNullDate ) + { + short nNumType = NUMBERFORMAT_NUMBER; + try + { + String rStr = xRow->getString(nCol); + double fValue = 0.0; + switch (nType) + { + case sdbc::DataType::BIT: + case sdbc::DataType::BOOLEAN: + { + nNumType = NUMBERFORMAT_LOGICAL; + fValue = xRow->getBoolean(nCol) ? 1 : 0; + return new ScDPItemData( rStr, fValue,TRUE,nNumType); + } + //break; + + case sdbc::DataType::TINYINT: + case sdbc::DataType::SMALLINT: + case sdbc::DataType::INTEGER: + case sdbc::DataType::BIGINT: + case sdbc::DataType::FLOAT: + case sdbc::DataType::REAL: + case sdbc::DataType::DOUBLE: + case sdbc::DataType::NUMERIC: + case sdbc::DataType::DECIMAL: + { + //! do the conversion here? + fValue = xRow->getDouble(nCol); + return new ScDPItemData( rStr, fValue,TRUE); + } + //break; + + case sdbc::DataType::DATE: + { + nNumType = NUMBERFORMAT_DATE; + + util::Date aDate = xRow->getDate(nCol); + fValue = Date(aDate.Day, aDate.Month, aDate.Year) - rNullDate; + return new ScDPItemData( rStr, fValue, TRUE, nNumType ); + } + //break; + + case sdbc::DataType::TIME: + { + nNumType = NUMBERFORMAT_TIME; + + util::Time aTime = xRow->getTime(nCol); + fValue = ( aTime.Hours * 3600 + aTime.Minutes * 60 + + aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; + return new ScDPItemData( rStr,fValue, TRUE, nNumType ); + } + //break; + + case sdbc::DataType::TIMESTAMP: + { + nNumType = NUMBERFORMAT_DATETIME; + + util::DateTime aStamp = xRow->getTimestamp(nCol); + fValue = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - rNullDate ) + + ( aStamp.Hours * 3600 + aStamp.Minutes * 60 + + aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; + return new ScDPItemData( rStr,fValue, TRUE, nNumType ); + } + //break; + case sdbc::DataType::CHAR: + case sdbc::DataType::VARCHAR: + case sdbc::DataType::LONGVARCHAR: + case sdbc::DataType::SQLNULL: + case sdbc::DataType::BINARY: + case sdbc::DataType::VARBINARY: + case sdbc::DataType::LONGVARBINARY: + default: + return new ScDPItemData ( rStr ); + //break; + } + } + catch (uno::Exception&) + { + } + catch ( ... ) + { + + } + return NULL; + } +} +// Wang Xu Ming -- 12/23/2008 +//Refactor cache data +ScDPItemData::ScDPItemData( const String& rS, double fV/* = 0.0*/, BOOL bHV/* = FALSE*/, const ULONG nNumFormatP /*= 0*/ , BOOL bData/* = TRUE*/) : +nNumFormat( nNumFormatP ), aString(rS), fValue(fV), +mbFlag( (MK_VAL*!!bHV) | (MK_DATA*!!bData) | (MK_ERR*!!FALSE) | (MK_DATE*!!lcl_isDate( nNumFormat ) ) ) +{ +} + +ScDPItemData::ScDPItemData( ScDocument* pDoc, SCROW nRow, USHORT nCol, USHORT nDocTab ): + nNumFormat( 0 ), fValue(0.0), mbFlag( 0 ) +{ + String aDocStr; + pDoc->GetString( nCol, nRow, nDocTab, aDocStr ); + + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + + ScAddress aPos( nCol, nRow, nDocTab ); + ScBaseCell* pCell = pDoc->GetCell( aPos ); + + if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetErrCode() ) + SetString ( aDocStr ); //[SODC_19347] add liyi + //bErr = TRUE; //[SODC_19347] del liyi + else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) ) + { + double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab)); + ULONG nFormat = NUMBERFORMAT_NUMBER; + if ( pFormatter ) + nFormat = pFormatter->GetType( pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ) ); + aString = aDocStr; + fValue = fVal; + mbFlag |= MK_VAL|MK_DATA; + nNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ); + lcl_isDate( nFormat ) ? ( mbFlag |= MK_DATE ) : (mbFlag &= ~MK_DATE); + } + else if ( pDoc->HasData( nCol,nRow, nDocTab ) ) + SetString ( aDocStr ); +} +// End Comments + +BOOL ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const +{ //TODO: indified Date? + //! pass Transliteration? + //! inline? + return IsValue() ? ( r.IsValue() && rtl::math::approxEqual( fValue, r.fValue ) ) : + ( !r.IsValue() && + ScGlobal::GetpTransliteration()->isEqual( aString, r.aString ) ); +} + +size_t ScDPItemData::Hash() const +{ + if ( IsValue() ) + return (size_t) rtl::math::approxFloor( fValue ); + else + // If we do unicode safe case insensitive hash we can drop + // ScDPItemData::operator== and use ::IsCasInsEqual + return rtl_ustr_hashCode_WithLength( aString.GetBuffer(), aString.Len() ); +} + +BOOL ScDPItemData::operator==( const ScDPItemData& r ) const +{ + if ( IsValue() ) + { + if( HasDatePart() != r.HasDatePart() || HasDatePart() && mnDatePart != r.mnDatePart ) + return FALSE; + +// Wang Xu Ming -- 1/9/2009 +// Add Data Cache Support. +// Identify date + if ( IsDate() != r.IsDate() ) + return FALSE; + else + if ( r.IsValue() ) + return rtl::math::approxEqual( fValue, r.fValue ); + else + return FALSE; +// End Comments + } + else if ( r.IsValue() ) + return FALSE; + else + // need exact equality until we have a safe case insensitive string hash + return aString == r.aString; +} + +sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA, + const ScDPItemData& rB ) +{ + if ( rA.IsValue() ) + { + if ( rB.IsValue() ) + { + if ( rtl::math::approxEqual( rA.fValue, rB.fValue ) ) + { +// Wang Xu Ming -- 1/9/2009 +// Add Data Cache Support. +// Date > number + if ( rA.IsDate() == rB.IsDate() ) + return 0; + else + return rA.IsDate() ? 1: -1; +// End Comments + } + else if ( rA.fValue < rB.fValue ) + return -1; + else + return 1; + } + else + return -1; // values first + } + else if ( rB.IsValue() ) + return 1; // values first + else + return ScGlobal::GetCollator()->compareString( rA.aString, rB.aString ); +} +// +//Wang Xu Ming SODC_17561 +#ifdef DEBUG +void ScDPItemData::dump() const +{ + DBG_TRACE1( "Numberformat= %o", nNumFormat ); + DBG_TRACESTR(aString ); + DBG_TRACE1( "fValue= %f", fValue ); + DBG_TRACE1( "bHasValue= %d", bHasValue ? 1:0); +} +#endif +//End + +TypedStrData* ScDPItemData::CreateTypeString( ) +{ + if ( IsValue() ) + return new TypedStrData( aString, fValue, SC_STRTYPE_VALUE ); + else + return new TypedStrData( aString ); +} + +sal_uInt8 ScDPItemData::GetType() const +{ + + if ( IsHasErr() ) + return SC_VALTYPE_ERROR; + else if ( !IsHasData() ) + return SC_VALTYPE_EMPTY; + else if ( IsValue()) + return SC_VALTYPE_VALUE; + else + return SC_VALTYPE_STRING; + +} + +BOOL ScDPItemData::IsHasData() const +{ + return !!(mbFlag&MK_DATA); +} + +BOOL ScDPItemData::IsHasErr() const +{ + return !!(mbFlag&MK_ERR); +} + +BOOL ScDPItemData::IsValue() const +{ + return !!(mbFlag&MK_VAL); +} + +String ScDPItemData::GetString() const +{ + + return aString; +} + +double ScDPItemData::GetValue() const +{ + return fValue; +} +ULONG ScDPItemData::GetNumFormat() const +{ + return nNumFormat; +} + +BOOL ScDPItemData::HasStringData() const + +{ + return IsHasData()&&!IsHasErr()&&!IsValue(); +} +BOOL ScDPItemData::IsDate() const +{ + return !!(mbFlag&MK_DATE); +} +BOOL ScDPItemData::HasDatePart() const +{ + return !!(mbFlag&MK_DATEPART); +} +void ScDPItemData::SetDate( BOOL b ) +{ + b ? ( mbFlag |= MK_DATE ) : ( mbFlag &= ~MK_DATE ); +} + +// ----------------------------------------------------------------------- +//class ScDPTableDataCache +//To cache the pivot table data source + +BOOL ScDPTableDataCache::operator== ( const ScDPTableDataCache& r ) const +{ + if ( GetColumnCount() == r.GetColumnCount() ) + { + for ( SCCOL i = 0 ; i < GetColumnCount(); i++ ) + { //check dim names + if ( GetDimensionName( i ) != r.GetDimensionName( i ) ) + return FALSE; + //check rows count + if ( GetRowCount() != r.GetRowCount() ) + return FALSE; + //check dim member values + size_t nMembersCount = GetDimMemberValues( i ).size(); + if ( GetDimMemberValues( i ).size() == r. GetDimMemberValues( i ).size() ) + { + for ( size_t j = 0; j < nMembersCount; j++ ) + { + if ( *( GetDimMemberValues( i )[j] ) == *( r.GetDimMemberValues( i )[j] ) ) + continue; + else + return FALSE; + } + } + else + return FALSE; + //check source table index + for ( SCROW k=0 ; k < GetRowCount(); k ++ ) + { + if ( GetItemDataId( i, k, FALSE ) == r.GetItemDataId( i,k,FALSE) ) + continue; + else + return FALSE; + } + } + } + return TRUE; +} + +ScDPTableDataCache::ScDPTableDataCache( ScDocument* pDoc ) : +mpDoc( pDoc ), +mnColumnCount ( 0 ), +mpTableDataValues ( NULL ), +mpSourceData ( NULL ), +mpGlobalOrder( NULL ), +mpIndexOrder( NULL) +{ + mnID = -1; +} + +ScDPTableDataCache::~ScDPTableDataCache() +{ + if ( IsValid() ) + { +// Wang Xu Ming -- 2/17/2009 +// Performance issue + USHORT nCol; + for ( nCol=0; nCol < GetColumnCount() ; nCol++ ) + { + for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ ) + delete mpTableDataValues[nCol][row]; + } + for ( nCol =0; nCol < mrLabelNames.size(); nCol++ ) + delete mrLabelNames[nCol]; +// End Comments + + mnColumnCount = 0; + delete [] mpTableDataValues; + mpTableDataValues = NULL; + delete [] mpSourceData; + mpSourceData = NULL; + delete [] mpGlobalOrder; + mpGlobalOrder = NULL; + delete [] mpIndexOrder; + mpIndexOrder = NULL; + } +} + +// ----------------------------------------------------------------------- +void ScDPTableDataCache::AddRow( ScDPItemData* pRow, USHORT nCount ) +{ + DBG_ASSERT( pRow , " empty pointer" ); + if ( !mrLabelNames.size() ) + { + mnColumnCount= nCount; + mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ]; + mpSourceData = new std::vector<SCROW>[ mnColumnCount ]; + mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ]; + mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ]; + + for ( USHORT i = 0; i < nCount ; i ++ ) + AddLabel( new ScDPItemData( pRow[i] ) ); + } + else + { + for ( USHORT i = 0; i < nCount && i < mnColumnCount; i ++ ) + AddData( i, new ScDPItemData( pRow[i] ) ); + } +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::IsValid() const +{ //TODO: continue check valid + return mpTableDataValues!=NULL && mpSourceData!= NULL && mnColumnCount>0; +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::InitFromDoc( ScDocument* pDoc, const ScRange& rRange ) +{ + // + SCROW nStartRow = rRange.aStart.Row(); // start of data + SCROW nEndRow = rRange.aEnd.Row(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nDocTab = rRange.aStart.Tab(); + + //init + long nOldColumCount = mnColumnCount; + mnColumnCount = nEndCol - nStartCol + 1; + if ( IsValid() ) + { + for ( USHORT nCol=0; nCol < nOldColumCount ; nCol++ ) + { + for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ ) + delete mpTableDataValues[nCol][row]; + delete mrLabelNames[nCol]; + } + delete [] mpTableDataValues; + delete [] mpSourceData; + delete [] mpGlobalOrder; + delete [] mpIndexOrder; + mrLabelNames.clear(); + } + + mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ]; + mpSourceData = new std::vector<SCROW>[ mnColumnCount ]; + mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ]; + mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ]; + //check valid + for ( SCROW nRow = nStartRow; nRow <= nEndRow; nRow ++ ) + { + for ( USHORT nCol = nStartCol; nCol <= nEndCol; nCol++ ) + { + if ( nRow == nStartRow ) + AddLabel( new ScDPItemData( pDoc, nRow, nCol, nDocTab ) ); + else + AddData( nCol - nStartCol, new ScDPItemData( pDoc, nRow, nCol, nDocTab ) ); + } + } + return TRUE; +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::InitFromDataBase (const Reference<sdbc::XRowSet>& xRowSet, const Date& rNullDate) +{ + if (!xRowSet.is()) + // Dont' even waste time to go any further. + return false; + try + { + Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp(xRowSet, UNO_QUERY_THROW); + Reference<sdbc::XResultSetMetaData> xMeta = xMetaSupp->getMetaData(); + if (!xMeta.is()) + return false; + + long nOldColumCount = mnColumnCount; + mnColumnCount = xMeta->getColumnCount(); + if ( IsValid() ) + { + for ( USHORT nCol=0; nCol < nOldColumCount ; nCol++ ) + { + for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ ) + delete mpTableDataValues[nCol][row]; + delete mrLabelNames[nCol]; + } + delete [] mpTableDataValues; + delete [] mpSourceData; + delete [] mpGlobalOrder; + delete [] mpIndexOrder; + mrLabelNames.clear(); + } + // Get column titles and types. + mrLabelNames.reserve(mnColumnCount); + mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ]; + mpSourceData = new std::vector<SCROW>[ mnColumnCount ]; + mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ]; + mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ]; + + std::vector<sal_Int32> aColTypes(mnColumnCount); + + for (sal_Int32 nCol = 0; nCol < mnColumnCount; ++nCol) + { + String aColTitle = xMeta->getColumnLabel(nCol+1); + aColTypes[nCol] = xMeta->getColumnType(nCol+1); + AddLabel( new ScDPItemData( aColTitle) ); + } + + // Now get the data rows. + Reference<sdbc::XRow> xRow(xRowSet, UNO_QUERY_THROW); + xRowSet->first(); + do + { + for (sal_Int32 nCol = 0; nCol < mnColumnCount; ++nCol) + { + ScDPItemData * pNew = lcl_GetItemValue( xRow, aColTypes[nCol], nCol+1, rNullDate ); + if ( pNew ) + AddData( nCol , pNew ); + } + } + while (xRowSet->next()); + + xRowSet->beforeFirst(); + + return true; + } + catch (const Exception&) + { + return false; + } +} +// ----------------------------------------------------------------------- +ULONG ScDPTableDataCache::GetDimNumType( SCCOL nDim) const +{ + DBG_ASSERT( IsValid(), " IsValid() == false " ); + DBG_ASSERT( nDim < mnColumnCount && nDim >=0, " dimention out of bound " ); + if ( mpTableDataValues[nDim].size()==0 ) + return NUMBERFORMAT_UNDEFINED; + else + return GetNumType(mpTableDataValues[nDim][0]->nNumFormat); +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, BOOL *pSpecial) +{ //Copied and modified from ScTable::ValidQuery + if (!rParam.GetEntry(0).bDoQuery) + return TRUE; + BOOL bMatchWholeCell = mpDoc->GetDocOptions().IsMatchWholeCell(); + + //--------------------------------------------------------------- + + const SCSIZE nFixedBools = 32; + BOOL aBool[nFixedBools]; + BOOL aTest[nFixedBools]; + SCSIZE nEntryCount = rParam.GetEntryCount(); + BOOL* pPasst = ( nEntryCount <= nFixedBools ? &aBool[0] : new BOOL[nEntryCount] ); + BOOL* pTest = ( nEntryCount <= nFixedBools ? &aTest[0] : new BOOL[nEntryCount] ); + + long nPos = -1; + SCSIZE i = 0; + CollatorWrapper* pCollator = (rParam.bCaseSens ? ScGlobal::GetCaseCollator() : + ScGlobal::GetCollator() ); + ::utl::TransliterationWrapper* pTransliteration = (rParam.bCaseSens ? + ScGlobal::GetCaseTransliteration() : ScGlobal::GetpTransliteration()); + + while ( (i < nEntryCount) && rParam.GetEntry(i).bDoQuery ) + { + ScQueryEntry& rEntry = rParam.GetEntry(i); + // we can only handle one single direct query + SCROW nId = GetItemDataId( (SCCOL)rEntry.nField, nRow, FALSE ); + const ScDPItemData* pCellData = GetItemDataById( (SCCOL)rEntry.nField, nId); + + BOOL bOk = FALSE; + BOOL bTestEqual = FALSE; + + if ( pSpecial && pSpecial[i] ) + { + if (rEntry.nVal == SC_EMPTYFIELDS) + bOk = ! pCellData->IsHasData(); + else // if (rEntry.nVal == SC_NONEMPTYFIELDS) + bOk = pCellData->IsHasData(); + } + else if ( !rEntry.bQueryByString && pCellData->IsValue() ) + { // by Value + double nCellVal = pCellData->GetValue(); + + switch (rEntry.eOp) + { + case SC_EQUAL : + bOk = ::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_LESS : + bOk = (nCellVal < rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_GREATER : + bOk = (nCellVal > rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_LESS_EQUAL : + bOk = (nCellVal < rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_GREATER_EQUAL : + bOk = (nCellVal > rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_NOT_EQUAL : + bOk = !::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + default: + bOk= FALSE; + break; + } + } + else if ( (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL) + || (rEntry.bQueryByString + && pCellData->HasStringData() ) + ) + { // by String + String aCellStr = pCellData->GetString(); + + BOOL bRealRegExp = (rParam.bRegExp && ((rEntry.eOp == SC_EQUAL) + || (rEntry.eOp == SC_NOT_EQUAL))); + BOOL bTestRegExp = FALSE; + if ( bRealRegExp || bTestRegExp ) + { + xub_StrLen nStart = 0; + xub_StrLen nEnd = aCellStr.Len(); + BOOL bMatch = (BOOL) rEntry.GetSearchTextPtr( rParam.bCaseSens ) + ->SearchFrwrd( aCellStr, &nStart, &nEnd ); + // from 614 on, nEnd is behind the found text + if ( bMatch && bMatchWholeCell + && (nStart != 0 || nEnd != aCellStr.Len()) ) + bMatch = FALSE; // RegExp must match entire cell string + if ( bRealRegExp ) + bOk = ((rEntry.eOp == SC_NOT_EQUAL) ? !bMatch : bMatch); + else + bTestEqual = bMatch; + } + if ( !bRealRegExp ) + { + if ( rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL ) + { + if ( bMatchWholeCell ) + { + bOk = pTransliteration->isEqual( aCellStr, *rEntry.pStr ); + //Added by zhaosz,for sodc_2702,20060808 + String aStr = *rEntry.pStr;//"f*" + //modified by weihuaw,for SODC_16698 + //use another way to find "*" in aStr + sal_Bool bHasStar = sal_False; + xub_StrLen nIndex; + if( ( nIndex = aStr.Search('*') ) != STRING_NOTFOUND ) + bHasStar = sal_True; + if(bHasStar && (nIndex>0)) + { + for(i=0;(i<nIndex) && (i< aCellStr.Len()) ; i++) + { + if(aCellStr.GetChar( (USHORT)i ) == aStr.GetChar((USHORT) i )) + { + bOk=1; + } + else + { + bOk=0; + break; + } + } + } + //end modified + //Added end,20060808 + } + else + { + ::com::sun::star::uno::Sequence< sal_Int32 > xOff; + String aCell( pTransliteration->transliterate( + aCellStr, ScGlobal::eLnge, 0, aCellStr.Len(), + &xOff ) ); + String aQuer( pTransliteration->transliterate( + *rEntry.pStr, ScGlobal::eLnge, 0, rEntry.pStr->Len(), + &xOff ) ); + bOk = (aCell.Search( aQuer ) != STRING_NOTFOUND); + } + if ( rEntry.eOp == SC_NOT_EQUAL ) + bOk = !bOk; + } + else + { // use collator here because data was probably sorted + sal_Int32 nCompare = pCollator->compareString( + aCellStr, *rEntry.pStr ); + switch (rEntry.eOp) + { + case SC_LESS : + bOk = (nCompare < 0); + break; + case SC_GREATER : + bOk = (nCompare > 0); + break; + case SC_LESS_EQUAL : + bOk = (nCompare <= 0); + break; + case SC_GREATER_EQUAL : + bOk = (nCompare >= 0); + break; + case SC_NOT_EQUAL: + DBG_ASSERT( false , "SC_NOT_EQUAL"); + break; + case SC_TOPVAL: + case SC_BOTVAL: + case SC_TOPPERC: + case SC_BOTPERC: + default: + break; + } + } + } + } + + if (nPos == -1) + { + nPos++; + pPasst[nPos] = bOk; + pTest[nPos] = bTestEqual; + } + else + { + if (rEntry.eConnect == SC_AND) + { + pPasst[nPos] = pPasst[nPos] && bOk; + pTest[nPos] = pTest[nPos] && bTestEqual; + } + else + { + nPos++; + pPasst[nPos] = bOk; + pTest[nPos] = bTestEqual; + } + } + i++; + } + + for ( long j=1; j <= nPos; j++ ) + { + pPasst[0] = pPasst[0] || pPasst[j]; + pTest[0] = pTest[0] || pTest[j]; + } + + BOOL bRet = pPasst[0]; + if ( pPasst != &aBool[0] ) + delete [] pPasst; + if ( pTest != &aTest[0] ) + delete [] pTest; + + return bRet; +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::IsRowEmpty( SCROW nRow ) const +{ + return mbEmptyRow[ nRow ]; + +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::IsEmptyMember( SCROW nRow, USHORT nColumn ) const +{ + return !GetItemDataById( nColumn, GetItemDataId( nColumn, nRow, FALSE ) )->IsHasData(); +} + +BOOL ScDPTableDataCache::AddData(long nDim, ScDPItemData* pitemData) +{ + DBG_ASSERT( IsValid(), " IsValid() == false " ); + DBG_ASSERT( nDim < mnColumnCount && nDim >=0 , "dimension out of bound" ); + SCROW nIndex = 0; + + BOOL bInserted = FALSE; + + pitemData->SetDate( lcl_isDate( GetNumType( pitemData->nNumFormat ) ) ); + + if ( !lcl_Search( mpTableDataValues[nDim], mpGlobalOrder[nDim], *pitemData, nIndex ) ) + { + mpTableDataValues[nDim].push_back( pitemData ); + mpGlobalOrder[nDim].insert( mpGlobalOrder[nDim].begin()+nIndex, mpTableDataValues[nDim].size()-1 ); + DBG_ASSERT( (size_t) mpGlobalOrder[nDim][nIndex] == mpTableDataValues[nDim].size()-1 ,"ScDPTableDataCache::AddData "); + mpSourceData[nDim].push_back( mpTableDataValues[nDim].size()-1 ); + bInserted = TRUE; + } + else + mpSourceData[nDim].push_back( mpGlobalOrder[nDim][nIndex] ); +//init empty row tag + size_t nCurRow = mpSourceData[nDim].size() -1 ; + + while ( mbEmptyRow.size() <= nCurRow ) + mbEmptyRow.push_back( TRUE ); + + if ( pitemData->IsHasData() ) + mbEmptyRow[ nCurRow ] = FALSE; + + if ( !bInserted ) + delete pitemData; + + return TRUE; +} + + +String ScDPTableDataCache::GetDimensionName( USHORT nColumn ) const +{ + DBG_ASSERT( /* nColumn>=0 && */ nColumn < mrLabelNames.size()-1 , "ScDPTableDataCache::GetDimensionName"); + DBG_ASSERT( mrLabelNames.size() == static_cast <USHORT> (mnColumnCount+1), "ScDPTableDataCache::GetDimensionName"); + if ( static_cast<size_t>(nColumn+1) < mrLabelNames.size() ) + { + return mrLabelNames[nColumn+1]->aString; + } + else + return String(); +} + +void ScDPTableDataCache::AddLabel(ScDPItemData *pData) +{ + DBG_ASSERT( IsValid(), " IsValid() == false " ); + + if ( mrLabelNames.size() == 0 ) + mrLabelNames.push_back( new ScDPItemData( ScGlobal::GetRscString(STR_PIVOT_DATA) ) ); + + + //reset name if needed + String strNewName = pData->aString; + BOOL bFound = FALSE; + long nIndex = 1; + do + { + for ( long i= mrLabelNames.size()-1; i>=0; i-- ) + { + if( mrLabelNames[i]->aString == strNewName ) + { + strNewName = pData->aString; + strNewName += String::CreateFromInt32( nIndex ); + nIndex ++ ; + bFound = TRUE; + } + } + bFound = !bFound; + } + while ( !bFound ); + + pData->aString = strNewName; + mrLabelNames.push_back( pData ); +} + +SCROW ScDPTableDataCache::GetItemDataId(USHORT nDim, SCROW nRow, BOOL bRepeatIfEmpty) const +{ // + DBG_ASSERT( IsValid(), " IsValid() == false " ); + DBG_ASSERT( /* nDim >= 0 && */ nDim < mnColumnCount, "ScDPTableDataCache::GetItemDataId " ); + + if ( bRepeatIfEmpty ) + { + while ( nRow >0 && !mpTableDataValues[nDim][ mpSourceData[nDim][nRow] ]->IsHasData() ) + --nRow; + } + + return mpSourceData[nDim][nRow]; +} + +const ScDPItemData* ScDPTableDataCache::GetItemDataById(long nDim, SCROW nId) const +{ + if ( nId >= GetRowCount() ) + return maAdditionalDatas.getData( nId - GetRowCount() ); + + if ( (size_t)nId >= mpTableDataValues[nDim].size() || nDim >= mnColumnCount || nId < 0 ) + return NULL; + else + return mpTableDataValues[nDim][nId]; +} + +SCROW ScDPTableDataCache::GetRowCount() const +{ + if ( IsValid() ) + return mpSourceData[0].size(); + else + return 0; +} + +const std::vector<ScDPItemData*>& ScDPTableDataCache::GetDimMemberValues(SCCOL nDim) const +{ + DBG_ASSERT( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount "); + return mpTableDataValues[nDim]; +} + +SCROW ScDPTableDataCache::GetSortedItemDataId(SCCOL nDim, SCROW nOrder) const +{ + DBG_ASSERT ( IsValid(), "IsValid"); + DBG_ASSERT( nDim>=0 && nDim < mnColumnCount, "nDim < mnColumnCount"); + DBG_ASSERT( nOrder >= 0 && (size_t) nOrder < mpGlobalOrder[nDim].size(), "nOrder < mpGlobalOrder[nDim].size()" ); + + return mpGlobalOrder[nDim][nOrder]; +} + +ULONG ScDPTableDataCache::GetNumType(ULONG nFormat) const +{ + SvNumberFormatter* pFormatter = mpDoc->GetFormatTable(); + ULONG nType = NUMBERFORMAT_NUMBER; + if ( pFormatter ) + nType = pFormatter->GetType( nFormat ); + return nType; +} + +ULONG ScDPTableDataCache::GetNumberFormat( long nDim ) const +{ + if ( nDim >= mnColumnCount ) + return 0; + if ( mpTableDataValues[nDim].size()==0 ) + return 0; + else + return mpTableDataValues[nDim][0]->nNumFormat; +} + +BOOL ScDPTableDataCache::IsDateDimension( long nDim ) const +{ + if ( nDim >= mnColumnCount ) + return false; + else if ( mpTableDataValues[nDim].size()==0 ) + return false; + else + return mpTableDataValues[nDim][0]->IsDate(); + +} + +SCROW ScDPTableDataCache::GetDimMemberCount( SCCOL nDim ) const +{ + DBG_ASSERT( nDim>=0 && nDim < mnColumnCount ," ScDPTableDataCache::GetDimMemberCount : out of bound "); + return mpTableDataValues[nDim].size(); +} + +const ScDPItemData* ScDPTableDataCache::GetSortedItemData(SCCOL nDim, SCROW nOrder) const +{ + SCROW n = GetSortedItemDataId( nDim, nOrder ); + return GetItemDataById( nDim, n ); +} + +SCCOL ScDPTableDataCache::GetDimensionIndex(String sName) const +{ + for ( size_t n = 1; n < mrLabelNames.size(); n ++ ) //defects, label name map wrong SODC_17590, SODC_18932,SODC_18827,SODC_18960,SODC_18923 + { + if ( mrLabelNames[n]->GetString() == sName ) + return (SCCOL)(n-1); + } + return -1; +} + +SCROW ScDPTableDataCache::GetIdByItemData(long nDim, String sItemData ) const +{ + if ( nDim < mnColumnCount && nDim >=0 ) + { + for ( size_t n = 0; n< mpTableDataValues[nDim].size(); n++ ) + { + if ( mpTableDataValues[nDim][n]->GetString() == sItemData ) + return n; + } + } + + ScDPItemData rData ( sItemData ); + return GetRowCount() +maAdditionalDatas.getDataId(rData); +} + +SCROW ScDPTableDataCache::GetIdByItemData( long nDim, const ScDPItemData& rData ) const +{ + if ( nDim < mnColumnCount && nDim >=0 ) + { + for ( size_t n = 0; n< mpTableDataValues[nDim].size(); n++ ) + { + if ( *mpTableDataValues[nDim][n] == rData ) + return n; + } + } + return GetRowCount() + maAdditionalDatas.getDataId(rData); +} + +SCROW ScDPTableDataCache::GetAdditionalItemID ( String sItemData ) +{ + ScDPItemData rData ( sItemData ); + return GetAdditionalItemID( rData ); +} + +SCROW ScDPTableDataCache::GetAdditionalItemID( const ScDPItemData& rData ) +{ + return GetRowCount() + maAdditionalDatas.insertData( rData ); +} + + +SCROW ScDPTableDataCache::GetOrder(long nDim, SCROW nIndex) const +{ + DBG_ASSERT( IsValid(), " IsValid() == false " ); + DBG_ASSERT( nDim >=0 && nDim < mnColumnCount, "ScDPTableDataCache::GetOrder : out of bound" ); + + if ( mpIndexOrder[nDim].size() != mpGlobalOrder[nDim].size() ) + { //not inited + SCROW i = 0; + mpIndexOrder[nDim].resize( mpGlobalOrder[nDim].size(), 0 ); + for ( size_t n = 0 ; n< mpGlobalOrder[nDim].size(); n++ ) + { + i = mpGlobalOrder[nDim][n]; + mpIndexOrder[nDim][ i ] = n; + } + } + + DBG_ASSERT( nIndex>=0 && (size_t)nIndex < mpIndexOrder[nDim].size() , "ScDPTableDataCache::GetOrder"); + return mpIndexOrder[nDim][nIndex]; +} + +ScDocument* ScDPTableDataCache::GetDoc() const +{ + return mpDoc; +}; + +long ScDPTableDataCache::GetColumnCount() const +{ + return mnColumnCount; +} +long ScDPTableDataCache::GetId() const +{ + return mnID; +} + diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index 63f5da3290d7..55f9fb771061 100644..100755 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -87,7 +87,44 @@ static USHORT nFuncStrIds[12] = // passend zum enum ScSubTotalFunc STR_FUN_TEXT_VAR, // SUBTOTAL_FUNC_VAR STR_FUN_TEXT_VAR // SUBTOTAL_FUNC_VARP }; +namespace { + template < typename T > + void lcl_ResizePointVector( T & vec, size_t nSize ) + { + for ( size_t i = 0 ; i < vec.size(); i++ ) + { + if ( vec[i] ) + delete vec[i]; + } + vec.resize( nSize, NULL ); + } + BOOL lcl_SearchMember( const std::vector <ScDPResultMember *>& list, SCROW nOrder, SCROW& rIndex) + { + rIndex = list.size(); + BOOL bFound = FALSE; + SCROW nLo = 0; + SCROW nHi = list.size() - 1; + SCROW nIndex; + while (nLo <= nHi) + { + nIndex = (nLo + nHi) / 2; + if ( list[nIndex]->GetOrder() < nOrder ) + nLo = nIndex + 1; + else + { + nHi = nIndex - 1; + if ( list[nIndex]->GetOrder() == nOrder ) + { + bFound = TRUE; + nLo = nIndex; + } + } + } + rIndex = nLo; + return bFound; + } +} // ----------------------------------------------------------------------- // @@ -194,12 +231,16 @@ BOOL ScDPRowMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) con { const ScDPResultMember* pMember1 = rDimension.GetMember(nIndex1); const ScDPResultMember* pMember2 = rDimension.GetMember(nIndex2); - +// Wang Xu Ming -- 3/17/2009 + +// make the hide item to the largest order. + if ( !pMember1->IsVisible() || !pMember2->IsVisible() ) + return pMember1->IsVisible(); + const ScDPDataMember* pDataMember1 = pMember1->GetDataRoot() ; + const ScDPDataMember* pDataMember2 = pMember2->GetDataRoot(); +// End Comments // GetDataRoot can be NULL if there was no data. // IsVisible == FALSE can happen after AutoShow. - const ScDPDataMember* pDataMember1 = pMember1->IsVisible() ? pMember1->GetDataRoot() : NULL; - const ScDPDataMember* pDataMember2 = pMember2->IsVisible() ? pMember2->GetDataRoot() : NULL; - return lcl_IsLess( pDataMember1, pDataMember2, nMeasure, bAscending ); } @@ -207,12 +248,12 @@ BOOL ScDPColMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) con { ScDPDataMember* pDataMember1 = rDimension.GetMember(nIndex1); ScDPDataMember* pDataMember2 = rDimension.GetMember(nIndex2); - - if ( pDataMember1 && !pDataMember1->IsVisible() ) //! IsColVisible? - pDataMember1 = NULL; - if ( pDataMember2 && !pDataMember2->IsVisible() ) - pDataMember2 = NULL; - + // Wang Xu Ming -- 2009-6-17 + BOOL bHide1 = pDataMember1 && !pDataMember1->IsVisible(); + BOOL bHide2 = pDataMember2 && !pDataMember2->IsVisible(); + if ( bHide1 || bHide2 ) + return !bHide1; + // End Comments return lcl_IsLess( pDataMember1, pDataMember2, nMeasure, bAscending ); } @@ -222,7 +263,7 @@ ScDPInitState::ScDPInitState() : nCount( 0 ) { pIndex = new long[SC_DAPI_MAXFIELDS]; - pData = new ScDPItemData[SC_DAPI_MAXFIELDS]; + pData = new SCROW[SC_DAPI_MAXFIELDS]; } ScDPInitState::~ScDPInitState() @@ -231,13 +272,13 @@ ScDPInitState::~ScDPInitState() delete[] pData; } -void ScDPInitState::AddMember( long nSourceIndex, const ScDPItemData& rName ) +void ScDPInitState::AddMember( long nSourceIndex, SCROW nMember ) { DBG_ASSERT( nCount < SC_DAPI_MAXFIELDS, "too many InitState members" ); if ( nCount < SC_DAPI_MAXFIELDS ) { pIndex[nCount] = nSourceIndex; - pData[nCount] = rName; + pData[nCount] = nMember; ++nCount; } } @@ -249,13 +290,13 @@ void ScDPInitState::RemoveMember() --nCount; } -const ScDPItemData* ScDPInitState::GetNameForIndex( long nIndexValue ) const +const SCROW ScDPInitState::GetNameIdForIndex( long nIndexValue ) const { for (long i=0; i<nCount; i++) if ( pIndex[i] == nIndexValue ) - return &pData[i]; + return pData[i]; - return NULL; // not found + return -1; // not found } // ----------------------------------------------------------------------- @@ -735,6 +776,8 @@ ScDPResultData::ScDPResultData( ScDPSource* pSrc ) : //! Ref bDataAtCol( FALSE ), bDataAtRow( FALSE ) { + + lcl_ResizePointVector( mpDimMembers , SC_DAPI_MAXFIELDS ); } ScDPResultData::~ScDPResultData() @@ -743,6 +786,8 @@ ScDPResultData::~ScDPResultData() delete[] pMeasRefs; delete[] pMeasRefOrient; delete[] pMeasNames; + + lcl_ResizePointVector( mpDimMembers , 0 ); } void ScDPResultData::SetMeasureData( long nCount, const ScSubTotalFunc* pFunctions, @@ -890,15 +935,32 @@ BOOL ScDPResultData::IsNumOrDateGroup( long nDim ) const } BOOL ScDPResultData::IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex, - const ScDPItemData& rBaseData, long nBaseIndex ) const + long nBaseDataId, long nBaseIndex ) const { - return pSource->GetData()->IsInGroup( rGroupData, nGroupIndex, rBaseData, nBaseIndex ); + const ScDPItemData* pData = pSource->GetItemDataById( nGroupIndex , nBaseDataId); + if ( pData ) + return pSource->GetData()->IsInGroup( rGroupData, nGroupIndex, *pData , nBaseIndex ); + else + return FALSE; +} +BOOL ScDPResultData::IsInGroup( SCROW nGroupDataId, long nGroupIndex, + const ScDPItemData& rBaseData, long nBaseIndex ) const +{ + const ScDPItemData* pGroupData = pSource->GetItemDataById( nGroupIndex , nGroupDataId); + if ( pGroupData ) + return pSource->GetData()->IsInGroup( *pGroupData, nGroupIndex, rBaseData , nBaseIndex ); + else + return FALSE; } -BOOL ScDPResultData::HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex, +BOOL ScDPResultData::HasCommonElement(/* const ScDPItemData& rFirstData*/SCROW nFirstDataId, long nFirstIndex, const ScDPItemData& rSecondData, long nSecondIndex ) const { - return pSource->GetData()->HasCommonElement( rFirstData, nFirstIndex, rSecondData, nSecondIndex ); + const ScDPItemData* pFirstData = pSource->GetItemDataById( nFirstIndex , nFirstDataId); + if ( pFirstData ) + return pSource->GetData()->HasCommonElement( *pFirstData, nFirstIndex, rSecondData, nSecondIndex ); + else + return FALSE; } const ScDPSource* ScDPResultData::GetSource() const @@ -906,27 +968,68 @@ const ScDPSource* ScDPResultData::GetSource() const return pSource; } +ResultMembers* ScDPResultData::GetDimResultMembers( long nDim , ScDPDimension* pDim, ScDPLevel* pLevel) const +{ + if ( mpDimMembers[ nDim ] == NULL ) + { + + //long nDimSource = pDim->GetDimension(); + + ResultMembers* pResultMembers = new ResultMembers(); + // global order is used to initialize aMembers, so it doesn't have to be looked at later + const ScMemberSortOrder& rGlobalOrder = pLevel->GetGlobalOrder(); + + ScDPMembers* pMembers = pLevel->GetMembersObject(); + long nMembCount = pMembers->getCount(); + for ( long i=0; i<nMembCount; i++ ) + { + long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i]; + ScDPMember* pMember = pMembers->getByIndex(nSorted); + if ( NULL == pResultMembers->FindMember( pMember->GetItemDataId() ) ) + { + ScDPParentDimData* pNew = new ScDPParentDimData( i, pDim, pLevel, pMember ); + pResultMembers->InsertMember( pNew ); + } + } + + mpDimMembers[ nDim ] = pResultMembers; + } + return mpDimMembers[ nDim ]; + +} + // ----------------------------------------------------------------------- -ScDPResultMember::ScDPResultMember( const ScDPResultData* pData, const ScDPDimension* pDim, - const ScDPLevel* pLev, const ScDPMember* pDesc, +ScDPResultMember::ScDPResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData , BOOL bForceSub ) : pResultData( pData ), - pParentDim( pDim ), - pParentLevel( pLev ), - pMemberDesc( pDesc ), + aParentDimData( rParentDimData ), pChildDimension( NULL ), pDataRoot( NULL ), bHasElements( FALSE ), bForceSubTotal( bForceSub ), bHasHiddenDetails( FALSE ), bInitialized( FALSE ), - bAutoHidden( FALSE ) + bAutoHidden( FALSE ), + nMemberStep( 1 ) { // pParentLevel/pMemberDesc is 0 for root members } +ScDPResultMember::ScDPResultMember( const ScDPResultData* pData, + BOOL bForceSub ) : + pResultData( pData ), + pChildDimension( NULL ), + pDataRoot( NULL ), + bHasElements( FALSE ), + bForceSubTotal( bForceSub ), + bHasHiddenDetails( FALSE ), + bInitialized( FALSE ), + bAutoHidden( FALSE ), + nMemberStep( 1 ) +{ +} ScDPResultMember::~ScDPResultMember() { delete pChildDimension; @@ -935,6 +1038,7 @@ ScDPResultMember::~ScDPResultMember() String ScDPResultMember::GetName() const { + const ScDPMember* pMemberDesc = GetDPMember(); if (pMemberDesc) return pMemberDesc->GetNameStr(); else @@ -943,22 +1047,23 @@ String ScDPResultMember::GetName() const void ScDPResultMember::FillItemData( ScDPItemData& rData ) const { + const ScDPMember* pMemberDesc = GetDPMember(); if (pMemberDesc) pMemberDesc->FillItemData( rData ); else rData.SetString( ScGlobal::GetRscString(STR_PIVOT_TOTAL) ); // root member } -BOOL ScDPResultMember::IsNamedItem( const ScDPItemData& r ) const +BOOL ScDPResultMember::IsNamedItem( SCROW nIndex ) const { //! store ScDPMember pointer instead of ScDPMember ??? - + const ScDPMember* pMemberDesc = GetDPMember(); if (pMemberDesc) - return ((ScDPMember*)pMemberDesc)->IsNamedItem( r ); + return ((ScDPMember*)pMemberDesc)->IsNamedItem( nIndex ); return FALSE; } -bool ScDPResultMember::IsValidEntry( const vector<ScDPItemData>& aMembers ) const +bool ScDPResultMember::IsValidEntry( const vector< SCROW >& aMembers ) const { if ( !IsValid() ) return false; @@ -969,8 +1074,8 @@ bool ScDPResultMember::IsValidEntry( const vector<ScDPItemData>& aMembers ) cons if (aMembers.size() < 2) return false; - vector<ScDPItemData>::const_iterator itr = aMembers.begin(); - vector<ScDPItemData> aChildMembers(++itr, aMembers.end()); + vector<SCROW>::const_iterator itr = aMembers.begin(); + vector<SCROW> aChildMembers(++itr, aMembers.end()); return pChildDim->IsValidEntry(aChildMembers); } else @@ -978,7 +1083,8 @@ bool ScDPResultMember::IsValidEntry( const vector<ScDPItemData>& aMembers ) cons } void ScDPResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - size_t nPos, ScDPInitState& rInitState ) + size_t nPos, ScDPInitState& rInitState , + BOOL bInitChild /*= TRUE */) { // with LateInit, initialize only those members that have data if ( pResultData->IsLateInit() ) @@ -990,18 +1096,40 @@ void ScDPResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vect return; // skip child dimension if details are not shown - if ( pMemberDesc && !pMemberDesc->getShowDetails() ) + if ( GetDPMember() && !GetDPMember()->getShowDetails() ) { + // Wang Xu Ming -- 2009-6-16 + // Show DataLayout dimention + nMemberStep = 1; + while ( nPos < ppDim.size() ) + { + if ( ppDim[nPos] ->getIsDataLayoutDimension() ) + { + if ( !pChildDimension ) + pChildDimension = new ScDPResultDimension( pResultData ); + pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState , FALSE ); + return; + } + else + { //find next dim + nPos ++; + nMemberStep ++; + } + } + // End Comments bHasHiddenDetails = TRUE; // only if there is a next dimension return; } - pChildDimension = new ScDPResultDimension( pResultData ); - pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState ); + if ( bInitChild ) + { + pChildDimension = new ScDPResultDimension( pResultData ); + pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState, TRUE ); + } } -void ScDPResultMember::LateInitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - const vector<ScDPItemData>& pItemData, size_t nPos, +void ScDPResultMember::LateInitFrom( LateInitParams& rParams/*const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/, + const vector< SCROW >& pItemData, size_t nPos, ScDPInitState& rInitState ) { // without LateInit, everything has already been initialized @@ -1010,29 +1138,52 @@ void ScDPResultMember::LateInitFrom( const vector<ScDPDimension*>& ppDim, const bInitialized = TRUE; - if (nPos >= ppDim.size()) + if ( rParams.IsEnd( nPos ) /*nPos >= ppDim.size()*/) // No next dimension. Bail out. return; // skip child dimension if details are not shown - if ( pMemberDesc && !pMemberDesc->getShowDetails() ) + if ( GetDPMember() && !GetDPMember()->getShowDetails() ) { + // Wang Xu Ming -- 2009-6-16 + // DataPilot Migration + // Show DataLayout dimention + nMemberStep = 1; + while ( !rParams.IsEnd( nPos ) ) + { + if ( rParams.GetDim( nPos ) ->getIsDataLayoutDimension() ) + { + if ( !pChildDimension ) + pChildDimension = new ScDPResultDimension( pResultData ); + rParams.SetInitChild( FALSE ); + pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); + return; + } + else + { //find next dim + nPos ++; + nMemberStep ++; + } + } + // End Comments bHasHiddenDetails = TRUE; // only if there is a next dimension return; } // LateInitFrom is called several times... - if ( !pChildDimension ) - pChildDimension = new ScDPResultDimension( pResultData ); - - pChildDimension->LateInitFrom( ppDim, ppLev, pItemData, nPos, rInitState ); + if ( rParams.GetInitChild() ) + { + if ( !pChildDimension ) + pChildDimension = new ScDPResultDimension( pResultData ); + pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); + } } BOOL ScDPResultMember::IsSubTotalInTitle(long nMeasure) const { BOOL bRet = FALSE; - if ( pChildDimension && pParentLevel && - pParentLevel->IsOutlineLayout() && pParentLevel->IsSubtotalsAtTop() ) + if ( pChildDimension && /*pParentLevel*/GetParentLevel() && + /*pParentLevel*/GetParentLevel()->IsOutlineLayout() && /*pParentLevel*/GetParentLevel()->IsSubtotalsAtTop() ) { long nUserSubStart; long nSubTotals = GetSubTotalCount( &nUserSubStart ); @@ -1054,7 +1205,7 @@ long ScDPResultMember::GetSize(long nMeasure) const { if ( !IsVisible() ) return 0; - + const ScDPLevel* pParentLevel = GetParentLevel(); long nExtraSpace = 0; if ( pParentLevel && pParentLevel->IsAddEmpty() ) ++nExtraSpace; @@ -1091,7 +1242,7 @@ BOOL ScDPResultMember::IsVisible() const { // not initialized -> shouldn't be there at all // (allocated only to preserve ordering) - + const ScDPLevel* pParentLevel = GetParentLevel(); return ( bHasElements || ( pParentLevel && pParentLevel->getShowEmpty() ) ) && IsValid() && bInitialized; } @@ -1100,6 +1251,7 @@ BOOL ScDPResultMember::IsValid() const // non-Valid members are left out of calculation // was member set no invisible at the DataPilotSource? + const ScDPMember* pMemberDesc =GetDPMember(); if ( pMemberDesc && !pMemberDesc->getIsVisible() ) return FALSE; @@ -1122,6 +1274,8 @@ long ScDPResultMember::GetSubTotalCount( long* pUserSubStart ) const if ( pUserSubStart ) *pUserSubStart = 0; // default + const ScDPLevel* pParentLevel = GetParentLevel(); + if ( bForceSubTotal ) // set if needed for root members return 1; // grand total is always "automatic" else if ( pParentLevel ) @@ -1145,8 +1299,8 @@ long ScDPResultMember::GetSubTotalCount( long* pUserSubStart ) const return 0; } -void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, const ScDPResultDimension* pDataDim, - const vector<ScDPItemData>& aDataMembers, const vector<ScDPValueData>& aValues ) +void ScDPResultMember::ProcessData( const vector< SCROW >& aChildMembers, const ScDPResultDimension* pDataDim, + const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues ) { SetHasElements(); @@ -1169,6 +1323,8 @@ void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, c if ( !nUserSubCount || !pChildDimension ) nUserSubCount = 1; + const ScDPLevel* pParentLevel = GetParentLevel(); + for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic" { // #i68338# if nUserSubCount is 1 (automatic only), don't set nRowSubTotalFunc @@ -1229,10 +1385,10 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS { ScDPItemData aItemData; FillItemData( aItemData ); - aName = aItemData.aString; - bIsNumeric = aItemData.bHasValue; + aName = aItemData.GetString(); + bIsNumeric = aItemData.IsValue(); } - + const ScDPDimension* pParentDim = GetParentDim(); if ( bIsNumeric && pParentDim && pResultData->IsNumOrDateGroup( pParentDim->GetDimension() ) ) { // Numeric group dimensions use numeric entries for proper sorting, @@ -1241,6 +1397,7 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS } String aCaption = aName; + const ScDPMember* pMemberDesc = GetDPMember(); if (pMemberDesc) { const OUString* pLayoutName = pMemberDesc->GetLayoutName(); @@ -1272,6 +1429,7 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS pArray[rPos+i].Flags |= sheet::MemberResultFlags::CONTINUE; } + const ScDPLevel* pParentLevel = GetParentLevel(); long nExtraSpace = 0; if ( pParentLevel && pParentLevel->IsAddEmpty() ) ++nExtraSpace; @@ -1293,7 +1451,8 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS if (bRoot) // same sequence for root member pChildDimension->FillMemberResults( pSequences, rPos, nMeasure ); else - pChildDimension->FillMemberResults( pSequences + 1, rPos, nMeasure ); + //pChildDimension->FillMemberResults( pSequences + 1, rPos, nMeasure ); + pChildDimension->FillMemberResults( pSequences + nMemberStep/*1*/, rPos, nMeasure ); if ( bTitleLine ) // title row is included in GetSize, so the following --rPos; // positions are calculated with the normal values @@ -1389,7 +1548,7 @@ void ScDPResultMember::FillDataResults( const ScDPResultMember* pRefMember, { // IsVisible() test is in ScDPResultDimension::FillDataResults // (not on data layout dimension) - + const ScDPLevel* pParentLevel = GetParentLevel(); long nStartRow = rRow; long nExtraSpace = 0; @@ -1409,7 +1568,7 @@ void ScDPResultMember::FillDataResults( const ScDPResultMember* pRefMember, ++rRow; // -> fill child dimension one row below pChildDimension->FillDataResults( pRefMember, rSequence, rRow, nMeasure ); // doesn't modify rRow - rRow += (USHORT) GetSize( nMeasure ); + rRow += GetSize( nMeasure ); if ( bTitleLine ) // title row is included in GetSize, so the following --rRow; // positions are calculated with the normal values @@ -1451,7 +1610,7 @@ void ScDPResultMember::FillDataResults( const ScDPResultMember* pRefMember, if ( bHasChild && nUserSubCount > 1 ) { aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos ); + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos ); } for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) @@ -1509,7 +1668,7 @@ void ScDPResultMember::UpdateDataResults( const ScDPResultMember* pRefMember, lo if ( bHasChild && nUserSubCount > 1 ) { aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos ); + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos ); } for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) @@ -1537,8 +1696,7 @@ void ScDPResultMember::SortMembers( ScDPResultMember* pRefMember ) if (bHasChild) pChildDimension->SortMembers( pRefMember ); // sorting is done at the dimension - BOOL bIsRoot = ( pParentLevel == NULL ); - if ( bIsRoot && pDataRoot ) + if ( IsRoot() && pDataRoot ) { // use the row root member to sort columns // sub total count is always 1 @@ -1553,8 +1711,7 @@ void ScDPResultMember::DoAutoShow( ScDPResultMember* pRefMember ) if (bHasChild) pChildDimension->DoAutoShow( pRefMember ); // sorting is done at the dimension - BOOL bIsRoot = ( pParentLevel == NULL ); - if ( bIsRoot && pDataRoot ) + if ( IsRoot()&& pDataRoot ) { // use the row root member to sort columns // sub total count is always 1 @@ -1563,7 +1720,7 @@ void ScDPResultMember::DoAutoShow( ScDPResultMember* pRefMember ) } } -void ScDPResultMember::ResetResults( BOOL bRoot ) +void ScDPResultMember::ResetResults( BOOL /*bRoot*/ ) { if (pDataRoot) pDataRoot->ResetResults(); @@ -1571,8 +1728,8 @@ void ScDPResultMember::ResetResults( BOOL bRoot ) if (pChildDimension) pChildDimension->ResetResults(); - if (!bRoot) - bHasElements = FALSE; + // if (!bRoot) + // bHasElements = FALSE; } void ScDPResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure, @@ -1581,13 +1738,12 @@ void ScDPResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, // IsVisible() test is in ScDPResultDimension::FillDataResults // (not on data layout dimension) - BOOL bIsRoot = ( pParentLevel == NULL ); - rTotals.SetInColRoot( bIsRoot ); + rTotals.SetInColRoot( IsRoot() ); BOOL bHasChild = ( pChildDimension != NULL ); long nUserSubCount = GetSubTotalCount(); - if ( nUserSubCount || !bHasChild ) + //if ( nUserSubCount || !bHasChild ) { // Calculate at least automatic if no subtotals are selected, // show only own values if there's no child dimension (innermost). @@ -1606,7 +1762,7 @@ void ScDPResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, if ( bHasChild && nUserSubCount > 1 ) { aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos ); + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel(), nUserPos ); } for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) @@ -1685,7 +1841,7 @@ BOOL ScDPDataMember::IsVisible() const return FALSE; } -BOOL ScDPDataMember::IsNamedItem( const ScDPItemData& r ) const +BOOL ScDPDataMember::IsNamedItem( /*const ScDPItemData& r*/SCROW r ) const { if (pResultMember) return pResultMember->IsNamedItem(r); @@ -1752,7 +1908,7 @@ void ScDPDataMember::UpdateValues( const vector<ScDPValueData>& aValues, const S } } -void ScDPDataMember::ProcessData( const vector<ScDPItemData>& aChildMembers, const vector<ScDPValueData>& aValues, +void ScDPDataMember::ProcessData( const vector< SCROW >& aChildMembers, const vector<ScDPValueData>& aValues, const ScDPSubTotalState& rSubState ) { if ( pResultData->IsLateInit() && !pChildDimension && pResultMember && pResultMember->GetChildDimension() ) @@ -2107,7 +2263,7 @@ void ScDPDataMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, BOOL bHasChild = ( pRefChild != NULL ); long nUserSubCount = pRefMember->GetSubTotalCount(); - if ( nUserSubCount || !bHasChild ) + //if ( nUserSubCount || !bHasChild ) { // Calculate at least automatic if no subtotals are selected, // show only own values if there's no child dimension (innermost). @@ -2496,8 +2652,10 @@ private: BOOL bIncludeAll; BOOL bIsBase; long nGroupBase; - const ScDPItemData* pBaseData; - + // Wang Xu Ming -- 2009-8-6 + // DataPilot Migration - Cache&&Performance + SCROW nBaseDataId; + // End Comments public: ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitState& rState, long nDimension ); ~ScDPGroupCompare() {} @@ -2510,12 +2668,12 @@ ScDPGroupCompare::ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitS pResultData( pData ), rInitState( rState ), nDimSource( nDimension ), - pBaseData( NULL ) + nBaseDataId( -1 ) { bIsBase = pResultData->IsBaseForGroup( nDimSource ); nGroupBase = pResultData->GetGroupBase( nDimSource ); //! get together in one call? if ( nGroupBase >= 0 ) - pBaseData = rInitState.GetNameForIndex( nGroupBase ); + nBaseDataId = rInitState.GetNameIdForIndex( nGroupBase ); // if bIncludeAll is set, TestIncluded doesn't need to be called bIncludeAll = !( bIsBase || nGroupBase >= 0 ); @@ -2524,11 +2682,11 @@ ScDPGroupCompare::ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitS BOOL ScDPGroupCompare::TestIncluded( const ScDPMember& rMember ) { BOOL bInclude = TRUE; - if ( pBaseData ) + if ( nBaseDataId >=0 ) { ScDPItemData aMemberData; rMember.FillItemData( aMemberData ); - bInclude = pResultData->IsInGroup( aMemberData, nDimSource, *pBaseData, nGroupBase ); + bInclude = pResultData->IsInGroup( aMemberData, nDimSource, nBaseDataId, nGroupBase ); } else if ( bIsBase ) { @@ -2538,7 +2696,8 @@ BOOL ScDPGroupCompare::TestIncluded( const ScDPMember& rMember ) rMember.FillItemData( aMemberData ); long nInitCount = rInitState.GetCount(); const long* pInitSource = rInitState.GetSource(); - const ScDPItemData* pInitNames = rInitState.GetNames(); + /*const ScDPItemData* pInitNames = rInitState.GetNames();*/ + const SCROW* pInitNames = rInitState.GetNameIds(); for (long nInitPos=0; nInitPos<nInitCount && bInclude; nInitPos++) if ( pResultData->GetGroupBase( pInitSource[nInitPos] ) == nDimSource ) { @@ -2556,7 +2715,8 @@ BOOL ScDPGroupCompare::TestIncluded( const ScDPMember& rMember ) rMember.FillItemData( aMemberData ); long nInitCount = rInitState.GetCount(); const long* pInitSource = rInitState.GetSource(); - const ScDPItemData* pInitNames = rInitState.GetNames(); + /*const ScDPItemData* pInitNames = rInitState.GetNames();*/ + const SCROW* pInitNames = rInitState.GetNameIds(); for (long nInitPos=0; nInitPos<nInitCount && bInclude; nInitPos++) if ( pResultData->GetGroupBase( pInitSource[nInitPos] ) == nGroupBase ) { @@ -2591,14 +2751,14 @@ ScDPResultDimension::~ScDPResultDimension() delete maMemberArray[i]; } -ScDPResultMember *ScDPResultDimension::FindMember( const ScDPItemData& rData ) const +ScDPResultMember *ScDPResultDimension::FindMember( SCROW iData ) const { if( bIsDataLayout ) return maMemberArray[0]; - MemberHash::const_iterator aRes = maMemberHash.find( rData ); + MemberHash::const_iterator aRes = maMemberHash.find( iData ); if( aRes != maMemberHash.end()) { - if ( aRes->second->IsNamedItem( rData ) ) + if ( aRes->second->IsNamedItem( iData ) ) return aRes->second; DBG_ERROR("problem! hash result is not the same as IsNamedItem"); } @@ -2609,14 +2769,14 @@ ScDPResultMember *ScDPResultDimension::FindMember( const ScDPItemData& rData ) c for( i = 0; i < nCount ; i++ ) { pResultMember = maMemberArray[i]; - if ( pResultMember->IsNamedItem( rData ) ) + if ( pResultMember->IsNamedItem( iData ) ) return pResultMember; } return NULL; } void ScDPResultDimension::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - size_t nPos, ScDPInitState& rInitState ) + size_t nPos, ScDPInitState& rInitState, BOOL bInitChild /*= TRUE */ ) { if (nPos >= ppDim.size() || nPos >= ppLev.size()) { @@ -2671,46 +2831,41 @@ void ScDPResultDimension::InitFrom( const vector<ScDPDimension*>& ppDim, const v ScDPMember* pMember = pMembers->getByIndex(nSorted); if ( aCompare.IsIncluded( *pMember ) ) { - ScDPResultMember* pNew = new ScDPResultMember( pResultData, pThisDim, - pThisLevel, pMember, FALSE ); - maMemberArray.push_back( pNew ); + ScDPParentDimData aData( i, pThisDim, pThisLevel, pMember); + ScDPResultMember* pNew = AddMember( aData ); - ScDPItemData aMemberData; - pMember->FillItemData( aMemberData ); - - // honour order of maMemberArray and only insert if it does not - // already exist - if ( maMemberHash.end() == maMemberHash.find( aMemberData ) ) - maMemberHash.insert( std::pair< const ScDPItemData, ScDPResultMember *>( aMemberData, pNew ) ); - - rInitState.AddMember( nDimSource, aMemberData ); - pNew->InitFrom( ppDim, ppLev, nPos+1, rInitState ); + rInitState.AddMember( nDimSource, /*aMemberData*/pNew->GetDataId() ); + pNew->InitFrom( ppDim, ppLev, nPos+1, rInitState, bInitChild ); rInitState.RemoveMember(); } } bInitialized = TRUE; } -void ScDPResultDimension::LateInitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - const vector<ScDPItemData>& pItemData, size_t nPos, +void ScDPResultDimension::LateInitFrom( LateInitParams& rParams/* const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/, + const vector<SCROW>& pItemData, size_t nPos, ScDPInitState& rInitState ) +// End Comments { - if (nPos >= ppDim.size() || nPos >= ppLev.size() || nPos >= pItemData.size()) + if ( rParams.IsEnd( nPos ) ) return; - - ScDPDimension* pThisDim = ppDim[nPos]; - ScDPLevel* pThisLevel = ppLev[nPos]; - const ScDPItemData& rThisData = pItemData[nPos]; +#ifdef DBG_UTIL + DBG_ASSERT( nPos <= pItemData.size(), ByteString::CreateFromInt32( pItemData.size()).GetBuffer() ); +#endif + ScDPDimension* pThisDim = rParams.GetDim( nPos ); + ScDPLevel* pThisLevel = rParams.GetLevel( nPos ); + SCROW rThisData = pItemData[nPos]; if (!pThisDim || !pThisLevel) return; long nDimSource = pThisDim->GetDimension(); //! check GetSourceDim? - if ( !bInitialized ) - { - // create all members at the first call (preserve order) + BOOL bShowEmpty = pThisLevel->getShowEmpty(); + if ( !bInitialized ) + { // init some values + // create all members at the first call (preserve order) bIsDataLayout = pThisDim->getIsDataLayoutDimension(); aDimensionName = pThisDim->getName(); @@ -2730,65 +2885,86 @@ void ScDPResultDimension::LateInitFrom( const vector<ScDPDimension*>& ppDim, con bSortAscending = rSortInfo.IsAscending; nSortMeasure = pThisLevel->GetSortMeasure(); } + } - // global order is used to initialize aMembers, so it doesn't have to be looked at later - const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder(); + bool bLateInitAllMembers= bIsDataLayout || rParams.GetInitAllChild() || bShowEmpty; - ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource ); + if ( !bLateInitAllMembers ) + { + ResultMembers* pMembers = pResultData->GetDimResultMembers(nDimSource, pThisDim, pThisLevel); + bLateInitAllMembers = pMembers->IsHasHideDetailsMembers(); +#ifdef DBG_UTIL + DBG_TRACESTR( aDimensionName ) + if ( pMembers->IsHasHideDetailsMembers() ) + DBG_TRACE ( "HasHideDetailsMembers" ); +#endif + pMembers->SetHasHideDetailsMembers( FALSE ); + } - ScDPMembers* pMembers = pThisLevel->GetMembersObject(); - long nMembCount = pMembers->getCount(); - for ( long i=0; i<nMembCount; i++ ) - { - long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i]; + bool bNewAllMembers =(!rParams.IsRow()) || nPos == 0 || bLateInitAllMembers ; - ScDPMember* pMember = pMembers->getByIndex(nSorted); - if ( aCompare.IsIncluded( *pMember ) ) + if (bNewAllMembers ) + { + // global order is used to initialize aMembers, so it doesn't have to be looked at later + if ( !bInitialized ) + { //init all members + const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder(); + + ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource ); + ScDPMembers* pMembers = pThisLevel->GetMembersObject(); + long nMembCount = pMembers->getCount(); + for ( long i=0; i<nMembCount; i++ ) { - ScDPResultMember* pNew = new ScDPResultMember( pResultData, pThisDim, - pThisLevel, pMember, FALSE ); - maMemberArray.push_back( pNew ); + long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i]; - ScDPItemData aMemberData; - pMember->FillItemData( aMemberData ); - - // honour order of maMemberArray and only insert if it does not - // already exist - if ( maMemberHash.end() == maMemberHash.find( aMemberData ) ) - maMemberHash.insert( std::pair< const ScDPItemData, ScDPResultMember *>( aMemberData, pNew ) ); + ScDPMember* pMember = pMembers->getByIndex(nSorted); + if ( aCompare.IsIncluded( *pMember ) ) + { // add all members + ScDPParentDimData aData( i, pThisDim, pThisLevel, pMember ); + AddMember( aData ); + } } + bInitialized = TRUE; // don't call again, even if no members were included } - bInitialized = TRUE; // don't call again, even if no members were included - } - // initialize only specific member (or all if "show empty" flag is set) - - BOOL bShowEmpty = pThisLevel->getShowEmpty(); - if ( bIsDataLayout || bShowEmpty ) - { - long nCount = maMemberArray.size(); - for (long i=0; i<nCount; i++) + if ( bLateInitAllMembers ) { - ScDPResultMember* pResultMember = maMemberArray[i]; - ScDPItemData aMemberData; - pResultMember->FillItemData( aMemberData ); - rInitState.AddMember( nDimSource, aMemberData ); - pResultMember->LateInitFrom( ppDim, ppLev, pItemData, nPos+1, rInitState ); - rInitState.RemoveMember(); + long nCount = maMemberArray.size(); + for (long i=0; i<nCount; i++) + { + ScDPResultMember* pResultMember = maMemberArray[i]; + + // check show empty + BOOL bAllChildren = FALSE; + if( bShowEmpty ) + { + if ( pResultMember->IsNamedItem( rThisData ) ) + bAllChildren = FALSE; + else + bAllChildren = TRUE; + } + rParams.SetInitAllChildren( bAllChildren ); + rInitState.AddMember( nDimSource, pResultMember->GetDataId() ); + pResultMember->LateInitFrom( rParams, pItemData, nPos+1, rInitState ); + rInitState.RemoveMember(); + } } - } - else - { - ScDPResultMember* pResultMember = FindMember( rThisData ); - if( NULL != pResultMember ) + else { - ScDPItemData aMemberData; - pResultMember->FillItemData( aMemberData ); - rInitState.AddMember( nDimSource, aMemberData ); - pResultMember->LateInitFrom( ppDim, ppLev, pItemData, nPos+1, rInitState ); - rInitState.RemoveMember(); + ScDPResultMember* pResultMember = FindMember( rThisData ); + if( NULL != pResultMember ) + { + //DBG_TRACE( "ScDPResultDimension::LateInitFrom"); + // DBG_TRACESTR( pResultMember->GetDPMember()->GetNameStr()); + + rInitState.AddMember( nDimSource, pResultMember->GetDataId() ); + pResultMember->LateInitFrom( rParams, pItemData, nPos+1, rInitState ); + rInitState.RemoveMember(); + } } } + else + InitWithMembers( rParams, pItemData, nPos, rInitState ); } long ScDPResultDimension::GetSize(long nMeasure) const @@ -2811,7 +2987,7 @@ long ScDPResultDimension::GetSize(long nMeasure) const return nTotal; } -bool ScDPResultDimension::IsValidEntry( const vector<ScDPItemData>& aMembers ) const +bool ScDPResultDimension::IsValidEntry( const vector< SCROW >& aMembers ) const { if (aMembers.empty()) return false; @@ -2819,14 +2995,18 @@ bool ScDPResultDimension::IsValidEntry( const vector<ScDPItemData>& aMembers ) c const ScDPResultMember* pMember = FindMember( aMembers[0] ); if ( NULL != pMember ) return pMember->IsValidEntry( aMembers ); - - DBG_ERROR("IsValidEntry: Member not found"); +#ifdef DBG_UTIL + ByteString strTemp ("IsValidEntry: Member not found, DimName = " ); + strTemp += ByteString( GetName(), RTL_TEXTENCODING_UTF8 ); + DBG_TRACE( strTemp.GetBuffer() ); + // DBG_ERROR("IsValidEntry: Member not found"); +#endif return false; } -void ScDPResultDimension::ProcessData( const vector<ScDPItemData>& aMembers, +void ScDPResultDimension::ProcessData( const vector< SCROW >& aMembers, const ScDPResultDimension* pDataDim, - const vector<ScDPItemData>& aDataMembers, + const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues ) const { if (aMembers.empty()) @@ -2835,11 +3015,11 @@ void ScDPResultDimension::ProcessData( const vector<ScDPItemData>& aMembers, ScDPResultMember* pMember = FindMember( aMembers[0] ); if ( NULL != pMember ) { - vector<ScDPItemData> aChildMembers; + vector</*ScDPItemData*/SCROW > aChildMembers; if (aMembers.size() > 1) { - vector<ScDPItemData>::const_iterator itr = aMembers.begin(); - aChildMembers.assign(++itr, aMembers.end()); + vector</*ScDPItemData*/SCROW >::const_iterator itr = aMembers.begin(); + aChildMembers.insert(aChildMembers.begin(), ++itr, aMembers.end()); } pMember->ProcessData( aChildMembers, pDataDim, aDataMembers, aValues ); return; @@ -3372,7 +3552,7 @@ void ScDPDataDimension::InitFrom( const ScDPResultDimension* pDim ) } } -void ScDPDataDimension::ProcessData( const vector<ScDPItemData>& aDataMembers, const vector<ScDPValueData>& aValues, +void ScDPDataDimension::ProcessData( const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues, const ScDPSubTotalState& rSubState ) { // the ScDPItemData array must contain enough entries for all dimensions - this isn't checked @@ -3385,11 +3565,11 @@ void ScDPDataDimension::ProcessData( const vector<ScDPItemData>& aDataMembers, c // always first member for data layout dim if ( bIsDataLayout || ( !aDataMembers.empty() && pMember->IsNamedItem(aDataMembers[0]) ) ) { - vector<ScDPItemData> aChildDataMembers; + vector</*ScDPItemData*/SCROW> aChildDataMembers; if (aDataMembers.size() > 1) { - vector<ScDPItemData>::const_iterator itr = aDataMembers.begin(); - aChildDataMembers.assign(++itr, aDataMembers.end()); + vector</*ScDPItemData*/SCROW >::const_iterator itr = aDataMembers.begin(); + aChildDataMembers.insert(aChildDataMembers.begin(), ++itr, aDataMembers.end()); } pMember->ProcessData( aChildDataMembers, aValues, rSubState ); return; @@ -3660,8 +3840,7 @@ ScDPDataMember* ScDPDataDimension::GetMember(long n) const // ---------------------------------------------------------------------------- ScDPResultVisibilityData::ScDPResultVisibilityData( - ScSimpleSharedString& rSharedString, ScDPSource* pSource) : - mrSharedString(rSharedString), + ScDPSource* pSource) : mpSource(pSource) { } @@ -3715,7 +3894,8 @@ void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion long nDimIndex = itrField->second; aCri.mnFieldIndex = static_cast<sal_Int32>(nDimIndex); - aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(mrSharedString)); + aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(/*mrSharedString*/)); + ScDPCacheTable::GroupFilter* pGrpFilter = static_cast<ScDPCacheTable::GroupFilter*>(aCri.mpFilter.get()); @@ -3724,7 +3904,7 @@ void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion itrMem != itrMemEnd; ++itrMem) { const ScDPItemData& rMemItem = *itrMem; - pGrpFilter->addMatchItem(rMemItem.aString, rMemItem.fValue, rMemItem.bHasValue); + pGrpFilter->addMatchItem(rMemItem.GetString(), rMemItem.GetValue(), rMemItem.IsValue()); } ScDPDimension* pDim = pDims->getByIndex(nDimIndex); @@ -3737,8 +3917,188 @@ void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion size_t ScDPResultVisibilityData::MemberHash::operator() (const ScDPItemData& r) const { - if (r.bHasValue) - return static_cast<size_t>(::rtl::math::approxFloor(r.fValue)); + if (r.IsValue()) + return static_cast<size_t>(::rtl::math::approxFloor(r.GetValue())); else - return rtl_ustr_hashCode_WithLength(r.aString.GetBuffer(), r.aString.Len()); + return rtl_ustr_hashCode_WithLength(r.GetString().GetBuffer(), r.GetString().Len()); +} +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration +SCROW ScDPResultMember::GetDataId( ) const +{ + const ScDPMember* pMemberDesc = GetDPMember(); + if (pMemberDesc) + return pMemberDesc->GetItemDataId(); + return -1; +} + +ScDPResultMember* ScDPResultDimension::AddMember(const ScDPParentDimData &aData ) +{ + ScDPResultMember* pMember = new ScDPResultMember( pResultData, aData, FALSE ); + SCROW nDataIndex = pMember->GetDataId(); + maMemberArray.push_back( pMember ); + + if ( maMemberHash.end() == maMemberHash.find( nDataIndex ) ) + maMemberHash.insert( std::pair< SCROW, ScDPResultMember *>( nDataIndex, pMember ) ); + return pMember; +} + +ResultMembers* ScDPResultDimension::GetResultMember( ScDPDimension* pThisDim, ScDPLevel* pThisLevel ) +{ + ResultMembers* pResultMembers = new ResultMembers(); + // global order is used to initialize aMembers, so it doesn't have to be looked at later + const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder(); + + ScDPMembers* pMembers = pThisLevel->GetMembersObject(); + long nMembCount = pMembers->getCount(); + for ( long i=0; i<nMembCount; i++ ) + { + long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i]; + ScDPMember* pMember = pMembers->getByIndex(nSorted); + if ( NULL == pResultMembers->FindMember( pMember->GetItemDataId() ) ) + { + ScDPParentDimData* pNew = new ScDPParentDimData( i, pThisDim, pThisLevel, pMember ); + pResultMembers->InsertMember( pNew ); + } + } + return pResultMembers; } + +ScDPResultMember* ScDPResultDimension::InsertMember(ScDPParentDimData *pMemberData) +{ + SCROW nInsert = 0; + if ( !lcl_SearchMember( maMemberArray, pMemberData->mnOrder , nInsert ) ) + { //Member not exist + ScDPResultMember* pNew = new ScDPResultMember( pResultData, *pMemberData, FALSE ); + maMemberArray.insert( maMemberArray.begin()+nInsert, pNew ); + + SCROW nDataIndex = pMemberData->mpMemberDesc->GetItemDataId(); + if ( maMemberHash.end() == maMemberHash.find( nDataIndex ) ) + maMemberHash.insert( std::pair< SCROW, ScDPResultMember *>( nDataIndex, pNew ) ); + return pNew; + } + return maMemberArray[ nInsert ]; +} + +void ScDPResultDimension:: InitWithMembers( LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState ) +{ + if ( rParams.IsEnd( nPos ) ) + return; + ScDPDimension* pThisDim = rParams.GetDim( nPos ); + ScDPLevel* pThisLevel = rParams.GetLevel( nPos ); + SCROW nDataID = pItemData[nPos]; + + if (pThisDim && pThisLevel) + { + long nDimSource = pThisDim->GetDimension(); //! check GetSourceDim? + + // create all members at the first call (preserve order) + ResultMembers* pMembers = pResultData->GetDimResultMembers(nDimSource, pThisDim, pThisLevel); + ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource ); + // initialize only specific member (or all if "show empty" flag is set) + ScDPResultMember* pResultMember = NULL; + if ( bInitialized ) + pResultMember = FindMember( nDataID ); + else + bInitialized = TRUE; + + if ( pResultMember == NULL ) + { //only insert found item + ScDPParentDimData* pMemberData = pMembers->FindMember( nDataID ); + if ( pMemberData && aCompare.IsIncluded( *( pMemberData->mpMemberDesc ) ) ) + pResultMember = InsertMember( pMemberData ); + } + if ( pResultMember ) + { + // DBG_TRACE( "ScDPResultDimension::InitWithMembers"); + // DBG_TRACESTR( pResultMember->GetDPMember()->GetNameStr()); + rInitState.AddMember( nDimSource, pResultMember->GetDataId() ); + pResultMember->LateInitFrom( rParams /*ppDim, ppLev*/, pItemData, nPos+1 , rInitState ); + rInitState.RemoveMember(); + } + } +} + +ScDPParentDimData* ResultMembers::FindMember( const SCROW& nIndex ) const +{ + DimMemberHash::const_iterator aRes = maMemberHash.find( nIndex ); + if( aRes != maMemberHash.end()) { + if ( aRes->second->mpMemberDesc && aRes->second->mpMemberDesc->GetItemDataId()==nIndex ) + return aRes->second; + } + return NULL; +} +void ResultMembers::InsertMember( ScDPParentDimData* pNew ) +{ + if ( !pNew->mpMemberDesc->getShowDetails() ) + mbHasHideDetailsMember = TRUE; + maMemberHash.insert( std::pair< const SCROW, ScDPParentDimData *>( pNew->mpMemberDesc->GetItemDataId(), pNew ) ); +} + +ResultMembers::ResultMembers(): + mbHasHideDetailsMember( FALSE ) +{ +} +ResultMembers::~ResultMembers() +{ + for ( DimMemberHash::const_iterator iter = maMemberHash.begin(); iter != maMemberHash.end(); iter++ ) + delete iter->second; +} +// ----------------------------------------------------------------------- +LateInitParams::LateInitParams( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, BOOL bRow, BOOL bInitChild, BOOL bAllChildren ): + mppDim( ppDim ), + mppLev( ppLev ), + mbRow( bRow ), + mbInitChild( bInitChild ), + mbAllChildren( bAllChildren ) +{ +} + +LateInitParams::~LateInitParams() +{ +} + +BOOL LateInitParams::IsEnd( size_t nPos ) const +{ + return nPos >= mppDim.size(); +} + +// End Comments +// Wang Xu Ming -- 2009-8-4 +// DataPilot Migration - old defects merge +void ScDPResultDimension::CheckShowEmpty( BOOL bShow ) +{ + long nCount = maMemberArray.size(); + + ScDPResultMember* pMember = NULL; + for (long i=0; i<nCount; i++) + { + pMember = maMemberArray.at(i); + pMember->CheckShowEmpty( bShow ); + } + +} + +void ScDPResultMember::CheckShowEmpty( BOOL bShow ) +{ + if ( bHasElements ) + { + ScDPResultDimension* pChildDim = GetChildDimension(); + if (pChildDim ) + pChildDim->CheckShowEmpty(); + } + else if ( IsValid() && bInitialized ) + { + bShow = bShow || ( GetParentLevel() && GetParentLevel()->getShowEmpty() ); + if ( bShow ) + { + SetHasElements(); + ScDPResultDimension* pChildDim = GetChildDimension(); + if (pChildDim ) + pChildDim->CheckShowEmpty( TRUE ); + } + } +}// End Comments diff --git a/sc/source/core/data/dptabresmember.cxx b/sc/source/core/data/dptabresmember.cxx new file mode 100644 index 000000000000..8c3b7b164bc3 --- /dev/null +++ b/sc/source/core/data/dptabresmember.cxx @@ -0,0 +1,831 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dptabresmember.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include "dptabresmember.hxx" +// ----------------------------------------------------------------------- +ScDPResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData , + BOOL bForceSub ) : + pResultData( pData ), + aParentDimData( rParentDimData ), + /* pParentDim( pDim ), + pParentLevel( pLev ), + pMemberDesc( pDesc ),*/ + pChildDimension( NULL ), + pDataRoot( NULL ), + bHasElements( FALSE ), + bForceSubTotal( bForceSub ), + bHasHiddenDetails( FALSE ), + bInitialized( FALSE ), + nMemberStep( 1 ), + bAutoHidden( FALSE ) +{ + // pParentLevel/pMemberDesc is 0 for root members +} + +ScDPNormalResultMember::ScDPNormalResultMember( const ScDPResultData* pData, + BOOL bForceSub ) : + pResultData( pData ), + pChildDimension( NULL ), + pDataRoot( NULL ), + bHasElements( FALSE ), + bForceSubTotal( bForceSub ), + bHasHiddenDetails( FALSE ), + bInitialized( FALSE ), + nMemberStep( 1 ), + bAutoHidden( FALSE ) +{ +} + +ScDPNormalResultMember::~ScDPNormalResultMember() +{ + delete pChildDimension; + delete pDataRoot; +} + +String ScDPNormalResultMember::GetName() const +{ +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration + const ScDPMember* pMemberDesc = GetDPMember(); + // End Comments + if (pMemberDesc) + return pMemberDesc->GetNameStr(); + else + return ScGlobal::GetRscString(STR_PIVOT_TOTAL); // root member +} + +void ScDPNormalResultMember::FillItemData( ScDPItemData& rData ) const +{ +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration + const ScDPMember* pMemberDesc = GetDPMember(); +// End Comments + if (pMemberDesc) + pMemberDesc->FillItemData( rData ); + else + rData.SetString( ScGlobal::GetRscString(STR_PIVOT_TOTAL) ); // root member +} + +BOOL ScDPNormalResultMember::IsNamedItem( /*const ScDPItemData& r */SCROW nIndex ) const +{ + //! store ScDPMember pointer instead of ScDPMember ??? + const ScDPMember* pMemberDesc = GetDPMember(); + if (pMemberDesc) + return ((ScDPMember*)pMemberDesc)->IsNamedItem(/* r*/ nIndex ); + return FALSE; +} + +// Wang Xu Ming -- 2009-5-27 +// DataPilot Migration +bool ScDPNormalResultMember::IsValidEntry( const vector< SCROW >& aMembers ) const +{ + return GetEntryStatus( aMembers ) != ENTRY_INVALID; +} +// End Comments + +ENTRYSTATUS ScDPNormalResultMember::GetEntryStatus( const vector< SCROW >& aMembers ) const +{ + if ( !IsValid() ) + return ENTRY_INVALID; + + const ScDPResultDimension* pChildDim = GetChildDimension(); + if (pChildDim) + { + if (aMembers.size() < 2) + return ENTRY_INVALID; + + vector</*ScDPItemData*/SCROW>::const_iterator itr = aMembers.begin(); + vector</*ScDPItemData*/SCROW> aChildMembers(++itr, aMembers.end()); + return pChildDim->GetEntryStatus(aChildMembers); + } + else if( bHasHiddenDetails ) + return ENTRY_HASHIDDENDETAIL; + else + return ENTRY_VALID; +} + +void ScDPNormalResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, + size_t nPos, ScDPInitState& rInitState , + BOOL bInitChild /*= TRUE */) + { + // with LateInit, initialize only those members that have data + if ( pResultData->IsLateInit() ) + return; + + bInitialized = TRUE; + + if (nPos >= ppDim.size() ) + return; + + // skip child dimension if details are not shown + if ( GetDPMember() && !GetDPMember()->getShowDetails() ) + { + // Wang Xu Ming -- 2009-6-16 + // Show DataLayout dimention + nMemberStep = 1; + while ( nPos < ppDim.size() ) + { + if ( ppDim[nPos] ->getIsDataLayoutDimension() ) + { + if ( !pChildDimension ) + pChildDimension = new ScDPResultDimension( pResultData ); + pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState , FALSE ); + return; + } + else + { //find next dim + nPos ++; + nMemberStep ++; + } + } + // End Comments + bHasHiddenDetails = TRUE; // only if there is a next dimension + return; + } + + if ( bInitChild ) + { + pChildDimension = new ScDPResultDimension( pResultData ); + pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState, TRUE ); + } +} + +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration +void ScDPNormalResultMember::LateInitFrom( LateInitParams& rParams/*const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/, + const vector< SCROW >& pItemData, size_t nPos, + ScDPInitState& rInitState ) +// End Comments +{ + // without LateInit, everything has already been initialized + if ( !pResultData->IsLateInit() ) + return; + + bInitialized = TRUE; + + if ( rParams.IsEnd( nPos ) /*nPos >= ppDim.size()*/) + // No next dimension. Bail out. + return; + + // skip child dimension if details are not shown + if ( GetDPMember() && !GetDPMember()->getShowDetails() ) + { + // Wang Xu Ming -- 2009-6-16 + // DataPilot Migration + // Show DataLayout dimention + nMemberStep = 1; + while ( !rParams.IsEnd( nPos ) ) + { + if ( rParams.GetDim( nPos ) ->getIsDataLayoutDimension() ) + { + if ( !pChildDimension ) + pChildDimension = new ScDPResultDimension( pResultData ); + rParams.SetInitChild( FALSE ); + pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); + return; + } + else + { //find next dim + nPos ++; + nMemberStep ++; + } + } + // End Comments + bHasHiddenDetails = TRUE; // only if there is a next dimension + return; + } + + // LateInitFrom is called several times... + if ( rParams.GetInitChild() ) + { + if ( !pChildDimension ) + pChildDimension = new ScDPResultDimension( pResultData ); + pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); + } +} + +BOOL ScDPNormalResultMember::IsSubTotalInTitle(long nMeasure) const +{ + BOOL bRet = FALSE; + if ( pChildDimension && /*pParentLevel*/GetParentLevel() && + /*pParentLevel*/GetParentLevel()->IsOutlineLayout() && /*pParentLevel*/GetParentLevel()->IsSubtotalsAtTop() ) + { + long nUserSubStart; + long nSubTotals = GetSubTotalCount( &nUserSubStart ); + nSubTotals -= nUserSubStart; // visible count + if ( nSubTotals ) + { + if ( nMeasure == SC_DPMEASURE_ALL ) + nSubTotals *= pResultData->GetMeasureCount(); // number of subtotals that will be inserted + + // only a single subtotal row will be shown in the outline title row + if ( nSubTotals == 1 ) + bRet = TRUE; + } + } + return bRet; +} + +long ScDPNormalResultMember::GetSize(long nMeasure) const +{ + if ( !IsVisible() ) + return 0; + const ScDPLevel* pParentLevel = GetParentLevel(); + long nExtraSpace = 0; + if ( pParentLevel && pParentLevel->IsAddEmpty() ) + ++nExtraSpace; + + if ( pChildDimension ) + { + // outline layout takes up an extra row for the title only if subtotals aren't shown in that row + if ( pParentLevel && pParentLevel->IsOutlineLayout() && !IsSubTotalInTitle( nMeasure ) ) + ++nExtraSpace; + + long nSize = pChildDimension->GetSize(nMeasure); + long nUserSubStart; + long nUserSubCount = GetSubTotalCount( &nUserSubStart ); + nUserSubCount -= nUserSubStart; // for output size, use visible count + if ( nUserSubCount ) + { + if ( nMeasure == SC_DPMEASURE_ALL ) + nSize += pResultData->GetMeasureCount() * nUserSubCount; + else + nSize += nUserSubCount; + } + return nSize + nExtraSpace; + } + else + { + if ( nMeasure == SC_DPMEASURE_ALL ) + return pResultData->GetMeasureCount() + nExtraSpace; + else + return 1 + nExtraSpace; + } +} + + +BOOL ScDPNormalResultMember::IsVisible() const +{ + // not initialized -> shouldn't be there at all + // (allocated only to preserve ordering) + const ScDPLevel* pParentLevel = GetParentLevel(); + return ( bHasElements || ( pParentLevel && pParentLevel->getShowEmpty() ) ) && IsValid() && bInitialized; +} + +BOOL ScDPNormalResultMember::IsValid() const +{ + // non-Valid members are left out of calculation + + // was member set no invisible at the DataPilotSource? + const ScDPMember* pMemberDesc =GetDPMember(); + if ( pMemberDesc && !pMemberDesc->getIsVisible() ) + return FALSE; + + if ( bAutoHidden ) + return FALSE; + + return TRUE; +} + +BOOL ScDPNormalResultMember::HasHiddenDetails() const +{ + // bHasHiddenDetails is set only if the "show details" flag is off, + // and there was a child dimension to skip + + return bHasHiddenDetails; +} + +long ScDPNormalResultMember::GetSubTotalCount( long* pUserSubStart ) const +{ + if ( pUserSubStart ) + *pUserSubStart = 0; // default + + const ScDPLevel* pParentLevel = GetParentLevel(); + + if ( bForceSubTotal ) // set if needed for root members + return 1; // grand total is always "automatic" + else if ( pParentLevel ) + { + //! direct access via ScDPLevel + + uno::Sequence<sheet::GeneralFunction> aSeq = pParentLevel->getSubTotals(); + long nSequence = aSeq.getLength(); + if ( nSequence && aSeq[0] != sheet::GeneralFunction_AUTO ) + { + // For manual subtotals, always add "automatic" as first function + // (used for calculation, but not for display, needed for sorting, see lcl_GetForceFunc) + + ++nSequence; + if ( pUserSubStart ) + *pUserSubStart = 1; // visible subtotals start at 1 + } + return nSequence; + } + else + return 0; +} + +void ScDPNormalResultMember::ProcessData( const vector< SCROW >& aChildMembers, const ScDPResultDimension* pDataDim, + const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues ) +{ + SetHasElements(); + + if (pChildDimension) + pChildDimension->ProcessData( aChildMembers, pDataDim, aDataMembers, aValues ); + + if ( !pDataRoot ) + { + pDataRoot = new ScDPDataMember( pResultData, NULL ); + if ( pDataDim ) + pDataRoot->InitFrom( pDataDim ); // recursive + } + + ScDPSubTotalState aSubState; // initial state + + long nUserSubCount = GetSubTotalCount(); + + // Calculate at least automatic if no subtotals are selected, + // show only own values if there's no child dimension (innermost). + if ( !nUserSubCount || !pChildDimension ) + nUserSubCount = 1; + + const ScDPLevel* pParentLevel = GetParentLevel(); + + for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic" + { + // #i68338# if nUserSubCount is 1 (automatic only), don't set nRowSubTotalFunc + if ( pChildDimension && nUserSubCount > 1 ) + { + aSubState.nRowSubTotalFunc = nUserPos; + aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos ); + } + + pDataRoot->ProcessData( aDataMembers, aValues, aSubState ); + } +} + +void ScDPNormalResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences, + long& rPos, long nMeasure, BOOL bRoot, + const String* pMemberName, + const String* pMemberCaption ) +{ + // IsVisible() test is in ScDPResultDimension::FillMemberResults + // (not on data layout dimension) + + long nSize = GetSize(nMeasure); + sheet::MemberResult* pArray = pSequences->getArray(); + DBG_ASSERT( rPos+nSize <= pSequences->getLength(), "bumm" ); + + BOOL bIsNumeric = FALSE; + String aName; + if ( pMemberName ) // if pMemberName != NULL, use instead of real member name + aName = *pMemberName; + else + { + ScDPItemData aItemData; + FillItemData( aItemData ); + aName = aItemData.GetString(); + bIsNumeric = aItemData.IsValue(); + } + const ScDPDimension* pParentDim = GetParentDim(); + if ( bIsNumeric && pParentDim && pResultData->IsNumOrDateGroup( pParentDim->GetDimension() ) ) + { + // Numeric group dimensions use numeric entries for proper sorting, + // but the group titles must be output as text. + bIsNumeric = FALSE; + } + + String aCaption = aName; + if ( pMemberCaption ) // use pMemberCaption if != NULL + aCaption = *pMemberCaption; + if (!aCaption.Len()) + aCaption = ScGlobal::GetRscString(STR_EMPTYDATA); + + if ( !bIsNumeric ) + { + // add a "'" character so a string isn't parsed as value in the output cell + //! have a separate bit in Flags (MemberResultFlags) instead? + aCaption.Insert( (sal_Unicode) '\'', 0 ); + } + + if ( nSize && !bRoot ) // root is overwritten by first dimension + { + pArray[rPos].Name = rtl::OUString(aName); + pArray[rPos].Caption = rtl::OUString(aCaption); + pArray[rPos].Flags |= sheet::MemberResultFlags::HASMEMBER; + + // set "continue" flag (removed for subtotals later) + for (long i=1; i<nSize; i++) + pArray[rPos+i].Flags |= sheet::MemberResultFlags::CONTINUE; + } + + const ScDPLevel* pParentLevel = GetParentLevel(); + long nExtraSpace = 0; + if ( pParentLevel && pParentLevel->IsAddEmpty() ) + ++nExtraSpace; + + BOOL bTitleLine = FALSE; + if ( pParentLevel && pParentLevel->IsOutlineLayout() ) + bTitleLine = TRUE; + + // if the subtotals are shown at the top (title row) in outline layout, + // no extra row for the subtotals is needed + BOOL bSubTotalInTitle = IsSubTotalInTitle( nMeasure ); + + BOOL bHasChild = ( pChildDimension != NULL ); + if (bHasChild) + { + if ( bTitleLine ) // in tabular layout the title is on a separate row + ++rPos; // -> fill child dimension one row below + + if (bRoot) // same sequence for root member + pChildDimension->FillMemberResults( pSequences, rPos, nMeasure ); + else + // Wang Xu Ming -- 2009-6-16 + // DataPilot Migration + // for show details + pChildDimension->FillMemberResults( pSequences + nMemberStep/*1*/, rPos, nMeasure ); + // End Comments + + if ( bTitleLine ) // title row is included in GetSize, so the following + --rPos; // positions are calculated with the normal values + } + + rPos += nSize; + + long nUserSubStart; + long nUserSubCount = GetSubTotalCount(&nUserSubStart); + if ( nUserSubCount && pChildDimension && !bSubTotalInTitle ) + { + long nMemberMeasure = nMeasure; + long nSubSize = pResultData->GetCountForMeasure(nMeasure); + + rPos -= nSubSize * (nUserSubCount - nUserSubStart); // GetSize includes space for SubTotal + rPos -= nExtraSpace; // GetSize includes the empty line + + for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++) + { + for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) + { + if ( nMeasure == SC_DPMEASURE_ALL ) + nMemberMeasure = nSubCount; + + ScSubTotalFunc eForce = SUBTOTAL_FUNC_NONE; + if (bHasChild) + eForce = lcl_GetForceFunc( pParentLevel, nUserPos ); + + String aSubStr = aName; //! caption? + aSubStr += ' '; + aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce); + + pArray[rPos].Name = rtl::OUString(aName); + pArray[rPos].Caption = rtl::OUString(aSubStr); + pArray[rPos].Flags = ( pArray[rPos].Flags | + ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL) ) & + ~sheet::MemberResultFlags::CONTINUE; + + if ( nMeasure == SC_DPMEASURE_ALL ) + { + // data layout dimension is (direct/indirect) child of this. + // data layout dimension must have name for all entries. + + uno::Sequence<sheet::MemberResult>* pLayoutSeq = pSequences; + if (!bRoot) + ++pLayoutSeq; + ScDPResultDimension* pLayoutDim = pChildDimension; + while ( pLayoutDim && !pLayoutDim->IsDataLayout() ) + { + pLayoutDim = pLayoutDim->GetFirstChildDimension(); + ++pLayoutSeq; + } + if ( pLayoutDim ) + { + sheet::MemberResult* pLayoutArray = pLayoutSeq->getArray(); + String aDataName = pResultData->GetMeasureDimensionName(nMemberMeasure); + pLayoutArray[rPos].Name = rtl::OUString(aDataName); + } + } + + rPos += 1; + } + } + + rPos += nExtraSpace; // add again (subtracted above) + } +} + +void ScDPNormalResultMember::FillDataResults( const ScDPResultMember* pRefMember, + uno::Sequence< uno::Sequence<sheet::DataResult> >& rSequence, + long& rRow, long nMeasure ) const +{ + // IsVisible() test is in ScDPResultDimension::FillDataResults + // (not on data layout dimension) + const ScDPLevel* pParentLevel = GetParentLevel(); + long nStartRow = rRow; + + long nExtraSpace = 0; + if ( pParentLevel && pParentLevel->IsAddEmpty() ) + ++nExtraSpace; + + BOOL bTitleLine = FALSE; + if ( pParentLevel && pParentLevel->IsOutlineLayout() ) + bTitleLine = TRUE; + + BOOL bSubTotalInTitle = IsSubTotalInTitle( nMeasure ); + + BOOL bHasChild = ( pChildDimension != NULL ); + if (bHasChild) + { + if ( bTitleLine ) // in tabular layout the title is on a separate row + ++rRow; // -> fill child dimension one row below + + pChildDimension->FillDataResults( pRefMember, rSequence, rRow, nMeasure ); // doesn't modify rRow + rRow += (USHORT) GetSize( nMeasure ); + + if ( bTitleLine ) // title row is included in GetSize, so the following + --rRow; // positions are calculated with the normal values + } + + long nUserSubStart; + long nUserSubCount = GetSubTotalCount(&nUserSubStart); + if ( nUserSubCount || !bHasChild ) + { + // Calculate at least automatic if no subtotals are selected, + // show only own values if there's no child dimension (innermost). + if ( !nUserSubCount || !bHasChild ) + { + nUserSubCount = 1; + nUserSubStart = 0; + } + + long nMemberMeasure = nMeasure; + long nSubSize = pResultData->GetCountForMeasure(nMeasure); + if (bHasChild) + { + rRow -= nSubSize * ( nUserSubCount - nUserSubStart ); // GetSize includes space for SubTotal + rRow -= nExtraSpace; // GetSize includes the empty line + } + + long nMoveSubTotal = 0; + if ( bSubTotalInTitle ) + { + nMoveSubTotal = rRow - nStartRow; // force to first (title) row + rRow = nStartRow; + } + + if ( pDataRoot ) + { + ScDPSubTotalState aSubState; // initial state + + for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++) + { + if ( bHasChild && nUserSubCount > 1 ) + { + aSubState.nRowSubTotalFunc = nUserPos; + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos ); + } + + for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) + { + if ( nMeasure == SC_DPMEASURE_ALL ) + nMemberMeasure = nSubCount; + else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL ) + nMemberMeasure = SC_DPMEASURE_ALL; + + DBG_ASSERT( rRow < rSequence.getLength(), "bumm" ); + uno::Sequence<sheet::DataResult>& rSubSeq = rSequence.getArray()[rRow]; + long nSeqCol = 0; + pDataRoot->FillDataRow( pRefMember, rSubSeq, nSeqCol, nMemberMeasure, bHasChild, aSubState ); + + rRow += 1; + } + } + } + else + rRow += nSubSize * ( nUserSubCount - nUserSubStart ); // empty rows occur when ShowEmpty is true + + // add extra space again if subtracted from GetSize above, + // add to own size if no children + rRow += nExtraSpace; + + rRow += nMoveSubTotal; + } +} + +void ScDPNormalResultMember::UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const +{ + // IsVisible() test is in ScDPResultDimension::FillDataResults + // (not on data layout dimension) + + BOOL bHasChild = ( pChildDimension != NULL ); + + long nUserSubCount = GetSubTotalCount(); + // process subtotals even if not shown +// if ( nUserSubCount || !bHasChild ) + { + // Calculate at least automatic if no subtotals are selected, + // show only own values if there's no child dimension (innermost). + if ( !nUserSubCount || !bHasChild ) + nUserSubCount = 1; + + long nMemberMeasure = nMeasure; + long nSubSize = pResultData->GetCountForMeasure(nMeasure); + + if ( pDataRoot ) + { + ScDPSubTotalState aSubState; // initial state + + for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic" + { + if ( bHasChild && nUserSubCount > 1 ) + { + aSubState.nRowSubTotalFunc = nUserPos; + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos ); + } + + for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) + { + if ( nMeasure == SC_DPMEASURE_ALL ) + nMemberMeasure = nSubCount; + else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL ) + nMemberMeasure = SC_DPMEASURE_ALL; + + pDataRoot->UpdateDataRow( pRefMember, nMemberMeasure, bHasChild, aSubState ); + } + } + } + } + + if (bHasChild) // child dimension must be processed last, so the column total is known + { + pChildDimension->UpdateDataResults( pRefMember, nMeasure ); + } +} + +void ScDPNormalResultMember::SortMembers( ScDPResultMember* pRefMember ) +{ + BOOL bHasChild = ( pChildDimension != NULL ); + if (bHasChild) + pChildDimension->SortMembers( pRefMember ); // sorting is done at the dimension + + if ( IsRoot() && pDataRoot ) + { + // use the row root member to sort columns + // sub total count is always 1 + + pDataRoot->SortMembers( pRefMember ); + } +} + +void ScDPNormalResultMember::DoAutoShow( ScDPResultMember* pRefMember ) +{ + BOOL bHasChild = ( pChildDimension != NULL ); + if (bHasChild) + pChildDimension->DoAutoShow( pRefMember ); // sorting is done at the dimension + + if ( IsRoot()&& pDataRoot ) + { + // use the row root member to sort columns + // sub total count is always 1 + + pDataRoot->DoAutoShow( pRefMember ); + } +} + +void ScDPNormalResultMember::ResetResults( BOOL bRoot ) +{ + if (pDataRoot) + pDataRoot->ResetResults(); + + if (pChildDimension) + pChildDimension->ResetResults(); + +// Wang Xu Ming -- 3/4/2009 +// Dim refresh and filter. SODC_19023 + // if (!bRoot) + // bHasElements = FALSE; +// End Comments +} + +void ScDPNormalResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure, + ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const +{ + // IsVisible() test is in ScDPResultDimension::FillDataResults + // (not on data layout dimension) + + rTotals.SetInColRoot( IsRoot() ); + + BOOL bHasChild = ( pChildDimension != NULL ); + + long nUserSubCount = GetSubTotalCount(); + if ( nUserSubCount || !bHasChild ) + { + // Calculate at least automatic if no subtotals are selected, + // show only own values if there's no child dimension (innermost). + if ( !nUserSubCount || !bHasChild ) + nUserSubCount = 1; + + long nMemberMeasure = nMeasure; + long nSubSize = pResultData->GetCountForMeasure(nMeasure); + + if ( pDataRoot ) + { + ScDPSubTotalState aSubState; // initial state + + for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic" + { + if ( bHasChild && nUserSubCount > 1 ) + { + aSubState.nRowSubTotalFunc = nUserPos; + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel(), nUserPos ); + } + + for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) + { + if ( nMeasure == SC_DPMEASURE_ALL ) + nMemberMeasure = nSubCount; + else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL ) + nMemberMeasure = SC_DPMEASURE_ALL; + + pDataRoot->UpdateRunningTotals( pRefMember, nMemberMeasure, + bHasChild, aSubState, rRunning, rTotals, *this ); + } + } + } + } + + if (bHasChild) // child dimension must be processed last, so the column total is known + { + pChildDimension->UpdateRunningTotals( pRefMember, nMeasure, rRunning, rTotals ); + } +} + +void ScDPNormalResultMember::DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const +{ + lcl_DumpRow( String::CreateFromAscii("ScDPResultMember"), GetName(), NULL, pDoc, rPos ); + SCROW nStartRow = rPos.Row(); + + if (pDataRoot) + pDataRoot->DumpState( pRefMember, pDoc, rPos ); + + if (pChildDimension) + pChildDimension->DumpState( pRefMember, pDoc, rPos ); + + lcl_Indent( pDoc, nStartRow, rPos ); +} + +ScDPAggData* ScDPNormalResultMember::GetColTotal( long nMeasure ) const +{ + return lcl_GetChildTotal( const_cast<ScDPAggData*>(&aColTotal), nMeasure ); +} + +void ScDPNormalResultMember::FillVisibilityData(ScDPResultVisibilityData& rData) const +{ + if (pChildDimension) + pChildDimension->FillVisibilityData(rData); +} +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration +SCROW ScDPNormalResultMember::GetDataId( ) const +{ +// TODO: + const ScDPMember* pMemberDesc = GetDPMember(); + if (pMemberDesc) + return pMemberDesc->GetItemDataId(); + return -1; +} + +// ----------------------------------------------------------------------- +ScDPHideDetailsMember:: ScDPHideDetailsMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData, + BOOL bForceSub ):ScDPResultMember(pData,rParentDimData, bForceSub) +{ + pOrigMember = new ScDPNormalResultMember(pData,rParentDimData, bForceSub); + +}
\ No newline at end of file diff --git a/sc/source/core/data/dptabresmember.hxx b/sc/source/core/data/dptabresmember.hxx new file mode 100644 index 000000000000..72657167d07d --- /dev/null +++ b/sc/source/core/data/dptabresmember.hxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dptabresmember.hxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef DPTABRESMEMBER_HXX +#define DPTABRESMEMBER_HXX + +class ScDPNormalResultMember: public ScDPResultMember +{ +private: + // Wang Xu Ming -- 2009-6-9 + // DataPilot Migration + ScDPParentDimData aParentDimData; + // End Comments + BOOL bHasElements:1; + BOOL bForceSubTotal:1; + BOOL bHasHiddenDetails:1; + BOOL bInitialized:1; + BOOL bAutoHidden:1; + ScDPAggData aColTotal; // to store column totals + +// Wang Xu Ming -- 2009-6-9 +// DataPilot Migration + USHORT nMemberStep; // step to show details +// End Comments +public: + // Wang Xu Ming -- 2009-6-9 + // DataPilot Migration + ScDPNormalResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData, + BOOL bForceSub ); //! Ref + ScDPNormalResultMember( const ScDPResultData* pData, BOOL bForceSub ); + // End Comments + ~ScDPNormalResultMember(); + + // Wang Xu Ming -- 2009-6-9 + // DataPilot Migration + // Add parameter: BOOL bInitChild + void InitFrom( const ::std::vector<ScDPDimension*>& ppDim, + const ::std::vector<ScDPLevel*>& ppLev, + size_t nPos, + ScDPInitState& rInitState, + BOOL bInitChild = TRUE ); + // End Comments + // Wang Xu Ming -- 2009-6-9 + // DataPilot Migration + void LateInitFrom( + LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState); + // End Comments + + String GetName() const; + void FillItemData( ScDPItemData& rData ) const; + BOOL IsValid() const; + BOOL IsVisible() const; + long GetSize(long nMeasure) const; + BOOL HasHiddenDetails() const; + BOOL IsSubTotalInTitle(long nMeasure) const; + +// BOOL SubTotalEnabled() const; + long GetSubTotalCount( long* pUserSubStart = NULL ) const; + +// Wang Xu Ming -- 2009-6-9 +// DataPilot Migration +// Use item index +// BOOL IsNamedItem( const ScDPItemData& r ) const; + BOOL IsNamedItem( SCROW nIndex ) const; +// End Comments + bool IsValidEntry( const ::std::vector< SCROW >& aMembers ) const; + ENTRYSTATUS GetEntryStatus( const ::std::vector<SCROW>& aMembers ) const; + + void SetHasElements() { bHasElements = TRUE; } + void SetAutoHidden() { bAutoHidden = TRUE; } + + void ProcessData( const ::std::vector<SCROW>& aChildMembers, + const ScDPResultDimension* pDataDim, + const ::std::vector<SCROW>& aDataMembers, + const ::std::vector<ScDPValueData>& aValues ); + + void FillMemberResults( com::sun::star::uno::Sequence< + com::sun::star::sheet::MemberResult>* pSequences, + long& rPos, long nMeasure, BOOL bRoot, + const String* pMemberName, + const String* pMemberCaption ); + + void FillDataResults( const ScDPResultMember* pRefMember, + com::sun::star::uno::Sequence< + com::sun::star::uno::Sequence< + com::sun::star::sheet::DataResult> >& rSequence, + long& rRow, long nMeasure ) const; + + void UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const; + void UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure, + ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const; + + void SortMembers( ScDPResultMember* pRefMember ); + void DoAutoShow( ScDPResultMember* pRefMember ); + + void ResetResults( BOOL bRoot ); + + void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const; + + // Wang Xu Ming -- 2009-6-9 + // DataPilot Migration + const ScDPDimension* GetParentDim() const { return aParentDimData.mpParentDim; } //! Ref + const ScDPLevel* GetParentLevel() const { return aParentDimData.mpParentLevel; } //! Ref + const ScDPMember* GetDPMember()const { return aParentDimData.mpMemberDesc; } //! Ref + inline SCROW GetOrder() const { return aParentDimData.mnOrder; } //! Ref + inline BOOL IsRoot() const { return GetParentLevel() == NULL; } + // End Comments + + ScDPAggData* GetColTotal( long nMeasure ) const; + + void FillVisibilityData(ScDPResultVisibilityData& rData) const; +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration + SCROW GetDataId( ) const ; +// End Comments +}; + +class ScDPHideDetailsMember: public ScDPResultMember +{ +private: + ScDPNormalResultMember * pOrigMember; +public: + ScDPHideDetailsMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData, + BOOL bForceSub ); + + +}; + + +#endif //DPTABRESMEMBER_HXX diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx index 205c14021444..da40e6e230c4 100644..100755 --- a/sc/source/core/data/dptabsrc.cxx +++ b/sc/source/core/data/dptabsrc.cxx @@ -300,10 +300,11 @@ void ScDPSource::SetOrientation(long nColumn, USHORT nNew) case sheet::DataPilotFieldOrientation_PAGE: nPageDims[nPageDimCount++] = nColumn; break; + // Wang Xu Ming -- 2009-9-1 + // DataPilot Migration - Cache&&Performance case sheet::DataPilotFieldOrientation_HIDDEN: - /* Do not assert HIDDEN as it occurs e.g. while using the - csss.XDataPilotTables.createDataPilotDescriptor() function. */ break; + // End Comments default: DBG_ERROR( "ScDPSource::SetOrientation: unexpected orientation" ); break; @@ -325,6 +326,11 @@ BOOL ScDPSource::IsDateDimension(long nDim) return pData->IsDateDimension(nDim); } +UINT32 ScDPSource::GetNumberFormat(long nDim) +{ + return pData->GetNumberFormat( nDim ); +} + ScDPDimensions* ScDPSource::GetDimensionsObject() { if (!pDimensions) @@ -442,7 +448,6 @@ Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<s throw (uno::RuntimeException) { long nColumnCount = GetData()->GetColumnCount(); - ScSimpleSharedString& rSharedString = GetData()->GetSharedString(); typedef hash_map<String, long, ScStringHashCode> FieldNameMapType; FieldNameMapType aFieldNames; @@ -472,17 +477,16 @@ Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<s ScDPItemData aItem; pMembers->getByIndex(nIndex)->FillItemData( aItem ); aFilterCriteria.push_back( ScDPCacheTable::Criterion() ); - sal_Int32 nMatchStrId = rSharedString.getStringId(aItem.aString); aFilterCriteria.back().mnFieldIndex = nCol; aFilterCriteria.back().mpFilter.reset( - new ScDPCacheTable::SingleFilter(rSharedString, nMatchStrId, aItem.fValue, aItem.bHasValue) ); + new ScDPCacheTable::SingleFilter(aItem.GetString()/*rSharedString, nMatchStrId*/, aItem.GetValue(), aItem.IsValue()) ); } } } } // Take into account the visibilities of field members. - ScDPResultVisibilityData aResVisData(rSharedString, this); + ScDPResultVisibilityData aResVisData(/*rSharedString, */this); pRowResRoot->FillVisibilityData(aResVisData); pColResRoot->FillVisibilityData(aResVisData); aResVisData.fillFieldFilters(aFilterCriteria); @@ -737,7 +741,6 @@ void ScDPSource::GetCategoryDimensionIndices(hash_set<sal_Int32>& rCatDims) void ScDPSource::FilterCacheTableByPageDimensions() { - ScSimpleSharedString& rSharedString = GetData()->GetSharedString(); // filter table by page dimensions. vector<ScDPCacheTable::Criterion> aCriteria; @@ -752,7 +755,7 @@ void ScDPSource::FilterCacheTableByPageDimensions() long nMemCount = pMems->getCount(); ScDPCacheTable::Criterion aFilter; aFilter.mnFieldIndex = static_cast<sal_Int32>(nField); - aFilter.mpFilter.reset(new ScDPCacheTable::GroupFilter(rSharedString)); + aFilter.mpFilter.reset(new ScDPCacheTable::GroupFilter(/*rSharedString*/)); ScDPCacheTable::GroupFilter* pGrpFilter = static_cast<ScDPCacheTable::GroupFilter*>(aFilter.mpFilter.get()); for (long j = 0; j < nMemCount; ++j) @@ -762,7 +765,7 @@ void ScDPSource::FilterCacheTableByPageDimensions() { ScDPItemData aData; pMem->FillItemData(aData); - pGrpFilter->addMatchItem(aData.aString, aData.fValue, aData.bHasValue); + pGrpFilter->addMatchItem(aData.GetString(), aData.GetValue(), aData.IsValue()); } } if (pGrpFilter->getMatchItemCount() < static_cast<size_t>(nMemCount)) @@ -776,9 +779,8 @@ void ScDPSource::FilterCacheTableByPageDimensions() aCriteria.push_back(ScDPCacheTable::Criterion()); ScDPCacheTable::Criterion& r = aCriteria.back(); r.mnFieldIndex = static_cast<sal_Int32>(nField); - sal_Int32 nStrId = rSharedString.getStringId(rData.aString); r.mpFilter.reset( - new ScDPCacheTable::SingleFilter(rSharedString, nStrId, rData.fValue, rData.bHasValue)); + new ScDPCacheTable::SingleFilter(rData.GetString()/*rSharedString, nStrId*/, rData.GetValue(), rData.IsValue())); } if (!aCriteria.empty()) { @@ -900,11 +902,11 @@ void ScDPSource::CreateRes_Impl() { ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nPageDims[i] ); if ( pDim->HasSelectedPage() ) - aInitState.AddMember( nPageDims[i], pDim->GetSelectedData() ); + aInitState.AddMember( nPageDims[i], GetMemberId( nPageDims[i], pDim->GetSelectedData() ) ); } - pColResRoot = new ScDPResultMember( pResData, NULL, NULL, NULL, bColumnGrand ); - pRowResRoot = new ScDPResultMember( pResData, NULL, NULL, NULL, bRowGrand ); + pColResRoot = new ScDPResultMember( pResData, /*NULL, NULL, NULL, */bColumnGrand ); + pRowResRoot = new ScDPResultMember( pResData, /*NULL, NULL, NULL, */bRowGrand ); FillCalcInfo(false, aInfo, bHasAutoShow); long nColLevelCount = aInfo.aColLevels.size(); @@ -944,7 +946,7 @@ void ScDPSource::CreateRes_Impl() long nMinColMembers = lcl_CountMinMembers( aInfo.aColDims, aInfo.aColLevels, nColLevelCount ); long nMinRowMembers = lcl_CountMinMembers( aInfo.aRowDims, aInfo.aRowLevels, nRowLevelCount ); - if ( nMinColMembers > SC_MINCOUNT_LIMIT || nMinRowMembers > SC_MINCOUNT_LIMIT ) + if ( nMinColMembers > MAXCOLCOUNT/*SC_MINCOUNT_LIMIT*/ || nMinRowMembers > SC_MINCOUNT_LIMIT ) { // resulting table is too big -> abort before calculating // (this relies on late init, so no members are allocated in InitFrom above) @@ -964,6 +966,8 @@ void ScDPSource::CreateRes_Impl() aInfo.pRowRoot = pRowResRoot; pData->CalcResults(aInfo, false); + pColResRoot->CheckShowEmpty(); + pRowResRoot->CheckShowEmpty(); // ---------------------------------------------------------------- // With all data processed, calculate the final results: @@ -1549,6 +1553,19 @@ const ScDPItemData& ScDPDimension::GetSelectedData() //UNUSED2009-05 return TRUE; // no selection -> all data //UNUSED2009-05 } +BOOL ScDPDimension::IsVisible( const ScDPItemData& rData ) +{ + if( ScDPMembers* pMembers = this->GetHierarchiesObject()->getByIndex(0)-> + GetLevelsObject()->getByIndex(0)->GetMembersObject() ) + { + for( long i = pMembers->getCount()-1; i>=0; i-- ) + if( ScDPMember *pDPMbr = pMembers->getByIndex( i ) ) + if( rData.IsCaseInsEqual( pDPMbr->GetItemData() ) && !pDPMbr->getIsVisible() ) + return FALSE; + } + + return TRUE; +} // XPropertySet uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPDimension::getPropertySetInfo() @@ -1692,6 +1709,23 @@ uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropert // #i63745# don't use source format for "count" if ( eFunc != sheet::GeneralFunction_COUNT && eFunc != sheet::GeneralFunction_COUNTNUMS ) nFormat = pSource->GetData()->GetNumberFormat( ( nSourceDim >= 0 ) ? nSourceDim : nDim ); + + switch ( aReferenceValue.ReferenceType ) + { + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE: + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE: + case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE: + case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE: + case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE: + nFormat = pSource->GetData()->GetNumberFormatByIdx( (NfIndexTableOffset)NF_PERCENT_DEC2 ); + break; + case sheet::DataPilotFieldReferenceType::INDEX: + nFormat = pSource->GetData()->GetNumberFormatByIdx( (NfIndexTableOffset)NF_NUMBER_SYSTEM ); + break; + default: + break; + } + aRet <<= nFormat; } else if ( aNameStr.EqualsAscii( SC_UNO_ORIGINAL ) ) @@ -2355,15 +2389,6 @@ SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPLevel ) // ----------------------------------------------------------------------- -USHORT lcl_GetFirstStringPos( const TypedScStrCollection& rColl ) -{ - USHORT nPos = 0; - USHORT nCount = rColl.GetCount(); - while ( nPos < nCount && !rColl[nPos]->IsStrData() ) - ++nPos; - return nPos; -} - ScDPMembers::ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL ) : pSource( pSrc ), nDim( nD ), @@ -2385,12 +2410,23 @@ ScDPMembers::ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL ) : { case SC_DAPI_LEVEL_YEAR: { - const TypedScStrCollection& rStrings = pSource->GetData()->GetColumnEntries(nSrcDim); - USHORT nFirstString = lcl_GetFirstStringPos( rStrings ); - if ( nFirstString > 0 ) + // Wang Xu Ming - DataPilot migration + const ScDPItemData* pLastNumData = NULL; + for ( SCROW n = 0 ;n <GetSrcItemsCount() ; n-- ) { - double fFirstVal = rStrings[0]->GetValue(); - double fLastVal = rStrings[nFirstString-1]->GetValue(); + const ScDPItemData* pData = GetSrcItemDataByIndex( n ); + if ( pData && pData->HasStringData() ) + break; + else + pLastNumData = pData; + } + // End Comments + + if ( pLastNumData ) + { + const ScDPItemData* pFirstData = GetSrcItemDataByIndex( 0 ); + double fFirstVal = pFirstData->GetValue(); + double fLastVal = pLastNumData->GetValue(); long nFirstYear = pSource->GetData()->GetDatePart( (long)::rtl::math::approxFloor( fFirstVal ), @@ -2427,11 +2463,7 @@ ScDPMembers::ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL ) : } } else - { - // StringCollection is cached at TableData - const TypedScStrCollection& rStrings = pSource->GetData()->GetColumnEntries(nSrcDim); - nMbrCount = rStrings.GetCount(); - } + nMbrCount = pSource->GetData()->GetMembersCount( nSrcDim ); } ScDPMembers::~ScDPMembers() @@ -2567,8 +2599,7 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const if ( pSource->IsDataLayoutDimension(nSrcDim) ) { // empty name (never shown, not used for lookup) - pNew = new ScDPMember( pSource, nDim, nHier, nLev, - String(), 0.0, FALSE ); + pNew = new ScDPMember( pSource, nDim, nHier, nLev, 0 ); } else if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) ) { @@ -2579,12 +2610,13 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const { //! cache year range here! - const TypedScStrCollection& rStrings = pSource->GetData()->GetColumnEntries(nSrcDim); - double fFirstVal = rStrings[0]->GetValue(); + // Wang Xu Ming - DataPilot migration + double fFirstVal = pSource->GetData()->GetMemberByIndex( nSrcDim, 0 )->GetValue(); long nFirstYear = pSource->GetData()->GetDatePart( (long)::rtl::math::approxFloor( fFirstVal ), nHier, nLev ); + // End Comments nVal = nFirstYear + nIndex; } else if ( nHier == SC_DAPI_HIERARCHY_WEEK && nLev == SC_DAPI_LEVEL_WEEKDAY ) @@ -2607,19 +2639,20 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const if ( !aName.Len() ) aName = String::CreateFromInt32(nVal); - pNew = new ScDPMember( pSource, nDim, nHier, nLev, aName, nVal, TRUE ); + ScDPItemData rData( aName, nVal, TRUE, 0 ) ; + pNew = new ScDPMember( pSource, nDim, nHier, nLev, pSource->GetCache()->GetAdditionalItemID(rData)); } else { - const TypedScStrCollection& rStrings = pSource->GetData()->GetColumnEntries(nSrcDim); - const TypedStrData* pData = rStrings[(USHORT)nIndex]; - pNew = new ScDPMember( pSource, nDim, nHier, nLev, - pData->GetString(), pData->GetValue(), !pData->IsStrData() ); + const std::vector< SCROW >& memberIndexs = pSource->GetData()->GetColumnEntries( nSrcDim ); + pNew = new ScDPMember( pSource, nDim, nHier, nLev, memberIndexs[nIndex] ); } pNew->acquire(); // ref-counted ppMbrs[nIndex] = pNew; } + DBG_ASSERT( ppMbrs[nIndex] ," member is not initialized " ); + return ppMbrs[nIndex]; } @@ -2629,12 +2662,12 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const // ----------------------------------------------------------------------- ScDPMember::ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL, - const String& rN, double fV, BOOL bHV ) : + SCROW nIndex /*const String& rN, double fV, BOOL bHV*/ ) : pSource( pSrc ), nDim( nD ), nHier( nH ), nLev( nL ), - maData( rN, fV, bHV ), + mnDataId( nIndex ), mpLayoutName(NULL), nPosition( -1 ), bVisible( TRUE ), @@ -2651,17 +2684,36 @@ ScDPMember::~ScDPMember() BOOL ScDPMember::IsNamedItem( const ScDPItemData& r ) const { long nSrcDim = pSource->GetSourceDim( nDim ); - if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) && r.bHasValue ) + if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) && r.IsValue() ) { long nComp = pSource->GetData()->GetDatePart( - (long)::rtl::math::approxFloor( r.fValue ), + (long)::rtl::math::approxFloor( r.GetValue() ), nHier, nLev ); // fValue is converted from integer, so simple comparison works - return nComp == maData.fValue; + return nComp == GetItemData().GetValue(); } - return r.IsCaseInsEqual( maData ); + return r.IsCaseInsEqual( GetItemData() ); +} + +BOOL ScDPMember::IsNamedItem( SCROW nIndex ) const +{ + long nSrcDim = pSource->GetSourceDim( nDim ); + if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) ) + { + const ScDPItemData* pData = pSource->GetCache()->GetItemDataById( (SCCOL) nSrcDim, nIndex ); + if ( pData->IsValue() ) + { + long nComp = pSource->GetData()->GetDatePart( + (long)::rtl::math::approxFloor( pData->GetValue() ), + nHier, nLev ); + // fValue is converted from integer, so simple comparison works + return nComp == GetItemData().GetValue(); + } + } + + return nIndex == mnDataId; } sal_Int32 ScDPMember::Compare( const ScDPMember& rOther ) const @@ -2686,14 +2738,14 @@ sal_Int32 ScDPMember::Compare( const ScDPMember& rOther ) const } // no positions set - compare names - return ScDPItemData::Compare( maData, rOther.maData ); + return pSource->GetData()->Compare( pSource->GetSourceDim(nDim),mnDataId,rOther.GetItemDataId()); } void ScDPMember::FillItemData( ScDPItemData& rData ) const { //! handle date hierarchy... - rData = maData; + rData = GetItemData() ; } const OUString* ScDPMember::GetLayoutName() const @@ -2703,12 +2755,12 @@ const OUString* ScDPMember::GetLayoutName() const String ScDPMember::GetNameStr() const { - return maData.aString; + return GetItemData().GetString(); } ::rtl::OUString SAL_CALL ScDPMember::getName() throw(uno::RuntimeException) { - return maData.aString; + return GetItemData().GetString(); } void SAL_CALL ScDPMember::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException) @@ -2822,4 +2874,48 @@ uno::Any SAL_CALL ScDPMember::getPropertyValue( const rtl::OUString& aPropertyNa SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPMember ) +ScDPTableDataCache* ScDPSource::GetCache() +{ + DBG_ASSERT( GetData() , "empty ScDPTableData pointer"); + return ( GetData()!=NULL) ? GetData()->GetCacheTable().GetCache() : NULL ; +} + +const ScDPItemData& ScDPMember::GetItemData() const +{ + return *pSource->GetItemDataById( (SCCOL)nDim, mnDataId );//ms-cache-core +} + +const ScDPItemData* ScDPSource::GetItemDataById(long nDim, long nId) +{ + long nSrcDim = GetSourceDim( nDim ); + const ScDPItemData* pItemData = GetData()->GetMemberById( nSrcDim, nId ); + if ( !pItemData ) + { //todo: + ScDPItemData item; + nId = GetCache()->GetAdditionalItemID( item ); + pItemData = GetData()->GetMemberById( nSrcDim, nId ); + } + return pItemData; +} + +SCROW ScDPSource::GetMemberId( long nDim, const ScDPItemData& rData ) +{ + long nSrcDim = GetSourceDim( nDim ); + return GetCache()->GetIdByItemData( nSrcDim, rData ); +} + +const ScDPItemData* ScDPMembers::GetSrcItemDataByIndex( SCROW nIndex) +{ + const std::vector< SCROW >& memberIds = pSource->GetData()->GetColumnEntries( nDim ); + if ( nIndex >= (long )(memberIds.size()) || nIndex < 0 ) + return NULL; + SCROW nId = memberIds[ nIndex ]; + return pSource->GetItemDataById( nDim, nId ); +} + + SCROW ScDPMembers::GetSrcItemsCount() + { + return pSource->GetData()->GetColumnEntries( nDim ).size(); + } +// End Comments diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 4e9de6179809..3d7fc007818b 100644..100755 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -28,6 +28,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/chart/XChartDocument.hpp> #include <com/sun/star/embed/XEmbeddedObject.hpp> #include <com/sun/star/embed/XVisualObject.hpp> #include <com/sun/star/embed/XClassifiedObject.hpp> @@ -79,6 +80,7 @@ #include "chartarr.hxx" #include "postit.hxx" #include "attrib.hxx" +#include "charthelper.hxx" #define DET_ARROW_OFFSET 1000 @@ -454,7 +456,7 @@ inline BOOL IsInBlock( const ScAddress& rPos, SCCOL nCol1,SCROW nRow1, SCCOL nCo } void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2, - SCsCOL nDx,SCsROW nDy ) + SCsCOL nDx,SCsROW nDy, bool bUpdateNoteCaptionPos ) { SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab)); DBG_ASSERT(pPage,"Page nicht gefunden"); @@ -490,13 +492,13 @@ void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SC if ( pObj->ISA( SdrRectObj ) && pData->maStart.IsValid() && pData->maEnd.IsValid() ) pData->maStart.PutInOrder( pData->maEnd ); AddCalcUndo( new ScUndoObjData( pObj, aOldStt, aOldEnd, pData->maStart, pData->maEnd ) ); - RecalcPos( pObj, *pData, bNegativePage ); + RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos ); } } } } -void ScDrawLayer::SetPageSize( USHORT nPageNo, const Size& rSize ) +void ScDrawLayer::SetPageSize( USHORT nPageNo, const Size& rSize, bool bUpdateNoteCaptionPos ) { SdrPage* pPage = GetPage(nPageNo); if (pPage) @@ -519,34 +521,31 @@ void ScDrawLayer::SetPageSize( USHORT nPageNo, const Size& rSize ) SdrObject* pObj = pPage->GetObj( i ); ScDrawObjData* pData = GetObjDataTab( pObj, static_cast<SCTAB>(nPageNo) ); if( pData ) - RecalcPos( pObj, *pData, bNegativePage ); + RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos ); } } } -void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage ) +void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos ) { DBG_ASSERT( pDoc, "ScDrawLayer::RecalcPos - missing document" ); if( !pDoc ) return; - /* TODO CleanUp: Updating note position works just by chance currently... - When inserting rows/columns, this function is called after the - insertion, and the note is located at the new position contained in the - passed ScDrawObjData already. But when deleting rows/columns, this - function is called *before* the deletion, so the note is still at the - old cell position, and ScDocument::GetNote() will fail to get the note - or will get another note. But after the rows/columns are deleted, a - call to ScDrawLayer::SetPageSize() will call this function again, and - now the note is at the expected position in the document. */ if( rData.mbNote ) { DBG_ASSERT( rData.maStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" ); - /* When inside an undo action, there may be pending note captions - where cell note is already deleted. The caption will be deleted - later with drawing undo. */ - if( ScPostIt* pNote = pDoc->GetNote( rData.maStart ) ) - pNote->UpdateCaptionPos( rData.maStart ); + /* #i109372# On insert/remove rows/columns/cells: Updating the caption + position must not be done, if the cell containing the note has not + been moved yet in the document. The calling code now passes an + additional boolean stating if the cells are already moved. */ + if( bUpdateNoteCaptionPos ) + /* When inside an undo action, there may be pending note captions + where cell note is already deleted (thus document cannot find + the note object anymore). The caption will be deleted later + with drawing undo. */ + if( ScPostIt* pNote = pDoc->GetNote( rData.maStart ) ) + pNote->UpdateCaptionPos( rData.maStart ); return; } @@ -1018,7 +1017,7 @@ void ScDrawLayer::MoveAreaTwips( SCTAB nTab, const Rectangle& rArea, } void ScDrawLayer::MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2, - SCsCOL nDx,SCsROW nDy, BOOL bInsDel ) + SCsCOL nDx,SCsROW nDy, BOOL bInsDel, bool bUpdateNoteCaptionPos ) { DBG_ASSERT( pDoc, "ScDrawLayer::MoveArea without document" ); if ( !pDoc ) @@ -1067,7 +1066,7 @@ void ScDrawLayer::MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCR // Detektiv-Pfeile: Zellpositionen anpassen // - MoveCells( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy ); + MoveCells( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy, bUpdateNoteCaptionPos ); } void ScDrawLayer::WidthChanged( SCTAB nTab, SCCOL nCol, long nDifTwips ) @@ -1386,7 +1385,9 @@ void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& pNewObject->SetModel(pDestModel); pNewObject->SetPage(pDestPage); - pNewObject->NbcMove(Size(0,0)); + uno::Reference< chart2::XChartDocument > xOldChart( ScChartHelper::GetChartFromSdrObject( pOldObject ) ); + if(!xOldChart.is())//#i110034# do not move charts as they loose all their data references otherwise + pNewObject->NbcMove(Size(0,0)); pDestPage->InsertObject( pNewObject ); // no undo needed in clipboard document @@ -1399,38 +1400,48 @@ void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& } } -BOOL lcl_IsAllInRange( const ScRangeList& rRanges, const ScRange& rClipRange ) +BOOL lcl_IsAllInRange( const ::std::vector< ScRangeList >& rRangesVector, const ScRange& rClipRange ) { - // check if every range of rRanges is completely in rClipRange + // check if every range of rRangesVector is completely in rClipRange - ULONG nCount = rRanges.Count(); - for (ULONG i=0; i<nCount; i++) + ::std::vector< ScRangeList >::const_iterator aIt = rRangesVector.begin(); + for( ;aIt!=rRangesVector.end(); ++aIt ) { - ScRange aRange = *rRanges.GetObject(i); - if ( !rClipRange.In( aRange ) ) + const ScRangeList& rRanges = *aIt; + ULONG nCount = rRanges.Count(); + for (ULONG i=0; i<nCount; i++) { - return FALSE; // at least one range is not valid + ScRange aRange = *rRanges.GetObject(i); + if ( !rClipRange.In( aRange ) ) + { + return FALSE; // at least one range is not valid + } } } return TRUE; // everything is fine } -BOOL lcl_MoveRanges( ScRangeList& rRanges, const ScRange& rSourceRange, const ScAddress& rDestPos ) +BOOL lcl_MoveRanges( ::std::vector< ScRangeList >& rRangesVector, const ScRange& rSourceRange, const ScAddress& rDestPos ) { BOOL bChanged = FALSE; - ULONG nCount = rRanges.Count(); - for (ULONG i=0; i<nCount; i++) + ::std::vector< ScRangeList >::iterator aIt = rRangesVector.begin(); + for( ;aIt!=rRangesVector.end(); ++aIt ) { - ScRange* pRange = rRanges.GetObject(i); - if ( rSourceRange.In( *pRange ) ) + ScRangeList& rRanges = *aIt; + ULONG nCount = rRanges.Count(); + for (ULONG i=0; i<nCount; i++) { - SCsCOL nDiffX = rDestPos.Col() - (SCsCOL)rSourceRange.aStart.Col(); - SCsROW nDiffY = rDestPos.Row() - (SCsROW)rSourceRange.aStart.Row(); - SCsTAB nDiffZ = rDestPos.Tab() - (SCsTAB)rSourceRange.aStart.Tab(); - pRange->Move( nDiffX, nDiffY, nDiffZ ); - bChanged = TRUE; + ScRange* pRange = rRanges.GetObject(i); + if ( rSourceRange.In( *pRange ) ) + { + SCsCOL nDiffX = rDestPos.Col() - (SCsCOL)rSourceRange.aStart.Col(); + SCsROW nDiffY = rDestPos.Row() - (SCsROW)rSourceRange.aStart.Row(); + SCsTAB nDiffZ = rDestPos.Tab() - (SCsTAB)rSourceRange.aStart.Tab(); + pRange->Move( nDiffX, nDiffY, nDiffZ ); + bChanged = TRUE; + } } } @@ -1469,6 +1480,37 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if ( !pSrcPage || !pDestPage ) return; + SdrObjListIter aIter( *pSrcPage, IM_FLAT ); + SdrObject* pOldObject = aIter.Next(); + + ScDocument* pClipDoc = pClipModel->GetDocument(); + // a clipboard document and its source share the same document item pool, + // so the pointers can be compared to see if this is copy&paste within + // the same document + BOOL bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool(); + BOOL bDestClip = pDoc && pDoc->IsClipboard(); + + //#i110034# charts need correct sheet names for xml range conversion during load + //so the target sheet name is temporarily renamed (if we have any SdrObjects) + String aDestTabName; + BOOL bRestoreDestTabName = FALSE; + if( pOldObject && !bSameDoc && !bDestClip ) + { + if( pDoc && pClipDoc ) + { + String aSourceTabName; + if( pClipDoc->GetName( nSourceTab, aSourceTabName ) + && pDoc->GetName( nDestTab, aDestTabName ) ) + { + if( !(aSourceTabName==aDestTabName) && + pDoc->ValidNewTabName(aSourceTabName) ) + { + bRestoreDestTabName = pDoc->RenameTab( nDestTab, aSourceTabName ); //BOOL bUpdateRef = TRUE, BOOL bExternalDocument = FALSE + } + } + } + } + // first mirror, then move Size aMove( rDestRange.Left() - aMirroredSource.Left(), rDestRange.Top() - aMirroredSource.Top() ); @@ -1497,8 +1539,6 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const } Point aRefPos = rDestRange.TopLeft(); // for resizing (after moving) - SdrObjListIter aIter( *pSrcPage, IM_FLAT ); - SdrObject* pOldObject = aIter.Next(); while (pOldObject) { Rectangle aObjRect = pOldObject->GetCurrentBoundRect(); @@ -1522,7 +1562,7 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if (bRecording) AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); - // handle chart data references (after InsertObject) + //#i110034# handle chart data references (after InsertObject) if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 ) { @@ -1541,73 +1581,63 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) ) { - String aNewName = ((SdrOle2Obj*)pNewObject)->GetPersistName(); - - //! need to set new DataProvider, or does Chart handle this itself? - - ScRangeListRef xRanges( new ScRangeList ); - BOOL bColHeaders = FALSE; - BOOL bRowHeaders = FALSE; - pDoc->GetOldChartParameters( aNewName, *xRanges, bColHeaders, bRowHeaders ); - - if ( xRanges->Count() > 0 ) + uno::Reference< chart2::XChartDocument > xNewChart( ScChartHelper::GetChartFromSdrObject( pNewObject ) ); + if( xNewChart.is() && !xNewChart->hasInternalDataProvider() ) { - ScDocument* pClipDoc = pClipModel->GetDocument(); - - // a clipboard document and its source share the same document item pool, - // so the pointers can be compared to see if this is copy&paste within - // the same document - BOOL bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool(); - - BOOL bDestClip = pDoc && pDoc->IsClipboard(); - - BOOL bInSourceRange = FALSE; - ScRange aClipRange; - if ( pClipDoc ) + String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName(); + ::std::vector< ScRangeList > aRangesVector; + pDoc->GetChartRanges( aChartName, aRangesVector, pDoc ); + if( !aRangesVector.empty() ) { - SCCOL nClipStartX; - SCROW nClipStartY; - SCCOL nClipEndX; - SCROW nClipEndY; - pClipDoc->GetClipStart( nClipStartX, nClipStartY ); - pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE ); - nClipEndX = nClipEndX + nClipStartX; - nClipEndY += nClipStartY; // GetClipArea returns the difference - - aClipRange = ScRange( nClipStartX, nClipStartY, nSourceTab, - nClipEndX, nClipEndY, nSourceTab ); - - bInSourceRange = lcl_IsAllInRange( *xRanges, aClipRange ); - } + BOOL bInSourceRange = FALSE; + ScRange aClipRange; + if ( pClipDoc ) + { + SCCOL nClipStartX; + SCROW nClipStartY; + SCCOL nClipEndX; + SCROW nClipEndY; + pClipDoc->GetClipStart( nClipStartX, nClipStartY ); + pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE ); + nClipEndX = nClipEndX + nClipStartX; + nClipEndY += nClipStartY; // GetClipArea returns the difference + + SCTAB nClipTab = bRestoreDestTabName ? nDestTab : nSourceTab; + aClipRange = ScRange( nClipStartX, nClipStartY, nClipTab, + nClipEndX, nClipEndY, nClipTab ); + + bInSourceRange = lcl_IsAllInRange( aRangesVector, aClipRange ); + } - // always lose references when pasting into a clipboard document (transpose) - if ( ( bInSourceRange || bSameDoc ) && !bDestClip ) - { - if ( bInSourceRange ) + // always lose references when pasting into a clipboard document (transpose) + if ( ( bInSourceRange || bSameDoc ) && !bDestClip ) { - if ( rDestPos != aClipRange.aStart ) + if ( bInSourceRange ) { - // update the data ranges to the new (copied) position - ScRangeListRef xNewRanges = new ScRangeList( *xRanges ); - if ( lcl_MoveRanges( *xNewRanges, aClipRange, rDestPos ) ) + if ( rDestPos != aClipRange.aStart ) { - pDoc->UpdateChartArea( aNewName, xNewRanges, bColHeaders, bRowHeaders, FALSE ); + // update the data ranges to the new (copied) position + if ( lcl_MoveRanges( aRangesVector, aClipRange, rDestPos ) ) + pDoc->SetChartRanges( aChartName, aRangesVector ); } } + else + { + // leave the ranges unchanged + } } else { - // leave the ranges unchanged - } - } - else - { - // pasting into a new document without the complete source data - // -> break connection to source data + // pasting into a new document without the complete source data + // -> break connection to source data and switch to own data - // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc) + uno::Reference< chart::XChartDocument > xOldChartDoc( ScChartHelper::GetChartFromSdrObject( pOldObject ), uno::UNO_QUERY ); + uno::Reference< chart::XChartDocument > xNewChartDoc( xNewChart, uno::UNO_QUERY ); + if( xOldChartDoc.is() && xNewChartDoc.is() ) + xNewChartDoc->attachData( xOldChartDoc->getData() ); - //! need chart interface to switch to own data + // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc) + } } } } @@ -1616,6 +1646,9 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const pOldObject = aIter.Next(); } + + if( bRestoreDestTabName ) + pDoc->RenameTab( nDestTab, aDestTabName ); } void ScDrawLayer::MirrorRTL( SdrObject* pObj ) diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx index 21c09688aeee..d32ebdafbf78 100644 --- a/sc/source/core/data/global2.cxx +++ b/sc/source/core/data/global2.cxx @@ -49,6 +49,10 @@ #include "rechead.hxx" #include "compiler.hxx" #include "paramisc.hxx" +// Wang Xu Ming -- 2009-5-18 +// DataPilot Migration +#include "dpglobal.hxx" +// End Comments #include "sc.hrc" #include "globstr.hrc" @@ -59,7 +63,6 @@ using ::std::vector; -#define MAX_LABELS 256 //!!! aus fieldwnd.hxx, muss noch nach global.hxx ??? //------------------------------------------------------------------------ // struct ScImportParam: @@ -905,90 +908,3 @@ String ScGlobal::GetDocTabName( const String& rFileName, return aDocTab; } -// ============================================================================ - -ScSimpleSharedString::StringTable::StringTable() : - mnStrCount(0) -{ - // empty string (ID = 0) - maSharedStrings.push_back(String()); - maSharedStringIds.insert( SharedStrMap::value_type(String(), mnStrCount++) ); -} - -ScSimpleSharedString::StringTable::StringTable(const ScSimpleSharedString::StringTable& r) : - maSharedStrings(r.maSharedStrings), - maSharedStringIds(r.maSharedStringIds), - mnStrCount(r.mnStrCount) -{ -} - -ScSimpleSharedString::StringTable::~StringTable() -{ -} - -sal_Int32 ScSimpleSharedString::StringTable::insertString(const String& aStr) -{ - SharedStrMap::const_iterator itr = maSharedStringIds.find(aStr), - itrEnd = maSharedStringIds.end(); - - if (itr == itrEnd) - { - // new string. - maSharedStrings.push_back(aStr); - maSharedStringIds.insert( SharedStrMap::value_type(aStr, mnStrCount) ); - return mnStrCount++; - } - - // existing string. - return itr->second; -} - -sal_Int32 ScSimpleSharedString::StringTable::getStringId(const String& aStr) -{ - SharedStrMap::const_iterator itr = maSharedStringIds.find(aStr), - itrEnd = maSharedStringIds.end(); - if (itr == itrEnd) - { - // string not found. - return insertString(aStr); - } - return itr->second; -} - -const String* ScSimpleSharedString::StringTable::getString(sal_Int32 nId) const -{ - if (nId >= mnStrCount) - return NULL; - - return &maSharedStrings[nId]; -} - -// ---------------------------------------------------------------------------- - -ScSimpleSharedString::ScSimpleSharedString() -{ -} - -ScSimpleSharedString::ScSimpleSharedString(const ScSimpleSharedString& r) : - maStringTable(r.maStringTable) -{ -} - -ScSimpleSharedString::~ScSimpleSharedString() -{ -} - -sal_Int32 ScSimpleSharedString::insertString(const String& aStr) -{ - return maStringTable.insertString(aStr); -} - -const String* ScSimpleSharedString::getString(sal_Int32 nId) -{ - return maStringTable.getString(nId); -} - -sal_Int32 ScSimpleSharedString::getStringId(const String& aStr) -{ - return maStringTable.getStringId(aStr); -} diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk index 1dd60f75176e..cf51e1e543a4 100644..100755 --- a/sc/source/core/data/makefile.mk +++ b/sc/source/core/data/makefile.mk @@ -72,6 +72,7 @@ SLOFILES = \ $(SLO)$/document.obj \ $(SLO)$/dpcachetable.obj \ $(SLO)$/dpdimsave.obj \ + $(SLO)$/dpglobal.obj \ $(SLO)$/dpgroup.obj \ $(SLO)$/dpobject.obj \ $(SLO)$/dpoutput.obj \ @@ -82,6 +83,8 @@ SLOFILES = \ $(SLO)$/dptabdat.obj \ $(SLO)$/dptabres.obj \ $(SLO)$/dptabsrc.obj \ + $(SLO)$/dptablecache.obj\ + $(SLO)$/scdpoutputimpl.obj\ $(SLO)$/drawpage.obj \ $(SLO)$/drwlayer.obj \ $(SLO)$/fillinfo.obj \ @@ -93,10 +96,8 @@ SLOFILES = \ $(SLO)$/olinetab.obj \ $(SLO)$/pagepar.obj \ $(SLO)$/patattr.obj \ - $(SLO)$/pivot.obj \ $(SLO)$/pivot2.obj \ $(SLO)$/poolhelp.obj \ - $(SLO)$/scimpexpmsg.obj \ $(SLO)$/sortparam.obj \ $(SLO)$/stlpool.obj \ $(SLO)$/stlsheet.obj \ @@ -121,6 +122,7 @@ EXCEPTIONSFILES= \ $(SLO)$/documen2.obj \ $(SLO)$/document.obj \ $(SLO)$/dpdimsave.obj \ + $(SLO)$/dpglobal.obj \ $(SLO)$/dpgroup.obj \ $(SLO)$/dpshttab.obj \ $(SLO)$/dptabres.obj \ @@ -135,7 +137,9 @@ EXCEPTIONSFILES= \ $(SLO)$/documen5.obj \ $(SLO)$/documen6.obj \ $(SLO)$/documen9.obj \ - $(SLO)$/dpcachetable.obj \ + $(SLO)$/dpcachetable.obj \ + $(SLO)$/dptablecache.obj \ + $(SLO)$/scdpoutputimpl.obj \ $(SLO)$/dpsdbtab.obj \ $(SLO)$/dpobject.obj \ $(SLO)$/dpoutput.obj \ diff --git a/sc/source/core/data/scdpoutputimpl.cxx b/sc/source/core/data/scdpoutputimpl.cxx new file mode 100644 index 000000000000..6a667806e097 --- /dev/null +++ b/sc/source/core/data/scdpoutputimpl.cxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: scdpoutputimpl.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- +#include "scdpoutputimpl.hxx" +#include "scitems.hxx" +#include <editeng/boxitem.hxx> +// ----------------------------------------------------------------------- + +namespace +{ + bool lcl_compareColfuc ( SCCOL i, SCCOL j) { return (i<j); } + bool lcl_compareRowfuc ( SCROW i, SCROW j) { return (i<j); } +} + + +void OutputImpl::OutputDataArea() +{ + AddRow( mnDataStartRow ); + AddCol( mnDataStartCol ); + + mnCols.push_back( mnTabEndCol+1); //set last row bottom + mnRows.push_back( mnTabEndRow+1); //set last col bottom + + BOOL bAllRows = ( ( mnTabEndRow - mnDataStartRow + 2 ) == (SCROW) mnRows.size() ); + + std::sort( mnCols.begin(), mnCols.end(), lcl_compareColfuc ); + std::sort( mnRows.begin(), mnRows.end(), lcl_compareRowfuc ); + + for( SCCOL nCol = 0; nCol < (SCCOL)mnCols.size()-1; nCol ++ ) + { + if ( !bAllRows ) + { + if ( nCol < (SCCOL)mnCols.size()-2) + { + for ( SCROW i = nCol%2; i < (SCROW)mnRows.size()-2; i +=2 ) + OutputBlockFrame( mnCols[nCol], mnRows[i], mnCols[nCol+1]-1, mnRows[i+1]-1 ); + if ( mnRows.size()>=2 ) + OutputBlockFrame( mnCols[nCol], mnRows[mnRows.size()-2], mnCols[nCol+1]-1, mnRows[mnRows.size()-1]-1 ); + } + else + { + for ( SCROW i = 0 ; i < (SCROW)mnRows.size()-1; i++ ) + OutputBlockFrame( mnCols[nCol], mnRows[i], mnCols[nCol+1]-1, mnRows[i+1]-1 ); + } + } + else + OutputBlockFrame( mnCols[nCol], mnRows.front(), mnCols[nCol+1]-1, mnRows.back()-1, bAllRows ); + } + //out put rows area outer framer + if ( mnTabStartCol != mnDataStartCol ) + { + if ( mnTabStartRow != mnDataStartRow ) + OutputBlockFrame( mnTabStartCol, mnTabStartRow, mnDataStartCol-1, mnDataStartRow-1 ); + OutputBlockFrame( mnTabStartCol, mnDataStartRow, mnDataStartCol-1, mnTabEndRow ); + } + //out put cols area outer framer + OutputBlockFrame( mnDataStartCol, mnTabStartRow, mnTabEndCol, mnDataStartRow-1 ); +} + +OutputImpl::OutputImpl( ScDocument* pDoc, USHORT nTab, + SCCOL nTabStartCol, + SCROW nTabStartRow, + SCCOL nMemberStartCol, + SCROW nMemberStartRow, + SCCOL nDataStartCol, + SCROW nDataStartRow, + SCCOL nTabEndCol, + SCROW nTabEndRow ): + mpDoc( pDoc ), + mnTab( nTab ), + mnTabStartCol( nTabStartCol ), + mnTabStartRow( nTabStartRow ), + mnMemberStartCol( nMemberStartCol), + mnMemberStartRow( nMemberStartRow), + mnDataStartCol ( nDataStartCol ), + mnDataStartRow ( nDataStartRow ), + mnTabEndCol( nTabEndCol ), + mnTabEndRow( nTabEndRow ) +{ + mbNeedLineCols.resize( nTabEndCol-nDataStartCol+1, false ); + mbNeedLineRows.resize( nTabEndRow-nDataStartRow+1, false ); + +} + +BOOL OutputImpl::AddRow( SCROW nRow ) +{ + if ( !mbNeedLineRows[ nRow - mnDataStartRow ] ) + { + mbNeedLineRows[ nRow - mnDataStartRow ] = true; + mnRows.push_back( nRow ); + return TRUE; + } + else + return FALSE; +} + +BOOL OutputImpl::AddCol( SCCOL nCol ) +{ + + if ( !mbNeedLineCols[ nCol - mnDataStartCol ] ) + { + mbNeedLineCols[ nCol - mnDataStartCol ] = true; + mnCols.push_back( nCol ); + return TRUE; + } + else + return FALSE; +} + +void OutputImpl::OutputBlockFrame ( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, BOOL bHori ) +{ + + SvxBorderLine aLine, aOutLine; + aLine.SetColor( SC_DP_FRAME_COLOR ); + aLine.SetOutWidth( SC_DP_FRAME_INNER_BOLD ); + aOutLine.SetColor( SC_DP_FRAME_COLOR ); + aOutLine.SetOutWidth( SC_DP_FRAME_OUTER_BOLD ); + + SvxBoxItem aBox( ATTR_BORDER ); + + if ( nStartCol == mnTabStartCol ) + aBox.SetLine(&aOutLine, BOX_LINE_LEFT); + else + aBox.SetLine(&aLine, BOX_LINE_LEFT); + + if ( nStartRow == mnTabStartRow ) + aBox.SetLine(&aOutLine, BOX_LINE_TOP); + else + aBox.SetLine(&aLine, BOX_LINE_TOP); + + if ( nEndCol == mnTabEndCol ) //bottom row + aBox.SetLine(&aOutLine, BOX_LINE_RIGHT); + else + aBox.SetLine(&aLine, BOX_LINE_RIGHT); + + if ( nEndRow == mnTabEndRow ) //bottom + aBox.SetLine(&aOutLine, BOX_LINE_BOTTOM); + else + aBox.SetLine(&aLine, BOX_LINE_BOTTOM); + + + SvxBoxInfoItem aBoxInfo( ATTR_BORDER_INNER ); + aBoxInfo.SetValid(VALID_VERT,FALSE ); + if ( bHori ) + { + aBoxInfo.SetValid(VALID_HORI,TRUE); + aBoxInfo.SetLine( &aLine, BOXINFO_LINE_HORI ); + } + else + aBoxInfo.SetValid(VALID_HORI,FALSE ); + + aBoxInfo.SetValid(VALID_DISTANCE,FALSE); + + mpDoc->ApplyFrameAreaTab( ScRange( nStartCol, nStartRow, mnTab, nEndCol, nEndRow , mnTab ), &aBox, &aBoxInfo ); + +} diff --git a/sc/source/core/data/scdpoutputimpl.hxx b/sc/source/core/data/scdpoutputimpl.hxx new file mode 100755 index 000000000000..9148fe91ba02 --- /dev/null +++ b/sc/source/core/data/scdpoutputimpl.hxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: scdpoutputimpl.hxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef SCDPOUTPUTIMPL_HXX +#define SCDPOUTPUTIMPL_HXX + +#include "document.hxx" + +#define SC_DP_FRAME_INNER_BOLD 20 +#define SC_DP_FRAME_OUTER_BOLD 40 + +#define SC_DP_FRAME_COLOR Color(0,0,0) //( 0x20, 0x40, 0x68 ) + +class OutputImpl +{ + ScDocument* mpDoc; + USHORT mnTab; + ::std::vector< bool > mbNeedLineCols; + ::std::vector< SCCOL > mnCols; + + ::std::vector< bool > mbNeedLineRows; + ::std::vector< SCROW > mnRows; + + SCCOL mnTabStartCol; + SCROW mnTabStartRow; + SCCOL mnMemberStartCol; + SCROW mnMemberStartRow; + + SCCOL mnDataStartCol; + SCROW mnDataStartRow; + SCCOL mnTabEndCol; + SCROW mnTabEndRow; + +public: + OutputImpl( ScDocument* pDoc, USHORT nTab, + SCCOL nTabStartCol, + SCROW nTabStartRow, + SCCOL nMemberStartCol, + SCROW nMemberStartRow, + SCCOL nDataStartCol, + SCROW nDataStartRow, + SCCOL nTabEndCol, + SCROW nTabEndRow ); + BOOL AddRow( SCROW nRow ); + BOOL AddCol( SCCOL nCol ); + + void OutputDataArea(); + void OutputBlockFrame ( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, BOOL bHori = FALSE ); + +}; + +#endif diff --git a/sc/source/core/data/scimpexpmsg.cxx b/sc/source/core/data/scimpexpmsg.cxx deleted file mode 100644 index 0d883fe5535a..000000000000 --- a/sc/source/core/data/scimpexpmsg.cxx +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_sc.hxx" - - - -// INCLUDE --------------------------------------------------------------- - -#include "document.hxx" -#include "scimpexpmsg.hxx" - -#include <tools/string.hxx> - -//UNUSED2008-05 ScImpExpLogMsg::ScImpExpLogMsg( ScImpExpMsg e ) : eId( e ), pPos( NULL ), pHint( NULL ) -//UNUSED2008-05 { -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 ScImpExpLogMsg::ScImpExpLogMsg( ScImpExpMsg e, const String& r ) : eId( e ), pHint( NULL ) -//UNUSED2008-05 { -//UNUSED2008-05 pPos = new String( r ); -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 ScImpExpLogMsg::ScImpExpLogMsg( ScImpExpMsg e, const String& rP, const String& rH ) : eId( e ) -//UNUSED2008-05 { -//UNUSED2008-05 pPos = new String( rP ); -//UNUSED2008-05 pHint = new String( rH ); -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 ScImpExpLogMsg::ScImpExpLogMsg( const ScImpExpLogMsg& r ) : eId( r.eId ) -//UNUSED2008-05 { -//UNUSED2008-05 if( r.pPos ) -//UNUSED2008-05 pPos = new String( *r.pPos ); -//UNUSED2008-05 else -//UNUSED2008-05 pPos = NULL; -//UNUSED2008-05 -//UNUSED2008-05 if( r.pHint ) -//UNUSED2008-05 pHint = new String( *r.pHint ); -//UNUSED2008-05 else -//UNUSED2008-05 pHint = NULL; -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 ScImpExpLogMsg::~ScImpExpLogMsg() -//UNUSED2008-05 { -//UNUSED2008-05 if( pPos ) -//UNUSED2008-05 delete pPos; -//UNUSED2008-05 -//UNUSED2008-05 if( pHint ) -//UNUSED2008-05 delete pHint; -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 void ScImpExpLogMsg::Set( ScImpExpMsg e, const String* pP, const String* pH ) -//UNUSED2008-05 { -//UNUSED2008-05 eId = e; -//UNUSED2008-05 if( pPos ) -//UNUSED2008-05 delete pPos; -//UNUSED2008-05 -//UNUSED2008-05 if( pHint ) -//UNUSED2008-05 delete pHint; -//UNUSED2008-05 -//UNUSED2008-05 if( pP ) -//UNUSED2008-05 pPos = new String( *pP ); -//UNUSED2008-05 else -//UNUSED2008-05 pPos = NULL; -//UNUSED2008-05 -//UNUSED2008-05 if( pH ) -//UNUSED2008-05 pHint = new String( *pH ); -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 -//UNUSED2008-05 String ScImpExpLogMsg::GetMsg( ScImpExpMsg e ) -//UNUSED2008-05 { -//UNUSED2008-05 const sal_Char* p; -//UNUSED2008-05 switch( e ) -//UNUSED2008-05 { -//UNUSED2008-05 case SC_IMPEXPMSG_UNKNOWN: p = "unknown log message"; break; -//UNUSED2008-05 default: p = "Not specified type of log message"; -//UNUSED2008-05 } -//UNUSED2008-05 -//UNUSED2008-05 String aRet; -//UNUSED2008-05 aRet.AssignAscii( p ); -//UNUSED2008-05 return aRet; -//UNUSED2008-05 } - diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 389000f77024..695a7ec2f1fe 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -190,7 +190,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName, pDrawLayer->ScRenamePage( nTab, aName ); ULONG nx = (ULONG) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS ); ULONG ny = (ULONG) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS ); - pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ) ); + pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ), false ); } } @@ -683,7 +683,7 @@ BOOL ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const } void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, - BOOL bIncludeOld ) const + BOOL bIncludeOld, bool bOnlyDown ) const { BOOL bLeft = FALSE; BOOL bRight = FALSE; @@ -698,26 +698,44 @@ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, S { bChanged = FALSE; - SCROW nStart = rStartRow; - SCROW nEnd = rEndRow; - if (nStart>0) --nStart; - if (nEnd<MAXROW) ++nEnd; + if (!bOnlyDown) + { + SCROW nStart = rStartRow; + SCROW nEnd = rEndRow; + if (nStart>0) --nStart; + if (nEnd<MAXROW) ++nEnd; - if (rEndCol < MAXCOL) - if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd)) - { - ++rEndCol; - bChanged = TRUE; - bRight = TRUE; - } + if (rEndCol < MAXCOL) + if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd)) + { + ++rEndCol; + bChanged = TRUE; + bRight = TRUE; + } - if (rStartCol > 0) - if (!aCol[rStartCol-1].IsEmptyBlock(nStart,nEnd)) + if (rStartCol > 0) + if (!aCol[rStartCol-1].IsEmptyBlock(nStart,nEnd)) + { + --rStartCol; + bChanged = TRUE; + bLeft = TRUE; + } + + if (rStartRow > 0) { - --rStartCol; - bChanged = TRUE; - bLeft = TRUE; + nTest = rStartRow-1; + bFound = FALSE; + for (i=rStartCol; i<=rEndCol && !bFound; i++) + if (aCol[i].HasDataAt(nTest)) + bFound = TRUE; + if (bFound) + { + --rStartRow; + bChanged = TRUE; + bTop = TRUE; + } } + } if (rEndRow < MAXROW) { @@ -733,21 +751,6 @@ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, S bBottom = TRUE; } } - - if (rStartRow > 0) - { - nTest = rStartRow-1; - bFound = FALSE; - for (i=rStartCol; i<=rEndCol && !bFound; i++) - if (aCol[i].HasDataAt(nTest)) - bFound = TRUE; - if (bFound) - { - --rStartRow; - bChanged = TRUE; - bTop = TRUE; - } - } } while( bChanged ); @@ -780,6 +783,77 @@ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, S } } + +bool ScTable::ShrinkToUsedDataArea( SCCOL& rStartCol, SCROW& rStartRow, + SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const +{ + bool bRet = false; + bool bChanged; + + do + { + bChanged = false; + + bool bCont = true; + while (rEndCol > 0 && bCont && rStartCol < rEndCol) + { + if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow)) + { + --rEndCol; + bChanged = true; + } + else + bCont = false; + } + + bCont = true; + while (rStartCol < MAXCOL && bCont && rStartCol < rEndCol) + { + if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow)) + { + ++rStartCol; + bChanged = true; + } + else + bCont = false; + } + + if (!bColumnsOnly) + { + if (rStartRow < MAXROW && rStartRow < rEndRow) + { + bool bFound = false; + for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++) + if (aCol[i].HasDataAt( rStartRow)) + bFound = true; + if (!bFound) + { + ++rStartRow; + bChanged = true; + } + } + + if (rEndRow > 0 && rStartRow < rEndRow) + { + bool bFound = false; + for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++) + if (aCol[i].HasDataAt( rEndRow)) + bFound = true; + if (!bFound) + { + --rEndRow; + bChanged = true; + } + } + } + + if (bChanged) + bRet = true; + } while( bChanged ); + return bRet; +} + + SCSIZE ScTable::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ) { @@ -1117,7 +1191,7 @@ BOOL ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMa void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, - SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) + SCsCOL nDx, SCsROW nDy, SCsTAB nDz, bool bUpdateNoteCaptionPos ) { if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // only within the table { @@ -1133,14 +1207,14 @@ void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nR nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy ); } pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy, - (eUpdateRefMode == URM_INSDEL) ); + (eUpdateRefMode == URM_INSDEL), bUpdateNoteCaptionPos ); } } } void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz, - ScDocument* pUndoDoc, BOOL bIncludeDraw ) + ScDocument* pUndoDoc, BOOL bIncludeDraw, bool bUpdateNoteCaptionPos ) { SCCOL i; SCCOL iMax; @@ -1159,7 +1233,7 @@ void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nDx, nDy, nDz, pUndoDoc ); if ( bIncludeDraw ) - UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz ); + UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz, bUpdateNoteCaptionPos ); if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // print ranges: only within the table { diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index b6aaa08a7db3..69d16df7be58 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -113,7 +113,7 @@ BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize ) void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize ) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); if (nStartCol==0 && nEndCol==MAXCOL) { @@ -132,15 +132,14 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE for (SCCOL j=nStartCol; j<=nEndCol; j++) aCol[j].InsertRow( nStartRow, nSize ); - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel( false ); } void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize, BOOL* pUndoOutline ) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); if (nStartCol==0 && nEndCol==MAXCOL) { @@ -160,8 +159,7 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE for (SCCOL j=nStartCol; j<=nEndCol; j++) aCol[j].DeleteRow( nStartRow, nSize ); } - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } @@ -184,7 +182,7 @@ BOOL ScTable::TestInsertCol( SCROW nStartRow, SCROW nEndRow, SCSIZE nSize ) void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize ) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); if (nStartRow==0 && nEndRow==MAXROW) { @@ -227,15 +225,14 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE aCol[nStartCol+i].ClearItems( nStartRow, nEndRow, nWhichArray ); } } - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize, BOOL* pUndoOutline ) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); if (nStartRow==0 && nEndRow==MAXROW) { @@ -270,8 +267,7 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE for (SCSIZE i=0; static_cast<SCCOL>(i+nSize)+nStartCol <= MAXCOL; i++) aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]); } - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } @@ -281,7 +277,7 @@ void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USH if (nRow2 > MAXROW) nRow2 = MAXROW; if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)) { -// nRecalcLvl++; +// IncRecalcLevel(); { // scope for bulk broadcast ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM()); @@ -300,9 +296,7 @@ void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USH ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern ); } -/* if( !--nRecalcLvl ) - SetDrawPageSize(); -*/ +// DecRecalcLevel(); } } @@ -389,7 +383,7 @@ void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, if (nRow2 > MAXROW) nRow2 = MAXROW; if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)) { - nRecalcLvl++; + IncRecalcLevel(); for ( i = nCol1; i <= nCol2; i++) aCol[i].CopyFromClip(nRow1, nRow2, nDy, nInsFlag, bAsLink, bSkipAttrForEmpty, pTable->aCol[i - nDx]); @@ -424,8 +418,7 @@ void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern ); } } - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } } @@ -691,7 +684,7 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight); if (bWidth||bHeight) - nRecalcLvl++; + IncRecalcLevel(); for ( SCCOL i = 0; i <= MAXCOL; i++) { @@ -709,8 +702,7 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, pDestTab->pColWidth[i] = pColWidth[i]; if (bHeight) pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2); - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } } } @@ -853,10 +845,12 @@ void ScTable::PutCell( const ScAddress& rPos, ScBaseCell* pCell ) //UNUSED2009-05 } -BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString ) +BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString, + SvNumberFormatter* pFormatter, bool bDetectNumberFormat ) { if (ValidColRow(nCol,nRow)) - return aCol[nCol].SetString( nRow, nTabP, rString ); + return aCol[nCol].SetString( + nRow, nTabP, rString, pDocument->GetAddressConvention(), pFormatter, bDetectNumberFormat ); else return FALSE; } @@ -1177,9 +1171,9 @@ const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, S } -BOOL ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const +bool ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const { - BOOL bFound=FALSE; + bool bFound = false; for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++) bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask ); return bFound; @@ -1947,14 +1941,13 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth ) if ( nNewWidth != pColWidth[nCol] ) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] ); pColWidth[nCol] = nNewWidth; - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } } else @@ -1977,14 +1970,13 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) USHORT nOldHeight = pRowHeight->GetValue(nRow); if ( nNewHeight != nOldHeight ) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight ); pRowHeight->SetValue( nRow, nNewHeight); - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } } else @@ -2000,7 +1992,7 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig BOOL bChanged = FALSE; if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); if (!nNewHeight) { @@ -2083,8 +2075,7 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig } while (!bChanged && aIter.NextRange()); pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight); } - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } else { @@ -2267,7 +2258,7 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow) BOOL bWasVis = ( pColFlags[nCol] & CR_HIDDEN ) == 0; if (bWasVis != bShow) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) @@ -2282,8 +2273,7 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow) pColFlags[nCol] &= ~CR_HIDDEN; else pColFlags[nCol] |= CR_HIDDEN; - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection(); if ( pCharts ) @@ -2305,7 +2295,7 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow) BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0; if (bWasVis != bShow) { - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) @@ -2320,8 +2310,7 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow) pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED)); else pRowFlags->SetValue( nRow, nFlags | CR_HIDDEN); - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection(); if ( pCharts ) @@ -2341,7 +2330,7 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow) { BYTE nFlags = pRowFlags->GetValue(nRow); BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0; - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); if (bWasVis != bShow) { @@ -2360,8 +2349,7 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow) pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED)); else pRowFlags->SetValue( nRow, nFlags | (CR_HIDDEN | CR_FILTERED)); - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); if (bWasVis != bShow) { @@ -2383,7 +2371,7 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow) void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) { SCROW nStartRow = nRow1; - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); while (nStartRow <= nRow2) { @@ -2428,15 +2416,14 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) if (pOutlineTable) UpdateOutlineRow( nRow1, nRow2, bShow ); - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) { SCROW nStartRow = nRow1; - nRecalcLvl++; + IncRecalcLevel(); InitializeNoteCaptions(); while (nStartRow <= nRow2) { @@ -2474,8 +2461,7 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) nStartRow = nEndRow + 1; } - if( !--nRecalcLvl ) - SetDrawPageSize(); + DecRecalcLevel(); } @@ -2841,7 +2827,7 @@ void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, String& rStr) // Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage -void ScTable::SetDrawPageSize(bool bResetStreamValid) +void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos) { ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if( pDrawLayer ) @@ -2854,7 +2840,7 @@ void ScTable::SetDrawPageSize(bool bResetStreamValid) if ( IsLayoutRTL() ) // IsNegativePage x = -x; - pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ) ); + pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ), bUpdateNoteCaptionPos ); } // #i102616# actions that modify the draw page size count as sheet modification diff --git a/sc/source/core/inc/core_pch.hxx b/sc/source/core/inc/core_pch.hxx index 3e637550cd64..899169154d8d 100644 --- a/sc/source/core/inc/core_pch.hxx +++ b/sc/source/core/inc/core_pch.hxx @@ -158,7 +158,6 @@ #include <svtools/compat.hxx> #include <svl/inetdef.hxx> #include <svl/inethist.hxx> -#include <svl/cancel.hxx> #include <vcl/accel.hxx> #include <sfx2/sfxdefs.hxx> #include <sfx2/module.hxx> diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx index 509a9fe293fb..ccbecd52d9f2 100644 --- a/sc/source/core/tool/address.cxx +++ b/sc/source/core/tool/address.cxx @@ -634,7 +634,9 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r, { const sal_Unicode* pTmp = NULL; String aExternDocName, aStartTabName, aEndTabName; - USHORT nFlags = SCA_VALID | SCA_VALID_TAB, nFlags2 = SCA_VALID_TAB2; + USHORT nFlags = SCA_VALID | SCA_VALID_TAB; + // Keep in mind that nFlags2 gets left-shifted by 4 bits before being merged. + USHORT nFlags2 = SCA_VALID_TAB; #if 0 { diff --git a/sc/source/core/tool/charthelper.cxx b/sc/source/core/tool/charthelper.cxx index 756493cc86e9..1b2cde3d4a6d 100644 --- a/sc/source/core/tool/charthelper.cxx +++ b/sc/source/core/tool/charthelper.cxx @@ -31,17 +31,18 @@ #include "charthelper.hxx" #include "document.hxx" #include "drwlayer.hxx" +#include "rangelst.hxx" +#include "chartlis.hxx" //#include <vcl/svapp.hxx> #include <svx/svditer.hxx> #include <svx/svdoole2.hxx> #include <svx/svdpage.hxx> -/* +#include <com/sun/star/chart2/data/XDataReceiver.hpp> + using namespace com::sun::star; using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::WeakReference; -*/ // ==================================================================== @@ -92,6 +93,37 @@ USHORT lcl_DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc, BOOL bAllCha return nFound; } +BOOL lcl_AdjustRanges( ScRangeList& rRanges, SCTAB nSourceTab, SCTAB nDestTab, SCTAB nTabCount ) +{ + //! if multiple sheets are copied, update references into the other copied sheets? + + BOOL bChanged = FALSE; + + ULONG nCount = rRanges.Count(); + for (ULONG i=0; i<nCount; i++) + { + ScRange* pRange = rRanges.GetObject(i); + if ( pRange->aStart.Tab() == nSourceTab && pRange->aEnd.Tab() == nSourceTab ) + { + pRange->aStart.SetTab( nDestTab ); + pRange->aEnd.SetTab( nDestTab ); + bChanged = TRUE; + } + if ( pRange->aStart.Tab() >= nTabCount ) + { + pRange->aStart.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); + bChanged = TRUE; + } + if ( pRange->aEnd.Tab() >= nTabCount ) + { + pRange->aEnd.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); + bChanged = TRUE; + } + } + + return bChanged; +} + }//end anonymous namespace // === ScChartHelper ====================================== @@ -107,3 +139,160 @@ USHORT ScChartHelper::DoUpdateAllCharts( ScDocument* pDoc ) { return lcl_DoUpdateCharts( ScAddress(), pDoc, TRUE ); } + +//static +void ScChartHelper::AdjustRangesOfChartsOnDestinationPage( ScDocument* pSrcDoc, ScDocument* pDestDoc, const SCTAB nSrcTab, const SCTAB nDestTab ) +{ + if( !pSrcDoc || !pDestDoc ) + return; + ScDrawLayer* pDrawLayer = pDestDoc->GetDrawLayer(); + if( !pDrawLayer ) + return; + + SdrPage* pDestPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nDestTab)); + if( pDestPage ) + { + SdrObjListIter aIter( *pDestPage, IM_FLAT ); + SdrObject* pObject = aIter.Next(); + while( pObject ) + { + if( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->IsChart() ) + { + String aChartName = ((SdrOle2Obj*)pObject)->GetPersistName(); + + Reference< chart2::XChartDocument > xChartDoc( pDestDoc->GetChartByName( aChartName ) ); + Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); + if( xChartDoc.is() && xReceiver.is() && !xChartDoc->hasInternalDataProvider() ) + { + ::std::vector< ScRangeList > aRangesVector; + pDestDoc->GetChartRanges( aChartName, aRangesVector, pSrcDoc ); + + ::std::vector< ScRangeList >::iterator aIt( aRangesVector.begin() ); + for( ; aIt!=aRangesVector.end(); aIt++ ) + { + ScRangeList& rScRangeList( *aIt ); + lcl_AdjustRanges( rScRangeList, nSrcTab, nDestTab, pDestDoc->GetTableCount() ); + } + pDestDoc->SetChartRanges( aChartName, aRangesVector ); + } + } + pObject = aIter.Next(); + } + } +} + +//static +uno::Reference< chart2::XChartDocument > ScChartHelper::GetChartFromSdrObject( SdrObject* pObject ) +{ + uno::Reference< chart2::XChartDocument > xReturn; + if( pObject ) + { + if( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->IsChart() ) + { + uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); + if( xIPObj.is() ) + { + svt::EmbeddedObjectRef::TryRunningState( xIPObj ); + uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); + xReturn.set( uno::Reference< chart2::XChartDocument >( xComponent, uno::UNO_QUERY ) ); + } + } + } + return xReturn; +} + +void ScChartHelper::GetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, + uno::Sequence< rtl::OUString >& rRanges ) +{ + rRanges.realloc(0); + uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); + if( !xDataSource.is() ) + return; + //uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); + + uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); + rRanges.realloc(2*aLabeledDataSequences.getLength()); + sal_Int32 nRealCount=0; + for( sal_Int32 nN=0;nN<aLabeledDataSequences.getLength();nN++) + { + uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); + if(!xLabeledSequence.is()) + continue; + uno::Reference< chart2::data::XDataSequence > xLabel( xLabeledSequence->getLabel()); + uno::Reference< chart2::data::XDataSequence > xValues( xLabeledSequence->getValues()); + + if( xLabel.is()) + rRanges[nRealCount++] = xLabel->getSourceRangeRepresentation(); + if( xValues.is()) + rRanges[nRealCount++] = xValues->getSourceRangeRepresentation(); + } + rRanges.realloc(nRealCount); +} + +void ScChartHelper::SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, + const uno::Sequence< rtl::OUString >& rRanges ) +{ + uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); + if( !xDataSource.is() ) + return; + uno::Reference< chart2::data::XDataProvider > xDataProvider = xChartDoc->getDataProvider(); + if( !xDataProvider.is() ) + return; + + uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY ); + if( xModel.is() ) + xModel->lockControllers(); + + try + { + rtl::OUString aPropertyNameRole( ::rtl::OUString::createFromAscii("Role") ); + + uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); + sal_Int32 nRange=0; + for( sal_Int32 nN=0; (nN<aLabeledDataSequences.getLength()) && (nRange<rRanges.getLength()); nN++ ) + { + uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); + if(!xLabeledSequence.is()) + continue; + uno::Reference< beans::XPropertySet > xLabel( xLabeledSequence->getLabel(), uno::UNO_QUERY ); + uno::Reference< beans::XPropertySet > xValues( xLabeledSequence->getValues(), uno::UNO_QUERY ); + + if( xLabel.is()) + { + // the range string must be in Calc A1 format. + uno::Reference< chart2::data::XDataSequence > xNewSeq( + xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); + + uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); + if( xNewProps.is() ) + xNewProps->setPropertyValue( aPropertyNameRole, xLabel->getPropertyValue( aPropertyNameRole ) ); + + xLabeledSequence->setLabel( xNewSeq ); + } + + if( !(nRange<rRanges.getLength()) ) + break; + + if( xValues.is()) + { + // the range string must be in Calc A1 format. + uno::Reference< chart2::data::XDataSequence > xNewSeq( + xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); + + uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); + if( xNewProps.is() ) + xNewProps->setPropertyValue( aPropertyNameRole, xValues->getPropertyValue( aPropertyNameRole ) ); + + xLabeledSequence->setValues( xNewSeq ); + } + } + } + catch ( uno::Exception& ex ) + { + (void)ex; + DBG_ERROR("Exception in ScChartHelper::SetChartRanges - invalid range string?"); + } + + if( xModel.is() ) + xModel->unlockControllers(); +} diff --git a/sc/source/core/tool/collect.cxx b/sc/source/core/tool/collect.cxx index 13df9307bc11..c7aa72343fbb 100644 --- a/sc/source/core/tool/collect.cxx +++ b/sc/source/core/tool/collect.cxx @@ -352,10 +352,18 @@ ScDataObject* ScStrCollection::Clone() const //UNUSED2008-05 } //UNUSED2008-05 } + ScDataObject* TypedStrData::Clone() const { return new TypedStrData(*this); } + +TypedScStrCollection::TypedScStrCollection( USHORT nLim , USHORT nDel , BOOL bDup ) + : ScSortedCollection( nLim, nDel, bDup ) +{ + bCaseSensitive = FALSE; +} + TypedScStrCollection::~TypedScStrCollection() {} ScDataObject* TypedScStrCollection::Clone() const @@ -363,6 +371,16 @@ ScDataObject* TypedScStrCollection::Clone() const return new TypedScStrCollection(*this); } +TypedStrData* TypedScStrCollection::operator[]( const USHORT nIndex) const +{ + return (TypedStrData*)At(nIndex); +} + +void TypedScStrCollection::SetCaseSensitive( BOOL bSet ) +{ + bCaseSensitive = bSet; +} + short TypedScStrCollection::Compare( ScDataObject* pKey1, ScDataObject* pKey2 ) const { short nResult = 0; diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx index 28fae20ddb62..5c2d3f575654 100644 --- a/sc/source/core/tool/doubleref.cxx +++ b/sc/source/core/tool/doubleref.cxx @@ -337,7 +337,9 @@ OUString ScDBInternalRange::getString(SCCOL nCol, SCROW nRow) const { String aStr; const ScAddress& s = maRange.aStart; - getDoc()->GetString(s.Col() + nCol, s.Row() + nRow, maRange.aStart.Tab(), aStr); + // #i109200# this is used in formula calculation, use GetInputString, not GetString + // (consistent with ScDBInternalRange::getCellString) + getDoc()->GetInputString(s.Col() + nCol, s.Row() + nRow, maRange.aStart.Tab(), aStr); return aStr; } diff --git a/sc/source/core/tool/hints.cxx b/sc/source/core/tool/hints.cxx index e2bcb11fc573..b2a8266705c7 100644 --- a/sc/source/core/tool/hints.cxx +++ b/sc/source/core/tool/hints.cxx @@ -40,6 +40,7 @@ TYPEINIT1(ScPointerChangedHint, SfxHint); TYPEINIT1(ScLinkRefreshedHint, SfxHint); TYPEINIT1(ScAutoStyleHint, SfxHint); TYPEINIT1(ScDBRangeRefreshedHint, SfxHint); +TYPEINIT1(ScDataPilotModifiedHint, SfxHint); // ----------------------------------------------------------------------- // ScPaintHint - Angabe, was neu gezeichnet werden muss @@ -150,3 +151,12 @@ ScDBRangeRefreshedHint::~ScDBRangeRefreshedHint() } +ScDataPilotModifiedHint::ScDataPilotModifiedHint( const String& rName ) + : maName(rName) +{ +} +ScDataPilotModifiedHint::~ScDataPilotModifiedHint() +{ +} + + diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 166261b98ffd..94cd5c1a02e9 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -6053,6 +6053,10 @@ void ScInterpreter::ScDBCount() // iterators. ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pQueryParam.get()); SCTAB nTab = p->nTab; + // ScQueryCellIterator doesn't make use of ScDBQueryParamBase::mnField, + // so the source range has to be restricted, like before the introduction + // of ScDBQueryParamBase. + p->nCol1 = p->nCol2 = p->mnField; ScQueryCellIterator aCellIter( pDok, nTab, *p); if ( aCellIter.GetFirst() ) { diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 8a6c0df0db16..ffba9aafc511 100755..100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -3115,7 +3115,7 @@ void ScInterpreter::ScColRowNameAuto() (SCROW&) aRefData.Ref1.nRow, (SCCOL&) aRefData.Ref2.nCol, (SCROW&) aRefData.Ref2.nRow, - TRUE ); + TRUE, false ); // DataArea im Ursprung begrenzen aRefData.Ref1.nCol = nStartCol; aRefData.Ref1.nRow = nStartRow; diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk index 0bc433a7b187..6c730f3a1743 100644 --- a/sc/source/core/tool/makefile.mk +++ b/sc/source/core/tool/makefile.mk @@ -105,6 +105,7 @@ SLOFILES = \ $(SLO)$/refupdat.obj \ $(SLO)$/scmatrix.obj \ $(SLO)$/sctictac.obj \ + $(SLO)$/stringutil.obj \ $(SLO)$/subtotal.obj \ $(SLO)$/token.obj \ $(SLO)$/unitconv.obj \ @@ -115,6 +116,7 @@ SLOFILES = \ EXCEPTIONSFILES= \ $(SLO)$/addincol.obj \ $(SLO)$/cellkeytranslator.obj \ + $(SLO)$/charthelper.obj \ $(SLO)$/chartarr.obj \ $(SLO)$/chartlis.obj \ $(SLO)$/chartlock.obj \ @@ -131,6 +133,7 @@ EXCEPTIONSFILES= \ $(SLO)$/prnsave.obj \ $(SLO)$/queryparam.obj \ $(SLO)$/reftokenhelper.obj \ + $(SLO)$/stringutil.obj \ $(SLO)$/token.obj # [kh] POWERPC compiler problem diff --git a/sc/source/core/tool/optutil.cxx b/sc/source/core/tool/optutil.cxx index 4de458f698da..dc63c7819eff 100644 --- a/sc/source/core/tool/optutil.cxx +++ b/sc/source/core/tool/optutil.cxx @@ -51,12 +51,12 @@ BOOL ScOptionsUtil::IsMetricSystem() //------------------------------------------------------------------ -ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString rSubTree ) : +ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString& rSubTree ) : ConfigItem( rSubTree ) { } -ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString rSubTree, sal_Int16 nMode ) : +ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString& rSubTree, sal_Int16 nMode ) : ConfigItem( rSubTree, nMode ) { } diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx index d0dd8ec9c163..1ab978866c67 100644 --- a/sc/source/core/tool/rangelst.cxx +++ b/sc/source/core/tool/rangelst.cxx @@ -41,7 +41,7 @@ #include "document.hxx" #include "refupdat.hxx" #include "rechead.hxx" - +#include "compiler.hxx" // === ScRangeList ==================================================== @@ -58,32 +58,14 @@ void ScRangeList::RemoveAll() Clear(); } -static void defaultDelimiter( char& cDelimiter, formula::FormulaGrammar::AddressConvention eConv) -{ - if( cDelimiter == 0) - { - switch( eConv ) - { - default : - case formula::FormulaGrammar::CONV_OOO : - cDelimiter = ';'; - break; - - case formula::FormulaGrammar::CONV_XL_A1 : - case formula::FormulaGrammar::CONV_XL_R1C1 : - cDelimiter = ','; - break; - } - } -} - USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask, formula::FormulaGrammar::AddressConvention eConv, - char cDelimiter ) + sal_Unicode cDelimiter ) { if ( rStr.Len() ) { - defaultDelimiter( cDelimiter, eConv); + if (!cDelimiter) + cDelimiter = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); nMask |= SCA_VALID; // falls das jemand vergessen sollte USHORT nResult = (USHORT)~0; // alle Bits setzen @@ -123,11 +105,12 @@ USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask, void ScRangeList::Format( String& rStr, USHORT nFlags, ScDocument* pDoc, formula::FormulaGrammar::AddressConvention eConv, - char cDelimiter ) const + sal_Unicode cDelimiter ) const { rStr.Erase(); - defaultDelimiter( cDelimiter, eConv); + if (!cDelimiter) + cDelimiter = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); ULONG nCnt = Count(); for ( ULONG nIdx = 0; nIdx < nCnt; nIdx++ ) @@ -246,6 +229,11 @@ BOOL ScRangeList::operator==( const ScRangeList& r ) const return TRUE; } +BOOL ScRangeList::operator!=( const ScRangeList& r ) const +{ + return !operator==( r ); +} + BOOL ScRangeList::UpdateReference( UpdateRefMode eUpdateRefMode, ScDocument* pDoc, const ScRange& rWhere, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 326fda49eb30..fbb859b64ebf 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -62,12 +62,17 @@ void ScMatrix::CreateMatrix(SCSIZE nC, SCSIZE nR) // nur fuer ctor mnNonValue = 0; } -ScMatrix::~ScMatrix() +void ScMatrix::Clear() { DeleteIsString(); delete [] pMat; } +ScMatrix::~ScMatrix() +{ + Clear(); +} + ScMatrix* ScMatrix::Clone() const { ScMatrix* pScMat = new ScMatrix( nColCount, nRowCount); @@ -76,6 +81,12 @@ ScMatrix* ScMatrix::Clone() const return pScMat; } +void ScMatrix::Resize( SCSIZE nC, SCSIZE nR) +{ + Clear(); + CreateMatrix(nC, nR); +} + ScMatrix* ScMatrix::CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows ) const { ScMatrix* pScMat = new ScMatrix( nNewCols, nNewRows); diff --git a/sc/source/core/tool/stringutil.cxx b/sc/source/core/tool/stringutil.cxx new file mode 100644 index 000000000000..28a4bc6755c2 --- /dev/null +++ b/sc/source/core/tool/stringutil.cxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: table.hxx,v $ + * $Revision: 1.35 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// System - Includes ----------------------------------------------------- + +#include "stringutil.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/math.hxx" + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +bool ScStringUtil::parseSimpleNumber( + const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal) +{ + if (gsep == 0x00A0) + // unicode space to ascii space + gsep = 0x0020; + + OUStringBuffer aBuf; + sal_Int32 n = rStr.getLength(); + const sal_Unicode* p = rStr.getStr(); + sal_Int32 nPosDSep = -1, nPosGSep = -1; + sal_uInt32 nDigitCount = 0; + + for (sal_Int32 i = 0; i < n; ++i) + { + sal_Unicode c = p[i]; + if (c == 0x00A0) + // unicode space to ascii space + c = 0x0020; + + if (sal_Unicode('0') <= c && c <= sal_Unicode('9')) + { + // this is a digit. + aBuf.append(c); + ++nDigitCount; + } + else if (c == dsep) + { + // this is a decimal separator. + + if (nPosDSep >= 0) + // a second decimal separator -> not a valid number. + return false; + + if (nPosGSep >= 0 && i - nPosGSep != 4) + // the number has a group separator and the decimal sep is not + // positioned correctly. + return false; + + nPosDSep = i; + nPosGSep = -1; + aBuf.append(c); + nDigitCount = 0; + } + else if (c == gsep) + { + // this is a group (thousand) separator. + + if (i == 0) + // not allowed as the first character. + return false; + + if (nPosDSep >= 0) + // not allowed after the decimal separator. + return false; + + if (nPosGSep >= 0 && nDigitCount != 3) + // must be exactly 3 digits since the last group separator. + return false; + + nPosGSep = i; + nDigitCount = 0; + } + else if (c == sal_Unicode('-') || c == sal_Unicode('+')) + { + // A sign must be the first character if it's given. + if (i == 0) + aBuf.append(c); + else + return false; + } + else + return false; + } + + // finished parsing the number. + + if (nPosGSep >= 0 && nDigitCount != 3) + // must be exactly 3 digits since the last group separator. + return false; + + rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; + sal_Int32 nParseEnd = 0; + rVal = ::rtl::math::stringToDouble(aBuf.makeStringAndClear(), dsep, gsep, &eStatus, &nParseEnd); + if (eStatus != rtl_math_ConversionStatus_Ok) + return false; + + return true; +} diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index b5e0f25f516c..bba1543dd403 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -200,8 +200,6 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) UINT16 nExcTabCount = rTabInfo.GetXclTabCount(); UINT16 nCodenames = static_cast< UINT16 >( GetExtDocOptions().GetCodeNameCount() ); - rR.pObjRecs = NULL; // per sheet - sal_uInt16 nWriteProtHash = 0; if( SfxObjectShell* pDocShell = GetDocShell() ) { @@ -416,7 +414,7 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) Add( new XclExpRecalcId ); // MSODRAWINGGROUP per-document data - Add( new XclMsodrawinggroup( rR, ESCHER_DggContainer ) ); + aRecList.AppendRecord( GetObjectManager().CreateDrawingGroup() ); // Shared string table: SST, EXTSST aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) ); @@ -438,9 +436,8 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx ) DBG_ASSERT( (mnScTab >= 0L) && (mnScTab <= MAXTAB), "-ExcTable::Table(): mnScTab - no ordinary table!" ); DBG_ASSERT( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" ); - if ( eBiff == EXC_BIFF8 ) - // list holding OBJ records and creating MSODRAWING per-sheet data - rR.pObjRecs = new XclObjList( GetRoot() ); + // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation) + GetObjectManager().StartSheet(); // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records mxCellTable.reset( new XclExpCellTable( GetRoot() ) ); @@ -512,13 +509,8 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx ) if( eBiff == EXC_BIFF8 ) { - rR.pEscher->AddSdrPage(); - //! close Escher group shape and ESCHER_DgContainer - //! opened by XclObjList ctor MSODRAWING - rR.pObjRecs->EndSheet(); // all MSODRAWING and OBJ stuff of this sheet goes here - Add( rR.pObjRecs ); - + aRecList.AppendRecord( GetObjectManager().ProcessDrawing( GetSdrPage( mnScTab ) ) ); // pivot tables aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) ); } @@ -590,12 +582,13 @@ void ExcTable::FillAsXmlTable( size_t nCodeNameIdx ) // label ranges Add( new XclExpLabelranges( GetRoot() ) ); - rR.pEscher->AddSdrPage(); - //! close Escher group shape and ESCHER_DgContainer - //! opened by XclObjList ctor MSODRAWING - rR.pObjRecs->EndSheet(); - // all MSODRAWING and OBJ stuff of this sheet goes here - Add( rR.pObjRecs ); + // DFF not needed in MSOOXML export +// GetObjectManager().AddSdrPage(); +// //! close Escher group shape and ESCHER_DgContainer +// //! opened by XclExpObjList ctor MSODRAWING +// rR.pObjRecs->EndSheet(); +// // all MSODRAWING and OBJ stuff of this sheet goes here +// Add( rR.pObjRecs ); // pivot tables aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) ); @@ -756,7 +749,7 @@ void ExcDocument::ReadDoc( void ) if ( GetBiff() == EXC_BIFF8 ) { // complete temporary Escher stream - GetOldRoot().pEscher->GetEx()->EndDocument(); + GetObjectManager().EndDocument(); // change tracking if ( GetDoc().GetChangeTrack() ) @@ -771,9 +764,6 @@ void ExcDocument::Write( SvStream& rSvStrm ) { InitializeSave(); - if ( GetBiff() == EXC_BIFF8 ) - GetOldRoot().pEscher->GetStrm().Seek(0); // ready for take off - XclExpStream aXclStrm( rSvStrm, GetRoot() ); aHeader.Write( aXclStrm ); @@ -807,8 +797,6 @@ void ExcDocument::WriteXml( SvStream& rStrm ) XclExpXmlStream aStrm( ::comphelper::getProcessServiceFactory(), rStrm, GetRoot() ); - GetOldRoot().pEscher->GetStrm().Seek(0); // ready for take off - sax_fastparser::FSHelperPtr& rWorkbook = aStrm.GetCurrentStream(); rWorkbook->startElement( XML_workbook, XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main", diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx index 5642c098027e..0652363e8822 100644 --- a/sc/source/filter/excel/excform.cxx +++ b/sc/source/filter/excel/excform.cxx @@ -471,10 +471,7 @@ ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, s aIn.Ignore( (meBiff == EXC_BIFF2) ? 3 : 4 ); if( bAllowArrays ) { - SCSIZE nC = nByte ? nByte : 256; - SCSIZE nR = nUINT16; - - aStack << aPool.StoreMatrix( nC, nR ); + aStack << aPool.StoreMatrix(); aExtensions.push_back( EXTENSION_ARRAY ); } else @@ -1892,6 +1889,7 @@ void ExcelToSc::ReadExtensionArray( unsigned int n, XclImpStream& aIn ) if( NULL != pMatrix ) { + pMatrix->Resize(nCols, nRows); pMatrix->GetDimensions( nC, nR); if( nC != nCols || nR != nRows ) { diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx index 608d65dfc801..148b1542913a 100644 --- a/sc/source/filter/excel/excform8.cxx +++ b/sc/source/filter/excel/excform8.cxx @@ -392,10 +392,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, aIn.Ignore( 4 ); if( bAllowArrays ) { - SCSIZE nC = nByte + 1; - SCSIZE nR = nUINT16 + 1; - - aStack << aPool.StoreMatrix( nC, nR ); + aStack << aPool.StoreMatrix(); aExtensions.push_back( EXTENSION_ARRAY ); } else diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx index d49c04624cdf..9a66325db419 100644 --- a/sc/source/filter/excel/excrecds.cxx +++ b/sc/source/filter/excel/excrecds.cxx @@ -88,6 +88,7 @@ #include "formula/errorcodes.hxx" #include "excdoc.hxx" +#include "xeescher.hxx" #include "xeformula.hxx" #include "xelink.hxx" #include "xename.hxx" @@ -976,8 +977,8 @@ void ExcAutoFilterRecs::AddObjRecs() ScAddress aAddr( pFilterInfo->GetStartPos() ); for( SCCOL nObj = 0, nCount = pFilterInfo->GetColCount(); nObj < nCount; nObj++ ) { - XclObjDropDown* pObj = new XclObjDropDown( GetRoot(), aAddr, IsFiltered( nObj ) ); - GetOldRoot().pObjRecs->Add( pObj ); + XclObj* pObjRec = new XclObjDropDown( GetObjectManager(), aAddr, IsFiltered( nObj ) ); + GetObjectManager().AddObj( pObjRec ); aAddr.IncCol( 1 ); } } diff --git a/sc/source/filter/excel/exctools.cxx b/sc/source/filter/excel/exctools.cxx index ba4a8339c829..e6453c2f11e2 100644 --- a/sc/source/filter/excel/exctools.cxx +++ b/sc/source/filter/excel/exctools.cxx @@ -76,9 +76,6 @@ RootData::RootData( void ) pTabId = NULL; pUserBViewList = NULL; - pObjRecs = NULL; - pEscher = NULL; - pIR = NULL; pER = NULL; } diff --git a/sc/source/filter/excel/expop2.cxx b/sc/source/filter/excel/expop2.cxx index d28fa2063c91..dbe70ae6a0ee 100644 --- a/sc/source/filter/excel/expop2.cxx +++ b/sc/source/filter/excel/expop2.cxx @@ -141,14 +141,11 @@ ExportBiff8::ExportBiff8( XclExpRootData& rExpData, SvStream& rStrm ) : ExportBiff5( rExpData, rStrm ) { pExcRoot->eDateiTyp = Biff8; - pExcRoot->pEscher = new XclEscher( GetRoot(), GetDoc().GetTableCount() ); } ExportBiff8::~ExportBiff8() { - delete pExcRoot->pEscher; - pExcRoot->pEscher = NULL; } @@ -159,16 +156,12 @@ ExportXml2007::ExportXml2007( XclExpRootData& rExpData, SvStream& rStrm ) pExcRoot = &GetOldRoot(); pExcRoot->pER = this; pExcRoot->eDateiTyp = Biff8; - pExcRoot->pEscher = new XclEscher( *pExcRoot->pER, GetDoc().GetTableCount() ); pExcDoc = new ExcDocument( *this ); } ExportXml2007::~ExportXml2007() { - delete pExcRoot->pEscher; - pExcRoot->pEscher = NULL; - delete pExcDoc; } diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx index dfb3a69c219a..e62f050f2351 100644 --- a/sc/source/filter/excel/impop.cxx +++ b/sc/source/filter/excel/impop.cxx @@ -1241,7 +1241,7 @@ void ImportExcel::PostDocLoad( void ) } // #111099# open forms in alive mode (has no effect, if no controls in document) - pDocObj->setPropertyValue( CREATE_OUSTRING( SC_UNO_APPLYFMDES ), ::comphelper::makeBoolAny( sal_False ) ); + pDocObj->setPropertyValue( CREATE_OUSTRING( SC_UNO_APPLYFMDES ), uno::Any( false ) ); } // enables extended options to be set to the view after import diff --git a/sc/source/filter/excel/makefile.mk b/sc/source/filter/excel/makefile.mk index 33a5babda815..04ba76d4a68a 100644 --- a/sc/source/filter/excel/makefile.mk +++ b/sc/source/filter/excel/makefile.mk @@ -151,6 +151,7 @@ EXCEPTIONSFILES = \ $(SLO)$/xlpivot.obj \ $(SLO)$/xlroot.obj \ $(SLO)$/xlstyle.obj \ + $(SLO)$/xltools.obj \ $(SLO)$/xlview.obj # --- Targets ------------------------------------------------------- diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 2f09f02f41a1..6b4ff0545c38 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -64,6 +64,8 @@ FltError ImportExcel::Read( void ) XclImpXFBuffer& rXFBfr = GetXFBuffer(); XclImpNameManager& rNameMgr = GetNameManager(); XclImpObjectManager& rObjMgr = GetObjectManager(); + (void)rObjMgr; + // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets) enum Zustand { Z_BiffNull, // Nicht in gueltigem Biff-Format @@ -246,7 +248,7 @@ FltError ImportExcel::Read( void ) case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break; case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345] case 0x18: rNameMgr.ReadName( maStrm ); break; - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break; case 0x20: Columndefault(); break; // COLUMNDEFAULT[ 2 ] @@ -309,7 +311,7 @@ FltError ImportExcel::Read( void ) case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345] case 0x1A: case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break; - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x1E: rNumFmtBfr.ReadFormat( maStrm ); break; case 0x22: Rec1904(); break; // 1904 [ 2345] @@ -328,7 +330,7 @@ FltError ImportExcel::Read( void ) case 0x41: rTabViewSett.ReadPane( maStrm ); break; case 0x42: Codepage(); break; // CODEPAGE [ 2345] case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] - case 0x5D: rObjMgr.ReadObj( maStrm ); break; + case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break; case 0x7D: Colinfo(); break; // COLINFO [ 345] case 0x8C: Country(); break; // COUNTRY [ 345] case 0x92: rPal.ReadPalette( maStrm ); break; @@ -380,7 +382,7 @@ FltError ImportExcel::Read( void ) case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345] case 0x1A: case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break; - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x22: Rec1904(); break; // 1904 [ 2345] case 0x26: @@ -399,7 +401,7 @@ FltError ImportExcel::Read( void ) case 0x42: Codepage(); break; // CODEPAGE [ 2345] case 0x55: DefColWidth(); break; case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] - case 0x5D: rObjMgr.ReadObj( maStrm ); break; + case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break; case 0x7D: Colinfo(); break; // COLINFO [ 345] case 0x8C: Country(); break; // COUNTRY [ 345] case 0x92: rPal.ReadPalette( maStrm ); break; @@ -496,7 +498,7 @@ FltError ImportExcel::Read( void ) case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break; case 0x1A: case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break; - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x2F: // FILEPASS [ 2345] eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm ); @@ -507,7 +509,7 @@ FltError ImportExcel::Read( void ) case 0x42: Codepage(); break; // CODEPAGE [ 2345] case 0x55: DefColWidth(); break; case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] - case 0x5D: rObjMgr.ReadObj( maStrm ); break; + case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break; case 0x7D: Colinfo(); break; // COLINFO [ 345] case 0x8C: Country(); break; // COUNTRY [ 345] case 0x8F: Bundleheader(); break; // BUNDLEHEADER [ 4 ] @@ -666,7 +668,7 @@ FltError ImportExcel::Read( void ) case 0x14: case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break; case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345] - case 0x1C: rObjMgr.ReadNote( maStrm ); break; + case 0x1C: GetCurrSheetDrawing().ReadNote( maStrm );break; case 0x1D: rTabViewSett.ReadSelection( maStrm ); break; case 0x23: Externname25(); break; // EXTERNNAME [ 2 5] case 0x26: @@ -680,7 +682,7 @@ FltError ImportExcel::Read( void ) if( eLastErr != ERRCODE_NONE ) eAkt = Z_Ende; break; - case 0x5D: rObjMgr.ReadObj( maStrm ); break; + case 0x5D: GetCurrSheetDrawing().ReadObj( maStrm );break; case 0x83: case 0x84: rPageSett.ReadCenter( maStrm ); break; case 0xA0: rTabViewSett.ReadScl( maStrm ); break; @@ -714,7 +716,7 @@ FltError ImportExcel::Read( void ) aIn.StoreGlobalPosition(); // und Position merken break; case Biff5C: // chart sheet - GetObjectManager().ReadTabChart( maStrm ); + GetCurrSheetDrawing().ReadTabChart( maStrm ); Eof(); GetTracer().TraceChartOnlySheet(); break; @@ -799,6 +801,7 @@ FltError ImportExcel8::Read( void ) XclImpNameManager& rNameMgr = GetNameManager(); XclImpLinkManager& rLinkMgr = GetLinkManager(); XclImpObjectManager& rObjMgr = GetObjectManager(); + // call to GetCurrSheetDrawing() cannot be cached (changes in new sheets) XclImpCondFormatManager& rCondFmtMgr = GetCondFormatManager(); XclImpPivotTableManager& rPTableMgr = GetPivotTableManager(); XclImpWebQueryBuffer& rWQBfr = GetWebQueryBuffer(); @@ -1040,7 +1043,7 @@ FltError ImportExcel8::Read( void ) aIn.StoreGlobalPosition(); break; case Biff8C: // chart sheet - rObjMgr.ReadTabChart( maStrm ); + GetCurrSheetDrawing().ReadTabChart( maStrm ); Eof(); GetTracer().TraceChartOnlySheet(); break; @@ -1161,10 +1164,10 @@ FltError ImportExcel8::Read( void ) case EXC_ID_SETUP: rPageSett.ReadSetup( maStrm ); break; case EXC_ID8_IMGDATA: rPageSett.ReadImgData( maStrm ); break; - case EXC_ID_MSODRAWING: rObjMgr.ReadMsoDrawing( maStrm ); break; + case EXC_ID_MSODRAWING: GetCurrSheetDrawing().ReadMsoDrawing( maStrm ); break; // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format - case EXC_ID_OBJ: rObjMgr.ReadObj( maStrm ); break; - case EXC_ID_NOTE: rObjMgr.ReadNote( maStrm ); break; + case EXC_ID_OBJ: GetCurrSheetDrawing().ReadObj( maStrm ); break; + case EXC_ID_NOTE: GetCurrSheetDrawing().ReadNote( maStrm ); break; case EXC_ID_HLINK: XclImpHyperlink::ReadHlink( maStrm ); break; case EXC_ID_LABELRANGES: XclImpLabelranges::ReadLabelranges( maStrm ); break; diff --git a/sc/source/filter/excel/tokstack.cxx b/sc/source/filter/excel/tokstack.cxx index 8685f404543a..b61a844d02a5 100644 --- a/sc/source/filter/excel/tokstack.cxx +++ b/sc/source/filter/excel/tokstack.cxx @@ -737,7 +737,7 @@ const TokenId TokenPool::StoreNlf( const ScSingleRefData& rTr ) return ( const TokenId ) nElementAkt; } -const TokenId TokenPool::StoreMatrix( SCSIZE nC, SCSIZE nR ) +const TokenId TokenPool::StoreMatrix() { ScMatrix* pM; @@ -750,8 +750,7 @@ const TokenId TokenPool::StoreMatrix( SCSIZE nC, SCSIZE nR ) pElement[ nElementAkt ] = nP_MatrixAkt; pType[ nElementAkt ] = T_Matrix; - pM = new ScMatrix( nC, nR ); - pM->FillDouble( 0., 0,0, nC-1, nR-1 ); + pM = new ScMatrix( 0, 0 ); pM->IncRef( ); ppP_Matrix[ nP_MatrixAkt ] = pM; diff --git a/sc/source/filter/excel/xechart.cxx b/sc/source/filter/excel/xechart.cxx index 637aacd4e722..1564b2db834e 100644 --- a/sc/source/filter/excel/xechart.cxx +++ b/sc/source/filter/excel/xechart.cxx @@ -33,6 +33,7 @@ #include <com/sun/star/i18n/XBreakIterator.hpp> #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/chart/ChartAxisLabelPosition.hpp> #include <com/sun/star/chart/ChartAxisPosition.hpp> #include <com/sun/star/chart/DataLabelPlacement.hpp> @@ -63,6 +64,7 @@ #include "compiler.hxx" #include "tokenarray.hxx" #include "token.hxx" +#include "xeescher.hxx" #include "xeformula.hxx" #include "xehelper.hxx" #include "xepage.hxx" @@ -77,6 +79,7 @@ using ::com::sun::star::uno::Exception; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::i18n::XBreakIterator; using ::com::sun::star::frame::XModel; +using ::com::sun::star::drawing::XShapes; using ::com::sun::star::chart2::XChartDocument; using ::com::sun::star::chart2::XDiagram; using ::com::sun::star::chart2::XCoordinateSystemContainer; @@ -97,7 +100,6 @@ using ::com::sun::star::chart2::XTitled; using ::com::sun::star::chart2::XTitle; using ::com::sun::star::chart2::XFormattedString; using ::com::sun::star::chart2::XColorScheme; - using ::com::sun::star::chart2::data::XDataSource; using ::com::sun::star::chart2::data::XLabeledDataSequence; using ::com::sun::star::chart2::data::XDataSequence; @@ -2766,6 +2768,15 @@ XclExpChAxesSet::XclExpChAxesSet( const XclExpChRoot& rRoot, sal_uInt16 nAxesSet { maData.mnAxesSetId = nAxesSetId; SetFutureRecordContext( 0, nAxesSetId ); + + /* Need to set a reasonable size for the plot area, otherwise Excel will + move away embedded shapes while auto-sizing the plot area. This is just + a wild guess, but will be fixed with implementing manual positioning of + chart elements. */ + maData.maRect.mnX = 262; + maData.maRect.mnY = 626; + maData.maRect.mnWidth = 3187; + maData.maRect.mnHeight = 2633; } sal_uInt16 XclExpChAxesSet::Convert( Reference< XDiagram > xDiagram, sal_uInt16 nFirstGroupIdx ) @@ -2904,6 +2915,14 @@ bool XclExpChAxesSet::Is3dChart() const void XclExpChAxesSet::WriteSubRecords( XclExpStream& rStrm ) { + /* Need to set a reasonable size for the plot area, otherwise Excel will + move away embedded shapes while auto-sizing the plot area. This is just + a wild guess, but will be fixed with implementing manual positioning of + chart elements. */ + rStrm.StartRecord( EXC_ID_CHFRAMEPOS, 20 ); + rStrm << sal_uInt16(2) << sal_uInt16(2) << sal_uInt32(66) << sal_uInt32(626) << sal_uInt32(3384) << sal_uInt32(3231); + rStrm.EndRecord(); + lclSaveRecord( rStrm, mxXAxis ); lclSaveRecord( rStrm, mxYAxis ); lclSaveRecord( rStrm, mxZAxis ); @@ -2965,8 +2984,8 @@ XclExpChChart::XclExpChChart( const XclExpRoot& rRoot, maRect.mnHeight = static_cast< sal_Int32 >( aPtSize.Height() << 16 ); // global chart properties (default values) - ::set_flag( maProps.mnFlags, EXC_CHPROPS_MANSERIES ); ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, false ); + ::set_flag( maProps.mnFlags, EXC_CHPROPS_MANPLOTAREA ); maProps.mnEmptyMode = EXC_CHPROPS_EMPTY_SKIP; // always create both axes set objects @@ -3073,12 +3092,49 @@ void XclExpChChart::WriteBody( XclExpStream& rStrm ) // ---------------------------------------------------------------------------- +XclExpChartDrawing::XclExpChartDrawing( const XclExpRoot& rRoot, + const Reference< XModel >& rxModel, const Size& rChartSize ) : + XclExpRoot( rRoot ) +{ + if( (rChartSize.Width() > 0) && (rChartSize.Height() > 0) ) + { + ScfPropertySet aPropSet( rxModel ); + Reference< XShapes > xShapes; + if( aPropSet.GetProperty( xShapes, EXC_CHPROP_ADDITIONALSHAPES ) && xShapes.is() && (xShapes->getCount() > 0) ) + { + /* Create a new independent object manager with own DFF stream for the + DGCONTAINER, pass global manager as parent for shared usage of + global DFF data (picture container etc.). */ + mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_UNIT, EXC_CHART_UNIT ) ); + // initialize the drawing object list + mxObjMgr->StartSheet(); + // process the draw page (convert all shapes) + mxObjRecs = mxObjMgr->ProcessDrawing( xShapes ); + // finalize the DFF stream + mxObjMgr->EndDocument(); + } + } +} + +XclExpChartDrawing::~XclExpChartDrawing() +{ +} + +void XclExpChartDrawing::Save( XclExpStream& rStrm ) +{ + if( mxObjRecs.is() ) + mxObjRecs->Save( rStrm ); +} + +// ---------------------------------------------------------------------------- + XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Size& rSize ) : XclExpSubStream( EXC_BOF_CHART ), XclExpRoot( rRoot ) { AppendNewRecord( new XclExpChartPageSettings( rRoot ) ); AppendNewRecord( new XclExpBoolRecord( EXC_ID_PROTECT, false ) ); + AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rSize ) ); AppendNewRecord( new XclExpUInt16Record( EXC_ID_CHUNITS, EXC_CHUNITS_TWIPS ) ); Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY ); diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx index 1f46bdb66178..2df531a9b932 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -28,9 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" -#include <set> -#include <iterator> - #include "xeescher.hxx" #include <com/sun/star/lang/XServiceInfo.hpp> @@ -45,12 +42,15 @@ #include <com/sun/star/form/binding/XListEntrySource.hpp> #include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <set> #include <rtl/ustrbuf.h> #include <vcl/bmpacc.hxx> #include <svx/svdoole2.hxx> #include <svx/svdocapt.hxx> #include <editeng/outlobj.hxx> #include <editeng/editobj.hxx> +#include <unotools/tempfile.hxx> +#include <unotools/ucbstreamhelper.hxx> #include "editutil.hxx" #include "unonames.hxx" @@ -75,6 +75,7 @@ using ::com::sun::star::uno::Sequence; using ::com::sun::star::lang::XServiceInfo; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::drawing::XShape; +using ::com::sun::star::drawing::XShapes; using ::com::sun::star::frame::XModel; using ::com::sun::star::embed::XEmbeddedObject; using ::com::sun::star::awt::XControlModel; @@ -86,6 +87,163 @@ using ::com::sun::star::script::ScriptEventDescriptor; using ::com::sun::star::table::CellAddress; using ::com::sun::star::table::CellRangeAddress; +// Escher client anchor ======================================================= + +XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags ) : + XclExpRoot( rRoot ), + mnFlags( nFlags ) +{ +} + +void XclExpDffAnchorBase::SetFlags( const SdrObject& rSdrObj ) +{ + ImplSetFlags( rSdrObj ); +} + +void XclExpDffAnchorBase::SetSdrObject( const SdrObject& rSdrObj ) +{ + ImplSetFlags( rSdrObj ); + ImplCalcAnchorRect( rSdrObj.GetCurrentBoundRect(), MAP_100TH_MM ); +} + +void XclExpDffAnchorBase::WriteDffData( EscherEx& rEscherEx ) const +{ + rEscherEx.AddAtom( 18, ESCHER_ClientAnchor ); + rEscherEx.GetStream() << mnFlags << maAnchor; +} + +void XclExpDffAnchorBase::WriteData( EscherEx& rEscherEx, const Rectangle& rRect ) +{ + // the passed rectangle is in twips + ImplCalcAnchorRect( rRect, MAP_TWIP ); + WriteDffData( rEscherEx ); +} + +void XclExpDffAnchorBase::ImplSetFlags( const SdrObject& ) +{ + OSL_ENSURE( false, "XclExpDffAnchorBase::ImplSetFlags - not implemented" ); +} + +void XclExpDffAnchorBase::ImplCalcAnchorRect( const Rectangle&, MapUnit ) +{ + OSL_ENSURE( false, "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" ); +} + +// ---------------------------------------------------------------------------- + +XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot& rRoot ) : + XclExpDffAnchorBase( rRoot ), + mnScTab( rRoot.GetCurrScTab() ) +{ +} + +void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject& rSdrObj ) +{ + // Special case "page anchor" (X==0,Y==1) -> lock pos and size. + const Point& rPos = rSdrObj.GetAnchorPos(); + mnFlags = ((rPos.X() == 0) && (rPos.Y() == 1)) ? EXC_ESC_ANCHOR_LOCKED : 0; +} + +void XclExpDffSheetAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ) +{ + maAnchor.SetRect( GetDoc(), mnScTab, rRect, eMapUnit ); +} + +// ---------------------------------------------------------------------------- + +XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot, + const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) : + XclExpDffAnchorBase( rRoot ), + maPageSize( rPageSize ), + mnScaleX( nScaleX ), + mnScaleY( nScaleY ) +{ +} + +void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject& /*rSdrObj*/ ) +{ + // TODO (unsupported feature): fixed size +} + +void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ) +{ + maAnchor.SetRect( maPageSize, mnScaleX, mnScaleY, rRect, eMapUnit, true ); +} + +// ---------------------------------------------------------------------------- + +XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ) : + XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_SIZELOCKED ) +{ + maAnchor.SetRect( GetDoc(), rRoot.GetCurrScTab(), rRect, MAP_100TH_MM ); +} + +// ---------------------------------------------------------------------------- + +XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ) : + XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_POSLOCKED ) +{ + GetAddressConverter().ConvertAddress( maAnchor.maFirst, rScPos, true ); + maAnchor.maLast.mnCol = maAnchor.maFirst.mnCol + 1; + maAnchor.maLast.mnRow = maAnchor.maFirst.mnRow + 1; + maAnchor.mnLX = maAnchor.mnTY = maAnchor.mnRX = maAnchor.mnBY = 0; +} + +// MSODRAWING* records ======================================================== + +XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId ) : + XclExpRecord( nRecId ), + mrEscherEx( rEscherEx ), + mnFragmentKey( rEscherEx.InitNextDffFragment() ) +{ +} + +void XclExpMsoDrawingBase::WriteBody( XclExpStream& rStrm ) +{ + OSL_ENSURE( mrEscherEx.GetStreamPos() == mrEscherEx.GetDffFragmentPos( mnFragmentKey ), + "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" ); + rStrm.CopyFromStream( mrEscherEx.GetStream(), mrEscherEx.GetDffFragmentSize( mnFragmentKey ) ); +} + +// ---------------------------------------------------------------------------- + +XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx& rEscherEx ) : + XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWINGGROUP ) +{ + SvStream& rDffStrm = mrEscherEx.GetStream(); + + // write the DGGCONTAINER with some default settings + mrEscherEx.OpenContainer( ESCHER_DggContainer ); + + // TODO: stuff the OPT atom with our own document defaults? + static const sal_uInt8 spnDffOpt[] = { + 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01, + 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00, + 0x00, 0x08 + }; + mrEscherEx.AddAtom( sizeof( spnDffOpt ), ESCHER_OPT, 3, 3 ); + rDffStrm.Write( spnDffOpt, sizeof( spnDffOpt ) ); + + // SPLITMENUCOLORS contains colors in toolbar + static const sal_uInt8 spnDffSplitMenuColors[] = { + 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08, + 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10 + }; + mrEscherEx.AddAtom( sizeof( spnDffSplitMenuColors ), ESCHER_SplitMenuColors, 0, 4 ); + rDffStrm.Write( spnDffSplitMenuColors, sizeof( spnDffSplitMenuColors ) ); + + // close the DGGCONTAINER + mrEscherEx.CloseContainer(); + mrEscherEx.UpdateDffFragmentEnd(); +} + +// ---------------------------------------------------------------------------- + +XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx& rEscherEx ) : + XclExpMsoDrawingBase( rEscherEx, EXC_ID_MSODRAWING ) +{ +} + // ============================================================================ XclExpImgData::XclExpImgData( const Graphic& rGraphic, sal_uInt16 nRecId ) : @@ -221,10 +379,10 @@ void XclExpControlHelper::WriteFormulaSubRec( XclExpStream& rStrm, sal_uInt16 nS #if EXC_EXP_OCX_CTRL -XclExpOcxControlObj::XclExpOcxControlObj( const XclExpRoot& rRoot, Reference< XShape > xShape, - const String& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ) : - XclObj( rRoot, EXC_OBJTYPE_PICTURE, true ), - XclExpControlHelper( rRoot ), +XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, + const Rectangle* pChildAnchor, const String& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ) : + XclObj( rObjMgr, EXC_OBJTYPE_PICTURE, true ), + XclExpControlHelper( rObjMgr.GetRoot() ), maClassName( rClassName ), mnStrmStart( nStrmStart ), mnStrmSize( nStrmSize ) @@ -238,11 +396,10 @@ XclExpOcxControlObj::XclExpOcxControlObj( const XclExpRoot& rRoot, Reference< XS SetAutoLine( FALSE ); // fill DFF property set - XclEscherEx& rEscherEx = *pMsodrawing->GetEscherEx(); - rEscherEx.OpenContainer( ESCHER_SpContainer ); - rEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVESPT | SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_OLESHAPE ); Rectangle aDummyRect; - EscherPropertyContainer aPropOpt( rEscherEx, rEscherEx.QueryPicStream(), aDummyRect ); + EscherPropertyContainer aPropOpt( mrEscherEx, mrEscherEx.QueryPicStream(), aDummyRect ); aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x08000040 ); aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field @@ -263,15 +420,14 @@ XclExpOcxControlObj::XclExpOcxControlObj( const XclExpRoot& rRoot, Reference< XS } // write DFF property set to stream - aPropOpt.Commit( rEscherEx.GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); // anchor - if( SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape ) ) - XclExpDffAnchor( rRoot, *pSdrObj ).WriteData( rEscherEx ); - rEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record - rEscherEx.CloseContainer(); // ESCHER_SpContainer + ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor ); - pMsodrawing->UpdateStopPos(); + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record + mrEscherEx.CloseContainer(); // ESCHER_SpContainer + mrEscherEx.UpdateDffFragmentEnd(); // spreadsheet links ConvertSheetLinks( xShape ); @@ -328,9 +484,9 @@ void XclExpOcxControlObj::WriteSubRecs( XclExpStream& rStrm ) #else -XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XShape > xShape ) : - XclObj( rRoot, EXC_OBJTYPE_UNKNOWN, true ), - XclExpControlHelper( rRoot ), +XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, const Rectangle* pChildAnchor ) : + XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN, true ), + XclExpControlHelper( rObjMgr.GetRoot() ), mnHeight( 0 ), mnState( 0 ), mnLineCount( 0 ), @@ -384,9 +540,8 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS SetAutoLine( FALSE ); // fill DFF property set - XclEscherEx& rEscherEx = *pMsodrawing->GetEscherEx(); - rEscherEx.OpenContainer( ESCHER_SpContainer ); - rEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); EscherPropertyContainer aPropOpt; bool bVisible = aCtrlProp.GetBoolProperty( CREATE_OUSTRING( "EnableVisible" ) ); aPropOpt.AddOpt( ESCHER_Prop_fPrint, bVisible ? 0x00080000 : 0x00080002 ); // visible flag @@ -404,13 +559,13 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS aPropOpt.AddOpt( ESCHER_Prop_wzName, aCtrlName ); // write DFF property set to stream - aPropOpt.Commit( rEscherEx.GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); // anchor - if( SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape ) ) - XclExpDffAnchor( rRoot, *pSdrObj ).WriteData( rEscherEx ); - rEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record - pMsodrawing->UpdateStopPos(); + ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape ), pChildAnchor ); + + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record + mrEscherEx.UpdateDffFragmentEnd(); // control label OUString aString; @@ -419,9 +574,9 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS /* Be sure to construct the MSODRAWING record containing the ClientTextbox atom after the base OBJ's MSODRAWING record data is completed. */ - pClientTextbox = new XclMsodrawing( GetRoot() ); - pClientTextbox->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox ); // TXO record - pClientTextbox->UpdateStopPos(); + pClientTextbox = new XclExpMsoDrawing( mrEscherEx ); + mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record + mrEscherEx.UpdateDffFragmentEnd(); sal_uInt16 nXclFont = EXC_FONT_APP; if( aString.getLength() > 0 ) @@ -437,7 +592,7 @@ XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot& rRoot, Reference< XS pTxo->SetVerAlign( EXC_OBJ_VER_CENTER ); } - rEscherEx.CloseContainer(); // ESCHER_SpContainer + mrEscherEx.CloseContainer(); // ESCHER_SpContainer // other properties aCtrlProp.GetProperty( mnLineCount, CREATE_OUSTRING( "LineCount" ) ); @@ -763,14 +918,13 @@ void XclExpTbxControlObj::WriteSbs( XclExpStream& rStrm ) // ---------------------------------------------------------------------------- -XclExpChartObj::XclExpChartObj( const XclExpRoot& rRoot, Reference< XShape > xShape ) : - XclObj( rRoot, EXC_OBJTYPE_CHART ), - XclExpRoot( rRoot ) +XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< XShape > xShape, const Rectangle* pChildAnchor ) : + XclObj( rObjMgr, EXC_OBJTYPE_CHART ), + XclExpRoot( rObjMgr.GetRoot() ) { // create the MSODRAWING record contents for the chart object - XclEscherEx& rEscherEx = *pMsodrawing->GetEscherEx(); - rEscherEx.OpenContainer( ESCHER_SpContainer ); - rEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); EscherPropertyContainer aPropOpt; aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); @@ -781,17 +935,16 @@ XclExpChartObj::XclExpChartObj( const XclExpRoot& rRoot, Reference< XShape > xSh aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080008 ); aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00020000 ); aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080000 ); - aPropOpt.Commit( rEscherEx.GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); - // client anchor + // anchor SdrObject* pSdrObj = SdrObject::getSdrObjectFromXShape( xShape ); - if( pSdrObj ) - XclExpDffAnchor( rRoot, *pSdrObj ).WriteData( rEscherEx ); + ImplWriteAnchor( GetRoot(), pSdrObj, pChildAnchor ); // client data (the following OBJ record) - rEscherEx.AddAtom( 0, ESCHER_ClientData ); - rEscherEx.CloseContainer(); // ESCHER_SpContainer - pMsodrawing->UpdateStopPos(); + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); + mrEscherEx.CloseContainer(); // ESCHER_SpContainer + mrEscherEx.UpdateDffFragmentEnd(); // load the chart OLE object if( SdrOle2Obj* pSdrOleObj = dynamic_cast< SdrOle2Obj* >( pSdrObj ) ) @@ -804,7 +957,7 @@ XclExpChartObj::XclExpChartObj( const XclExpRoot& rRoot, Reference< XShape > xSh ::com::sun::star::awt::Rectangle aBoundRect; aShapeProp.GetProperty( aBoundRect, CREATE_OUSTRING( "BoundRect" ) ); Size aSize( aBoundRect.Width, aBoundRect.Height ); - mxChart.reset( new XclExpChart( rRoot, xModel, aSize ) ); + mxChart.reset( new XclExpChart( GetRoot(), xModel, aSize ) ); } XclExpChartObj::~XclExpChartObj() @@ -849,7 +1002,7 @@ XclExpNote::XclExpNote( const XclExpRoot& rRoot, const ScAddress& rScPos, if( pScNote ) if( SdrCaptionObj* pCaption = pScNote->GetOrCreateCaption( maScPos ) ) if( const OutlinerParaObject* pOPO = pCaption->GetOutlinerParaObject() ) - mnObjId = rRoot.GetOldRoot().pObjRecs->Add( new XclObjComment( rRoot, pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible ) ); + mnObjId = rRoot.GetObjectManager().AddObj( new XclObjComment( rRoot.GetObjectManager(), pCaption->GetLogicRect(), pOPO->GetTextObject(), pCaption, mbVisible ) ); SetRecSize( 9 + maAuthor.GetSize() ); } @@ -1007,5 +1160,125 @@ void XclExpComments::SaveXml( XclExpXmlStream& rStrm ) rStrm.PopStream(); } +// object manager ============================================================= + +XclExpObjectManager::XclExpObjectManager( const XclExpRoot& rRoot ) : + XclExpRoot( rRoot ) +{ + InitStream( true ); + mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm ) ); +} + +XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager& rParent ) : + XclExpRoot( rParent.GetRoot() ) +{ + InitStream( false ); + mxEscherEx.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm, rParent.mxEscherEx.get() ) ); +} + +XclExpObjectManager::~XclExpObjectManager() +{ +} + +XclExpDffAnchorBase* XclExpObjectManager::CreateDffAnchor() const +{ + return new XclExpDffSheetAnchor( GetRoot() ); +} + +ScfRef< XclExpRecordBase > XclExpObjectManager::CreateDrawingGroup() +{ + return ScfRef< XclExpRecordBase >( new XclExpMsoDrawingGroup( *mxEscherEx ) ); +} + +void XclExpObjectManager::StartSheet() +{ + mxObjList.reset( new XclExpObjList( GetRoot(), *mxEscherEx ) ); +} + +ScfRef< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( SdrPage* pSdrPage ) +{ + if( pSdrPage ) + mxEscherEx->AddSdrPage( *pSdrPage ); + // #106213# the first dummy object may still be open + DBG_ASSERT( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" ); + while( mxEscherEx->GetGroupLevel() ) + mxEscherEx->LeaveGroup(); + mxObjList->EndSheet(); + return mxObjList; +} + +ScfRef< XclExpRecordBase > XclExpObjectManager::ProcessDrawing( const Reference< XShapes >& rxShapes ) +{ + if( rxShapes.is() ) + mxEscherEx->AddUnoShapes( rxShapes ); + // #106213# the first dummy object may still be open + DBG_ASSERT( mxEscherEx->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" ); + while( mxEscherEx->GetGroupLevel() ) + mxEscherEx->LeaveGroup(); + mxObjList->EndSheet(); + return mxObjList; +} + +void XclExpObjectManager::EndDocument() +{ + mxEscherEx->EndDocument(); +} + +XclExpMsoDrawing* XclExpObjectManager::GetMsodrawingPerSheet() +{ + return mxObjList->GetMsodrawingPerSheet(); +} + +bool XclExpObjectManager::HasObj() const +{ + return mxObjList->Count() > 0; +} + +sal_uInt16 XclExpObjectManager::AddObj( XclObj* pObjRec ) +{ + return mxObjList->Add( pObjRec ); +} + +XclObj* XclExpObjectManager::RemoveLastObj() +{ + XclObj* pLastObj = static_cast< XclObj* >( mxObjList->Last() ); + mxObjList->Remove(); // remove current, which is the Last() + return pLastObj; +} + +void XclExpObjectManager::InitStream( bool bTempFile ) +{ + if( bTempFile ) + { + mxTempFile.reset( new ::utl::TempFile ); + if( mxTempFile->IsValid() ) + { + mxTempFile->EnableKillingFile(); + mxDffStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxTempFile->GetURL(), STREAM_STD_READWRITE ) ); + } + } + + if( !mxDffStrm.get() ) + mxDffStrm.reset( new SvMemoryStream ); + + mxDffStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); +} + +// ---------------------------------------------------------------------------- + +XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager( + const XclExpObjectManager& rParent, const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ) : + XclExpObjectManager( rParent ), + maPageSize( rPageSize ), + mnScaleX( nScaleX ), + mnScaleY( nScaleY ) +{ +} + +XclExpDffAnchorBase* XclExpEmbeddedObjectManager::CreateDffAnchor() const +{ + return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize, mnScaleX, mnScaleY ); +} + // ============================================================================ diff --git a/sc/source/filter/excel/xelink.cxx b/sc/source/filter/excel/xelink.cxx index 421a15b6da95..fcf738527025 100644 --- a/sc/source/filter/excel/xelink.cxx +++ b/sc/source/filter/excel/xelink.cxx @@ -43,7 +43,8 @@ using ::std::auto_ptr; using ::std::find_if; using ::std::vector; -using namespace formula; +using ::rtl::OUString; +using ::com::sun::star::uno::Any; // ============================================================================ // *** Helper classes *** @@ -166,105 +167,59 @@ private: // Cached external cells ====================================================== -/** Base class to store the contents of one external cell (record CRN). */ +/** Stores the contents of a consecutive row of external cells (record CRN). */ class XclExpCrn : public XclExpRecord { -protected: - /** @param nAddSize The size of additional data derived classes will write. */ - explicit XclExpCrn( SCCOL nScCol, SCROW nScRow, sal_uInt8 nId, sal_uInt32 nAddLen = 0 ); - -private: - /** Writes the start of the record that is equal in all CRN records and calls WriteAddData(). */ - virtual void WriteBody( XclExpStream& rStrm ); - - /** Called to write additional data following the common record contents. - @descr Derived classes should overwrite this function to write their data. */ - virtual void WriteAddData( XclExpStream& rStrm ) = 0; - -private: - sal_uInt16 mnXclCol; /// Column index of the external cell. - sal_uInt16 mnXclRow; /// Row index of the external cell. - sal_uInt8 mnId; /// Identifier for data type (EXC_CACHEDVAL_***). -}; - -// ---------------------------------------------------------------------------- - -/** Cached data of an external value cell. */ -class XclExpCrnDouble : public XclExpCrn -{ public: - explicit XclExpCrnDouble( SCCOL nScCol, SCROW nScRow, double fVal ); + explicit XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue ); -private: - /** Writes the double value following the common record contents. */ - virtual void WriteAddData( XclExpStream& rStrm ); + /** Returns true, if the passed value could be appended to this record. */ + bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue ); private: - double mfVal; /// Value of the cached cell. -}; - -// ---------------------------------------------------------------------------- + virtual void WriteBody( XclExpStream& rStrm ); -/** Cached data of an external text cell. */ -class XclExpCrnString : public XclExpCrn -{ -public: - explicit XclExpCrnString( SCCOL nScCol, SCROW nScRow, const String& rText ); + void WriteBool( XclExpStream& rStrm, bool bValue ); + void WriteDouble( XclExpStream& rStrm, double fValue ); + void WriteString( XclExpStream& rStrm, const OUString& rValue ); + void WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode ); + void WriteEmpty( XclExpStream& rStrm ); private: - /** Writes the string following the common record contents. */ - virtual void WriteAddData( XclExpStream& rStrm ); + typedef ::std::vector< Any > CachedValues; -private: - XclExpString maText; /// Text of the cached cell. + CachedValues maValues; /// All cached values. + SCCOL mnScCol; /// Column index of the first external cell. + SCROW mnScRow; /// Row index of the external cells. }; // ---------------------------------------------------------------------------- -/// Cached data of an external Boolean cell. */ -class XclExpCrnBool : public XclExpCrn -{ -public: - explicit XclExpCrnBool( SCCOL nScCol, SCROW nScRow, bool bBoolVal ); - -private: - /** Writes the Boolean value following the common record contents. */ - virtual void WriteAddData( XclExpStream& rStrm ); - -private: - sal_uInt16 mnBool; /// Boolean value of the cached cell. -}; - -// Cached cells of a sheet ==================================================== - -/// Represents the record XCT which is the header record of a CRN record list. */ -class XclExpXct : public XclExpRecord +/** Represents the record XCT which is the header record of a CRN record list. + */ +class XclExpXct : public XclExpRecordBase, protected XclExpRoot { public: - explicit XclExpXct( const String& rTabName, sal_uInt16 nSBTab ); + explicit XclExpXct( const XclExpRoot& rRoot, + const String& rTabName, sal_uInt16 nSBTab, + ScExternalRefCache::TableTypeRef xCacheTable ); /** Returns the external sheet name. */ inline const XclExpString& GetTabName() const { return maTabName; } /** Stores all cells in the given range in the CRN list. */ - void StoreCellRange( const XclExpRoot& rRoot, const ScRange& rRange ); + void StoreCellRange( const ScRange& rRange ); - void StoreCell( const XclExpRoot& rRoot, const ScAddress& rCell, const formula::FormulaToken& rToken ); - void StoreCellRange( const XclExpRoot& rRoot, const ScRange& rRange, const formula::FormulaToken& rToken ); + void StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken ); + void StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken ); /** Writes the XCT and all CRN records. */ virtual void Save( XclExpStream& rStrm ); private: - /** Writes the XCT record contents. */ - virtual void WriteBody( XclExpStream& rStrm ); - -private: - typedef XclExpRecordList< XclExpCrn > XclExpCrnList; - typedef XclExpCrnList::RecordRefType XclExpCrnRef; - - XclExpCrnList maCrnList; /// CRN records that follow this record. + ScExternalRefCache::TableTypeRef mxCacheTable; ScMarkData maUsedCells; /// Contains addresses of all stored cells. + ScRange maBoundRange; /// Bounding box of maUsedCells. XclExpString maTabName; /// Sheet name of the external sheet. sal_uInt16 mnSBTab; /// Referred sheet index in SUPBOOK record. }; @@ -353,14 +308,14 @@ public: /** Stores all cells in the given range in the CRN list of the specified SUPBOOK sheet. */ void StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab ); - void StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const formula::FormulaToken& rToken ); - void StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const formula::FormulaToken& rToken ); + void StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const ::formula::FormulaToken& rToken ); + void StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const ::formula::FormulaToken& rToken ); sal_uInt16 GetTabIndex( const String& rTabName ) const; sal_uInt16 GetTabCount() const; /** Inserts a new sheet name into the SUPBOOK and returns the SUPBOOK internal sheet index. */ - sal_uInt16 InsertTabName( const String& rTabName ); + sal_uInt16 InsertTabName( const String& rTabName, ScExternalRefCache::TableTypeRef xCacheTable ); /** Finds or inserts an EXTERNNAME record for add-ins. @return The 1-based EXTERNNAME record index; or 0, if the record list is full. */ sal_uInt16 InsertAddIn( const String& rName ); @@ -1006,6 +961,7 @@ void XclExpExtName::WriteAddData( XclExpStream& rStrm ) // range address. Excel just writes '02 00 1C 17' for all the other types // of external names. + using namespace ::formula; do { if (mpArray->GetLen() != 1) @@ -1162,209 +1118,200 @@ sal_uInt16 XclExpExtNameBuffer::AppendNew( XclExpExtNameBase* pExtName ) // Cached external cells ====================================================== -XclExpCrn::XclExpCrn( SCCOL nScCol, SCROW nScRow, sal_uInt8 nId, sal_uInt32 nAddLen ) : - XclExpRecord( EXC_ID_CRN, 5 + nAddLen ), - mnXclCol( static_cast< sal_uInt16 >( nScCol ) ), - mnXclRow( static_cast< sal_uInt16 >( nScRow ) ), - mnId( nId ) +XclExpCrn::XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue ) : + XclExpRecord( EXC_ID_CRN, 4 ), + mnScCol( nScCol ), + mnScRow( nScRow ) { + maValues.push_back( rValue ); } -void XclExpCrn::WriteBody( XclExpStream& rStrm ) +bool XclExpCrn::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue ) { - rStrm << static_cast< sal_uInt8 >( mnXclCol ) - << static_cast< sal_uInt8 >( mnXclCol ) - << mnXclRow - << mnId; - WriteAddData( rStrm ); + if( (nScRow != mnScRow) || (nScCol != static_cast< SCCOL >( mnScCol + maValues.size() )) ) + return false; + maValues.push_back( rValue ); + return true; } -// ---------------------------------------------------------------------------- - -XclExpCrnDouble::XclExpCrnDouble( SCCOL nScCol, SCROW nScRow, double fVal ) : - XclExpCrn( nScCol, nScRow, EXC_CACHEDVAL_DOUBLE, 8 ), - mfVal( fVal ) +void XclExpCrn::WriteBody( XclExpStream& rStrm ) { + rStrm << static_cast< sal_uInt8 >( mnScCol + maValues.size() - 1 ) + << static_cast< sal_uInt8 >( mnScCol ) + << static_cast< sal_uInt16 >( mnScRow ); + for( CachedValues::iterator aIt = maValues.begin(), aEnd = maValues.end(); aIt != aEnd; ++aIt ) + { + if( aIt->has< bool >() ) + WriteBool( rStrm, aIt->get< bool >() ); + else if( aIt->has< double >() ) + WriteDouble( rStrm, aIt->get< double >() ); + else if( aIt->has< OUString >() ) + WriteString( rStrm, aIt->get< OUString >() ); + else + WriteEmpty( rStrm ); + } } -void XclExpCrnDouble::WriteAddData( XclExpStream& rStrm ) +void XclExpCrn::WriteBool( XclExpStream& rStrm, bool bValue ) { - rStrm << mfVal; + rStrm << EXC_CACHEDVAL_BOOL << sal_uInt8( bValue ? 1 : 0); + rStrm.WriteZeroBytes( 7 ); } -// ---------------------------------------------------------------------------- - -XclExpCrnString::XclExpCrnString( SCCOL nScCol, SCROW nScRow, const String& rText ) : - XclExpCrn( nScCol, nScRow, EXC_CACHEDVAL_STRING ), - maText( rText ) +void XclExpCrn::WriteDouble( XclExpStream& rStrm, double fValue ) { - // set correct size after maText is initialized - AddRecSize( maText.GetSize() ); + if( ::rtl::math::isNan( fValue ) ) + { + USHORT nScError = static_cast< USHORT >( reinterpret_cast< const sal_math_Double* >( &fValue )->nan_parts.fraction_lo ); + WriteError( rStrm, XclTools::GetXclErrorCode( nScError ) ); + } + else + { + rStrm << EXC_CACHEDVAL_DOUBLE << fValue; + } } -void XclExpCrnString::WriteAddData( XclExpStream& rStrm ) +void XclExpCrn::WriteString( XclExpStream& rStrm, const OUString& rValue ) { - rStrm << maText; + rStrm << EXC_CACHEDVAL_STRING << XclExpString( rValue ); } -// ---------------------------------------------------------------------------- - -XclExpCrnBool::XclExpCrnBool( SCCOL nScCol, SCROW nScRow, bool bBoolVal ) : - XclExpCrn( nScCol, nScRow, EXC_CACHEDVAL_BOOL, 8 ), - mnBool( bBoolVal ? 1 : 0 ) +void XclExpCrn::WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode ) { + rStrm << EXC_CACHEDVAL_ERROR << nErrCode; + rStrm.WriteZeroBytes( 7 ); } -void XclExpCrnBool::WriteAddData( XclExpStream& rStrm ) +void XclExpCrn::WriteEmpty( XclExpStream& rStrm ) { - rStrm << mnBool; - rStrm.WriteZeroBytes( 6 ); + rStrm << EXC_CACHEDVAL_EMPTY; + rStrm.WriteZeroBytes( 8 ); } // Cached cells of a sheet ==================================================== -XclExpXct::XclExpXct( const String& rTabName, sal_uInt16 nSBTab ) : - XclExpRecord( EXC_ID_XCT, 4 ), +XclExpXct::XclExpXct( const XclExpRoot& rRoot, const String& rTabName, + sal_uInt16 nSBTab, ScExternalRefCache::TableTypeRef xCacheTable ) : + XclExpRoot( rRoot ), + mxCacheTable( xCacheTable ), + maBoundRange( ScAddress::INITIALIZE_INVALID ), maTabName( rTabName ), mnSBTab( nSBTab ) { } -void XclExpXct::StoreCellRange( const XclExpRoot& rRoot, const ScRange& rRange ) +void XclExpXct::StoreCellRange( const ScRange& rRange ) { // #i70418# restrict size of external range to prevent memory overflow if( (rRange.aEnd.Col() - rRange.aStart.Col()) * (rRange.aEnd.Row() - rRange.aStart.Row()) > 1024 ) return; - ScDocument& rDoc = rRoot.GetDoc(); - SvNumberFormatter& rFormatter = rRoot.GetFormatter(); - SCTAB nScTab = rRange.aStart.Tab(); - SCCOL nScLastCol = rRange.aEnd.Col(); - SCROW nScLastRow = rRange.aEnd.Row(); + maUsedCells.SetMultiMarkArea( rRange ); + maBoundRange.ExtendTo( rRange ); +} - for( SCROW nScRow = rRange.aStart.Row(); nScRow <= nScLastRow; ++nScRow ) - { - for( SCCOL nScCol = rRange.aStart.Col(); nScCol <= nScLastCol; ++nScCol ) - { - if( !maUsedCells.IsCellMarked( nScCol, nScRow, TRUE ) ) - { - XclExpCrnRef xCrn; - if( rDoc.HasValueData( nScCol, nScRow, nScTab ) ) - { - ScAddress aAddr( nScCol, nScRow, nScTab ); - double fVal = rDoc.GetValue( aAddr ); - ULONG nFormat = rDoc.GetNumberFormat( aAddr ); - short nType = rFormatter.GetType( nFormat ); - bool bIsBool = (nType == NUMBERFORMAT_LOGICAL); - - if( !bIsBool && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) && - (rDoc.GetCellType( aAddr ) == CELLTYPE_FORMULA) ) - if( ScFormulaCell* pCell = static_cast< ScFormulaCell* >( rDoc.GetCell( aAddr ) ) ) - bIsBool = (pCell->GetFormatType() == NUMBERFORMAT_LOGICAL); - - if( bIsBool && ((fVal == 0.0) || (fVal == 1.0)) ) - xCrn.reset( new XclExpCrnBool( nScCol, nScRow, (fVal == 1.0) ) ); - else - xCrn.reset( new XclExpCrnDouble( nScCol, nScRow, fVal ) ); - } - else - { - String aText; - rDoc.GetString( nScCol, nScRow, nScTab, aText ); - xCrn.reset( new XclExpCrnString( nScCol, nScRow, aText ) ); - } - maCrnList.AppendRecord( xCrn ); - } - } - } +void XclExpXct::StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken ) +{ + maUsedCells.SetMultiMarkArea( ScRange( rCell ) ); + maBoundRange.ExtendTo( ScRange( rCell ) ); + (void)rToken; +} +void XclExpXct::StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken ) +{ maUsedCells.SetMultiMarkArea( rRange ); + maBoundRange.ExtendTo( rRange ); + (void)rToken; } -void XclExpXct::StoreCell( const XclExpRoot& /*rRoot*/, const ScAddress& rCell, const formula::FormulaToken& rToken ) +namespace { + +class XclExpCrnList : public XclExpRecordList< XclExpCrn > { - switch (rToken.GetType()) - { - case svString: - { - XclExpCrnRef xCrn( - new XclExpCrnString(rCell.Col(), rCell.Row(), rToken.GetString())); - maCrnList.AppendRecord(xCrn); - } - break; - case svDouble: - { - XclExpCrnRef xCrn( - new XclExpCrnDouble(rCell.Col(), rCell.Row(), rToken.GetDouble())); - maCrnList.AppendRecord(xCrn); - } - break; - case svEmptyCell: - { - XclExpCrnRef xCrn( - new XclExpCrnDouble(rCell.Col(), rCell.Row(), 0.0)); - maCrnList.AppendRecord(xCrn); - } - break; - default: - ; // nothing - } +public: + /** Inserts the passed value into an existing or new CRN record. + @return True = value inserted successfully, false = CRN list is full. */ + bool InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue ); +}; + +bool XclExpCrnList::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue ) +{ + RecordRefType xLastRec = GetLastRecord(); + if( xLastRec.is() && xLastRec->InsertValue( nScCol, nScRow, rValue ) ) + return true; + if( GetSize() == SAL_MAX_UINT16 ) + return false; + AppendNewRecord( new XclExpCrn( nScCol, nScRow, rValue ) ); + return true; } -void XclExpXct::StoreCellRange( const XclExpRoot& /*rRoot*/, const ScRange& rRange, const formula::FormulaToken& rToken ) +} // namespace + +void XclExpXct::Save( XclExpStream& rStrm ) { - if (rToken.GetType() != svMatrix) + if( !mxCacheTable ) return; - if (rRange.aStart.Tab() != rRange.aEnd.Tab()) - // multi-table range is not supported here. + /* Get the range of used rows in the cache table. This may help to + optimize building the CRN record list if the cache table does not + contain all referred cells, e.g. if big empty ranges are used in the + formulas. */ + ::std::pair< SCROW, SCROW > aRowRange = mxCacheTable->getRowRange(); + if( aRowRange.first >= aRowRange.second ) return; - const ScMatrix* pMtx = static_cast<const ScToken*>(&rToken)->GetMatrix(); - if (!pMtx) + /* Crop the bounding range of used cells in this table to Excel limits. + Return if there is no external cell inside these limits. */ + if( !GetAddressConverter().ValidateRange( maBoundRange, false ) ) return; - SCSIZE nCols, nRows; - pMtx->GetDimensions(nCols, nRows); - const ScAddress& s = rRange.aStart; - const ScAddress& e = rRange.aEnd; - if (static_cast<SCCOL>(nCols) != e.Col() - s.Col() + 1 || - static_cast<SCROW>(nRows) != e.Row() - s.Row() + 1) - { - // size mis-match! + /* Find the resulting row range that needs to be processed. */ + SCROW nScRow1 = ::std::max( aRowRange.first, maBoundRange.aStart.Row() ); + SCROW nScRow2 = ::std::min( aRowRange.second - 1, maBoundRange.aEnd.Row() ); + if( nScRow1 > nScRow2 ) return; - } - for (SCCOL nCol = 0; nCol < static_cast< SCCOL >( nCols ); ++nCol) + /* Build and collect all CRN records before writing the XCT record. This + is needed to determine the total number of CRN records which must be + known when writing the XCT record (possibly encrypted, so seeking the + output strem back after writing the CRN records is not an option). */ + XclExpCrnList aCrnRecs; + SvNumberFormatter& rFormatter = GetFormatter(); + bool bValid = true; + for( SCROW nScRow = nScRow1; bValid && (nScRow <= nScRow2); ++nScRow ) { - for (SCROW nRow = 0; nRow < static_cast< SCROW >( nRows ); ++nRow) + ::std::pair< SCCOL, SCCOL > aColRange = mxCacheTable->getColRange( nScRow ); + for( SCCOL nScCol = aColRange.first; bValid && (nScCol < aColRange.second); ++nScCol ) { - if (pMtx->IsString(nCol, nRow)) + if( maUsedCells.IsCellMarked( nScCol, nScRow, TRUE ) ) { - XclExpCrnRef xCrn(new XclExpCrnString( - s.Col() + nCol, s.Row() + nRow, pMtx->GetString(nCol, nRow))); - maCrnList.AppendRecord(xCrn); - } - else if (pMtx->IsValueOrEmpty(nCol, nRow)) - { - XclExpCrnRef xCrn(new XclExpCrnDouble( - s.Col() + nCol, s.Row() + nRow, pMtx->GetDouble(nCol, nRow))); - maCrnList.AppendRecord(xCrn); + sal_uInt32 nScNumFmt = 0; + ScExternalRefCache::TokenRef xToken = mxCacheTable->getCell( nScCol, nScRow, &nScNumFmt ); + using namespace ::formula; + if( xToken.get() ) switch( xToken->GetType() ) + { + case svDouble: + bValid = (rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL) ? + aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() != 0 ) ) : + aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() ) ); + break; + case svString: + // do not save empty strings (empty cells) to cache + if( xToken->GetString().Len() > 0 ) + bValid = aCrnRecs.InsertValue( nScCol, nScRow, Any( OUString( xToken->GetString() ) ) ); + break; + default: + break; + } } } } -} -void XclExpXct::Save( XclExpStream& rStrm ) -{ - XclExpRecord::Save( rStrm ); - maCrnList.Save( rStrm ); -} - -void XclExpXct::WriteBody( XclExpStream& rStrm ) -{ - sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maCrnList.GetSize() ); - rStrm << nCount << mnSBTab; + // write the XCT record and the list of CRN records + rStrm.StartRecord( EXC_ID_XCT, 4 ); + rStrm << static_cast< sal_uInt16 >( aCrnRecs.GetSize() ) << mnSBTab; + rStrm.EndRecord(); + aCrnRecs.Save( rStrm ); } // External documents (EXTERNSHEET/SUPBOOK), base class ======================= @@ -1471,15 +1418,11 @@ XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl ) : // We need to create all tables up front to ensure the correct table order. ScExternalRefManager* pRefMgr = rRoot.GetDoc().GetExternalRefManager(); - sal_uInt16 nFileId = pRefMgr->getExternalFileId(rUrl); - vector<String> aTabNames; - pRefMgr->getAllCachedTableNames(nFileId, aTabNames); - if (aTabNames.empty()) - return; - - vector<String>::const_iterator itr = aTabNames.begin(), itrEnd = aTabNames.end(); - for (; itr != itrEnd; ++itr) - InsertTabName(*itr); + sal_uInt16 nFileId = pRefMgr->getExternalFileId( rUrl ); + ScfStringVec aTabNames; + pRefMgr->getAllCachedTableNames( nFileId, aTabNames ); + for( ScfStringVec::const_iterator aBeg = aTabNames.begin(), aIt = aBeg, aEnd = aTabNames.end(); aIt != aEnd; ++aIt ) + InsertTabName( *aIt, pRefMgr->getCacheTable( nFileId, aIt - aBeg ) ); } XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic ) : @@ -1513,31 +1456,22 @@ void XclExpSupbook::FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry, void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab ) { - XclExpXctRef xXct = maXctList.GetRecord( nSBTab ); - if( xXct.is() ) - xXct->StoreCellRange( GetRoot(), rRange ); + if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() ) + pXct->StoreCellRange( rRange ); } void XclExpSupbook::StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const formula::FormulaToken& rToken ) { - XclExpXctRef xXct = maXctList.GetRecord(nSBTab); - if (!xXct.is()) - return; - - xXct->StoreCell(GetRoot(), rCell, rToken); + if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() ) + pXct->StoreCell( rCell, rToken ); } void XclExpSupbook::StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const formula::FormulaToken& rToken ) { - if (rRange.aStart.Tab() != rRange.aEnd.Tab()) - // multi-table range is not allowed! - return; - - XclExpXctRef xXct = maXctList.GetRecord(nSBTab); - if (!xXct.is()) - return; - - xXct->StoreCellRange(GetRoot(), rRange, rToken); + // multi-table range is not allowed! + if( rRange.aStart.Tab() == rRange.aEnd.Tab() ) + if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() ) + pXct->StoreCellRange( rRange, rToken ); } sal_uInt16 XclExpSupbook::GetTabIndex( const String& rTabName ) const @@ -1558,11 +1492,11 @@ sal_uInt16 XclExpSupbook::GetTabCount() const return ulimit_cast<sal_uInt16>(maXctList.GetSize()); } -sal_uInt16 XclExpSupbook::InsertTabName( const String& rTabName ) +sal_uInt16 XclExpSupbook::InsertTabName( const String& rTabName, ScExternalRefCache::TableTypeRef xCacheTable ) { DBG_ASSERT( meType == EXC_SBTYPE_EXTERN, "XclExpSupbook::InsertTabName - don't insert sheet names here" ); sal_uInt16 nSBTab = ulimit_cast< sal_uInt16 >( maXctList.GetSize() ); - XclExpXctRef xXct( new XclExpXct( rTabName, nSBTab ) ); + XclExpXctRef xXct( new XclExpXct( GetRoot(), rTabName, nSBTab, xCacheTable ) ); AddRecSize( xXct->GetTabName().GetSize() ); maXctList.AppendRecord( xXct ); return nSBTab; @@ -1786,6 +1720,7 @@ void XclExpSupbookBuffer::StoreCellRange( sal_uInt16 nFileId, const String& rTab SCTAB nTabCount = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1; // If this is a multi-table range, get token for each table. + using namespace ::formula; vector<FormulaToken*> aMatrixList; aMatrixList.reserve(nTabCount); diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx index cb248f0eaf76..ddcdb3243167 100644 --- a/sc/source/filter/excel/xepivot.cxx +++ b/sc/source/filter/excel/xepivot.cxx @@ -538,16 +538,21 @@ void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScD { // get the string collection with original source elements ScSheetDPData aDPData( GetDocPtr(), *pSrcDesc ); - const TypedScStrCollection& rOrigColl = aDPData.GetColumnEntries( static_cast< long >( GetBaseFieldIndex() ) ); - + // Wang Xu Ming - DataPilot migration + // 2009-05-08 + const std::vector< SCROW > aOrignial = aDPData.GetColumnEntries( static_cast< long >( GetBaseFieldIndex() ) ); // get the string collection with generated grouping elements ScDPNumGroupDimension aTmpDim( rNumInfo ); if( nDatePart != 0 ) aTmpDim.MakeDateHelper( rNumInfo, nDatePart ); - const TypedScStrCollection& rGroupColl = aTmpDim.GetNumEntries( rOrigColl, GetDocPtr() ); - for( USHORT nIdx = 0, nCount = rGroupColl.GetCount(); nIdx < nCount; ++nIdx ) - if( const TypedStrData* pStrData = rGroupColl[ nIdx ] ) - InsertGroupItem( new XclExpPCItem( pStrData->GetString() ) ); + const std::vector< SCROW > aMemberIds = aTmpDim.GetNumEntries( static_cast< SCCOL >( GetBaseFieldIndex() ), aDPData.GetCacheTable().GetCache(), aOrignial ); + for ( size_t nIdx = 0 ; nIdx < aMemberIds.size(); nIdx++ ) + { + const ScDPItemData* pData = aDPData.GetMemberById( static_cast< long >( GetBaseFieldIndex() ) , aMemberIds[ nIdx] ); + if ( pData ) + InsertGroupItem( new XclExpPCItem( pData->GetString() ) ); + } +// End Comments } } diff --git a/sc/source/filter/excel/xerecord.cxx b/sc/source/filter/excel/xerecord.cxx index 853a0e52bc8b..fed58411aa5c 100644 --- a/sc/source/filter/excel/xerecord.cxx +++ b/sc/source/filter/excel/xerecord.cxx @@ -46,16 +46,10 @@ void XclExpRecordBase::SaveXml( XclExpXmlStream& /*rStrm*/ ) { } -//UNUSED2008-05 void XclExpRecordBase::SaveRepeated( XclExpStream& rStrm, size_t nCount ) -//UNUSED2008-05 { -//UNUSED2008-05 for( size_t nIndex = 0; nIndex < nCount; ++nIndex ) -//UNUSED2008-05 Save( rStrm ); -//UNUSED2008-05 } - // ---------------------------------------------------------------------------- -XclExpDelegatingRecord::XclExpDelegatingRecord( XclExpRecordBase* pRecord ) - : mpRecord( pRecord ) +XclExpDelegatingRecord::XclExpDelegatingRecord( XclExpRecordBase* pRecord ) : + mpRecord( pRecord ) { } @@ -67,9 +61,8 @@ XclExpDelegatingRecord::~XclExpDelegatingRecord() void XclExpDelegatingRecord::SaveXml( XclExpXmlStream& rStrm ) { - if( !mpRecord ) - return; - mpRecord->SaveXml( rStrm ); + if( mpRecord ) + mpRecord->SaveXml( rStrm ); } // ---------------------------------------------------------------------------- diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx index 922adceb061b..834873740d68 100644 --- a/sc/source/filter/excel/xeroot.cxx +++ b/sc/source/filter/excel/xeroot.cxx @@ -27,6 +27,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" + #include <sfx2/docfile.hxx> #include <sfx2/sfxsids.hrc> #include <unotools/saveopt.hxx> @@ -35,12 +36,13 @@ #include <svl/eitem.hxx> #include "xecontent.hxx" #include "xltracer.hxx" -#include "xehelper.hxx" +#include "xeescher.hxx" #include "xeformula.hxx" +#include "xehelper.hxx" #include "xelink.hxx" #include "xename.hxx" -#include "xestyle.hxx" #include "xepivot.hxx" +#include "xestyle.hxx" #include "xeroot.hxx" #include "excrecds.hxx" // for filter manager @@ -142,6 +144,12 @@ XclExpNameManager& XclExpRoot::GetNameManager() const return *mrExpData.mxNameMgr; } +XclExpObjectManager& XclExpRoot::GetObjectManager() const +{ + DBG_ASSERT( mrExpData.mxObjMgr.is(), "XclExpRoot::GetObjectManager - missing object (wrong BIFF?)" ); + return *mrExpData.mxObjMgr; +} + XclExpFilterManager& XclExpRoot::GetFilterManager() const { DBG_ASSERT( mrExpData.mxFilterMgr.is(), "XclExpRoot::GetFilterManager - missing object (wrong BIFF?)" ); @@ -181,6 +189,7 @@ void XclExpRoot::InitializeGlobals() if( GetBiff() == EXC_BIFF8 ) { mrExpData.mxSst.reset( new XclExpSst ); + mrExpData.mxObjMgr.reset( new XclExpObjectManager( GetRoot() ) ); mrExpData.mxFilterMgr.reset( new XclExpFilterManager( GetRoot() ) ); mrExpData.mxPTableMgr.reset( new XclExpPivotTableManager( GetRoot() ) ); // BIFF8: only one link manager for all sheets diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx index 4470bf789412..6734f90948e4 100644 --- a/sc/source/filter/excel/xichart.cxx +++ b/sc/source/filter/excel/xichart.cxx @@ -37,6 +37,7 @@ #include <com/sun/star/drawing/Direction3D.hpp> #include <com/sun/star/drawing/ProjectionMode.hpp> #include <com/sun/star/drawing/ShadeMode.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp> #include <com/sun/star/chart/ChartAxisLabelPosition.hpp> #include <com/sun/star/chart/ChartAxisMarkPosition.hpp> @@ -63,6 +64,8 @@ #include <com/sun/star/chart/MissingValueTreatment.hpp> #include <sfx2/objsh.hxx> +#include <svx/svdpage.hxx> +#include <svx/unoapi.hxx> #include "document.hxx" #include "drwlayer.hxx" @@ -79,7 +82,6 @@ #include "xistyle.hxx" #include "xipage.hxx" #include "xiview.hxx" -#include "xiescher.hxx" using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -88,11 +90,14 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::uno::Exception; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::frame::XModel; using ::com::sun::star::util::XNumberFormatsSupplier; +using ::com::sun::star::drawing::XDrawPage; +using ::com::sun::star::drawing::XDrawPageSupplier; using ::com::sun::star::chart2::XChartDocument; using ::com::sun::star::chart2::XDiagram; @@ -123,8 +128,6 @@ using ::com::sun::star::chart2::data::XDataSequence; using ::formula::FormulaToken; using ::formula::StackVar; -using ::std::vector; - // Helpers ==================================================================== namespace { @@ -248,14 +251,14 @@ void XclImpChRoot::InitConversion( Reference< XChartDocument > xChartDoc ) const } } -void XclImpChRoot::FinishConversion( ScfProgressBar& rProgress ) const +void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const { - rProgress.Progress( EXC_CHART_PROGRESS_SIZE ); + rDffConv.Progress( EXC_CHART_PROGRESS_SIZE ); // unlock the model Reference< XModel > xModel( mxChData->GetChartDoc(), UNO_QUERY ); if( xModel.is() ) xModel->unlockControllers(); - rProgress.Progress( EXC_CHART_PROGRESS_SIZE ); + rDffConv.Progress( EXC_CHART_PROGRESS_SIZE ); mxChData->FinishConversion(); } @@ -793,9 +796,9 @@ Sequence< Reference< XFormattedString > > XclImpChSourceLink::CreateStringSequen return ScfApiHelper::VectorToSequence( aStringVec ); } -void XclImpChSourceLink::FillSourceLink(vector<ScSharedTokenRef>& rTokens) const +void XclImpChSourceLink::FillSourceLink( ::std::vector< ScSharedTokenRef >& rTokens ) const { - if (!mxTokenArray.is()) + if( !mxTokenArray.is() ) // no links to fill. return; @@ -1855,16 +1858,16 @@ Reference< XDataSeries > XclImpChSeries::CreateDataSeries() const return xDataSeries; } -void XclImpChSeries::FillAllSourceLinks(vector<ScSharedTokenRef>& rTokens) const +void XclImpChSeries::FillAllSourceLinks( ::std::vector< ScSharedTokenRef >& rTokens ) const { - if (mxValueLink.is()) - mxValueLink->FillSourceLink(rTokens); - if (mxCategLink.is()) - mxCategLink->FillSourceLink(rTokens); - if (mxTitleLink.is()) - mxTitleLink->FillSourceLink(rTokens); - if (mxBubbleLink.is()) - mxBubbleLink->FillSourceLink(rTokens); + if( mxValueLink.is() ) + mxValueLink->FillSourceLink( rTokens ); + if( mxCategLink.is() ) + mxCategLink->FillSourceLink( rTokens ); + if( mxTitleLink.is() ) + mxTitleLink->FillSourceLink( rTokens ); + if( mxBubbleLink.is() ) + mxBubbleLink->FillSourceLink( rTokens ); } void XclImpChSeries::ReadChSourceLink( XclImpStream& rStrm ) @@ -3513,7 +3516,7 @@ XclImpChTextRef XclImpChChart::GetDefaultText( XclChTextType eTextType ) const return maDefTexts.get( nDefTextId ); } -void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, ScfProgressBar& rProgress, const OUString& rObjName ) const +void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, XclImpDffConverter& rDffConv, const OUString& rObjName ) const { // initialize conversion (locks the model to suppress any internal updates) InitConversion( xChartDoc ); @@ -3555,27 +3558,21 @@ void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, ScfProgressB } // unlock the model - FinishConversion( rProgress ); + FinishConversion( rDffConv ); - ScDocument* pDoc = &GetRoot().GetDoc(); - ScChartListenerCollection* pChartCollection = pDoc->GetChartListenerCollection(); - if (pChartCollection) + // start listening to this chart + ScDocument& rDoc = GetRoot().GetDoc(); + if( ScChartListenerCollection* pChartCollection = rDoc.GetChartListenerCollection() ) { - // Now, start listening to this chart. - ::std::auto_ptr< vector<ScSharedTokenRef> > pRefTokens(new vector<ScSharedTokenRef>); - for (XclImpChSeriesVec::const_iterator itr = maSeries.begin(), itrEnd = maSeries.end(); itr != itrEnd; ++itr) - { - const XclImpChSeriesRef& rSeries = *itr; - rSeries->FillAllSourceLinks(*pRefTokens); - } - if (!pRefTokens->empty()) + ::std::auto_ptr< ::std::vector< ScSharedTokenRef > > xRefTokens( new ::std::vector< ScSharedTokenRef > ); + for( XclImpChSeriesVec::const_iterator aIt = maSeries.begin(), aEnd = maSeries.end(); aIt != aEnd; ++aIt ) + (*aIt)->FillAllSourceLinks( *xRefTokens ); + if( !xRefTokens->empty() ) { - ::std::auto_ptr<ScChartListener> pListener( - new ScChartListener(rObjName, pDoc, pRefTokens.release())); - pListener->SetUsed(true); - pListener->StartListeningTo(); - pChartCollection->Insert(pListener.release()); - + ::std::auto_ptr< ScChartListener > xListener( new ScChartListener( rObjName, &rDoc, xRefTokens.release() ) ); + xListener->SetUsed( true ); + xListener->StartListeningTo(); + pChartCollection->Insert( xListener.release() ); } } } @@ -3733,6 +3730,68 @@ Reference< XDiagram > XclImpChChart::CreateDiagram() const // ---------------------------------------------------------------------------- +XclImpChartDrawing::XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab ) : + XclImpDrawing( rRoot, bOwnTab ), // sheet charts may contain OLE objects + mnScTab( rRoot.GetCurrScTab() ), + mbOwnTab( bOwnTab ) +{ +} + +void XclImpChartDrawing::ConvertObjects( XclImpDffConverter& rDffConv, + const Reference< XModel >& rxModel, const Rectangle& rChartRect ) +{ + maChartRect = rChartRect; // needed in CalcAnchorRect() callback + + SdrModel* pSdrModel = 0; + SdrPage* pSdrPage = 0; + if( mbOwnTab ) + { + // chart sheet: insert all shapes into the sheet, not into the chart object + pSdrModel = GetDoc().GetDrawLayer(); + pSdrPage = GetSdrPage( mnScTab ); + } + else + { + // embedded chart object: insert all shapes into the chart + try + { + Reference< XDrawPageSupplier > xDrawPageSupp( rxModel, UNO_QUERY_THROW ); + Reference< XDrawPage > xDrawPage( xDrawPageSupp->getDrawPage(), UNO_SET_THROW ); + pSdrPage = ::GetSdrPageFromXDrawPage( xDrawPage ); + pSdrModel = pSdrPage ? pSdrPage->GetModel() : 0; + } + catch( Exception& ) + { + } + } + + if( pSdrModel && pSdrPage ) + ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage ); +} + +Rectangle XclImpChartDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const +{ + /* In objects with DFF client anchor, the position of the shape is stored + in the cell address components of the client anchor. In old BIFF3-BIFF5 + objects, the position is stored in the offset components of the anchor. */ + Rectangle aRect( + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_UNIT * maChartRect.GetWidth() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_UNIT * maChartRect.GetHeight() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_UNIT * maChartRect.GetWidth() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_UNIT * maChartRect.GetHeight() + 0.5 ) ); + aRect.Justify(); + // move shapes into chart area for sheet charts + if( mbOwnTab ) + aRect.Move( maChartRect.Left(), maChartRect.Top() ); + return aRect; +} + +void XclImpChartDrawing::OnObjectInserted( const XclImpDrawObjBase& ) +{ +} + +// ---------------------------------------------------------------------------- + XclImpChart::XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ) : XclImpRoot( rRoot ), mbOwnTab( bOwnTab ), @@ -3740,6 +3799,10 @@ XclImpChart::XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ) : { } +XclImpChart::~XclImpChart() +{ +} + void XclImpChart::ReadChartSubStream( XclImpStream& rStrm ) { XclImpPageSettings& rPageSett = GetPageSettings(); @@ -3770,6 +3833,7 @@ void XclImpChart::ReadChartSubStream( XclImpStream& rStrm ) case EXC_ID_SCL: rTabViewSett.ReadScl( rStrm ); break; } + // common records switch( rStrm.GetRecId() ) { case EXC_ID_EOF: bLoop = false; break; @@ -3781,12 +3845,29 @@ void XclImpChart::ReadChartSubStream( XclImpStream& rStrm ) case EXC_ID5_BOF: XclTools::SkipSubStream( rStrm ); break; case EXC_ID_CHCHART: ReadChChart( rStrm ); break; - case EXC_ID_OBJ: GetTracer().TraceChartEmbeddedObj(); break; case EXC_ID8_CHPIVOTREF: GetTracer().TracePivotChartExists(); mbIsPivotChart = true; break; + + // BIFF specific records + default: switch( GetBiff() ) + { + case EXC_BIFF5: switch( rStrm.GetRecId() ) + { + case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break; + } + break; + case EXC_BIFF8: switch( rStrm.GetRecId() ) + { + case EXC_ID_MSODRAWING: GetChartDrawing().ReadMsoDrawing( rStrm ); break; + // #i61786# weird documents: OBJ without MSODRAWING -> read in BIFF5 format + case EXC_ID_OBJ: GetChartDrawing().ReadObj( rStrm ); break; + } + break; + default:; + } } } } @@ -3800,14 +3881,28 @@ void XclImpChart::UpdateObjFrame( const XclObjLineData& rLineData, const XclObjF sal_Size XclImpChart::GetProgressSize() const { - return mxChartData.is() ? mxChartData->GetProgressSize() : 0; + return + (mxChartData.is() ? mxChartData->GetProgressSize() : 0) + + (mxChartDrawing.is() ? mxChartDrawing->GetProgressSize() : 0); } -void XclImpChart::Convert( Reference< XModel > xModel, ScfProgressBar& rProgress, const OUString& rObjName ) const +void XclImpChart::Convert( Reference< XModel > xModel, XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const { Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY ); - if( mxChartData.is() && xChartDoc.is() ) - mxChartData->Convert( xChartDoc, rProgress, rObjName ); + if( xChartDoc.is() ) + { + if( mxChartData.is() ) + mxChartData->Convert( xChartDoc, rDffConv, rObjName ); + if( mxChartDrawing.is() ) + mxChartDrawing->ConvertObjects( rDffConv, xModel, rChartRect ); + } +} + +XclImpChartDrawing& XclImpChart::GetChartDrawing() +{ + if( !mxChartDrawing ) + mxChartDrawing.reset( new XclImpChartDrawing( GetRoot(), mbOwnTab ) ); + return *mxChartDrawing; } void XclImpChart::ReadChChart( XclImpStream& rStrm ) diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx index 9c130d2ebb78..fb1eb9a3bf44 100644 --- a/sc/source/filter/excel/xicontent.cxx +++ b/sc/source/filter/excel/xicontent.cxx @@ -710,7 +710,7 @@ void XclImpValidation::ReadDval( XclImpStream& rStrm ) if( nObjId != EXC_DVAL_NOOBJ ) { DBG_ASSERT( nObjId <= 0xFFFF, "XclImpValidation::ReadDval - invalid object ID" ); - rRoot.GetObjectManager().SetSkipObj( rRoot.GetCurrScTab(), static_cast< sal_uInt16 >( nObjId ) ); + rRoot.GetCurrSheetDrawing().SetSkipObj( static_cast< sal_uInt16 >( nObjId ) ); } } @@ -1213,7 +1213,29 @@ void XclImpSheetProtectBuffer::ReadProtect( XclImpStream& rStrm, SCTAB nTab ) void XclImpSheetProtectBuffer::ReadOptions( XclImpStream& rStrm, SCTAB nTab ) { - rStrm.Ignore(19); + rStrm.Ignore(12); + + // feature type can be either 2 or 4. If 2, this record stores flag for + // enhanced protection, whereas if 4 it stores flag for smart tag. + sal_uInt16 nFeatureType; + rStrm >> nFeatureType; + if (nFeatureType != 2) + // We currently only support import of enhanced protection data. + return; + + rStrm.Ignore(1); // always 1 + + // The flag size specifies the size of bytes that follows that stores + // feature data. If -1 it depends on the feature type imported earlier. + // For enhanced protection data, the size is always 4. For the most xls + // documents out there this value is almost always -1. + sal_Int32 nFlagSize; + rStrm >> nFlagSize; + if (nFlagSize != -1) + return; + + // There are actually 4 bytes to read, but the upper 2 bytes currently + // don't store any bits. sal_uInt16 nOptions; rStrm >> nOptions; diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index e963495a3f4b..64ed79e3d3b2 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -118,13 +118,13 @@ using ::rtl::OUString; using ::rtl::OUStringBuffer; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Any; -using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::beans::NamedValue; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::container::XIndexContainer; @@ -193,10 +193,11 @@ typedef TSdrObjectPtr< SdrObject > SdrObjectPtr; XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) : XclImpRoot( rRoot ), - maObjId( rRoot.GetCurrScTab(), EXC_OBJ_INVALID_ID ), + mnObjId( EXC_OBJ_INVALID_ID ), mnObjType( EXC_OBJTYPE_UNKNOWN ), mnDffShapeId( 0 ), mnDffFlags( 0 ), + mbHasAnchor( false ), mbHidden( false ), mbVisible( true ), mbPrintable( true ), @@ -213,9 +214,8 @@ XclImpDrawObjBase::~XclImpDrawObjBase() { } -XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( XclImpStream& rStrm ) +/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm ) { - const XclImpRoot& rRoot = rStrm.GetRoot(); XclImpDrawObjRef xDrawObj; if( rStrm.GetRecLeft() >= 30 ) @@ -245,9 +245,8 @@ XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( XclImpStream& rStrm ) return xDrawObj; } -XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( XclImpStream& rStrm ) +/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm ) { - const XclImpRoot& rRoot = rStrm.GetRoot(); XclImpDrawObjRef xDrawObj; if( rStrm.GetRecLeft() >= 30 ) @@ -278,9 +277,8 @@ XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( XclImpStream& rStrm ) return xDrawObj; } -XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( XclImpStream& rStrm ) +/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm ) { - const XclImpRoot& rRoot = rStrm.GetRoot(); XclImpDrawObjRef xDrawObj; if( rStrm.GetRecLeft() >= 34 ) @@ -321,9 +319,8 @@ XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( XclImpStream& rStrm ) return xDrawObj; } -XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( XclImpStream& rStrm ) +/*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm ) { - const XclImpRoot& rRoot = rStrm.GetRoot(); XclImpDrawObjRef xDrawObj; if( rStrm.GetRecLeft() >= 10 ) @@ -380,6 +377,12 @@ XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( XclImpStream& rStrm ) return xDrawObj; } +void XclImpDrawObjBase::SetAnchor( const XclObjAnchor& rAnchor ) +{ + maAnchor = rAnchor; + mbHasAnchor = true; +} + void XclImpDrawObjBase::SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin ) { mnDffShapeId = rDffObjData.nShapeId; @@ -390,11 +393,6 @@ void XclImpDrawObjBase::SetDffData( const DffObjData& rDffObjData, const String& mbAutoMargin = bAutoMargin; } -void XclImpDrawObjBase::SetAnchor( const XclObjAnchor& rAnchor ) -{ - mxAnchor.reset( new XclObjAnchor( rAnchor ) ); -} - String XclImpDrawObjBase::GetObjName() const { /* #118053# #i51348# Always return a non-empty name. Create English @@ -404,6 +402,11 @@ String XclImpDrawObjBase::GetObjName() const return (maObjName.Len() > 0) ? maObjName : GetObjectManager().GetDefaultObjName( *this ); } +const XclObjAnchor* XclImpDrawObjBase::GetAnchor() const +{ + return mbHasAnchor ? &maAnchor : 0; +} + bool XclImpDrawObjBase::IsValidSize( const Rectangle& rAnchorRect ) const { // XclObjAnchor rounds up the width, width of 3 is the result of an Excel width of 0 @@ -412,56 +415,45 @@ bool XclImpDrawObjBase::IsValidSize( const Rectangle& rAnchorRect ) const ((rAnchorRect.GetWidth() > 3) || (rAnchorRect.GetHeight() > 1)); } -ScRange XclImpDrawObjBase::GetUsedArea() const +ScRange XclImpDrawObjBase::GetUsedArea( SCTAB nScTab ) const { ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID ); - if( mxAnchor.is() ) + // #i44077# object inserted -> update used area for OLE object import + if( mbHasAnchor && GetAddressConverter().ConvertRange( aScUsedArea, maAnchor, nScTab, nScTab, false ) ) { - // #i44077# object inserted -> update used area for OLE object import - if( GetAddressConverter().ConvertRange( aScUsedArea, *mxAnchor, GetScTab(), GetScTab(), false ) ) - { - // reduce range, if object ends directly on borders between two columns or rows - if( (mxAnchor->mnRX == 0) && (aScUsedArea.aStart.Col() < aScUsedArea.aEnd.Col()) ) - aScUsedArea.aEnd.IncCol( -1 ); - if( (mxAnchor->mnBY == 0) && (aScUsedArea.aStart.Row() < aScUsedArea.aEnd.Row()) ) - aScUsedArea.aEnd.IncRow( -1 ); - } + // reduce range, if object ends directly on borders between two columns or rows + if( (maAnchor.mnRX == 0) && (aScUsedArea.aStart.Col() < aScUsedArea.aEnd.Col()) ) + aScUsedArea.aEnd.IncCol( -1 ); + if( (maAnchor.mnBY == 0) && (aScUsedArea.aStart.Row() < aScUsedArea.aEnd.Row()) ) + aScUsedArea.aEnd.IncRow( -1 ); } return aScUsedArea; } -Rectangle XclImpDrawObjBase::GetAnchorRect() const -{ - Rectangle aAnchorRect; - if( mxAnchor.is() ) - aAnchorRect = mxAnchor->GetRect( GetDoc(), MAP_100TH_MM ); - return aAnchorRect; -} - sal_Size XclImpDrawObjBase::GetProgressSize() const { return DoGetProgressSize(); } -SdrObject* XclImpDrawObjBase::CreateSdrObject( const Rectangle& rAnchorRect, ScfProgressBar& rProgress, bool bDffImport ) const +SdrObject* XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const { SdrObjectPtr xSdrObj; - if( bDffImport && !mbCustomDff ) + if( bIsDff && !mbCustomDff ) { - rProgress.Progress( GetProgressSize() ); + rDffConv.Progress( GetProgressSize() ); } else { - xSdrObj.reset( DoCreateSdrObj( rAnchorRect, rProgress ) ); + xSdrObj.reset( DoCreateSdrObj( rDffConv, rAnchorRect ) ); if( xSdrObj.is() ) - xSdrObj->SetModel( GetDoc().GetDrawLayer() ); + xSdrObj->SetModel( rDffConv.GetModel() ); } return xSdrObj.release(); } -void XclImpDrawObjBase::ProcessSdrObject( SdrObject& rSdrObj ) const +void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const { - // default: front layer, derived classes may have to set other layer in DoProcessSdrObj() + // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj() rSdrObj.NbcSetLayer( SC_LAYER_FRONT ); // set object name (GetObjName() will always return a non-empty name) @@ -473,7 +465,7 @@ void XclImpDrawObjBase::ProcessSdrObject( SdrObject& rSdrObj ) const // automatic text margin if( mbAutoMargin ) { - sal_Int32 nMargin = GetObjectManager().GetDffManager().GetDefaultTextMargin(); + sal_Int32 nMargin = rDffConv.GetDefaultTextMargin(); rSdrObj.SetMergedItem( SdrTextLeftDistItem( nMargin ) ); rSdrObj.SetMergedItem( SdrTextRightDistItem( nMargin ) ); rSdrObj.SetMergedItem( SdrTextUpperDistItem( nMargin ) ); @@ -497,7 +489,13 @@ void XclImpDrawObjBase::ProcessSdrObject( SdrObject& rSdrObj ) const #endif // call virtual function for object type specific processing - DoProcessSdrObj( rSdrObj ); + DoPreProcessSdrObj( rDffConv, rSdrObj ); +} + +void XclImpDrawObjBase::PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const +{ + // call virtual function for object type specific processing + DoPostProcessSdrObj( rDffConv, rSdrObj ); } // protected ------------------------------------------------------------------ @@ -759,68 +757,69 @@ sal_Size XclImpDrawObjBase::DoGetProgressSize() const return 1; } -SdrObject* XclImpDrawObjBase::DoCreateSdrObj( const Rectangle&, ScfProgressBar& rProgress ) const +SdrObject* XclImpDrawObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& ) const { - rProgress.Progress( GetProgressSize() ); + rDffConv.Progress( GetProgressSize() ); return 0; } -void XclImpDrawObjBase::DoProcessSdrObj( SdrObject& /*rSdrObj*/ ) const +void XclImpDrawObjBase::DoPreProcessSdrObj( XclImpDffConverter&, SdrObject& ) const { // trace if object is not printable if( !IsPrintable() ) GetTracer().TraceObjectNotPrintable(); } -void XclImpDrawObjBase::ImplReadObj3( XclImpStream& rStrm ) +void XclImpDrawObjBase::DoPostProcessSdrObj( XclImpDffConverter&, SdrObject& ) const { - sal_uInt16 nObjFlags, nMacroSize; - XclObjAnchor aAnchor( GetCurrScTab() ); +} +void XclImpDrawObjBase::ImplReadObj3( XclImpStream& rStrm ) +{ // back to offset 4 (ignore object count field) rStrm.Seek( 4 ); - rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize; + + sal_uInt16 nObjFlags, nMacroSize; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; rStrm.Ignore( 2 ); + mbHasAnchor = true; mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN ); mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE ); - SetAnchor( aAnchor ); DoReadObj3( rStrm, nMacroSize ); } void XclImpDrawObjBase::ImplReadObj4( XclImpStream& rStrm ) { - sal_uInt16 nObjFlags, nMacroSize; - XclObjAnchor aAnchor( GetCurrScTab() ); - // back to offset 4 (ignore object count field) rStrm.Seek( 4 ); - rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize; + + sal_uInt16 nObjFlags, nMacroSize; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; rStrm.Ignore( 2 ); + mbHasAnchor = true; mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN ); mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE ); mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE ); - SetAnchor( aAnchor ); DoReadObj4( rStrm, nMacroSize ); } void XclImpDrawObjBase::ImplReadObj5( XclImpStream& rStrm ) { - sal_uInt16 nObjFlags, nMacroSize, nNameLen; - XclObjAnchor aAnchor( GetCurrScTab() ); - // back to offset 4 (ignore object count field) rStrm.Seek( 4 ); - rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize; + + sal_uInt16 nObjFlags, nMacroSize, nNameLen; + rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize; rStrm.Ignore( 2 ); rStrm >> nNameLen; rStrm.Ignore( 2 ); + mbHasAnchor = true; mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN ); mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE ); mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE ); - SetAnchor( aAnchor ); DoReadObj5( rStrm, nNameLen, nMacroSize ); } @@ -845,7 +844,7 @@ void XclImpDrawObjBase::ImplReadObj8( XclImpStream& rStrm ) if( (rStrm.GetRecPos() == 4) && (nSubRecSize >= 6) ) { sal_uInt16 nObjFlags; - rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags; + rStrm >> mnObjType >> mnObjId >> nObjFlags; mbPrintable = ::get_flag( nObjFlags, EXC_OBJCMO_PRINTABLE ); } break; @@ -928,7 +927,7 @@ XclImpGroupObj::XclImpGroupObj( const XclImpRoot& rRoot ) : bool XclImpGroupObj::TryInsert( XclImpDrawObjRef xDrawObj ) { - if( (xDrawObj->GetScTab() != GetScTab()) || (xDrawObj->GetObjId().mnObjId == mnFirstUngrouped) ) + if( xDrawObj->GetObjId() == mnFirstUngrouped ) return false; // insert into own list or into nested group maChildren.InsertGrouped( xDrawObj ); @@ -965,13 +964,14 @@ sal_Size XclImpGroupObj::DoGetProgressSize() const return XclImpDrawObjBase::DoGetProgressSize() + maChildren.GetProgressSize(); } -SdrObject* XclImpGroupObj::DoCreateSdrObj( const Rectangle& /*rAnchorRect*/, ScfProgressBar& rProgress ) const +SdrObject* XclImpGroupObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& /*rAnchorRect*/ ) const { TSdrObjectPtr< SdrObjGroup > xSdrObj( new SdrObjGroup ); // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle + SdrObjList& rObjList = *xSdrObj->GetSubList(); // SdrObjGroup always returns existing sublist for( XclImpDrawObjVector::const_iterator aIt = maChildren.begin(), aEnd = maChildren.end(); aIt != aEnd; ++aIt ) - GetObjectManager().GetDffManager().ProcessObject( xSdrObj->GetSubList(), **aIt ); - rProgress.Progress(); + rDffConv.ProcessObject( rObjList, **aIt ); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1007,7 +1007,7 @@ void XclImpLineObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uI ReadMacro5( rStrm, nMacroSize ); } -SdrObject* XclImpLineObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpLineObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { ::basegfx::B2DPolygon aB2DPolygon; switch( mnStartPoint ) @@ -1100,7 +1100,7 @@ SdrObject* XclImpLineObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgr xSdrObj->SetMergedItem( XLineEndCenterItem( FALSE ) ); } } - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1144,11 +1144,11 @@ void XclImpRectObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uI ReadMacro5( rStrm, nMacroSize ); } -SdrObject* XclImpRectObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpRectObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { SdrObjectPtr xSdrObj( new SdrRectObj( rAnchorRect ) ); ConvertRectStyle( *xSdrObj ); - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1159,11 +1159,11 @@ XclImpOvalObj::XclImpOvalObj( const XclImpRoot& rRoot ) : { } -SdrObject* XclImpOvalObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpOvalObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { SdrObjectPtr xSdrObj( new SdrCircObj( OBJ_CIRC, rAnchorRect ) ); ConvertRectStyle( *xSdrObj ); - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1198,7 +1198,7 @@ void XclImpArcObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uIn ReadMacro5( rStrm, nMacroSize ); } -SdrObject* XclImpArcObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpArcObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { Rectangle aNewRect = rAnchorRect; long nStartAngle = 0; @@ -1235,7 +1235,7 @@ SdrObject* XclImpArcObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgre SdrObjectPtr xSdrObj( new SdrCircObj( eObjKind, aNewRect, nStartAngle, nEndAngle ) ); ConvertFillStyle( *xSdrObj, maFillData ); ConvertLineStyle( *xSdrObj, maLineData ); - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1297,7 +1297,7 @@ namespace { } // namespace -SdrObject* XclImpPolygonObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpPolygonObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { SdrObjectPtr xSdrObj; if( maCoords.size() >= 2 ) @@ -1314,7 +1314,7 @@ SdrObject* XclImpPolygonObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfPr xSdrObj.reset( new SdrPathObj( eObjKind, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) ); ConvertRectStyle( *xSdrObj ); } - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } @@ -1375,7 +1375,7 @@ void XclImpTextObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uI maTextData.ReadFormats( rStrm ); } -SdrObject* XclImpTextObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpTextObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { TSdrObjectPtr< SdrObjCustomShape > xSdrObj( new SdrObjCustomShape ); xSdrObj->NbcSetSnapRect( rAnchorRect ); @@ -1386,11 +1386,11 @@ SdrObject* XclImpTextObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgr xSdrObj->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoSize ) ); xSdrObj->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoSize ) ); xSdrObj->SetMergedItem( SdrTextWordWrapItem( TRUE ) ); - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } -void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const +void XclImpTextObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const { // set text data if( SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj ) ) @@ -1469,7 +1469,7 @@ void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break; case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break; } - MSO_Anchor eTextAnchor = (MSO_Anchor)GetObjectManager().GetDffManager().GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); + MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); switch( eTextAnchor ) { case mso_anchorTopCentered : @@ -1508,7 +1508,7 @@ void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_TOP; break; case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break; } - MSO_Anchor eTextAnchor = (MSO_Anchor)GetObjectManager().GetDffManager().GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); + MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ); switch ( eTextAnchor ) { case mso_anchorTopCentered : @@ -1539,7 +1539,7 @@ void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const } } // base class processing - XclImpRectObj::DoProcessSdrObj( rSdrObj ); + XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); } // ---------------------------------------------------------------------------- @@ -1633,11 +1633,11 @@ sal_Size XclImpChartObj::DoGetProgressSize() const return mxChart.is() ? mxChart->GetProgressSize() : 1; } -SdrObject* XclImpChartObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpChartObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { SdrObjectPtr xSdrObj; SfxObjectShell* pDocShell = GetDocShell(); - if( SvtModuleOptions().IsChart() && pDocShell && mxChart.is() && !mxChart->IsPivotChart() ) + if( rDffConv.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell && mxChart.is() && !mxChart->IsPivotChart() ) { // create embedded chart object OUString aEmbObjName; @@ -1655,20 +1655,28 @@ SdrObject* XclImpChartObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProg // create the container OLE object xSdrObj.reset( new SdrOle2Obj( svt::EmbeddedObjectRef( xEmbObj, nAspect ), aEmbObjName, rAnchorRect ) ); + } - // convert Excel chart to OOo Chart - if( svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) ) - { - Reference< XModel > xModel( xEmbObj->getComponent(), UNO_QUERY ); - mxChart->Convert( xModel, rProgress, aEmbObjName ); + return xSdrObj.release(); +} - Reference< XEmbedPersist > xPers( xEmbObj, UNO_QUERY ); - if( xPers.is() ) - xPers->storeOwn(); +void XclImpChartObj::DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const +{ + const SdrOle2Obj* pSdrOleObj = dynamic_cast< const SdrOle2Obj* >( &rSdrObj ); + if( mxChart.is() && pSdrOleObj ) + { + Reference< XEmbeddedObject > xEmbObj = pSdrOleObj->GetObjRef(); + if( xEmbObj.is() && ::svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) ) try + { + Reference< XEmbedPersist > xPersist( xEmbObj, UNO_QUERY_THROW ); + Reference< XModel > xModel( xEmbObj->getComponent(), UNO_QUERY_THROW ); + mxChart->Convert( xModel, rDffConv, xPersist->getEntryName(), rSdrObj.GetLogicRect() ); + xPersist->storeOwn(); + } + catch( Exception& ) + { } } - - return xSdrObj.release(); } void XclImpChartObj::FinalizeTabChart() @@ -1683,12 +1691,12 @@ void XclImpChartObj::FinalizeTabChart() // calculate size of the chart object const XclPageData& rPageData = GetPageSettings().GetPageData(); - Size aPaperSize( rPageData.GetScPaperSize() ); + Size aPaperSize = rPageData.GetScPaperSize(); long nWidth = XclTools::GetHmmFromTwips( aPaperSize.Width() ); long nHeight = XclTools::GetHmmFromTwips( aPaperSize.Height() ); - // subtract page margins, give 1cm extra space + // subtract page margins, give some more extra space nWidth -= (XclTools::GetHmmFromInch( rPageData.mfLeftMargin + rPageData.mfRightMargin ) + 2000); nHeight -= (XclTools::GetHmmFromInch( rPageData.mfTopMargin + rPageData.mfBottomMargin ) + 1000); @@ -1700,8 +1708,8 @@ void XclImpChartObj::FinalizeTabChart() } // create the object anchor - XclObjAnchor aAnchor( GetScTab() ); - aAnchor.SetRect( GetDoc(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM ); + XclObjAnchor aAnchor; + aAnchor.SetRect( GetDoc(), GetCurrScTab(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM ); SetAnchor( aAnchor ); } @@ -1723,10 +1731,10 @@ void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags mnNoteFlags = nNoteFlags; } -void XclImpNoteObj::DoProcessSdrObj( SdrObject& rSdrObj ) const +void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const { // create formatted text - XclImpTextObj::DoProcessSdrObj( rSdrObj ); + XclImpTextObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject(); if( maScPos.IsValid() && pOutlinerObj ) { @@ -1970,16 +1978,16 @@ void XclImpTbxObjBase::ConvertLabel( ScfPropertySet& rPropSet ) const ConvertFont( rPropSet ); } -SdrObject* XclImpTbxObjBase::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpTbxObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { - SdrObjectPtr xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect ) ); - rProgress.Progress(); + SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) ); + rDffConv.Progress(); return xSdrObj.release(); } -void XclImpTbxObjBase::DoProcessSdrObj( SdrObject& /*rSdrObj*/ ) const +void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter& /*rDffConv*/, SdrObject& /*rSdrObj*/ ) const { - // do not call DoProcessSdrObj() from base class (to skip text processing) + // do not call DoPreProcessSdrObj() from base class (to skip text processing) ProcessControl( *this ); } @@ -2740,7 +2748,7 @@ void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize ) ReadPictFmla( rStrm, nLinkSize ); if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() ) - maGraphic = XclImpObjectManager::ReadImgData( rStrm ); + maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); } void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) @@ -2755,7 +2763,7 @@ void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize ) ReadPictFmla( rStrm, nLinkSize ); if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() ) - maGraphic = XclImpObjectManager::ReadImgData( rStrm ); + maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); } void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ) @@ -2777,7 +2785,7 @@ void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) ) GetPageSettings().ReadImgData( rStrm ); else - maGraphic = XclImpObjectManager::ReadImgData( rStrm ); + maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); } } @@ -2796,10 +2804,10 @@ void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRec } } -SdrObject* XclImpPictureObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const +SdrObject* XclImpPictureObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const { // try to create an OLE object or form control - SdrObjectPtr xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect ) ); + SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) ); // no OLE - create a plain picture from IMGDATA record data if( !xSdrObj && (maGraphic.GetType() != GRAPHIC_NONE) ) @@ -2808,21 +2816,21 @@ SdrObject* XclImpPictureObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfPr ConvertRectStyle( *xSdrObj ); } - rProgress.Progress(); + rDffConv.Progress(); return xSdrObj.release(); } -void XclImpPictureObj::DoProcessSdrObj( SdrObject& rSdrObj ) const +void XclImpPictureObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const { if( IsOcxControl() ) { - // do not call XclImpRectObj::DoProcessSdrObj(), it would trace missing "printable" feature + // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature ProcessControl( *this ); } else if( mbEmbedded || mbLinked ) { // trace missing "printable" feature - XclImpRectObj::DoProcessSdrObj( rSdrObj ); + XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj ); SfxObjectShell* pDocShell = GetDocShell(); SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj ); @@ -3062,18 +3070,18 @@ void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject* // ---------------------------------------------------------------------------- -XclImpSimpleDffManager::XclImpSimpleDffManager( const XclImpRoot& rRoot, SvStream& rDffStrm ) : +XclImpSimpleDffConverter::XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) : SvxMSDffManager( rDffStrm, rRoot.GetBasePath(), 0, 0, rRoot.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT, 24, 0, &rRoot.GetTracer().GetBaseTracer() ), XclImpRoot( rRoot ) { SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS | SVXMSDFF_SETTINGS_IMPORT_EXCEL ); } -XclImpSimpleDffManager::~XclImpSimpleDffManager() +XclImpSimpleDffConverter::~XclImpSimpleDffConverter() { } -FASTBOOL XclImpSimpleDffManager::GetColorFromPalette( USHORT nIndex, Color& rColor ) const +FASTBOOL XclImpSimpleDffConverter::GetColorFromPalette( USHORT nIndex, Color& rColor ) const { ColorData nColor = GetPalette().GetColorData( static_cast< sal_uInt16 >( nIndex ) ); @@ -3086,14 +3094,23 @@ FASTBOOL XclImpSimpleDffManager::GetColorFromPalette( USHORT nIndex, Color& rCol // ---------------------------------------------------------------------------- -XclImpDffManager::XclImpDffManager( - const XclImpRoot& rRoot, XclImpObjectManager& rObjManager, SvStream& rDffStrm ) : - XclImpSimpleDffManager( rRoot, rDffStrm ), - SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ), - mrObjManager( rObjManager ), - mnOleImpFlags( 0 ), +XclImpDffConverter::XclImpDffConvData::XclImpDffConvData( + XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) : + mrDrawing( rDrawing ), + mrSdrModel( rSdrModel ), + mrSdrPage( rSdrPage ), mnLastCtrlIndex( -1 ), - mnCurrFormScTab( -1 ) + mbHasCtrlForm( false ) +{ +} + +// ---------------------------------------------------------------------------- + +XclImpDffConverter::XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) : + XclImpSimpleDffConverter( rRoot, rDffStrm ), + SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ), + maStdFormName( CREATE_OUSTRING( "Standard" ) ), + mnOleImpFlags( 0 ) { if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() ) { @@ -3113,81 +3130,104 @@ XclImpDffManager::XclImpDffManager( ScaleEmu( mnDefTextMargin ); } -XclImpDffManager::~XclImpDffManager() +XclImpDffConverter::~XclImpDffConverter() { } -void XclImpDffManager::StartProgressBar( sal_Size nProgressSize ) +void XclImpDffConverter::StartProgressBar( sal_Size nProgressSize ) { mxProgress.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING ) ); mxProgress->AddSegment( nProgressSize ); mxProgress->Activate(); } -void XclImpDffManager::ProcessObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj ) +void XclImpDffConverter::Progress( sal_Size nDelta ) { - Rectangle aAnchorRect = rDrawObj.GetAnchorRect(); - if( rDrawObj.IsProcessSdrObj() && rDrawObj.IsValidSize( aAnchorRect ) ) - { - // CreateSdrObject() recursively creates embedded child objects - SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( aAnchorRect, *mxProgress, false ) ); - if( xSdrObj.is() ) - rDrawObj.ProcessSdrObject( *xSdrObj ); - // call InsertSdrObject() also, if SdrObject is missing - InsertSdrObject( pObjList, rDrawObj, xSdrObj.release() ); - UpdateUsedArea( rDrawObj ); - } + DBG_ASSERT( mxProgress.is(), "XclImpDffConverter::Progress - invalid call, no progress bar" ); + mxProgress->Progress( nDelta ); } -void XclImpDffManager::ProcessDrawingGroup( SvStream& rDffStrm ) +void XclImpDffConverter::InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) { - rDffStrm.Seek( STREAM_SEEK_TO_BEGIN ); - DffRecordHeader aHeader; - rDffStrm >> aHeader; - if( aHeader.nRecType == DFF_msofbtDggContainer ) - ProcessDggContainer( rDffStrm, aHeader ); - else + XclImpDffConvDataRef xConvData( new XclImpDffConvData( rDrawing, rSdrModel, rSdrPage ) ); + maDataStack.push_back( xConvData ); + SetModel( &xConvData->mrSdrModel, 1440 ); +} + +void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj ) +{ + if( rDrawObj.IsProcessSdrObj() ) { - DBG_ERRORFILE( "XclImpDffManager::ProcessDrawingGroup - unexpected record" ); + if( const XclObjAnchor* pAnchor = rDrawObj.GetAnchor() ) + { + Rectangle aAnchorRect = GetConvData().mrDrawing.CalcAnchorRect( *pAnchor, false ); + if( rDrawObj.IsValidSize( aAnchorRect ) ) + { + // CreateSdrObject() recursively creates embedded child objects + SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( *this, aAnchorRect, false ) ); + if( xSdrObj.is() ) + rDrawObj.PreProcessSdrObject( *this, *xSdrObj ); + // call InsertSdrObject() also, if SdrObject is missing + InsertSdrObject( rObjList, rDrawObj, xSdrObj.release() ); + } + } } } -void XclImpDffManager::ProcessDrawing( SvStream& rDffStrm, sal_Size nStrmPos ) +void XclImpDffConverter::ProcessDrawing( const XclImpDrawObjVector& rDrawObjs ) { - rDffStrm.Seek( nStrmPos ); - DffRecordHeader aHeader; - rDffStrm >> aHeader; - if( aHeader.nRecType == DFF_msofbtDgContainer ) - ProcessDgContainer( rDffStrm, aHeader ); - else + SdrPage& rSdrPage = GetConvData().mrSdrPage; + for( XclImpDrawObjVector::const_iterator aIt = rDrawObjs.begin(), aEnd = rDrawObjs.end(); aIt != aEnd; ++aIt ) + ProcessObject( rSdrPage, **aIt ); +} + +void XclImpDffConverter::ProcessDrawing( SvStream& rDffStrm ) +{ + rDffStrm.Seek( STREAM_SEEK_TO_END ); + if( rDffStrm.Tell() > 0 ) { - DBG_ERRORFILE( "XclImpDffManager::ProcessDrawing - unexpected record" ); + rDffStrm.Seek( STREAM_SEEK_TO_BEGIN ); + DffRecordHeader aHeader; + rDffStrm >> aHeader; + DBG_ASSERT( aHeader.nRecType == DFF_msofbtDgContainer, "XclImpDffConverter::ProcessDrawing - unexpected record" ); + if( aHeader.nRecType == DFF_msofbtDgContainer ) + ProcessDgContainer( rDffStrm, aHeader ); } } -SdrObject* XclImpDffManager::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect ) +void XclImpDffConverter::FinalizeDrawing() +{ + DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::FinalizeDrawing - no drawing manager on stack" ); + maDataStack.pop_back(); + // restore previous model at core DFF converter + if( !maDataStack.empty() ) + SetModel( &maDataStack.back()->mrSdrModel, 1440 ); +} + +SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect ) { SdrObjectPtr xSdrObj; OUString aServiceName = rTbxObj.GetServiceName(); - if( aServiceName.getLength() > 0 ) try + if( SupportsOleObjects() && (aServiceName.getLength() > 0) ) try { // create the form control from scratch Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW ); - // set current controls form, needed in virtual function InsertControl() - SetCurrentForm( rTbxObj.GetScTab() ); + // set controls form, needed in virtual function InsertControl() + InitControlForm(); // try to insert the control into the form ::com::sun::star::awt::Size aDummySize; Reference< XShape > xShape; - if( mxCurrForm.is() && InsertControl( xFormComp, aDummySize, &xShape, TRUE ) ) + XclImpDffConvData& rConvData = GetConvData(); + if( rConvData.mxCtrlForm.is() && InsertControl( xFormComp, aDummySize, &xShape, TRUE ) ) { xSdrObj.reset( rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) ); // try to attach a macro to the control ScriptEventDescriptor aDescriptor; - if( (mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) ) + if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) ) { - Reference< XEventAttacherManager > xEventMgr( mxCurrForm, UNO_QUERY_THROW ); - xEventMgr->registerScriptEvent( mnLastCtrlIndex, aDescriptor ); + Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW ); + xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor ); } } } @@ -3198,52 +3238,55 @@ SdrObject* XclImpDffManager::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, c return xSdrObj.release(); } -SdrObject* XclImpDffManager::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect ) +SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect ) { SdrObjectPtr xSdrObj; - if( rPicObj.IsOcxControl() ) - { - if( mxCtlsStrm.Is() ) try - { - /* set current controls form, needed in virtual function InsertControl() - called from ReadOCXExcelKludgeStream() */ - SetCurrentForm( rPicObj.GetScTab() ); - // seek to stream position of the extra data for this control - mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() ); - // read from mxCtlsStrm into xShape, insert the control model into the form - Reference< XShape > xShape; - if( mxCurrForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, TRUE ) ) - xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) ); - } - catch( Exception& ) - { - } - } - else + if( SupportsOleObjects() ) { - SfxObjectShell* pDocShell = GetDocShell(); - SotStorageRef xSrcStrg = GetRootStorage(); - String aStrgName = rPicObj.GetOleStorageName(); - if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) ) + if( rPicObj.IsOcxControl() ) { - // first try to resolve graphic from DFF storage - Graphic aGraphic; - Rectangle aVisArea; - if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) ) + if( mxCtlsStrm.Is() ) try { - // if not found, use graphic from object (imported from IMGDATA record) - aGraphic = rPicObj.GetGraphic(); - aVisArea = rPicObj.GetVisArea(); + /* set controls form, needed in virtual function InsertControl() + called from ReadOCXExcelKludgeStream() */ + InitControlForm(); + // seek to stream position of the extra data for this control + mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() ); + // read from mxCtlsStrm into xShape, insert the control model into the form + Reference< XShape > xShape; + if( GetConvData().mxCtrlForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, TRUE ) ) + xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) ); } - if( aGraphic.GetType() != GRAPHIC_NONE ) + catch( Exception& ) { - ErrCode nError = ERRCODE_NONE; - namespace cssea = ::com::sun::star::embed::Aspects; - sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT; - xSdrObj.reset( CreateSdrOLEFromStorage( - aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic, - rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) ); + } + } + else + { + SfxObjectShell* pDocShell = GetDocShell(); + SotStorageRef xSrcStrg = GetRootStorage(); + String aStrgName = rPicObj.GetOleStorageName(); + if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) ) + { + // first try to resolve graphic from DFF storage + Graphic aGraphic; + Rectangle aVisArea; + if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) ) + { + // if not found, use graphic from object (imported from IMGDATA record) + aGraphic = rPicObj.GetGraphic(); + aVisArea = rPicObj.GetVisArea(); + } + if( aGraphic.GetType() != GRAPHIC_NONE ) + { + ErrCode nError = ERRCODE_NONE; + namespace cssea = ::com::sun::star::embed::Aspects; + sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT; + xSdrObj.reset( CreateSdrOLEFromStorage( + aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic, + rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) ); + } } } } @@ -3251,44 +3294,43 @@ SdrObject* XclImpDffManager::CreateSdrObject( const XclImpPictureObj& rPicObj, c return xSdrObj.release(); } -ScRange XclImpDffManager::GetUsedArea( SCTAB nScTab ) const +bool XclImpDffConverter::SupportsOleObjects() const { - ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID ); - ScRangeMap::const_iterator aIt = maUsedAreaMap.find( nScTab ); - if( aIt != maUsedAreaMap.end() ) - aScUsedArea = aIt->second; - return aScUsedArea; + return GetConvData().mrDrawing.SupportsOleObjects(); } // virtual functions ---------------------------------------------------------- -void XclImpDffManager::ProcessClientAnchor2( SvStream& rDffStrm, +void XclImpDffConverter::ProcessClientAnchor2( SvStream& rDffStrm, DffRecordHeader& rHeader, void* /*pClientData*/, DffObjData& rObjData ) { // find the OBJ record data related to the processed shape - if( XclImpDrawObjBase* pDrawObj = mrObjManager.FindDrawObj( rObjData.rSpHd ).get() ) + XclImpDffConvData& rConvData = GetConvData(); + if( XclImpDrawObjBase* pDrawObj = rConvData.mrDrawing.FindDrawObj( rObjData.rSpHd ).get() ) { - DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffManager::ProcessClientAnchor2 - no client anchor record" ); - XclObjAnchor aAnchor( pDrawObj->GetScTab() ); + DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffConverter::ProcessClientAnchor2 - no client anchor record" ); + XclObjAnchor aAnchor; rHeader.SeekToContent( rDffStrm ); rDffStrm.SeekRel( 2 ); // flags rDffStrm >> aAnchor; // anchor format equal to BIFF5 OBJ records pDrawObj->SetAnchor( aAnchor ); - rObjData.aChildAnchor = pDrawObj->GetAnchorRect(); + rObjData.aChildAnchor = rConvData.mrDrawing.CalcAnchorRect( aAnchor, true ); rObjData.bChildAnchor = sal_True; } } -SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm, - DffObjData& rDffObjData, void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj ) +SdrObject* XclImpDffConverter::ProcessObj( SvStream& rDffStrm, DffObjData& rDffObjData, + void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj ) { + XclImpDffConvData& rConvData = GetConvData(); + /* pOldSdrObj passes a generated SdrObject. This function owns this object and can modify it. The function has either to return it back to caller or to delete it by itself. */ SdrObjectPtr xSdrObj( pOldSdrObj ); // find the OBJ record data related to the processed shape - XclImpDrawObjRef xDrawObj = mrObjManager.FindDrawObj( rDffObjData.rSpHd ); + XclImpDrawObjRef xDrawObj = rConvData.mrDrawing.FindDrawObj( rDffObjData.rSpHd ); const Rectangle& rAnchorRect = rDffObjData.aChildAnchor; // #102378# Do not process the global page group shape (flag SP_FPATRIARCH) @@ -3326,7 +3368,7 @@ SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm, /* Connect textbox data (string, alignment, text orientation) to object. #98132# don't ask for a text-ID, DFF export doesn't set one. */ if( XclImpTextObj* pTextObj = dynamic_cast< XclImpTextObj* >( xDrawObj.get() ) ) - if( const XclImpObjTextData* pTextData = mrObjManager.FindTextData( rDffObjData.rSpHd ) ) + if( const XclImpObjTextData* pTextData = rConvData.mrDrawing.FindTextData( rDffObjData.rSpHd ) ) pTextObj->SetTextData( *pTextData ); // copy line and fill formatting of TBX form controls from DFF properties @@ -3334,7 +3376,7 @@ SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm, pTbxObj->SetDffProperties( *this ); // try to create a custom SdrObject that overwrites the passed object - SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( rAnchorRect, *mxProgress, true ) ); + SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( *this, rAnchorRect, true ) ); if( xNewSdrObj.is() ) xSdrObj.reset( xNewSdrObj.release() ); @@ -3346,40 +3388,50 @@ SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm, xSdrObj->SetMergedItem( XFillColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) ); // additional processing on the SdrObject - xDrawObj->ProcessSdrObject( *xSdrObj ); - - // add the area used by this object to the internal map of used areas - UpdateUsedArea( *xDrawObj ); + xDrawObj->PreProcessSdrObject( *this, *xSdrObj ); /* If the SdrObject will not be inserted into the draw page, delete it - here. Happens e.g. for notes: The ProcessSdrObject() call above has - inserted the note into the document, and the SdrObject is not + here. Happens e.g. for notes: The PreProcessSdrObject() call above + has inserted the note into the document, and the SdrObject is not needed anymore. */ if( !xDrawObj->IsInsertSdrObj() ) xSdrObj.reset(); } - /* Store the relation between shape ID and SdrObject for connectors. Must - be done here (and not in InsertSdrObject() function), otherwise all - SdrObjects embedded in groups would be lost. */ if( xSdrObj.is() ) - maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() ); + { + /* Store the relation between shape ID and SdrObject for connectors. + Must be done here (and not in InsertSdrObject() function), + otherwise all SdrObjects embedded in groups would be lost. */ + rConvData.maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() ); + + /* If the drawing object is embedded in a group object, call + PostProcessSdrObject() here. For top-level objects this will be + done automatically in InsertSdrObject() but grouped shapes are + inserted into their groups somewhere in the SvxMSDffManager base + class without chance of notification. Unfortunately, now this is + called before the object is really inserted into its group object, + but that should not have any effect for grouped objects. */ + if( !bIsTopLevel ) + xDrawObj->PostProcessSdrObject( *this, *xSdrObj ); + } return xSdrObj.release(); } -ULONG XclImpDffManager::Calc_nBLIPPos( ULONG /*nOrgVal*/, ULONG nStreamPos ) const +ULONG XclImpDffConverter::Calc_nBLIPPos( ULONG /*nOrgVal*/, ULONG nStreamPos ) const { return nStreamPos + 4; } -sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxFormComp, +sal_Bool XclImpDffConverter::InsertControl( const Reference< XFormComponent >& rxFormComp, const ::com::sun::star::awt::Size& /*rSize*/, Reference< XShape >* pxShape, BOOL /*bFloatingCtrl*/ ) { if( GetDocShell() ) try { - Reference< XIndexContainer > xFormIC( mxCurrForm, UNO_QUERY_THROW ); + XclImpDffConvData& rConvData = GetConvData(); + Reference< XIndexContainer > xFormIC( rConvData.mxCtrlForm, UNO_QUERY_THROW ); Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW ); // create the control shape @@ -3390,7 +3442,7 @@ sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxF sal_Int32 nNewIndex = xFormIC->getCount(); xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) ); // on success: store new index of the control for later use (macro events) - mnLastCtrlIndex = nNewIndex; + rConvData.mnLastCtrlIndex = nNewIndex; // set control model at control shape and pass back shape to caller xCtrlShape->setControl( xCtrlModel ); @@ -3399,7 +3451,7 @@ sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxF } catch( Exception& ) { - DBG_ERRORFILE( "XclImpDffManager::InsertControl - cannot create form control" ); + DBG_ERRORFILE( "XclImpDffConverter::InsertControl - cannot create form control" ); } return sal_False; @@ -3407,7 +3459,19 @@ sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxF // private -------------------------------------------------------------------- -String XclImpDffManager::ReadHlinkProperty( SvStream& rDffStrm ) const +XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData() +{ + DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" ); + return *maDataStack.back(); +} + +const XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData() const +{ + DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" ); + return *maDataStack.back(); +} + +String XclImpDffConverter::ReadHlinkProperty( SvStream& rDffStrm ) const { /* Reads hyperlink data from a complex DFF property. Contents of this property are equal to the HLINK record, import of this record is @@ -3438,13 +3502,7 @@ String XclImpDffManager::ReadHlinkProperty( SvStream& rDffStrm ) const return aString; } -void XclImpDffManager::ProcessDggContainer( SvStream& rDffStrm, const DffRecordHeader& rDggHeader ) -{ - // seek to end of drawing group container - rDggHeader.SeekToEndOfRecord( rDffStrm ); -} - -void XclImpDffManager::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader ) +void XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader ) { sal_Size nEndPos = rDgHeader.GetRecEndFilePos(); while( rDffStrm.Tell() < nEndPos ) @@ -3467,12 +3525,13 @@ void XclImpDffManager::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHe rDgHeader.SeekToEndOfRecord( rDffStrm ); // #i12638# #i37900# connector rules - maSolverCont.UpdateConnectorRules(); - SolveSolver( maSolverCont ); - maSolverCont.RemoveConnectorRules(); + XclImpSolverContainer& rSolverCont = GetConvData().maSolverCont; + rSolverCont.UpdateConnectorRules(); + SolveSolver( rSolverCont ); + rSolverCont.RemoveConnectorRules(); } -void XclImpDffManager::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader ) +void XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader ) { sal_Size nEndPos = rShGrHeader.GetRecEndFilePos(); while( rDffStrm.Tell() < nEndPos ) @@ -3493,17 +3552,17 @@ void XclImpDffManager::ProcessShGrContainer( SvStream& rDffStrm, const DffRecord rShGrHeader.SeekToEndOfRecord( rDffStrm ); } -void XclImpDffManager::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader ) +void XclImpDffConverter::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader ) { // solver container wants to read the solver container header again rSolverHeader.SeekToBegOfRecord( rDffStrm ); // read the entire solver container - rDffStrm >> maSolverCont; + rDffStrm >> GetConvData().maSolverCont; // seek to end of solver container rSolverHeader.SeekToEndOfRecord( rDffStrm ); } -void XclImpDffManager::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader ) +void XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader ) { rShHeader.SeekToBegOfRecord( rDffStrm ); Rectangle aDummy; @@ -3516,112 +3575,70 @@ void XclImpDffManager::ProcessShContainer( SvStream& rDffStrm, const DffRecordHe the pointer to the related draw object data (OBJ record) into pDrawObj. */ SdrObjectPtr xSdrObj( ImportObj( rDffStrm, &pDrawObj, aDummy, aDummy, 0, 0 ) ); if( pDrawObj && xSdrObj.is() ) - InsertSdrObject( GetSdrPage( pDrawObj->GetScTab() ), *pDrawObj, xSdrObj.release() ); + InsertSdrObject( GetConvData().mrSdrPage, *pDrawObj, xSdrObj.release() ); rShHeader.SeekToEndOfRecord( rDffStrm ); } -void XclImpDffManager::InsertSdrObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ) +void XclImpDffConverter::InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ) { + XclImpDffConvData& rConvData = GetConvData(); /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj - states to skip insertion, or missing draw page), the object is - automatically deleted. */ + states to skip insertion), the object is automatically deleted. */ SdrObjectPtr xSdrObj( pSdrObj ); - if( pObjList && xSdrObj.is() && rDrawObj.IsInsertSdrObj() ) - pObjList->NbcInsertObject( xSdrObj.release() ); - // SdrObject still here? Insertion failed, remove data from shape ID map. + if( xSdrObj.is() && rDrawObj.IsInsertSdrObj() ) + { + rObjList.NbcInsertObject( xSdrObj.release() ); + // callback to drawing manager for e.g. tracking of used sheet area + rConvData.mrDrawing.OnObjectInserted( rDrawObj ); + // callback to drawing object for post processing (use pSdrObj, xSdrObj already released) + rDrawObj.PostProcessSdrObject( *this, *pSdrObj ); + } + /* SdrObject still here? Insertion failed, remove data from shape ID map. + The SdrObject will be destructed then. */ if( xSdrObj.is() ) - maSolverCont.RemoveSdrObjectInfo( *xSdrObj ); + rConvData.maSolverCont.RemoveSdrObjectInfo( *xSdrObj ); } -void XclImpDffManager::SetCurrentForm( SCTAB nScTab ) +void XclImpDffConverter::InitControlForm() { - if( nScTab != mnCurrFormScTab ) - { - mxCurrForm.clear(); - mnCurrFormScTab = nScTab; + XclImpDffConvData& rConvData = GetConvData(); + if( rConvData.mbHasCtrlForm ) + return; - SdrPage* pSdrPage = GetSdrPage( nScTab ); - if( GetDocShell() && pSdrPage ) try + rConvData.mbHasCtrlForm = true; + if( SupportsOleObjects() ) try + { + Reference< XFormsSupplier > xFormsSupplier( rConvData.mrSdrPage.getUnoPage(), UNO_QUERY_THROW ); + Reference< XNameContainer > xFormsNC( xFormsSupplier->getForms(), UNO_SET_THROW ); + // find or create the Standard form used to insert the imported controls + if( xFormsNC->hasByName( maStdFormName ) ) { - Reference< XFormsSupplier > xFormsSupplier( pSdrPage->getUnoPage(), UNO_QUERY_THROW ); - Reference< XNameContainer > xFormsNC = xFormsSupplier->getForms(); - if( xFormsNC.is() ) - { - // find or create the Standard form used to insert the imported controls - OUString aFormName = CREATE_OUSTRING( "Standard" ); - if( xFormsNC->hasByName( aFormName ) ) - { - xFormsNC->getByName( aFormName ) >>= mxCurrForm; - } - else - { - mxCurrForm.set( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW ); - xFormsNC->insertByName( aFormName, Any( mxCurrForm ) ); - } - } + xFormsNC->getByName( maStdFormName ) >>= rConvData.mxCtrlForm; } - catch( Exception& ) + else if( SfxObjectShell* pDocShell = GetDocShell() ) { + rConvData.mxCtrlForm.set( ScfApiHelper::CreateInstance( pDocShell, CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW ); + xFormsNC->insertByName( maStdFormName, Any( rConvData.mxCtrlForm ) ); } } -} - -void XclImpDffManager::UpdateUsedArea( const XclImpDrawObjBase& rDrawObj ) -{ - ScRange aScObjArea = rDrawObj.GetUsedArea(); - if( aScObjArea.IsValid() ) + catch( Exception& ) { - ScRange* pScTabArea = 0; - ScRangeMap::iterator aIt = maUsedAreaMap.find( rDrawObj.GetScTab() ); - if( aIt == maUsedAreaMap.end() ) - { - pScTabArea = &maUsedAreaMap[ rDrawObj.GetScTab() ]; - pScTabArea->SetInvalid(); - } - else - pScTabArea = &aIt->second; - - if( pScTabArea ) - pScTabArea->ExtendTo( aScObjArea ); } } -// The object manager ========================================================= +// Drawing manager ============================================================ -XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) : - XclImpRoot( rRoot ) +XclImpDrawing::XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ) : + XclImpRoot( rRoot ), + mbOleObjs( bOleObjects ) { - maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" ); - maDefObjNames[ EXC_OBJTYPE_LINE ] = CREATE_STRING( "Line" ); - maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = CREATE_STRING( "Rectangle" ); - maDefObjNames[ EXC_OBJTYPE_OVAL ] = CREATE_STRING( "Oval" ); - maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" ); - maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" ); - maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" ); - maDefObjNames[ EXC_OBJTYPE_BUTTON ] = CREATE_STRING( "Button" ); - maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" ); - maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" ); - maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = CREATE_STRING( "Check Box" ); - maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = CREATE_STRING( "Option Button" ); - maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" ); - maDefObjNames[ EXC_OBJTYPE_LABEL ] = CREATE_STRING( "Label" ); - maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" ); - maDefObjNames[ EXC_OBJTYPE_SPIN ] = CREATE_STRING( "Spinner" ); - maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = CREATE_STRING( "Scroll Bar" ); - maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = CREATE_STRING( "List Box" ); - maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = CREATE_STRING( "Group Box" ); - maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = CREATE_STRING( "Drop Down" ); - maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" ); - maDefObjNames[ EXC_OBJTYPE_DRAWING ] = CREATE_STRING( "AutoShape" ); } -XclImpObjectManager::~XclImpObjectManager() +XclImpDrawing::~XclImpDrawing() { } -// *** Read Excel records *** ------------------------------------------------- - -Graphic XclImpObjectManager::ReadImgData( XclImpStream& rStrm ) // static helper +/*static*/ Graphic XclImpDrawing::ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm ) { Graphic aGraphic; sal_uInt16 nFormat, nEnv; @@ -3631,33 +3648,33 @@ Graphic XclImpObjectManager::ReadImgData( XclImpStream& rStrm ) // static helper { switch( nFormat ) { - case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rStrm ); break; - case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rStrm ); break; - default: DBG_ERRORFILE( "XclImpObjectManager::ReadImgData - unknown image format" ); + case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rRoot, rStrm ); break; + case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rRoot, rStrm ); break; + default: DBG_ERRORFILE( "XclImpDrawing::ReadImgData - unknown image format" ); } } return aGraphic; } -void XclImpObjectManager::ReadObj( XclImpStream& rStrm ) +void XclImpDrawing::ReadObj( XclImpStream& rStrm ) { XclImpDrawObjRef xDrawObj; /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING records. In this case, the OBJ records are in BIFF5 format. Do a sanity check here that there is no DFF data loaded before. */ - DBG_ASSERT( maDffStrm.Tell() == 0, "XclImpObjectManager::ReadObj - unexpected DFF stream data, OBJ will be ignored" ); + DBG_ASSERT( maDffStrm.Tell() == 0, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" ); if( maDffStrm.Tell() == 0 ) switch( GetBiff() ) { case EXC_BIFF3: - xDrawObj = XclImpDrawObjBase::ReadObj3( rStrm ); + xDrawObj = XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm ); break; case EXC_BIFF4: - xDrawObj = XclImpDrawObjBase::ReadObj4( rStrm ); + xDrawObj = XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm ); break; case EXC_BIFF5: case EXC_BIFF8: - xDrawObj = XclImpDrawObjBase::ReadObj5( rStrm ); + xDrawObj = XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm ); break; default: DBG_ERROR_BIFF(); @@ -3672,30 +3689,11 @@ void XclImpObjectManager::ReadObj( XclImpStream& rStrm ) } } -void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm ) -{ - DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 ); - // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm. - rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP ); - ReadDffRecord( rStrm ); -} - -void XclImpObjectManager::ReadMsoDrawing( XclImpStream& rStrm ) +void XclImpDrawing::ReadMsoDrawing( XclImpStream& rStrm ) { DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 ); // disable internal CONTINUE handling rStrm.ResetRecord( false ); - /* #i60510# real life: MSODRAWINGSELECTION record may contain garbage - - this makes it impossible to process the DFF stream in one run. - Store stream start position for every sheet separately, will be used - to seek the stream to these positions later, when processing the next - sheet. */ - size_t nTabIdx = static_cast< size_t >( GetCurrScTab() ); - if( nTabIdx >= maTabStrmPos.size() ) - { - maTabStrmPos.resize( nTabIdx, STREAM_SEEK_TO_END ); - maTabStrmPos.push_back( maDffStrm.Tell() ); - } // read leading MSODRAWING record ReadDffRecord( rStrm ); @@ -3725,36 +3723,7 @@ void XclImpObjectManager::ReadMsoDrawing( XclImpStream& rStrm ) rStrm.ResetRecord( true ); } -void XclImpObjectManager::ReadNote( XclImpStream& rStrm ) -{ - switch( GetBiff() ) - { - case EXC_BIFF2: - case EXC_BIFF3: - case EXC_BIFF4: - case EXC_BIFF5: - ReadNote3( rStrm ); - break; - case EXC_BIFF8: - ReadNote8( rStrm ); - break; - default: - DBG_ERROR_BIFF(); - } -} - -void XclImpObjectManager::ReadTabChart( XclImpStream& rStrm ) -{ - DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 ); - ScfRef< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) ); - xChartObj->ReadChartSubStream( rStrm ); - // insert the chart as raw object without connected DFF data - maRawObjs.push_back( xChartObj ); -} - -// *** Drawing objects *** ---------------------------------------------------- - -XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const DffRecordHeader& rHeader ) const +XclImpDrawObjRef XclImpDrawing::FindDrawObj( const DffRecordHeader& rHeader ) const { /* maObjMap stores objects by position of the client data (OBJ record) in the DFF stream, which is always behind shape start position of the @@ -3769,16 +3738,16 @@ XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const DffRecordHeader& rHeade return xDrawObj; } -XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const XclObjId& rObjId ) const +XclImpDrawObjRef XclImpDrawing::FindDrawObj( sal_uInt16 nObjId ) const { XclImpDrawObjRef xDrawObj; - XclImpObjMapById::const_iterator aIt = maObjMapId.find( rObjId ); + XclImpObjMapById::const_iterator aIt = maObjMapId.find( nObjId ); if( aIt != maObjMapId.end() ) xDrawObj = aIt->second; return xDrawObj; } -const XclImpObjTextData* XclImpObjectManager::FindTextData( const DffRecordHeader& rHeader ) const +const XclImpObjTextData* XclImpDrawing::FindTextData( const DffRecordHeader& rHeader ) const { /* maTextMap stores textbox data by position of the client data (TXO record) in the DFF stream, which is always behind shape start position @@ -3792,75 +3761,46 @@ const XclImpObjTextData* XclImpObjectManager::FindTextData( const DffRecordHeade return 0; } -void XclImpObjectManager::SetSkipObj( SCTAB nScTab, sal_uInt16 nObjId ) +void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId ) { - maSkipObjs.push_back( XclObjId( nScTab, nObjId ) ); + maSkipObjs.push_back( nObjId ); } -// *** Drawing object conversion *** ------------------------------------------ - -XclImpDffManager& XclImpObjectManager::GetDffManager() +sal_Size XclImpDrawing::GetProgressSize() const { - if( !mxDffManager ) - mxDffManager.reset( new XclImpDffManager( GetRoot(), *this, maDffStrm ) ); - return *mxDffManager; + sal_Size nProgressSize = maRawObjs.GetProgressSize(); + for( XclImpObjMap::const_iterator aIt = maObjMap.begin(), aEnd = maObjMap.end(); aIt != aEnd; ++aIt ) + nProgressSize += aIt->second->GetProgressSize(); + return nProgressSize; } -void XclImpObjectManager::ConvertObjects() +void XclImpDrawing::ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" ); - - // do nothing if the document does not contain a drawing layer - if( GetDoc().GetDrawLayer() ) - { - // process list of identifiers of objects to be skipped - for( XclObjIdVec::const_iterator aVIt = maSkipObjs.begin(), aVEnd = maSkipObjs.end(); aVIt != aVEnd; ++aVIt ) - if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aVIt ).get() ) - pDrawObj->SetProcessSdrObj( false ); - - // get progress bar size for all valid objects - sal_Size nProgressSize = GetProgressSize(); - if( nProgressSize > 0 ) - { - XclImpDffManager& rDffManager = GetDffManager(); - rDffManager.StartProgressBar( nProgressSize ); - // process drawing objects without DFF data - for( XclImpDrawObjVector::const_iterator aVIt = maRawObjs.begin(), aVEnd = maRawObjs.end(); aVIt != aVEnd; ++aVIt ) - rDffManager.ProcessObject( GetSdrPage( (*aVIt)->GetScTab() ), **aVIt ); - // process the global DFF container, contains pictures - if( !maTabStrmPos.empty() && (maTabStrmPos.front() > 0) ) - rDffManager.ProcessDrawingGroup( maDffStrm ); - // process the sheet records, this inserts the objects into the drawing layer - for( StreamPosVec::const_iterator aPIt = maTabStrmPos.begin(), aPEnd = maTabStrmPos.end(); aPIt != aPEnd; ++aPIt ) - if( *aPIt != STREAM_SEEK_TO_END ) - rDffManager.ProcessDrawing( maDffStrm, *aPIt ); - } - } - ScChartListenerCollection* pChartListeners = GetDoc().GetChartListenerCollection(); - if (pChartListeners && pChartListeners->GetCount()) - pChartListeners->SetDirty(); + // register this drawing manager at the passed (global) DFF manager + rDffConv.InitializeDrawing( *this, rSdrModel, rSdrPage ); + // process list of objects to be skipped + for( ScfUInt16Vec::const_iterator aIt = maSkipObjs.begin(), aEnd = maSkipObjs.end(); aIt != aEnd; ++aIt ) + if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aIt ).get() ) + pDrawObj->SetProcessSdrObj( false ); + // process drawing objects without DFF data + rDffConv.ProcessDrawing( maRawObjs ); + // process all objects in the DFF stream + rDffConv.ProcessDrawing( maDffStrm ); + // unregister this drawing manager at the passed (global) DFF manager + rDffConv.FinalizeDrawing(); } -String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const -{ - String aDefName; - DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() ); - if( aIt != maDefObjNames.end() ) - aDefName.Append( aIt->second ); - return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId().mnObjId ) ); -} +// protected ------------------------------------------------------------------ -ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const +void XclImpDrawing::AppendRawObject( const XclImpDrawObjRef& rxDrawObj ) { - ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID ); - if( mxDffManager.is() ) - aScUsedArea = mxDffManager->GetUsedArea( nScTab ); - return aScUsedArea; + DBG_ASSERT( rxDrawObj.is(), "XclImpDrawing::AppendRawObject - unexpected empty reference" ); + maRawObjs.push_back( rxDrawObj ); } // private -------------------------------------------------------------------- -void XclImpObjectManager::ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ) // static helper +void XclImpDrawing::ReadWmf( Graphic& rGraphic, const XclImpRoot&, XclImpStream& rStrm ) // static helper { // extract graphic data from IMGDATA and following CONTINUE records rStrm.Ignore( 8 ); @@ -3873,7 +3813,7 @@ void XclImpObjectManager::ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ) // s rGraphic = aGDIMetaFile; } -void XclImpObjectManager::ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ) // static helper +void XclImpDrawing::ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ) // static helper { // extract graphic data from IMGDATA and following CONTINUE records SvMemoryStream aMemStrm; @@ -3883,7 +3823,7 @@ void XclImpObjectManager::ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ) // s pixel depth = 32 bit. After that, 3 unused bytes are added before the actual pixel data. This does even confuse Excel 5 and later, which cannot read the image data correctly. */ - if( rStrm.GetRoot().GetBiff() <= EXC_BIFF4 ) + if( rRoot.GetBiff() <= EXC_BIFF4 ) { rStrm.PushPosition(); sal_uInt32 nHdrSize; @@ -3910,21 +3850,21 @@ void XclImpObjectManager::ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ) // s rGraphic = aBitmap; } -void XclImpObjectManager::ReadDffRecord( XclImpStream& rStrm ) +void XclImpDrawing::ReadDffRecord( XclImpStream& rStrm ) { maDffStrm.Seek( STREAM_SEEK_TO_END ); rStrm.CopyRecordToStream( maDffStrm ); } -void XclImpObjectManager::ReadObj8( XclImpStream& rStrm ) +void XclImpDrawing::ReadObj8( XclImpStream& rStrm ) { - XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( rStrm ); + XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm ); // store the new object in the internal containers maObjMap[ maDffStrm.Tell() ] = xDrawObj; maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj; } -void XclImpObjectManager::ReadTxo( XclImpStream& rStrm ) +void XclImpDrawing::ReadTxo( XclImpStream& rStrm ) { XclImpObjTextRef xTextData( new XclImpObjTextData ); maTextMap[ maDffStrm.Tell() ] = xTextData; @@ -3938,7 +3878,7 @@ void XclImpObjectManager::ReadTxo( XclImpStream& rStrm ) if( xTextData->maData.mnTextLen > 0 ) { bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord(); - DBG_ASSERT( bValid, "XclImpObjectManager::ReadTxo - missing CONTINUE record" ); + DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" ); if( bValid ) xTextData->mxString.reset( new XclImpString( rStrm.ReadUniString( xTextData->maData.mnTextLen ) ) ); } @@ -3947,21 +3887,78 @@ void XclImpObjectManager::ReadTxo( XclImpStream& rStrm ) if( xTextData->maData.mnFormatSize > 0 ) { bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord(); - DBG_ASSERT( bValid, "XclImpObjectManager::ReadTxo - missing CONTINUE record" ); + DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" ); if( bValid ) xTextData->ReadFormats( rStrm ); } } -void XclImpObjectManager::ReadNote3( XclImpStream& rStrm ) +// ---------------------------------------------------------------------------- + +XclImpSheetDrawing::XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab ) : + XclImpDrawing( rRoot, true ), + maScUsedArea( ScAddress::INITIALIZE_INVALID ) +{ + maScUsedArea.aStart.SetTab( nScTab ); + maScUsedArea.aEnd.SetTab( nScTab ); +} + +void XclImpSheetDrawing::ReadNote( XclImpStream& rStrm ) +{ + switch( GetBiff() ) + { + case EXC_BIFF2: + case EXC_BIFF3: + case EXC_BIFF4: + case EXC_BIFF5: + ReadNote3( rStrm ); + break; + case EXC_BIFF8: + ReadNote8( rStrm ); + break; + default: + DBG_ERROR_BIFF(); + } +} + +void XclImpSheetDrawing::ReadTabChart( XclImpStream& rStrm ) +{ + DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 ); + ScfRef< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) ); + xChartObj->ReadChartSubStream( rStrm ); + // insert the chart as raw object without connected DFF data + AppendRawObject( xChartObj ); +} + +void XclImpSheetDrawing::ConvertObjects( XclImpDffConverter& rDffConv ) +{ + if( SdrModel* pSdrModel = GetDoc().GetDrawLayer() ) + if( SdrPage* pSdrPage = GetSdrPage( maScUsedArea.aStart.Tab() ) ) + ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage ); +} + +Rectangle XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool /*bDffAnchor*/ ) const +{ + return rAnchor.GetRect( GetDoc(), maScUsedArea.aStart.Tab(), MAP_100TH_MM ); +} + +void XclImpSheetDrawing::OnObjectInserted( const XclImpDrawObjBase& rDrawObj ) +{ + ScRange aScObjArea = rDrawObj.GetUsedArea( maScUsedArea.aStart.Tab() ); + if( aScObjArea.IsValid() ) + maScUsedArea.ExtendTo( aScObjArea ); +} + +// private -------------------------------------------------------------------- + +void XclImpSheetDrawing::ReadNote3( XclImpStream& rStrm ) { XclAddress aXclPos; sal_uInt16 nTotalLen; rStrm >> aXclPos >> nTotalLen; - SCTAB nScTab = GetCurrScTab(); ScAddress aScNotePos( ScAddress::UNINITIALIZED ); - if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, nScTab, true ) ) + if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) ) { sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.GetRecLeft() ) ); String aNoteText = rStrm.ReadRawByteString( nPartLen ); @@ -3988,33 +3985,117 @@ void XclImpObjectManager::ReadNote3( XclImpStream& rStrm ) } } -void XclImpObjectManager::ReadNote8( XclImpStream& rStrm ) +void XclImpSheetDrawing::ReadNote8( XclImpStream& rStrm ) { XclAddress aXclPos; sal_uInt16 nFlags, nObjId; rStrm >> aXclPos >> nFlags >> nObjId; - SCTAB nScTab = GetCurrScTab(); ScAddress aScNotePos( ScAddress::UNINITIALIZED ); - if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, nScTab, true ) ) + if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) ) if( nObjId != EXC_OBJ_INVALID_ID ) - if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( XclObjId( nScTab, nObjId ) ).get() ) ) + if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( nObjId ).get() ) ) pNoteObj->SetNoteData( aScNotePos, nFlags ); } -sal_Size XclImpObjectManager::GetProgressSize() const +// The object manager ========================================================= + +XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) : + XclImpRoot( rRoot ) { - sal_Size nProgressSize = maRawObjs.GetProgressSize(); - for( XclImpObjMap::const_iterator aMIt = maObjMap.begin(), aMEnd = maObjMap.end(); aMIt != aMEnd; ++aMIt ) - nProgressSize += aMIt->second->GetProgressSize(); - return nProgressSize; + maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" ); + maDefObjNames[ EXC_OBJTYPE_LINE ] = CREATE_STRING( "Line" ); + maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = CREATE_STRING( "Rectangle" ); + maDefObjNames[ EXC_OBJTYPE_OVAL ] = CREATE_STRING( "Oval" ); + maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" ); + maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" ); + maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" ); + maDefObjNames[ EXC_OBJTYPE_BUTTON ] = CREATE_STRING( "Button" ); + maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" ); + maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" ); + maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = CREATE_STRING( "Check Box" ); + maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = CREATE_STRING( "Option Button" ); + maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" ); + maDefObjNames[ EXC_OBJTYPE_LABEL ] = CREATE_STRING( "Label" ); + maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" ); + maDefObjNames[ EXC_OBJTYPE_SPIN ] = CREATE_STRING( "Spinner" ); + maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = CREATE_STRING( "Scroll Bar" ); + maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = CREATE_STRING( "List Box" ); + maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = CREATE_STRING( "Group Box" ); + maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = CREATE_STRING( "Drop Down" ); + maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" ); + maDefObjNames[ EXC_OBJTYPE_DRAWING ] = CREATE_STRING( "AutoShape" ); +} + +XclImpObjectManager::~XclImpObjectManager() +{ +} + +void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm ) +{ + DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 ); + // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm. + rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP ); + maDggStrm.Seek( STREAM_SEEK_TO_END ); + rStrm.CopyRecordToStream( maDggStrm ); +} + +XclImpSheetDrawing& XclImpObjectManager::GetSheetDrawing( SCTAB nScTab ) +{ + XclImpSheetDrawingRef& rxDrawing = maSheetDrawings[ nScTab ]; + if( !rxDrawing ) + rxDrawing.reset( new XclImpSheetDrawing( GetRoot(), nScTab ) ); + return *rxDrawing; +} + +void XclImpObjectManager::ConvertObjects() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" ); + + // do nothing if the document does not contain a drawing layer + if( !GetDoc().GetDrawLayer() ) + return; + + // get total progress bar size for all sheet drawing managers + sal_Size nProgressSize = 0; + for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt ) + nProgressSize += aIt->second->GetProgressSize(); + // nothing to do if progress bar is zero (no objects present) + if( nProgressSize == 0 ) + return; + + XclImpDffConverter aDffConv( GetRoot(), maDggStrm ); + aDffConv.StartProgressBar( nProgressSize ); + for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt ) + aIt->second->ConvertObjects( aDffConv ); + + ScChartListenerCollection* pChartListeners = GetDoc().GetChartListenerCollection(); + if( pChartListeners && (pChartListeners->GetCount() > 0) ) + pChartListeners->SetDirty(); +} + +String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const +{ + String aDefName; + DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() ); + if( aIt != maDefObjNames.end() ) + aDefName.Append( aIt->second ); + return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId() ) ); +} + +ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const +{ + XclImpSheetDrawingMap::const_iterator aIt = maSheetDrawings.find( nScTab ); + if( aIt != maSheetDrawings.end() ) + return aIt->second->GetUsedArea(); + return ScRange( ScAddress::INITIALIZE_INVALID ); } // DFF property set helper ==================================================== XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot& rRoot ) : XclImpRoot( rRoot ), - maDffManager( rRoot, maDummyStrm ) + maDffConv( rRoot, maDummyStrm ) { } @@ -4030,18 +4111,18 @@ void XclImpDffPropSet::Read( XclImpStream& rStrm ) mxMemStrm.reset( new SvMemoryStream ); rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize ); mxMemStrm->Seek( STREAM_SEEK_TO_BEGIN ); - maDffManager.ReadPropSet( *mxMemStrm, 0 ); + maDffConv.ReadPropSet( *mxMemStrm, 0 ); } sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault ) const { - return maDffManager.GetPropertyValue( nPropId, nDefault ); + return maDffConv.GetPropertyValue( nPropId, nDefault ); } void XclImpDffPropSet::FillToItemSet( SfxItemSet& rItemSet ) const { if( mxMemStrm.get() ) - maDffManager.ApplyAttributes( *mxMemStrm, rItemSet ); + maDffConv.ApplyAttributes( *mxMemStrm, rItemSet ); } XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet ) diff --git a/sc/source/filter/excel/xihelper.cxx b/sc/source/filter/excel/xihelper.cxx index 1afcba154c4a..ad04a1f3930c 100644 --- a/sc/source/filter/excel/xihelper.cxx +++ b/sc/source/filter/excel/xihelper.cxx @@ -837,7 +837,7 @@ XclImpCachedValue::~XclImpCachedValue() { } -USHORT XclImpCachedValue::GetError() const +USHORT XclImpCachedValue::GetScError() const { return (mnType == EXC_CACHEDVAL_ERROR) ? XclTools::GetScErrorCode( mnBoolErr ) : 0; } @@ -901,7 +901,7 @@ ScMatrixRef XclImpCachedMatrix::CreateScMatrix() const xScMatrix->PutBoolean( pValue->GetBool(), nScCol, nScRow ); break; case EXC_CACHEDVAL_ERROR: - xScMatrix->PutError( pValue->GetError(), nScCol, nScRow ); + xScMatrix->PutError( pValue->GetScError(), nScCol, nScRow ); break; default: DBG_ERRORFILE( "XclImpCachedMatrix::CreateScMatrix - unknown value type" ); diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx index 9f730b202e18..dc2234570ea6 100644 --- a/sc/source/filter/excel/xilink.cxx +++ b/sc/source/filter/excel/xilink.cxx @@ -413,6 +413,11 @@ void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheT switch (p->GetType()) { case EXC_CACHEDVAL_BOOL: + { + bool b = p->GetBool(); + ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(b ? 1.0 : 0.0)); + pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken); + } break; case EXC_CACHEDVAL_DOUBLE: { @@ -421,9 +426,12 @@ void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheT pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken); } break; - case EXC_CACHEDVAL_EMPTY: - break; case EXC_CACHEDVAL_ERROR: + { + double fError = XclTools::ErrorToDouble( p->GetXclError() ); + ScExternalRefCache::TokenRef pToken(new formula::FormulaDoubleToken(fError)); + pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken); + } break; case EXC_CACHEDVAL_STRING: { diff --git a/sc/source/filter/excel/xipage.cxx b/sc/source/filter/excel/xipage.cxx index 75ec91626cf6..c689d0eb7feb 100644 --- a/sc/source/filter/excel/xipage.cxx +++ b/sc/source/filter/excel/xipage.cxx @@ -168,7 +168,7 @@ void XclImpPageSettings::ReadPrintGridLines( XclImpStream& rStrm ) void XclImpPageSettings::ReadImgData( XclImpStream& rStrm ) { - Graphic aGraphic = XclImpObjectManager::ReadImgData( rStrm ); + Graphic aGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm ); if( aGraphic.GetType() != GRAPHIC_NONE ) maData.mxBrushItem.reset( new SvxBrushItem( aGraphic, GPOS_TILED, ATTR_BACKGROUND ) ); } diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx index ac184224c611..29e27a698a42 100644 --- a/sc/source/filter/excel/xipivot.cxx +++ b/sc/source/filter/excel/xipivot.cxx @@ -1311,7 +1311,7 @@ void XclImpPivotTable::ReadSxpi( XclImpStream& rStrm ) maPageFields.push_back( aPageInfo.mnField ); pField->SetPageFieldInfo( aPageInfo ); } - GetObjectManager().SetSkipObj( GetCurrScTab(), aPageInfo.mnObjId ); + GetCurrSheetDrawing().SetSkipObj( aPageInfo.mnObjId ); } } diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx index 7b03d56408c9..3384cf248c87 100644 --- a/sc/source/filter/excel/xiroot.cxx +++ b/sc/source/filter/excel/xiroot.cxx @@ -206,6 +206,12 @@ XclImpObjectManager& XclImpRoot::GetObjectManager() const return *mrImpData.mxObjMgr; } +XclImpSheetDrawing& XclImpRoot::GetCurrSheetDrawing() const +{ + DBG_ASSERT( !IsInGlobals(), "XclImpRoot::GetCurrSheetDrawing - must not be called from workbook globals" ); + return mrImpData.mxObjMgr->GetSheetDrawing( GetCurrScTab() ); +} + XclImpCondFormatManager& XclImpRoot::GetCondFormatManager() const { DBG_ASSERT( mrImpData.mxCondFmtMgr.is(), "XclImpRoot::GetCondFormatManager - invalid call, wrong BIFF" ); diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx index 4e0ff5079471..1559ef5530f5 100644 --- a/sc/source/filter/excel/xistyle.cxx +++ b/sc/source/filter/excel/xistyle.cxx @@ -701,7 +701,6 @@ void XclImpCellAlign::FillToItemSet( SfxItemSet& rItemSet, const XclImpFont* pFo sal_uInt8 nXclRot = (mnOrient == EXC_ORIENT_NONE) ? mnRotation : XclTools::GetXclRotFromOrient( mnOrient ); bool bStacked = (nXclRot == EXC_ROT_STACKED); ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, bStacked ), bSkipPoolDefs ); - ScfTools::PutItem( rItemSet, SvxRotateModeItem( SVX_ROTATE_MODE_STANDARD, ATTR_ROTATE_MODE ), bSkipPoolDefs ); // set an angle in the range from -90 to 90 degrees sal_Int32 nAngle = XclTools::GetScRotation( nXclRot, 0 ); ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, nAngle ), bSkipPoolDefs ); @@ -799,6 +798,15 @@ void XclImpCellBorder::FillFromCF8( sal_uInt16 nLineStyle, sal_uInt32 nLineColor mbDiagUsed = false; } +bool XclImpCellBorder::HasAnyOuterBorder() const +{ + return + (mbLeftUsed && (mnLeftLine != EXC_LINE_NONE)) || + (mbRightUsed && (mnRightLine != EXC_LINE_NONE)) || + (mbTopUsed && (mnTopLine != EXC_LINE_NONE)) || + (mbBottomUsed && (mnBottomLine != EXC_LINE_NONE)); +} + namespace { /** Converts the passed line style to a SvxBorderLine, or returns false, if style is "no line". */ @@ -1091,13 +1099,32 @@ const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs ) // create new pattern attribute set mpPattern.reset( new ScPatternAttr( GetDoc().GetPool() ) ); SfxItemSet& rItemSet = mpPattern->GetItemSet(); + XclImpXF* pParentXF = IsCellXF() ? GetXFBuffer().GetXF( mnParent ) : 0; // parent cell style if( IsCellXF() && !mpStyleSheet ) { mpStyleSheet = GetXFBuffer().CreateStyleSheet( mnParent ); - if( XclImpXF* pParentXF = GetXFBuffer().GetXF( mnParent ) ) - UpdateUsedFlags( *pParentXF ); + + /* Enables mb***Used flags, if the formatting attributes differ from + the passed XF record. In cell XFs Excel uses the cell attributes, + if they differ from the parent style XF. + #109899# ...or if the respective flag is not set in parent style XF. */ + if( pParentXF ) + { + if( !mbProtUsed ) + mbProtUsed = !pParentXF->mbProtUsed || !(maProtection == pParentXF->maProtection); + if( !mbFontUsed ) + mbFontUsed = !pParentXF->mbFontUsed || (mnXclFont != pParentXF->mnXclFont); + if( !mbFmtUsed ) + mbFmtUsed = !pParentXF->mbFmtUsed || (mnXclNumFmt != pParentXF->mnXclNumFmt); + if( !mbAlignUsed ) + mbAlignUsed = !pParentXF->mbAlignUsed || !(maAlignment == pParentXF->maAlignment); + if( !mbBorderUsed ) + mbBorderUsed = !pParentXF->mbBorderUsed || !(maBorder == pParentXF->maBorder); + if( !mbAreaUsed ) + mbAreaUsed = !pParentXF->mbAreaUsed || !(maArea == pParentXF->maArea); + } } // cell protection @@ -1137,6 +1164,20 @@ const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs ) maArea.mnPattern != EXC_PATT_SOLID); } + /* #i38709# Decide which rotation reference mode to use. If any outer + border line of the cell is set (either explicitly or via cell style), + and the cell contents are rotated, set rotation reference to bottom of + cell. This causes the borders to be painted rotated with the text. */ + if( mbAlignUsed || mbBorderUsed ) + { + SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD; + const XclImpCellAlign* pAlign = mbAlignUsed ? &maAlignment : (pParentXF ? &pParentXF->maAlignment : 0); + const XclImpCellBorder* pBorder = mbBorderUsed ? &maBorder : (pParentXF ? &pParentXF->maBorder : 0); + if( pAlign && pBorder && (0 < pAlign->mnRotation) && (pAlign->mnRotation <= 180) && pBorder->HasAnyOuterBorder() ) + eRotateMode = SVX_ROTATE_MODE_BOTTOM; + ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs ); + } + return *mpPattern; } @@ -1180,26 +1221,6 @@ void XclImpXF::SetUsedFlags( sal_uInt8 nUsedFlags ) mbAreaUsed = (mbCellXF == ::get_flag( nUsedFlags, EXC_XF_DIFF_AREA )); } -void XclImpXF::UpdateUsedFlags( const XclImpXF& rParentXF ) -{ - /* Enables mb***Used flags, if the formatting attributes differ from - the passed XF record. In cell XFs Excel uses the cell attributes, - if they differ from the parent style XF. - #109899# ...or if the respective flag is not set in parent style XF. */ - if( !mbProtUsed ) - mbProtUsed = !rParentXF.mbProtUsed || !(maProtection == rParentXF.maProtection); - if( !mbFontUsed ) - mbFontUsed = !rParentXF.mbFontUsed || (mnXclFont != rParentXF.mnXclFont); - if( !mbFmtUsed ) - mbFmtUsed = !rParentXF.mbFmtUsed || (mnXclNumFmt != rParentXF.mnXclNumFmt); - if( !mbAlignUsed ) - mbAlignUsed = !rParentXF.mbAlignUsed || !(maAlignment == rParentXF.maAlignment); - if( !mbBorderUsed ) - mbBorderUsed = !rParentXF.mbBorderUsed || !(maBorder == rParentXF.maBorder); - if( !mbAreaUsed ) - mbAreaUsed = !rParentXF.mbAreaUsed || !(maArea == rParentXF.maArea); -} - // ---------------------------------------------------------------------------- XclImpStyle::XclImpStyle( const XclImpRoot& rRoot ) : diff --git a/sc/source/filter/excel/xlchart.cxx b/sc/source/filter/excel/xlchart.cxx index 2391eb7ef92e..41e682f85808 100644 --- a/sc/source/filter/excel/xlchart.cxx +++ b/sc/source/filter/excel/xlchart.cxx @@ -308,7 +308,7 @@ XclChTypeGroup::XclChTypeGroup() : // ---------------------------------------------------------------------------- XclChProperties::XclChProperties() : - mnFlags( EXC_CHPROPS_MANSERIES ), + mnFlags( 0 ), mnEmptyMode( EXC_CHPROPS_EMPTY_SKIP ) { } @@ -988,8 +988,8 @@ void XclChPropSetHelper::ReadLegendProperties( XclChLegend& rLegend, const ScfPr cssc::RelativePosition aRelPos; if( aRelPosAny >>= aRelPos ) { - rLegend.maRect.mnX = limit_cast< sal_Int32 >( aRelPos.Primary * 4000.0, 0, 4000 ); - rLegend.maRect.mnY = limit_cast< sal_Int32 >( aRelPos.Secondary * 4000.0, 0, 4000 ); + rLegend.maRect.mnX = limit_cast< sal_Int32 >( aRelPos.Primary * EXC_CHART_UNIT, 0, EXC_CHART_UNIT ); + rLegend.maRect.mnY = limit_cast< sal_Int32 >( aRelPos.Secondary * EXC_CHART_UNIT, 0, EXC_CHART_UNIT ); } else rLegend.mnDockMode = EXC_CHLEGEND_LEFT; @@ -1240,8 +1240,8 @@ void XclChPropSetHelper::WriteLegendProperties( eApiExpand = cssc::LegendExpansion_BALANCED; // set position cssc::RelativePosition aRelPos; - aRelPos.Primary = rLegend.maRect.mnX / 4000.0; - aRelPos.Secondary = rLegend.maRect.mnY / 4000.0; + aRelPos.Primary = static_cast< double >( rLegend.maRect.mnX ) / EXC_CHART_UNIT; + aRelPos.Secondary = static_cast< double >( rLegend.maRect.mnY ) / EXC_CHART_UNIT; aRelPos.Anchor = cssd::Alignment_TOP_LEFT; aRelPosAny <<= aRelPos; } diff --git a/sc/source/filter/excel/xlescher.cxx b/sc/source/filter/excel/xlescher.cxx index 5d74346608fd..538fd7fd7242 100644 --- a/sc/source/filter/excel/xlescher.cxx +++ b/sc/source/filter/excel/xlescher.cxx @@ -159,12 +159,16 @@ void lclMirrorRectangle( Rectangle& rRect ) rRect.Right() = -nLeft; } +sal_uInt16 lclGetEmbeddedScale( long nPageSize, sal_Int32 nPageScale, long nPos, double fPosScale ) +{ + return static_cast< sal_uInt16 >( nPos * fPosScale / nPageSize * nPageScale + 0.5 ); +} + } // namespace // ---------------------------------------------------------------------------- -XclObjAnchor::XclObjAnchor( SCTAB nScTab ) : - mnScTab( nScTab ), +XclObjAnchor::XclObjAnchor() : mnLX( 0 ), mnTY( 0 ), mnRX( 0 ), @@ -172,35 +176,61 @@ XclObjAnchor::XclObjAnchor( SCTAB nScTab ) : { } -Rectangle XclObjAnchor::GetRect( ScDocument& rDoc, MapUnit eMapUnit ) const +Rectangle XclObjAnchor::GetRect( ScDocument& rDoc, SCTAB nScTab, MapUnit eMapUnit ) const { double fScale = lclGetTwipsScale( eMapUnit ); Rectangle aRect( - lclGetXFromCol( rDoc, mnScTab, maFirst.mnCol, mnLX, fScale ), - lclGetYFromRow( rDoc, mnScTab, maFirst.mnRow, mnTY, fScale ), - lclGetXFromCol( rDoc, mnScTab, maLast.mnCol, mnRX + 1, fScale ), - lclGetYFromRow( rDoc, mnScTab, maLast.mnRow, mnBY, fScale ) ); + lclGetXFromCol( rDoc, nScTab, maFirst.mnCol, mnLX, fScale ), + lclGetYFromRow( rDoc, nScTab, maFirst.mnRow, mnTY, fScale ), + lclGetXFromCol( rDoc, nScTab, maLast.mnCol, mnRX + 1, fScale ), + lclGetYFromRow( rDoc, nScTab, maLast.mnRow, mnBY, fScale ) ); // #106948# adjust coordinates in mirrored sheets - if( rDoc.IsLayoutRTL( mnScTab ) ) + if( rDoc.IsLayoutRTL( nScTab ) ) lclMirrorRectangle( aRect ); return aRect; } -void XclObjAnchor::SetRect( ScDocument& rDoc, const Rectangle& rRect, MapUnit eMapUnit ) +void XclObjAnchor::SetRect( ScDocument& rDoc, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit ) { Rectangle aRect( rRect ); // #106948# adjust coordinates in mirrored sheets - if( rDoc.IsLayoutRTL( mnScTab ) ) + if( rDoc.IsLayoutRTL( nScTab ) ) lclMirrorRectangle( aRect ); double fScale = lclGetTwipsScale( eMapUnit ); long nDummy = 0; - lclGetColFromX( rDoc, mnScTab, maFirst.mnCol, mnLX, 0, nDummy, aRect.Left(), fScale ); - lclGetColFromX( rDoc, mnScTab, maLast.mnCol, mnRX, maFirst.mnCol, nDummy, aRect.Right(), fScale ); + lclGetColFromX( rDoc, nScTab, maFirst.mnCol, mnLX, 0, nDummy, aRect.Left(), fScale ); + lclGetColFromX( rDoc, nScTab, maLast.mnCol, mnRX, maFirst.mnCol, nDummy, aRect.Right(), fScale ); nDummy = 0; - lclGetRowFromY( rDoc, mnScTab, maFirst.mnRow, mnTY, 0, nDummy, aRect.Top(), fScale ); - lclGetRowFromY( rDoc, mnScTab, maLast.mnRow, mnBY, maFirst.mnRow, nDummy, aRect.Bottom(), fScale ); + lclGetRowFromY( rDoc, nScTab, maFirst.mnRow, mnTY, 0, nDummy, aRect.Top(), fScale ); + lclGetRowFromY( rDoc, nScTab, maLast.mnRow, mnBY, maFirst.mnRow, nDummy, aRect.Bottom(), fScale ); +} + +void XclObjAnchor::SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY, + const Rectangle& rRect, MapUnit eMapUnit, bool bDffAnchor ) +{ + double fScale = 1.0; + switch( eMapUnit ) + { + case MAP_TWIP: fScale = HMM_PER_TWIPS; break; // Calc twips -> 1/100mm + case MAP_100TH_MM: fScale = 1.0; break; // Calc 1/100mm -> 1/100mm + default: DBG_ERRORFILE( "XclObjAnchor::SetRect - map unit not implemented" ); + } + + /* In objects with DFF client anchor, the position of the shape is stored + in the cell address components of the client anchor. In old BIFF3-BIFF5 + objects, the position is stored in the offset components of the anchor. */ + (bDffAnchor ? maFirst.mnCol : mnLX) = lclGetEmbeddedScale( rPageSize.Width(), nScaleX, rRect.Left(), fScale ); + (bDffAnchor ? maFirst.mnRow : mnTY) = lclGetEmbeddedScale( rPageSize.Height(), nScaleY, rRect.Top(), fScale ); + (bDffAnchor ? maLast.mnCol : mnRX) = lclGetEmbeddedScale( rPageSize.Width(), nScaleX, rRect.Right(), fScale ); + (bDffAnchor ? maLast.mnRow : mnBY) = lclGetEmbeddedScale( rPageSize.Height(), nScaleY, rRect.Bottom(), fScale ); + + // for safety, clear the other members + if( bDffAnchor ) + mnLX = mnTY = mnRX = mnBY = 0; + else + Set( 0, 0, 0, 0 ); } // ---------------------------------------------------------------------------- diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx index c46df189ab74..d613f1279242 100644 --- a/sc/source/filter/excel/xlformula.cxx +++ b/sc/source/filter/excel/xlformula.cxx @@ -68,22 +68,28 @@ const sal_uInt8 A = EXC_TOKCLASS_ARR; #define VR_E { EXC_PARAM_EXCELONLY, EXC_PARAMCONV_RPT, true } #define C { EXC_PARAM_CALCONLY, EXC_PARAMCONV_ORG, false } +const sal_uInt16 NOID = SAL_MAX_UINT16; /// No BIFF/OOBIN function identifier available. +const sal_uInt8 MX = 30; /// Maximum parameter count. + +#define EXC_FUNCNAME( ascii ) "_xlfn." ascii +#define EXC_FUNCNAME_ODF( ascii ) "_xlfnodf." ascii + /** Functions new in BIFF2. */ static const XclFunctionInfo saFuncTable_2[] = { - { ocCount, 0, 0, 30, V, { RX }, 0, 0 }, + { ocCount, 0, 0, MX, V, { RX }, 0, 0 }, { ocIf, 1, 2, 3, R, { VO, RO }, 0, 0 }, { ocIsNA, 2, 1, 1, V, { VR }, 0, 0 }, { ocIsError, 3, 1, 1, V, { VR }, 0, 0 }, - { ocSum, 4, 0, 30, V, { RX }, 0, 0 }, - { ocAverage, 5, 1, 30, V, { RX }, 0, 0 }, - { ocMin, 6, 1, 30, V, { RX }, 0, 0 }, - { ocMax, 7, 1, 30, V, { RX }, 0, 0 }, + { ocSum, 4, 0, MX, V, { RX }, 0, 0 }, + { ocAverage, 5, 1, MX, V, { RX }, 0, 0 }, + { ocMin, 6, 1, MX, V, { RX }, 0, 0 }, + { ocMax, 7, 1, MX, V, { RX }, 0, 0 }, { ocRow, 8, 0, 1, V, { RO }, 0, 0 }, { ocColumn, 9, 0, 1, V, { RO }, 0, 0 }, { ocNotAvail, 10, 0, 0, V, {}, 0, 0 }, - { ocNPV, 11, 2, 30, V, { VR, RX }, 0, 0 }, - { ocStDev, 12, 1, 30, V, { RX }, 0, 0 }, + { ocNPV, 11, 2, MX, V, { VR, RX }, 0, 0 }, + { ocStDev, 12, 1, MX, V, { RX }, 0, 0 }, { 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 }, @@ -109,8 +115,8 @@ static const XclFunctionInfo saFuncTable_2[] = { ocValue, 33, 1, 1, V, { VR }, 0, 0 }, { ocTrue, 34, 0, 0, V, {}, 0, 0 }, { ocFalse, 35, 0, 0, V, {}, 0, 0 }, - { ocAnd, 36, 1, 30, V, { RX }, 0, 0 }, - { ocOr, 37, 1, 30, V, { RX }, 0, 0 }, + { ocAnd, 36, 1, MX, V, { RX }, 0, 0 }, + { ocOr, 37, 1, MX, V, { RX }, 0, 0 }, { ocNot, 38, 1, 1, V, { VR }, 0, 0 }, { ocMod, 39, 2, 2, V, { VR }, 0, 0 }, { ocDBCount, 40, 3, 3, V, { RO, RR }, 0, 0 }, @@ -119,7 +125,7 @@ static const XclFunctionInfo saFuncTable_2[] = { ocDBMin, 43, 3, 3, V, { RO, RR }, 0, 0 }, { ocDBMax, 44, 3, 3, V, { RO, RR }, 0, 0 }, { ocDBStdDev, 45, 3, 3, V, { RO, RR }, 0, 0 }, - { ocVar, 46, 1, 30, V, { RX }, 0, 0 }, + { ocVar, 46, 1, MX, V, { RX }, 0, 0 }, { ocDBVar, 47, 3, 3, V, { RO, RR }, 0, 0 }, { ocText, 48, 2, 2, V, { VR }, 0, 0 }, { ocRGP, 49, 1, 2, A, { RA, RA, C, C }, 0, 0 }, @@ -155,7 +161,7 @@ static const XclFunctionInfo saFuncTable_2[] = { ocArcTan2, 97, 2, 2, V, { VR }, 0, 0 }, { ocArcSin, 98, 1, 1, V, { VR }, 0, 0 }, { ocArcCos, 99, 1, 1, V, { VR }, 0, 0 }, - { ocChose, 100, 2, 30, R, { VO, RO }, 0, 0 }, + { ocChose, 100, 2, MX, R, { VO, RO }, 0, 0 }, { ocHLookup, 101, 3, 3, V, { VV, RO, RO, C }, 0, 0 }, { ocVLookup, 102, 3, 3, V, { VV, RO, RO, C }, 0, 0 }, { ocIsRef, 105, 1, 1, V, { RX }, 0, 0 }, @@ -191,13 +197,13 @@ static const XclFunctionInfo saFuncTable_2[] = { ocMatMult, 165, 2, 2, A, { VA }, 0, 0 }, { ocZinsZ, 167, 4, 6, V, { VR }, 0, 0 }, { ocKapz, 168, 4, 6, V, { VR }, 0, 0 }, - { ocCount2, 169, 0, 30, V, { RX }, 0, 0 }, - { ocProduct, 183, 0, 30, V, { RX }, 0, 0 }, + { ocCount2, 169, 0, MX, V, { RX }, 0, 0 }, + { ocProduct, 183, 0, MX, V, { RX }, 0, 0 }, { ocFact, 184, 1, 1, V, { VR }, 0, 0 }, { ocDBProduct, 189, 3, 3, V, { RO, RR }, 0, 0 }, { ocIsNonString, 190, 1, 1, V, { VR }, 0, 0 }, - { ocStDevP, 193, 1, 30, V, { RX }, 0, 0 }, - { ocVarP, 194, 1, 30, V, { RX }, 0, 0 }, + { ocStDevP, 193, 1, MX, V, { RX }, 0, 0 }, + { ocVarP, 194, 1, MX, V, { RX }, 0, 0 }, { ocDBStdDevP, 195, 3, 3, V, { RO, RR }, 0, 0 }, { ocDBVarP, 196, 3, 3, V, { RO, RR }, 0, 0 }, { ocTrunc, 197, 1, 1, V, { VR, C }, 0, 0 }, @@ -206,7 +212,7 @@ static const XclFunctionInfo saFuncTable_2[] = { ocCurrency, 204, 1, 2, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, 0 }, { ocRoundUp, 212, 2, 2, V, { VR }, 0, 0 }, { ocRoundDown, 213, 2, 2, V, { VR }, 0, 0 }, - { ocExternal, 255, 1, 30, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 } + { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_IMPORTONLY, 0 } }; /** Functions new in BIFF3. */ @@ -221,8 +227,8 @@ static const XclFunctionInfo saFuncTable_3[] = { ocGetDiffDate360, 220, 2, 2, V, { VR, VR, C }, 0, 0 }, { ocGetActDate, 221, 0, 0, V, {}, EXC_FUNCFLAG_VOLATILE, 0 }, { ocVBD, 222, 5, 7, V, { VR }, 0, 0 }, - { ocMedian, 227, 1, 30, V, { RX }, 0, 0 }, - { ocSumProduct, 228, 1, 30, V, { VA }, 0, 0 }, + { ocMedian, 227, 1, MX, V, { RX }, 0, 0 }, + { ocSumProduct, 228, 1, MX, V, { VA }, 0, 0 }, { ocSinHyp, 229, 1, 1, V, { VR }, 0, 0 }, { ocCosHyp, 230, 1, 1, V, { VR }, 0, 0 }, { ocTanHyp, 231, 1, 1, V, { VR }, 0, 0 }, @@ -245,7 +251,7 @@ static const XclFunctionInfo saFuncTable_4[] = { ocGDA2, 247, 4, 5, V, { VR }, 0, 0 }, { ocFrequency, 252, 2, 2, A, { RA }, 0, 0 }, { ocErrorType, 261, 1, 1, V, { VR }, 0, 0 }, - { ocAveDev, 269, 1, 30, V, { RX }, 0, 0 }, + { ocAveDev, 269, 1, MX, V, { RX }, 0, 0 }, { ocBetaDist, 270, 3, 5, V, { VR }, 0, 0 }, { ocGammaLn, 271, 1, 1, V, { VR }, 0, 0 }, { ocBetaInv, 272, 3, 5, V, { VR }, 0, 0 }, @@ -294,19 +300,19 @@ static const XclFunctionInfo saFuncTable_4[] = { ocSlope, 315, 2, 2, V, { VA }, 0, 0 }, { ocTTest, 316, 4, 4, V, { VA, VA, VR }, 0, 0 }, { ocProb, 317, 3, 4, V, { VA, VA, VR }, 0, 0 }, - { ocDevSq, 318, 1, 30, V, { RX }, 0, 0 }, - { ocGeoMean, 319, 1, 30, V, { RX }, 0, 0 }, - { ocHarMean, 320, 1, 30, V, { RX }, 0, 0 }, - { ocSumSQ, 321, 0, 30, V, { RX }, 0, 0 }, - { ocKurt, 322, 1, 30, V, { RX }, 0, 0 }, - { ocSchiefe, 323, 1, 30, V, { RX }, 0, 0 }, + { ocDevSq, 318, 1, MX, V, { RX }, 0, 0 }, + { ocGeoMean, 319, 1, MX, V, { RX }, 0, 0 }, + { ocHarMean, 320, 1, MX, V, { RX }, 0, 0 }, + { ocSumSQ, 321, 0, MX, V, { RX }, 0, 0 }, + { ocKurt, 322, 1, MX, V, { RX }, 0, 0 }, + { ocSchiefe, 323, 1, MX, V, { RX }, 0, 0 }, { ocZTest, 324, 2, 3, V, { RX, VR }, 0, 0 }, { ocLarge, 325, 2, 2, V, { RX, VR }, 0, 0 }, { ocSmall, 326, 2, 2, V, { RX, VR }, 0, 0 }, { ocQuartile, 327, 2, 2, V, { RX, VR }, 0, 0 }, { ocPercentile, 328, 2, 2, V, { RX, VR }, 0, 0 }, { ocPercentrank, 329, 2, 3, V, { RX, VR, VR_E }, 0, 0 }, - { ocModalValue, 330, 1, 30, V, { VA }, 0, 0 }, + { ocModalValue, 330, 1, MX, V, { VA }, 0, 0 }, { ocTrimMean, 331, 2, 2, V, { RX, VR }, 0, 0 }, { ocTInv, 332, 2, 2, V, { VR }, 0, 0 } }; @@ -318,13 +324,13 @@ static const XclFunctionInfo saFuncTable_5[] = { ocHLookup, 101, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4 { ocVLookup, 102, 3, 4, V, { VV, RO, RO, VV }, 0, 0 }, // BIFF2-4: 3, BIFF5: 3-4 { ocGetDiffDate360, 220, 2, 3, V, { VR }, 0, 0 }, // BIFF3-4: 2, BIFF5: 2-3 - { ocMacro, 255, 1, 30, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 }, - { ocExternal, 255, 1, 30, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 }, - { ocConcat, 336, 0, 30, V, { VR }, 0, 0 }, + { ocMacro, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 }, + { ocExternal, 255, 1, MX, R, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, 0 }, + { ocConcat, 336, 0, MX, V, { VR }, 0, 0 }, { ocPower, 337, 2, 2, V, { VR }, 0, 0 }, { ocRad, 342, 1, 1, V, { VR }, 0, 0 }, { ocDeg, 343, 1, 1, V, { VR }, 0, 0 }, - { ocSubTotal, 344, 2, 30, V, { VR, RO }, 0, 0 }, + { ocSubTotal, 344, 2, MX, V, { VR, RO }, 0, 0 }, { ocSumIf, 345, 2, 3, V, { RO, VR, RO }, 0, 0 }, { ocCountIf, 346, 2, 2, V, { RO, VR }, 0, 0 }, { ocCountEmptyCells, 347, 1, 1, V, { RO }, 0, 0 }, @@ -335,66 +341,90 @@ static const XclFunctionInfo saFuncTable_5[] = { ocRoman, 354, 1, 2, V, { VR }, 0, 0 } }; -#define EXC_FUNCNAME_PREFIX "_xlfn." - -const sal_Char* const EXC_FUNCNAME_BAHTTEXT = EXC_FUNCNAME_PREFIX "BAHTTEXT"; - /** Functions new in BIFF8. Unsupported functions: PHONETIC. */ static const XclFunctionInfo saFuncTable_8[] = { - { ocGetPivotData, 358, 2, 30, V, { RR, RR, VR }, 0, 0 }, + { ocGetPivotData, 358, 2, MX, V, { RR, RR, VR }, 0, 0 }, { ocHyperLink, 359, 1, 2, V, { VV, VO }, 0, 0 }, { ocNoName, 360, 1, 1, V, { RO }, EXC_FUNCFLAG_IMPORTONLY, 0 }, // PHONETIC - { ocAverageA, 361, 1, 30, V, { RX }, 0, 0 }, - { ocMaxA, 362, 1, 30, V, { RX }, 0, 0 }, - { ocMinA, 363, 1, 30, V, { RX }, 0, 0 }, - { ocStDevPA, 364, 1, 30, V, { RX }, 0, 0 }, - { ocVarPA, 365, 1, 30, V, { RX }, 0, 0 }, - { ocStDevA, 366, 1, 30, V, { RX }, 0, 0 }, - { ocVarA, 367, 1, 30, V, { RX }, 0, 0 }, - { ocBahtText, 368, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME_BAHTTEXT }, - { ocBahtText, 255, 2, 2, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME_BAHTTEXT }, + { ocAverageA, 361, 1, MX, V, { RX }, 0, 0 }, + { ocMaxA, 362, 1, MX, V, { RX }, 0, 0 }, + { ocMinA, 363, 1, MX, V, { RX }, 0, 0 }, + { ocStDevPA, 364, 1, MX, V, { RX }, 0, 0 }, + { ocVarPA, 365, 1, MX, V, { RX }, 0, 0 }, + { ocStDevA, 366, 1, MX, V, { RX }, 0, 0 }, + { ocVarA, 367, 1, MX, V, { RX }, 0, 0 }, + { ocBahtText, 368, 1, 1, V, { VR }, EXC_FUNCFLAG_IMPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) }, + { ocBahtText, 255, 2, 2, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, EXC_FUNCNAME( "BAHTTEXT" ) }, { ocEuroConvert, 255, 4, 6, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY, "EUROCONVERT" } }; +#define EXC_FUNCENTRY_ODF( opcode, minparam, maxparam, flags, asciiname ) \ + { opcode, NOID, minparam, maxparam, V, { VR }, EXC_FUNCFLAG_IMPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) }, \ + { opcode, 255, (minparam)+1, (maxparam)+1, V, { RO_E, RO }, EXC_FUNCFLAG_EXPORTONLY|(flags), EXC_FUNCNAME_ODF( asciiname ) } + +/** Functions defined by OpenFormula, but not supported by Calc (ocNoName) or by Excel (defined op-code). */ +static const XclFunctionInfo saFuncTable_Odf[] = +{ + EXC_FUNCENTRY_ODF( ocArabic, 1, 1, 0, "ARABIC" ), + EXC_FUNCENTRY_ODF( ocB, 3, 4, 0, "B" ), + EXC_FUNCENTRY_ODF( ocBase, 2, 3, 0, "BASE" ), + EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITAND" ), + EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITLSHIFT" ), + EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITOR" ), + EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITRSHIFT" ), + EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "BITXOR" ), + EXC_FUNCENTRY_ODF( ocChiSqDist, 2, 3, 0, "CHISQDIST" ), + EXC_FUNCENTRY_ODF( ocChiSqInv, 2, 2, 0, "CHISQINV" ), + EXC_FUNCENTRY_ODF( ocKombin2, 2, 2, 0, "COMBINA" ), + EXC_FUNCENTRY_ODF( ocGetDiffDate, 2, 2, 0, "DAYS" ), + EXC_FUNCENTRY_ODF( ocDecimal, 2, 2, 0, "DECIMAL" ), + EXC_FUNCENTRY_ODF( ocFDist, 3, 4, 0, "FDIST" ), + EXC_FUNCENTRY_ODF( ocFInv, 3, 3, 0, "FINV" ), + EXC_FUNCENTRY_ODF( ocFormula, 1, 1, 0, "FORMULA" ), + EXC_FUNCENTRY_ODF( ocGamma, 1, 1, 0, "GAMMA" ), + EXC_FUNCENTRY_ODF( ocGauss, 1, 1, 0, "GAUSS" ), + EXC_FUNCENTRY_ODF( ocNoName, 2, 2, 0, "IFNA" ), + EXC_FUNCENTRY_ODF( ocIsFormula, 1, 1, 0, "ISFORMULA" ), + EXC_FUNCENTRY_ODF( ocWeek, 1, 2, 0, "ISOWEEKNUM" ), + EXC_FUNCENTRY_ODF( ocMatrixUnit, 1, 1, 0, "MUNIT" ), + EXC_FUNCENTRY_ODF( ocNumberValue, 2, 2, 0, "NUMBERVALUE" ), + EXC_FUNCENTRY_ODF( ocLaufz, 3, 3, 0, "PDURATION" ), + EXC_FUNCENTRY_ODF( ocVariationen2, 2, 2, 0, "PERMUTATIONA" ), + EXC_FUNCENTRY_ODF( ocPhi, 1, 1, 0, "PHI" ), + EXC_FUNCENTRY_ODF( ocZGZ, 3, 3, 0, "RRI" ), + EXC_FUNCENTRY_ODF( ocTable, 1, 1, 0, "SHEET" ), + EXC_FUNCENTRY_ODF( ocTables, 0, 1, 0, "SHEETS" ), + EXC_FUNCENTRY_ODF( ocNoName, 1, MX, 0, "SKEWP" ), + EXC_FUNCENTRY_ODF( ocUnichar, 1, 1, 0, "UNICHAR" ), + EXC_FUNCENTRY_ODF( ocUnicode, 1, 1, 0, "UNICODE" ), + EXC_FUNCENTRY_ODF( ocNoName, 1, MX, 0, "XOR" ) +}; + +#undef EXC_FUNCENTRY_ODF + // ---------------------------------------------------------------------------- XclFunctionProvider::XclFunctionProvider( const XclRoot& rRoot ) { - XclBiff eBiff = rRoot.GetBiff(); + void (XclFunctionProvider::*pFillFunc)( const XclFunctionInfo*, const XclFunctionInfo* ) = + rRoot.IsImport() ? &XclFunctionProvider::FillXclFuncMap : &XclFunctionProvider::FillScFuncMap; - if( rRoot.IsImport() ) - { - /* Import: only read functions supported in the current BIFF version. - Function tables from later BIFF versions may overwrite single - functions from earlier tables. */ - if( eBiff >= EXC_BIFF2 ) - FillXclFuncMap( saFuncTable_2, STATIC_TABLE_END( saFuncTable_2 ) ); - if( eBiff >= EXC_BIFF3 ) - FillXclFuncMap( saFuncTable_3, STATIC_TABLE_END( saFuncTable_3 ) ); - if( eBiff >= EXC_BIFF4 ) - FillXclFuncMap( saFuncTable_4, STATIC_TABLE_END( saFuncTable_4 ) ); - if( eBiff >= EXC_BIFF5 ) - FillXclFuncMap( saFuncTable_5, STATIC_TABLE_END( saFuncTable_5 ) ); - if( eBiff >= EXC_BIFF8 ) - FillXclFuncMap( saFuncTable_8, STATIC_TABLE_END( saFuncTable_8 ) ); - } - else - { - /* Export: only write functions supported in the current BIFF version. - Function tables from later BIFF versions may overwrite single - functions from earlier tables. */ - if( eBiff >= EXC_BIFF2 ) - FillScFuncMap( saFuncTable_2, STATIC_TABLE_END( saFuncTable_2 ) ); - if( eBiff >= EXC_BIFF3 ) - FillScFuncMap( saFuncTable_3, STATIC_TABLE_END( saFuncTable_3 ) ); - if( eBiff >= EXC_BIFF4 ) - FillScFuncMap( saFuncTable_4, STATIC_TABLE_END( saFuncTable_4 ) ); - if( eBiff >= EXC_BIFF5 ) - FillScFuncMap( saFuncTable_5, STATIC_TABLE_END( saFuncTable_5 ) ); - if( eBiff >= EXC_BIFF8 ) - FillScFuncMap( saFuncTable_8, STATIC_TABLE_END( saFuncTable_8 ) ); - } + /* Only read/write functions supported in the current BIFF version. + Function tables from later BIFF versions may overwrite single functions + from earlier tables. */ + XclBiff eBiff = rRoot.GetBiff(); + if( eBiff >= EXC_BIFF2 ) + (this->*pFillFunc)( saFuncTable_2, STATIC_TABLE_END( saFuncTable_2 ) ); + if( eBiff >= EXC_BIFF3 ) + (this->*pFillFunc)( saFuncTable_3, STATIC_TABLE_END( saFuncTable_3 ) ); + if( eBiff >= EXC_BIFF4 ) + (this->*pFillFunc)( saFuncTable_4, STATIC_TABLE_END( saFuncTable_4 ) ); + if( eBiff >= EXC_BIFF5 ) + (this->*pFillFunc)( saFuncTable_5, STATIC_TABLE_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 ) ); } const XclFunctionInfo* XclFunctionProvider::GetFuncInfoFromXclFunc( sal_uInt16 nXclFunc ) const diff --git a/sc/source/filter/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx index 926eb3e54fdc..90393ae6a787 100644 --- a/sc/source/filter/excel/xltools.cxx +++ b/sc/source/filter/excel/xltools.cxx @@ -113,7 +113,12 @@ const XclGuid XclTools::maGuidFileMoniker( double XclTools::GetDoubleFromRK( sal_Int32 nRKValue ) { - double fVal = 0.0; + union + { + double fVal; + sal_math_Double smD; + }; + fVal = 0.0; if( ::get_flag( nRKValue, EXC_RK_INTFLAG ) ) { @@ -123,8 +128,7 @@ double XclTools::GetDoubleFromRK( sal_Int32 nRKValue ) } else { - sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &fVal ); - pDouble->w32_parts.msw = nRKValue & EXC_RK_VALUEMASK; + smD.w32_parts.msw = nRKValue & EXC_RK_VALUEMASK; } if( ::get_flag( nRKValue, EXC_RK_100FLAG ) ) @@ -161,50 +165,6 @@ bool XclTools::GetRKFromDouble( sal_Int32& rnRKValue, double fValue ) return false; } - -sal_uInt8 XclTools::GetXclErrorCode( USHORT nScError ) -{ - using namespace ScErrorCodes; - switch( nScError ) - { - case errIllegalArgument: return EXC_ERR_VALUE; - case errIllegalFPOperation: return EXC_ERR_NUM; // maybe DIV/0 or NUM... - case errDivisionByZero: return EXC_ERR_DIV0; - case errIllegalParameter: return EXC_ERR_VALUE; - case errPairExpected: return EXC_ERR_VALUE; - case errOperatorExpected: return EXC_ERR_VALUE; - case errVariableExpected: return EXC_ERR_VALUE; - case errParameterExpected: return EXC_ERR_VALUE; - case errNoValue: return EXC_ERR_VALUE; - case errCircularReference: return EXC_ERR_VALUE; - case errNoCode: return EXC_ERR_NULL; - case errNoRef: return EXC_ERR_REF; - case errNoName: return EXC_ERR_NAME; - case errNoAddin: return EXC_ERR_NAME; - case errNoMacro: return EXC_ERR_NAME; - case NOTAVAILABLE: return EXC_ERR_NA; - } - return EXC_ERR_NA; -} - -USHORT XclTools::GetScErrorCode( sal_uInt8 nXclError ) -{ - using namespace ScErrorCodes; - switch( nXclError ) - { - case EXC_ERR_NULL: return errNoCode; - case EXC_ERR_DIV0: return errDivisionByZero; - case EXC_ERR_VALUE: return errNoValue; - case EXC_ERR_REF: return errNoRef; - case EXC_ERR_NAME: return errNoName; - case EXC_ERR_NUM: return errIllegalFPOperation; - case EXC_ERR_NA: return NOTAVAILABLE; - default: DBG_ERRORFILE( "XclTools::GetScErrorCode - unknown error code" ); - } - return NOTAVAILABLE; -} - - sal_Int32 XclTools::GetScRotation( sal_uInt16 nXclRot, sal_Int32 nRotForStacked ) { if( nXclRot == EXC_ROT_STACKED ) @@ -252,6 +212,59 @@ sal_uInt8 XclTools::GetXclOrientFromRot( sal_uInt16 nXclRot ) return EXC_ORIENT_NONE; } +sal_uInt8 XclTools::GetXclErrorCode( USHORT nScError ) +{ + using namespace ScErrorCodes; + switch( nScError ) + { + case errIllegalArgument: return EXC_ERR_VALUE; + case errIllegalFPOperation: return EXC_ERR_NUM; // maybe DIV/0 or NUM... + case errDivisionByZero: return EXC_ERR_DIV0; + case errIllegalParameter: return EXC_ERR_VALUE; + case errPairExpected: return EXC_ERR_VALUE; + case errOperatorExpected: return EXC_ERR_VALUE; + case errVariableExpected: return EXC_ERR_VALUE; + case errParameterExpected: return EXC_ERR_VALUE; + case errNoValue: return EXC_ERR_VALUE; + case errCircularReference: return EXC_ERR_VALUE; + case errNoCode: return EXC_ERR_NULL; + case errNoRef: return EXC_ERR_REF; + case errNoName: return EXC_ERR_NAME; + case errNoAddin: return EXC_ERR_NAME; + case errNoMacro: return EXC_ERR_NAME; + case NOTAVAILABLE: return EXC_ERR_NA; + } + return EXC_ERR_NA; +} + +USHORT XclTools::GetScErrorCode( sal_uInt8 nXclError ) +{ + using namespace ScErrorCodes; + switch( nXclError ) + { + case EXC_ERR_NULL: return errNoCode; + case EXC_ERR_DIV0: return errDivisionByZero; + case EXC_ERR_VALUE: return errNoValue; + case EXC_ERR_REF: return errNoRef; + case EXC_ERR_NAME: return errNoName; + case EXC_ERR_NUM: return errIllegalFPOperation; + case EXC_ERR_NA: return NOTAVAILABLE; + default: DBG_ERRORFILE( "XclTools::GetScErrorCode - unknown error code" ); + } + return NOTAVAILABLE; +} + +double XclTools::ErrorToDouble( sal_uInt8 nXclError ) +{ + union + { + double fVal; + sal_math_Double smD; + }; + ::rtl::math::setNan( &fVal ); + smD.nan_parts.fraction_lo = GetScErrorCode( nXclError ); + return fVal; +} XclBoolError XclTools::ErrorToEnum( double& rfDblValue, sal_uInt8 bErrOrBool, sal_uInt8 nValue ) { @@ -281,7 +294,6 @@ XclBoolError XclTools::ErrorToEnum( double& rfDblValue, sal_uInt8 bErrOrBool, sa return eType; } - sal_uInt16 XclTools::GetTwipsFromInch( double fInches ) { return static_cast< sal_uInt16 >( diff --git a/sc/source/filter/html/htmlimp.cxx b/sc/source/filter/html/htmlimp.cxx index ad3a5e041151..1c0b9fc8ec33 100644 --- a/sc/source/filter/html/htmlimp.cxx +++ b/sc/source/filter/html/htmlimp.cxx @@ -60,13 +60,14 @@ //------------------------------------------------------------------------ FltError ScFormatFilterPluginImpl::ScImportHTML( SvStream &rStream, const String& rBaseURL, ScDocument *pDoc, - ScRange& rRange, double nOutputFactor, BOOL bCalcWidthHeight ) + ScRange& rRange, double nOutputFactor, BOOL bCalcWidthHeight, SvNumberFormatter* pFormatter, + bool bConvertDate ) { ScHTMLImport aImp( pDoc, rBaseURL, rRange, bCalcWidthHeight ); FltError nErr = (FltError) aImp.Read( rStream, rBaseURL ); ScRange aR = aImp.GetRange(); rRange.aEnd = aR.aEnd; - aImp.WriteToDocument( TRUE, nOutputFactor ); + aImp.WriteToDocument( TRUE, nOutputFactor, pFormatter, bConvertDate ); return nErr; } @@ -134,9 +135,10 @@ void ScHTMLImport::InsertRangeName( ScDocument* pDoc, const String& rName, const delete pRangeData; } -void ScHTMLImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) +void ScHTMLImport::WriteToDocument( + BOOL bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate ) { - ScEEImport::WriteToDocument( bSizeColsRows, nOutputFactor ); + ScEEImport::WriteToDocument( bSizeColsRows, nOutputFactor, pFormatter, bConvertDate ); const ScHTMLParser* pParser = GetParser(); const ScHTMLTable* pGlobTable = pParser->GetGlobalTable(); diff --git a/sc/source/filter/inc/eeimport.hxx b/sc/source/filter/inc/eeimport.hxx index 59225a5a7138..634dfd1b4a33 100644 --- a/sc/source/filter/inc/eeimport.hxx +++ b/sc/source/filter/inc/eeimport.hxx @@ -60,7 +60,9 @@ public: virtual ULONG Read( SvStream& rStream, const String& rBaseURL ); virtual ScRange GetRange() { return maRange; } virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, - double nOutputFactor = 1.0 ); + double nOutputFactor = 1.0, + SvNumberFormatter* pFormatter = NULL, + bool bConvertDate = true ); }; #endif diff --git a/sc/source/filter/inc/ftools.hxx b/sc/source/filter/inc/ftools.hxx index bdb17178d75c..c17aaa70445c 100644 --- a/sc/source/filter/inc/ftools.hxx +++ b/sc/source/filter/inc/ftools.hxx @@ -517,7 +517,9 @@ class ScFormatFilterPluginImpl : public ScFormatFilterPlugin { virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress& rInsPos, const CharSet eSrc = RTL_TEXTENCODING_DONTKNOW, UINT32 nDifOption = SC_DIFOPT_EXCEL ); virtual FltError ScImportRTF( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange ); - virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange, double nOutputFactor = 1.0, BOOL bCalcWidthHeight = TRUE ); + virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange, + double nOutputFactor = 1.0, BOOL bCalcWidthHeight = TRUE, + SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true ); virtual ScEEAbsImport *CreateRTFImport( ScDocument* pDoc, const ScRange& rRange ); virtual ScEEAbsImport *CreateHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, BOOL bCalcWidthHeight ); diff --git a/sc/source/filter/inc/htmlimp.hxx b/sc/source/filter/inc/htmlimp.hxx index 8a1d1c41b4fd..0376b3cd72f5 100644 --- a/sc/source/filter/inc/htmlimp.hxx +++ b/sc/source/filter/inc/htmlimp.hxx @@ -42,7 +42,8 @@ public: virtual ~ScHTMLImport(); const ScHTMLParser* GetParser() const { return (ScHTMLParser*)mpParser; } - virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0 ); + virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0, + SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true ); static String GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName ); }; diff --git a/sc/source/filter/inc/root.hxx b/sc/source/filter/inc/root.hxx index fcac4da4be62..facc8b1b2fa0 100644 --- a/sc/source/filter/inc/root.hxx +++ b/sc/source/filter/inc/root.hxx @@ -52,9 +52,6 @@ class _ScRangeListTabs; class XclExpChTrTabId; class XclExpUserBViewList; -class XclObjList; -class XclEscher; - class XclImpRoot; class XclExpRoot; @@ -78,10 +75,6 @@ struct RootData // -> Inkarnation jeweils im ImportExcel-Objekt! XclExpChTrTabId* pTabId; // pointer to rec list, do not destroy XclExpUserBViewList* pUserBViewList; // pointer to rec list, do not destroy - // Biff8 - XclObjList* pObjRecs; - XclEscher* pEscher; - XclImpRoot* pIR; XclExpRoot* pER; diff --git a/sc/source/filter/inc/tokstack.hxx b/sc/source/filter/inc/tokstack.hxx index 80c94c729270..06a37639be89 100644 --- a/sc/source/filter/inc/tokstack.hxx +++ b/sc/source/filter/inc/tokstack.hxx @@ -207,7 +207,7 @@ class TokenPool const TokenId Store( const DefTokenId eId, const String& rName ); // 4 externals (e.g. AddIns, Makros...) const TokenId StoreNlf( const ScSingleRefData& rTr ); - const TokenId StoreMatrix( SCSIZE nC, SCSIZE nR ); + const TokenId StoreMatrix(); const TokenId StoreExtName( sal_uInt16 nFileId, const String& rName ); const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef ); const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef ); diff --git a/sc/source/filter/inc/xcl97esc.hxx b/sc/source/filter/inc/xcl97esc.hxx index 2aa7c824af99..fde03337cc0f 100644 --- a/sc/source/filter/inc/xcl97esc.hxx +++ b/sc/source/filter/inc/xcl97esc.hxx @@ -28,9 +28,10 @@ #ifndef SC_XCL97ESC_HXX #define SC_XCL97ESC_HXX -#include <filter/msfilter/escherex.hxx> +#include <memory> #include <tools/table.hxx> #include <tools/stack.hxx> +#include <filter/msfilter/escherex.hxx> #include "xlescher.hxx" #include "xeroot.hxx" @@ -39,10 +40,28 @@ namespace utl { class TempFile; } -// --- class XclEscherEx --------------------------------------------- +// ============================================================================ class SvStream; + +class XclEscherExGlobal : public EscherExGlobal, protected XclExpRoot +{ +public: + explicit XclEscherExGlobal( const XclExpRoot& rRoot ); + +private: + /** Overloaded to create a new temporary file and return its stream. */ + virtual SvStream* ImplQueryPictureStream(); + +private: + ::std::auto_ptr< ::utl::TempFile > mxPicTempFile; + ::std::auto_ptr< SvStream > mxPicStrm; +}; + +// ============================================================================ + class XclObj; +class XclExpDffAnchorBase; class XclEscherHostAppData; class XclEscherClientData; class XclEscherClientTextbox; @@ -54,56 +73,56 @@ class XclExpTbxControlObj; class XclEscherEx : public EscherEx, protected XclExpRoot { -private: - List aOffsetMap; - Stack aStack; - utl::TempFile* pPicTempFile; - SvStream* pPicStrm; - XclObj* pCurrXclObj; - XclEscherHostAppData* pCurrAppData; - XclEscherClientData* pTheClientData; // always the same - XclEscherClientTextbox* pAdditionalText; - USHORT nAdditionalText; - - void DeleteCurrAppData(); - public: - XclEscherEx( const XclExpRoot& rRoot, SvStream& rStrm, UINT32 nDrawings ); - virtual ~XclEscherEx(); - - /// maintains OffsetMap - virtual void InsertAtCurrentPos( UINT32 nBytes, BOOL bCont = FALSE ); - - virtual SvStream* QueryPicStream(); - virtual EscherExHostAppData* StartShape( const com::sun::star::uno::Reference< - com::sun::star::drawing::XShape>& rShape ); + explicit XclEscherEx( + const XclExpRoot& rRoot, + XclExpObjectManager& rObjMgr, + SvStream& rStrm, + const XclEscherEx* pParent = 0 ); + virtual ~XclEscherEx(); + + /** Called by MSODRAWING record constructors to initialize the DFF stream + fragment they will own. returns the DFF fragment identifier. */ + sal_uInt32 InitNextDffFragment(); + /** Called after some data has been written to the DFF stream, to update + the end position of the DFF fragment owned by an MSODRAWING record. */ + void UpdateDffFragmentEnd(); + + /** Returns the position of the specified DFF stream fragment. */ + sal_uInt32 GetDffFragmentPos( sal_uInt32 nFragmentKey ); + /** Returns the size of the specified DFF stream fragment. */ + sal_uInt32 GetDffFragmentSize( sal_uInt32 nFragmentKey ); + /** Returns true, if there is more data left in the DFF stream than owned + by the last MSODRAWING record. */ + bool HasPendingDffData(); + + /** Creates a new DFF client anchor object and calculates the anchor + position of the passed object. Caller takes ownership! */ + XclExpDffAnchorBase* CreateDffAnchor( const SdrObject& rSdrObj ) const; + + virtual EscherExHostAppData* StartShape( + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>& rxShape, + const Rectangle* pChildAnchor ); virtual void EndShape( UINT16 nShapeType, UINT32 nShapeID ); virtual EscherExHostAppData* EnterAdditionalTextGroup(); - /// appends stream offset to list and returns position in list - ULONG AddCurrentOffsetToMap(); - /// replaces position in list with current stream offset - void ReplaceCurrentOffsetInMap( ULONG nPos ); - /// returns stream offset for position in list - inline ULONG GetOffsetFromMap( ULONG nPos ) const; - /// last position in list (count-1) - inline ULONG GetLastOffsetMapPos() const; - /// Flush and merge PicStream into EscherStream void EndDocument(); #if EXC_EXP_OCX_CTRL /** Creates an OCX form control OBJ record from the passed form control. @descr Writes the form control data to the 'Ctls' stream. */ - XclExpOcxControlObj* CreateCtrlObj( ::com::sun::star::uno::Reference< - ::com::sun::star::drawing::XShape > xShape ); + XclExpOcxControlObj* CreateCtrlObj( + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor ); private: SotStorageStreamRef mxCtlsStrm; /// The 'Ctls' stream. #else /** Creates a TBX form control OBJ record from the passed form control. */ - XclExpTbxControlObj* CreateCtrlObj( ::com::sun::star::uno::Reference< - ::com::sun::star::drawing::XShape > xShape ); + XclExpTbxControlObj* CreateCtrlObj( + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor ); private: /** Tries to get the name of a Basic macro from a control. */ @@ -112,43 +131,21 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xCtrlModel ); #endif -}; - - -inline ULONG XclEscherEx::GetOffsetFromMap( ULONG nPos ) const -{ - return (ULONG) aOffsetMap.GetObject( nPos ); -} - - -inline ULONG XclEscherEx::GetLastOffsetMapPos() const -{ - return aOffsetMap.Count() - 1; -} - -// --- class XclEscher ----------------------------------------------- + void DeleteCurrAppData(); -struct RootData; - -class XclEscher : protected XclExpRoot -{ private: - utl::TempFile* pTempFile; - SvStream* pStrm; - XclEscherEx* pEx; - -public: - XclEscher( const XclExpRoot& rRoot, UINT32 nDrawings ); - ~XclEscher(); - - inline XclEscherEx* GetEx() const { return pEx; } - inline SvStream& GetStrm() const { return *pStrm; } - - void AddSdrPage(); + XclExpObjectManager& mrObjMgr; + Stack aStack; + XclObj* pCurrXclObj; + XclEscherHostAppData* pCurrAppData; + XclEscherClientData* pTheClientData; // always the same + XclEscherClientTextbox* pAdditionalText; + USHORT nAdditionalText; + sal_uInt32 mnNextKey; + bool mbIsRootDff; }; - // --- class XclEscherHostAppData ------------------------------------ class XclEscherHostAppData : public EscherExHostAppData @@ -164,55 +161,6 @@ public: }; -// DFF client anchor ========================================================== - -class Rectangle; -class SdrObject; -class ScAddress; - -/** Represents the position (anchor) of an object in a Calc document. */ -class XclExpDffAnchor : public EscherExClientAnchor_Base, protected XclExpRoot -{ -public: - /** Constructs a dummy client anchor. */ - explicit XclExpDffAnchor( const XclExpRoot& rRoot, sal_uInt16 nFlags = 0 ); - /** Constructs a client anchor directly from an SdrObject. */ - explicit XclExpDffAnchor( const XclExpRoot& rRoot, const SdrObject& rSdrObj ); - - /** Sets the flags according to the passed SdrObject. */ - void SetFlags( const SdrObject& rSdrObj ); - - /** Called from SVX Escher exporter. - @param rRect The object anchor rectangle to be exported (in twips). */ - virtual void WriteData( EscherEx& rEx, const Rectangle& rRect ); - - /** Writes the anchor structure with the current anchor position. */ - void WriteData( EscherEx& rEx ) const; - -protected: // for access in derived classes - XclObjAnchor maAnchor; /// The client anchor data. - sal_uInt16 mnFlags; /// Flags for DFF stream export. -}; - -// ---------------------------------------------------------------------------- - -/** Represents the position (anchor) of a note object. */ -class XclExpDffNoteAnchor : public XclExpDffAnchor -{ -public: - explicit XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ); -}; - - -// ---------------------------------------------------------------------------- - -/** Represents the position (anchor) of a cell dropdown object. */ -class XclExpDffDropDownAnchor : public XclExpDffAnchor -{ -public: - explicit XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ); -}; - // ============================================================================ @@ -221,8 +169,8 @@ public: class XclEscherClientData : public EscherExClientRecord_Base { public: - XclEscherClientData() {} - virtual void WriteData( EscherEx& rEx ) const; + XclEscherClientData() {} + virtual void WriteData( EscherEx& rEx ) const; }; @@ -233,20 +181,19 @@ class SdrTextObj; class XclEscherClientTextbox : public EscherExClientRecord_Base, protected XclExpRoot { private: - const SdrTextObj& rTextObj; - XclObj* pXclObj; + const SdrTextObj& rTextObj; + XclObj* pXclObj; public: - XclEscherClientTextbox( - const XclExpRoot& rRoot, - const SdrTextObj& rObj, - XclObj* pObj - ); + XclEscherClientTextbox( + const XclExpRoot& rRoot, + const SdrTextObj& rObj, + XclObj* pObj ); //! ONLY for the AdditionalText mimic - inline void SetXclObj( XclObj* p ) { pXclObj = p; } + inline void SetXclObj( XclObj* p ) { pXclObj = p; } - virtual void WriteData( EscherEx& rEx ) const; + virtual void WriteData( EscherEx& rEx ) const; }; diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx index 2c6ae2f9ab0c..7a2a33795520 100644 --- a/sc/source/filter/inc/xcl97rec.hxx +++ b/sc/source/filter/inc/xcl97rec.hxx @@ -32,88 +32,35 @@ #include "xcl97esc.hxx" #include "xlstyle.hxx" -#include <vector> - -// --- class XclMsodrawing_Base -------------------------------------- - -class XclMsodrawing_Base -{ -protected: - XclEscher* pEscher; - sal_Size nStartPos; // position in OffsetMap - sal_Size nStopPos; // position in OffsetMap - -public: - XclMsodrawing_Base( XclEscher& rEscher, sal_Size nInitialSize = 0 ); - virtual ~XclMsodrawing_Base(); - - inline XclEscher* GetEscher() const { return pEscher; } - inline XclEscherEx* GetEscherEx() const { return pEscher->GetEx(); } - void UpdateStopPos(); - sal_Size GetDataLen() const; -}; - - -// --- class XclMsodrawinggroup -------------------------------------- - -class XclMsodrawinggroup : public XclMsodrawing_Base, public XclExpRecord -{ -private: - - virtual void WriteBody( XclExpStream& rStrm ); - -public: - XclMsodrawinggroup( RootData& rRoot, - UINT16 nEscherType = 0 ); - virtual ~XclMsodrawinggroup(); -}; - - -// --- class XclMsodrawing ------------------------------------------- - -class XclMsodrawing : public XclMsodrawing_Base, public XclExpRecord -{ -private: - - virtual void WriteBody( XclExpStream& rStrm ); - -public: - XclMsodrawing( - const XclExpRoot& rRoot, - UINT16 nEscherType = 0, - sal_Size nInitialSize = 0 ); - virtual ~XclMsodrawing(); -}; - - -// --- class XclObjList ---------------------------------------------- +// ============================================================================ class XclObj; -class XclMsodrawing; +class XclExpMsoDrawing; -class XclObjList : public List, public ExcEmptyRec, protected XclExpRoot +class XclExpObjList : public List, public ExcEmptyRec, protected XclExpRoot { -private: - XclMsodrawing* pMsodrawingPerSheet; - XclMsodrawing* pSolverContainer; - public: - XclObjList( const XclExpRoot& rRoot ); - virtual ~XclObjList(); + explicit XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ); + virtual ~XclExpObjList(); - XclObj* First() { return (XclObj*) List::First(); } - XclObj* Next() { return (XclObj*) List::Next(); } + XclObj* First() { return (XclObj*) List::First(); } + XclObj* Next() { return (XclObj*) List::Next(); } - /// return: 1-based ObjId - ///! count>=0xFFFF: Obj will be deleted, return 0 - UINT16 Add( XclObj* ); + /// return: 1-based ObjId + ///! count>=0xFFFF: Obj will be deleted, return 0 + UINT16 Add( XclObj* ); - inline XclMsodrawing* GetMsodrawingPerSheet() { return pMsodrawingPerSheet; } + inline XclExpMsoDrawing* GetMsodrawingPerSheet() { return pMsodrawingPerSheet; } /// close groups and DgContainer opened in ctor - void EndSheet(); + void EndSheet(); - virtual void Save( XclExpStream& rStrm ); + virtual void Save( XclExpStream& rStrm ); + +private: + XclEscherEx& mrEscherEx; + XclExpMsoDrawing* pMsodrawingPerSheet; + XclExpMsoDrawing* pSolverContainer; }; @@ -125,8 +72,9 @@ class SdrTextObj; class XclObj : public XclExpRecord { protected: - XclMsodrawing* pMsodrawing; - XclMsodrawing* pClientTextbox; + XclEscherEx& mrEscherEx; + XclExpMsoDrawing* pMsodrawing; + XclExpMsoDrawing* pClientTextbox; XclTxo* pTxo; sal_uInt16 mnObjType; UINT16 nObjId; @@ -137,7 +85,9 @@ protected: /** @param bOwnEscher If set to true, this object will create its escher data. See SetOwnEscher() for details. */ - explicit XclObj( const XclExpRoot& rRoot, sal_uInt16 nObjType, bool bOwnEscher = false ); + explicit XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher = false ); + + void ImplWriteAnchor( const XclExpRoot& rRoot, const SdrObject* pSdrObj, const Rectangle* pChildAnchor ); // overwritten for writing MSODRAWING record virtual void WriteBody( XclExpStream& rStrm ); @@ -179,27 +129,15 @@ public: //! actually writes ESCHER_ClientTextbox void SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj ); - inline void UpdateStopPos(); - virtual void Save( XclExpStream& rStrm ); }; - -inline void XclObj::UpdateStopPos() -{ - if ( pClientTextbox ) - pClientTextbox->UpdateStopPos(); - else - pMsodrawing->UpdateStopPos(); -} - - // --- class XclObjComment ------------------------------------------- class XclObjComment : public XclObj { public: - XclObjComment( const XclExpRoot& rRoot, + XclObjComment( XclExpObjectManager& rObjMgr, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible ); virtual ~XclObjComment(); @@ -224,7 +162,7 @@ private: protected: public: - XclObjDropDown( const XclExpRoot& rRoot, const ScAddress& rPos, BOOL bFilt ); + XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, BOOL bFilt ); virtual ~XclObjDropDown(); }; @@ -271,7 +209,7 @@ private: virtual void WriteSubRecs( XclExpStream& rStrm ); public: - XclObjOle( const XclExpRoot& rRoot, const SdrObject& rObj ); + XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ); virtual ~XclObjOle(); virtual void Save( XclExpStream& rStrm ); @@ -286,7 +224,7 @@ private: virtual void WriteSubRecs( XclExpStream& rStrm ); public: - XclObjAny( const XclExpRoot& rRoot ); + XclObjAny( XclExpObjectManager& rObjMgr ); virtual ~XclObjAny(); virtual void Save( XclExpStream& rStrm ); diff --git a/sc/source/filter/inc/xechart.hxx b/sc/source/filter/inc/xechart.hxx index eb6026a82e9a..2cf976b11efe 100644 --- a/sc/source/filter/inc/xechart.hxx +++ b/sc/source/filter/inc/xechart.hxx @@ -28,6 +28,7 @@ #ifndef SC_XECHART_HXX #define SC_XECHART_HXX +#include <tools/gen.hxx> #include "xerecord.hxx" #include "xlchart.hxx" #include "xlformula.hxx" @@ -1194,6 +1195,27 @@ private: // ---------------------------------------------------------------------------- +/** Represents the group of DFF and OBJ records containing all drawing shapes + embedded in the chart object. + */ +class XclExpChartDrawing : public XclExpRecordBase, protected XclExpRoot +{ +public: + explicit XclExpChartDrawing( + const XclExpRoot& rRoot, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel, + const Size& rChartSize ); + virtual ~XclExpChartDrawing(); + + virtual void Save( XclExpStream& rStrm ); + +private: + ScfRef< XclExpObjectManager > mxObjMgr; + ScfRef< XclExpRecordBase > mxObjRecs; +}; + +// ---------------------------------------------------------------------------- + /** Represents the entire chart substream (all records in BOF/EOF block). */ class XclExpChart : public XclExpSubStream, protected XclExpRoot { diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx index 6448ccb4853e..d227db184f1a 100644 --- a/sc/source/filter/inc/xeescher.hxx +++ b/sc/source/filter/inc/xeescher.hxx @@ -29,6 +29,7 @@ #define SC_XEESCHER_HXX #include <vcl/graph.hxx> +#include <filter/msfilter/escherex.hxx> #include "xcl97rec.hxx" #include "xlescher.hxx" @@ -36,6 +37,127 @@ namespace com { namespace sun { namespace star { namespace script { struct ScriptEventDescriptor; } } } } +// DFF client anchor ========================================================== + +/** Base class for DFF client anchor atoms used in spreadsheets. */ +class XclExpDffAnchorBase : public EscherExClientAnchor_Base, protected XclExpRoot +{ +public: + /** Constructs a dummy client anchor. */ + explicit XclExpDffAnchorBase( const XclExpRoot& rRoot, sal_uInt16 nFlags = 0 ); + + /** Sets the flags according to the passed SdrObject. */ + void SetFlags( const SdrObject& rSdrObj ); + /** Sets the anchor position and flags according to the passed SdrObject. */ + void SetSdrObject( const SdrObject& rSdrObj ); + + /** Writes the DFF client anchor structure with the current anchor position. */ + void WriteDffData( EscherEx& rEscherEx ) const; + + /** Called from SVX DFF converter. + @param rRect The object anchor rectangle to be exported (in twips). */ + virtual void WriteData( EscherEx& rEscherEx, const Rectangle& rRect ); + +private: + virtual void ImplSetFlags( const SdrObject& rSdrObj ); + virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ); + +protected: // for access in derived classes + XclObjAnchor maAnchor; /// The client anchor data. + sal_uInt16 mnFlags; /// Flags for DFF stream export. +}; + +// ---------------------------------------------------------------------------- + +/** Represents the position (anchor) of an object in a Calc sheet. */ +class XclExpDffSheetAnchor : public XclExpDffAnchorBase +{ +public: + explicit XclExpDffSheetAnchor( const XclExpRoot& rRoot ); + +private: + virtual void ImplSetFlags( const SdrObject& rSdrObj ); + virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ); + +private: + SCTAB mnScTab; /// Calc sheet index. +}; + +// ---------------------------------------------------------------------------- + +/** Represents the position (anchor) of a shape in an embedded draw page. */ +class XclExpDffEmbeddedAnchor : public XclExpDffAnchorBase +{ +public: + explicit XclExpDffEmbeddedAnchor( const XclExpRoot& rRoot, + const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY ); + +private: + virtual void ImplSetFlags( const SdrObject& rSdrObj ); + virtual void ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ); + +private: + Size maPageSize; + sal_Int32 mnScaleX; + sal_Int32 mnScaleY; +}; + +// ---------------------------------------------------------------------------- + +/** Represents the position (anchor) of a note object. */ +class XclExpDffNoteAnchor : public XclExpDffAnchorBase +{ +public: + explicit XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ); +}; + +// ---------------------------------------------------------------------------- + +/** Represents the position (anchor) of a cell dropdown object. */ +class XclExpDffDropDownAnchor : public XclExpDffAnchorBase +{ +public: + explicit XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ); +}; + +// MSODRAWING* records ======================================================== + +/** Base class for records holding DFF stream fragments. */ +class XclExpMsoDrawingBase : public XclExpRecord +{ +public: + explicit XclExpMsoDrawingBase( XclEscherEx& rEscherEx, sal_uInt16 nRecId ); + +private: + virtual void WriteBody( XclExpStream& rStrm ); + +protected: + XclEscherEx& mrEscherEx; /// Reference to the DFF converter containing the DFF stream. + sal_uInt32 mnFragmentKey; /// The key of the DFF stream fragment to be written by this record. +}; + +// ---------------------------------------------------------------------------- + +/** The MSODRAWINGGROUP record contains the DGGCONTAINER with global DFF data + such as the picture container. + */ +class XclExpMsoDrawingGroup : public XclExpMsoDrawingBase +{ +public: + explicit XclExpMsoDrawingGroup( XclEscherEx& rEscherEx ); +}; + +// ---------------------------------------------------------------------------- + +/** One or more MSODRAWING records contain the DFF stream data for a drawing + shape. + */ +class XclExpMsoDrawing : public XclExpMsoDrawingBase +{ +public: + explicit XclExpMsoDrawing( XclEscherEx& rEscherEx ); +}; + // ============================================================================ /** Provides export of bitmap data to an IMGDATA record. */ @@ -94,8 +216,9 @@ class XclExpOcxControlObj : public XclObj, public XclExpControlHelper { public: explicit XclExpOcxControlObj( - const XclExpRoot& rRoot, + XclExpObjectManager& rObjMgr, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor, const String& rClassName, sal_uInt32 nStrmStart, sal_uInt32 nStrmSize ); @@ -115,8 +238,9 @@ class XclExpTbxControlObj : public XclObj, public XclExpControlHelper { public: explicit XclExpTbxControlObj( - const XclExpRoot& rRoot, - ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); + XclExpObjectManager& rObjMgr, + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor ); /** Sets the name of a macro attached to this control. @return true = The passed event descriptor was valid, macro name has been found. */ @@ -161,10 +285,10 @@ class XclExpChart; class XclExpChartObj : public XclObj, protected XclExpRoot { public: - typedef ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > XShapeRef; - -public: - explicit XclExpChartObj( const XclExpRoot& rRoot, XShapeRef xShape ); + explicit XclExpChartObj( + XclExpObjectManager& rObjMgr, + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, + const Rectangle* pChildAnchor ); virtual ~XclExpChartObj(); /** Writes the OBJ record and the entire chart substream. */ @@ -237,6 +361,74 @@ private: XclExpNoteList& mrNotes; }; +// object manager ============================================================= + +class XclExpObjectManager : public XclExpRoot +{ +public: + explicit XclExpObjectManager( const XclExpRoot& rRoot ); + virtual ~XclExpObjectManager(); + + /** Creates a new DFF client anchor object. Caller takes ownership! May be + overwritten in derived classes. */ + virtual XclExpDffAnchorBase* CreateDffAnchor() const; + + /** Creates and returns the MSODRAWINGGROUP record containing global DFF + data in the DGGCONTAINER. */ + ScfRef< XclExpRecordBase > CreateDrawingGroup(); + + /** Initializes the object manager for a new sheet. */ + void StartSheet(); + + /** Processes a drawing page and returns the record block containing all + related records (MSODRAWING, OBJ, TXO, charts, etc.). */ + ScfRef< XclExpRecordBase > ProcessDrawing( SdrPage* pSdrPage ); + /** Processes a collection of UNO shapes and returns the record block + containing all related records (MSODRAWING, OBJ, TXO, charts, etc.). */ + ScfRef< XclExpRecordBase > ProcessDrawing( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes ); + + /** Finalizes the object manager after conversion of all sheets. */ + void EndDocument(); + + inline XclEscherEx& GetEscherEx() { return *mxEscherEx; } + XclExpMsoDrawing* GetMsodrawingPerSheet(); + bool HasObj() const; + sal_uInt16 AddObj( XclObj* pObjRec ); + XclObj* RemoveLastObj(); + +protected: + explicit XclExpObjectManager( const XclExpObjectManager& rParent ); + +private: + void InitStream( bool bTempFile ); + +private: + ScfRef< ::utl::TempFile > mxTempFile; + ScfRef< SvStream > mxDffStrm; + ScfRef< XclEscherEx > mxEscherEx; + ScfRef< XclExpObjList > mxObjList; +}; + +// ---------------------------------------------------------------------------- + +class XclExpEmbeddedObjectManager : public XclExpObjectManager +{ +public: + explicit XclExpEmbeddedObjectManager( + const XclExpObjectManager& rParent, + const Size& rPageSize, + sal_Int32 nScaleX, sal_Int32 nScaleY ); + + /** Creates a new DFF client anchor object for embedded objects according + to the scaling data passed to the constructor. Caller takes ownership! */ + virtual XclExpDffAnchorBase* CreateDffAnchor() const; + +private: + Size maPageSize; + sal_Int32 mnScaleX; + sal_Int32 mnScaleY; +}; + // ============================================================================ #endif diff --git a/sc/source/filter/inc/xerecord.hxx b/sc/source/filter/inc/xerecord.hxx index fa3810c0e92b..a191cd9b1c20 100644 --- a/sc/source/filter/inc/xerecord.hxx +++ b/sc/source/filter/inc/xerecord.hxx @@ -48,9 +48,6 @@ public: /** Overwrite this method to do any operation while saving the record. */ virtual void Save( XclExpStream& rStrm ); virtual void SaveXml( XclExpXmlStream& rStrm ); - -//UNUSED2008-05 /** Calls Save(XclExpStream&) nCount times. */ -//UNUSED2008-05 void SaveRepeated( XclExpStream& rStrm, size_t nCount ); }; // ---------------------------------------------------------------------------- diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx index ce32a46cbc66..f9d3a6ab2f95 100644 --- a/sc/source/filter/inc/xeroot.hxx +++ b/sc/source/filter/inc/xeroot.hxx @@ -52,6 +52,7 @@ class XclExpNumFmtBuffer; class XclExpXFBuffer; class XclExpLinkManager; class XclExpNameManager; +class XclExpObjectManager; class XclExpFilterManager; class XclExpPivotTableManager; @@ -70,6 +71,7 @@ struct XclExpRootData : public XclRootData typedef ScfRef< XclExpXFBuffer > XclExpXFBfrRef; typedef ScfRef< XclExpNameManager > XclExpNameMgrRef; typedef ScfRef< XclExpLinkManager > XclExpLinkMgrRef; + typedef ScfRef< XclExpObjectManager > XclExpObjectMgrRef; typedef ScfRef< XclExpFilterManager > XclExpFilterMgrRef; typedef ScfRef< XclExpPivotTableManager > XclExpPTableMgrRef; @@ -86,6 +88,7 @@ struct XclExpRootData : public XclRootData XclExpNameMgrRef mxNameMgr; /// Internal defined names. XclExpLinkMgrRef mxGlobLinkMgr; /// Global link manager for defined names. XclExpLinkMgrRef mxLocLinkMgr; /// Local link manager for a sheet. + XclExpObjectMgrRef mxObjMgr; /// All drawing objects. XclExpFilterMgrRef mxFilterMgr; /// Manager for filtered areas in all sheets. XclExpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches. @@ -134,6 +137,8 @@ public: XclExpLinkManager& GetLocalLinkManager() const; /** Returns the buffer that contains internal defined names. */ XclExpNameManager& GetNameManager() const; + /** Returns the drawing object manager. */ + XclExpObjectManager& GetObjectManager() const; /** Returns the filter manager. */ XclExpFilterManager& GetFilterManager() const; /** Returns the pivot table manager. */ diff --git a/sc/source/filter/inc/xichart.hxx b/sc/source/filter/inc/xichart.hxx index 25e52f3f0168..5d03c99b124a 100644 --- a/sc/source/filter/inc/xichart.hxx +++ b/sc/source/filter/inc/xichart.hxx @@ -39,8 +39,8 @@ #include "token.hxx" #include "xlchart.hxx" #include "xlstyle.hxx" +#include "xiescher.hxx" #include "xistring.hxx" -#include "xiroot.hxx" namespace com { namespace sun { namespace star { namespace frame @@ -111,7 +111,7 @@ public: /** Starts the API chart document conversion. Must be called once before all API conversion. */ void InitConversion( XChartDocRef xChartDoc ) const; /** Finishes the API chart document conversion. Must be called once after all API conversion. */ - void FinishConversion( ScfProgressBar& rProgress ) const; + void FinishConversion( XclImpDffConverter& rDffConv ) const; /** Returns the data provider for the chart document. */ XDataProviderRef GetDataProvider() const; @@ -1355,7 +1355,9 @@ public: inline sal_Size GetProgressSize() const { return 2 * EXC_CHART_PROGRESS_SIZE; } /** Converts and writes all properties to the passed chart. */ - void Convert( XChartDocRef xChartDoc, ScfProgressBar& rProgress, const ::rtl::OUString& rObjName ) const; + void Convert( XChartDocRef xChartDoc, + XclImpDffConverter& rDffConv, + const ::rtl::OUString& rObjName ) const; private: /** Reads a CHSERIES group (data series source and formatting). */ @@ -1400,6 +1402,31 @@ typedef ScfRef< XclImpChChart > XclImpChChartRef; // ---------------------------------------------------------------------------- +/** Drawing container of a chart. */ +class XclImpChartDrawing : public XclImpDrawing +{ +public: + explicit XclImpChartDrawing( const XclImpRoot& rRoot, bool bOwnTab ); + + /** Converts all objects and inserts them into the chart drawing page. */ + void ConvertObjects( + XclImpDffConverter& rDffConv, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel, + const Rectangle& rChartRect ); + + /** Calculate the resulting rectangle of the passed anchor. */ + virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const; + /** Called whenever an object has been inserted into the draw page. */ + virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj ); + +private: + Rectangle maChartRect; /// Position and size of the chart shape in 1/100 mm. + SCTAB mnScTab; /// Index of the sheet that contains the chart. + bool mbOwnTab; /// True = own sheet, false = embedded object. +}; + +// ---------------------------------------------------------------------------- + /** Represents the entire chart substream (all records in BOF/EOF block). */ class XclImpChart : protected XclImpRoot { @@ -1410,6 +1437,7 @@ public: /** Constructs a new chart object. @param bOwnTab True = chart is on an own sheet; false = chart is an embedded object. */ explicit XclImpChart( const XclImpRoot& rRoot, bool bOwnTab ); + virtual ~XclImpChart(); /** Reads the complete chart substream (BOF/EOF block). @descr The passed stream must be located in the BOF record of the chart substream. */ @@ -1423,14 +1451,22 @@ public: inline bool IsPivotChart() const { return mbIsPivotChart; } /** Creates the chart object in the passed component. */ - void Convert( XModelRef xModel, ScfProgressBar& rProgress, const ::rtl::OUString& rObjName ) const; + void Convert( XModelRef xModel, + XclImpDffConverter& rDffConv, + const ::rtl::OUString& rObjName, + const Rectangle& rChartRect ) const; private: + /** Returns (initially creates) the drawing container for embedded shapes. **/ + XclImpChartDrawing& GetChartDrawing(); /** Reads the CHCHART group (entire chart data). */ void ReadChChart( XclImpStream& rStrm ); private: + typedef ScfRef< XclImpChartDrawing > XclImpChartDrawingRef; + XclImpChChartRef mxChartData; /// The chart data (CHCHART group). + XclImpChartDrawingRef mxChartDrawing; /// Drawing container for embedded shapes. bool mbOwnTab; /// true = own sheet; false = embedded object. bool mbIsPivotChart; /// true = chart is based on a pivot table. }; diff --git a/sc/source/filter/inc/xiescher.hxx b/sc/source/filter/inc/xiescher.hxx index 258720e89584..0167d160f297 100644 --- a/sc/source/filter/inc/xiescher.hxx +++ b/sc/source/filter/inc/xiescher.hxx @@ -42,9 +42,12 @@ namespace com { namespace sun { namespace star { namespace form { class XForm; } } } } +class SdrObjList; class ScfProgressBar; class ScfPropertySet; class XclImpChart; +class XclImpDffConverter; +class XclImpDrawing; // Drawing objects ============================================================ @@ -59,23 +62,23 @@ public: virtual ~XclImpDrawObjBase(); /** Reads the BIFF3 OBJ record, returns a new drawing object. */ - static XclImpDrawObjRef ReadObj3( XclImpStream& rStrm ); + static XclImpDrawObjRef ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads the BIFF4 OBJ record, returns a new drawing object. */ - static XclImpDrawObjRef ReadObj4( XclImpStream& rStrm ); + static XclImpDrawObjRef ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads the BIFF5 OBJ record, returns a new drawing object. */ - static XclImpDrawObjRef ReadObj5( XclImpStream& rStrm ); + static XclImpDrawObjRef ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads the BIFF8 OBJ record, returns a new drawing object. */ - static XclImpDrawObjRef ReadObj8( XclImpStream& rStrm ); + static XclImpDrawObjRef ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Sets whether this is an area object (then its width and height must be greater than 0). */ inline void SetAreaObj( bool bAreaObj ) { mbAreaObj = bAreaObj; } /** If set to true, a new SdrObject will be created while in DFF import. */ inline void SetSimpleMacro( bool bMacro ) { mbSimpleMacro = bMacro; } - /** Sets shape data from DFF stream. */ - void SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin ); /** Sets the object anchor explicitly. */ void SetAnchor( const XclObjAnchor& rAnchor ); + /** Sets shape data from DFF stream. */ + void SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin ); /** If set to false, the SdrObject will not be created, processed, or inserted into the draw page. */ inline void SetProcessSdrObj( bool bProcess ) { mbProcessSdr = bProcess; } @@ -84,10 +87,8 @@ public: /** If set to true, a new SdrObject will be created while in DFF import. */ inline void SetCustomDffObj( bool bCustom ) { mbCustomDff = bCustom; } - /** Returns the Calc sheet index of this object. */ - inline SCTAB GetScTab() const { return maObjId.mnScTab; } /** Returns the sheet index and Excel object identifier from OBJ record. */ - inline const XclObjId& GetObjId() const { return maObjId; } + inline sal_uInt16 GetObjId() const { return mnObjId; } /** Returns the Excel object type from OBJ record. */ inline sal_uInt16 GetObjType() const { return mnObjType; } /** Returns the name of this object, may generate a default name. */ @@ -107,14 +108,14 @@ public: /** Returns true, if the object is printable. */ inline bool IsPrintable() const { return mbPrintable; } + /** Returns the object anchor if existing, null otherwise. */ + const XclObjAnchor* GetAnchor() const; /** Returns true, if the passed size is valid for this object. */ bool IsValidSize( const Rectangle& rAnchorRect ) const; - /** Returns the area in the sheet used by this object. */ - ScRange GetUsedArea() const; - /** Returns the area on the drawing layer for this object. */ - Rectangle GetAnchorRect() const; + /** Returns the range in the sheet covered by this object. */ + ScRange GetUsedArea( SCTAB nScTab ) const; - /** Returns true, if the object is valid and will be processed.. */ + /** Returns true, if the object is valid and will be processed. */ inline bool IsProcessSdrObj() const { return mbProcessSdr && !mbHidden; } /** Returns true, if the SdrObject will be created or processed, but not be inserted into the draw page. */ inline bool IsInsertSdrObj() const { return mbInsertSdr; } @@ -122,9 +123,13 @@ public: /** Returns the needed size on the progress bar (calls virtual DoGetProgressSize() function). */ sal_Size GetProgressSize() const; /** Creates and returns an SdrObject from the contained data. Caller takes ownership! */ - SdrObject* CreateSdrObject( const Rectangle& rAnchorRect, ScfProgressBar& rProgress, bool bDffImport ) const; - /** Additional processing for the passed SdrObject (calls virtual DoProcessSdrObj() function). */ - void ProcessSdrObject( SdrObject& rSdrObj ) const; + SdrObject* CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const; + /** Additional processing for the passed SdrObject before insertion into + the drawing page (calls virtual DoPreProcessSdrObj() function). */ + void PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; + /** Additional processing for the passed SdrObject after insertion into the + drawing page (calls virtual DoPostProcessSdrObj() function). */ + void PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; protected: /** Reads the object name in a BIFF5 OBJ record. */ @@ -162,9 +167,11 @@ protected: /** Derived classes may return a progress bar size different from 1. */ virtual sal_Size DoGetProgressSize() const; /** Derived classes create and return a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; - /** Derived classes may perform additional processing for the passed SdrObject. */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; + /** Derived classes may perform additional processing for the passed SdrObject before insertion. */ + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; + /** Derived classes may perform additional processing for the passed SdrObject after insertion. */ + virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; private: /** Reads the contents of a BIFF3 OBJ record. */ @@ -177,16 +184,15 @@ private: void ImplReadObj8( XclImpStream& rStrm ); private: - typedef ScfRef< XclObjAnchor > XclObjAnchorRef; - - XclObjAnchorRef mxAnchor; /// The position of the object in the containing sheet. - XclObjId maObjId; /// Sheet index and object identifier. + XclObjAnchor maAnchor; /// The position of the object in its parent. + sal_uInt16 mnObjId; /// The object identifier (unique per drawing). sal_uInt16 mnObjType; /// The Excel object type from OBJ record. sal_uInt32 mnDffShapeId; /// Shape ID from DFF stream. sal_uInt32 mnDffFlags; /// Shape flags from DFF stream. String maObjName; /// Name of the object. String maMacroName; /// Name of an attached macro. String maHyperlink; /// On-click hyperlink URL. + bool mbHasAnchor; /// true = maAnchor is initialized. bool mbHidden; /// true = Object is hidden. bool mbVisible; /// true = Object is visible. bool mbPrintable; /// true = Object is printable. @@ -242,7 +248,7 @@ protected: /** Returns a progress bar size that takes all group children into account. */ virtual sal_Size DoGetProgressSize() const; /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: XclImpDrawObjVector maChildren; /// Grouped objects. @@ -265,7 +271,7 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: XclObjLineData maLineData; /// BIFF5 line formatting. @@ -295,7 +301,7 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: XclObjFillData maFillData; /// BIFF5 fill formatting. @@ -313,7 +319,7 @@ public: protected: /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; }; // ---------------------------------------------------------------------------- @@ -332,7 +338,7 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: XclObjFillData maFillData; /// BIFF5 fill formatting. @@ -357,7 +363,7 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; protected: typedef ::std::vector< Point > PointVector; @@ -398,9 +404,9 @@ protected: /** Reads the contents of the a BIFF5 OBJ record from the passed stream. */ virtual void DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; /** Inserts the contained text data at the passed object. */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; protected: XclImpObjTextData maTextData; /// Textbox data from BIFF5 OBJ or BIFF8 TXO record. @@ -430,7 +436,9 @@ protected: /** Returns the needed size on the progress bar. */ virtual sal_Size DoGetProgressSize() const; /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; + /** Converts the chart document. */ + virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; private: /** Calculates the object anchor of a sheet chart (chart fills one page). */ @@ -456,7 +464,7 @@ public: protected: /** Inserts the note into the document, sets visibility. */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; private: ScAddress maScPos; /// Cell position of the note object. @@ -533,9 +541,9 @@ protected: void ConvertLabel( ScfPropertySet& rPropSet ) const; /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; /** Additional processing on the SdrObject, calls new virtual function DoProcessControl(). */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; /** Derived classes return the service name of the control component to be created. */ virtual ::rtl::OUString DoGetServiceName() const = 0; @@ -882,9 +890,9 @@ protected: /** Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream. */ virtual void DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize ); /** Creates and returns a new SdrObject from the contained data. Caller takes ownership! */ - virtual SdrObject* DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const; + virtual SdrObject* DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const; /** Overloaded to do additional processing on the SdrObject. */ - virtual void DoProcessSdrObj( SdrObject& rSdrObj ) const; + virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; private: /** Reads and sets the picture flags from a BIFF3-BIFF5 OBJ picture record. */ @@ -955,13 +963,13 @@ private: // ---------------------------------------------------------------------------- /** Simple implementation of the SVX DFF manager. Implements resolving palette - colors. Used by XclImpDffPropSet (as is), extended by XclImpDffManager. + colors. Used by XclImpDffPropSet (as is), extended by XclImpDffConverter. */ -class XclImpSimpleDffManager : public SvxMSDffManager, protected XclImpRoot +class XclImpSimpleDffConverter : public SvxMSDffManager, protected XclImpRoot { public: - explicit XclImpSimpleDffManager( const XclImpRoot& rRoot, SvStream& rDffStrm ); - virtual ~XclImpSimpleDffManager(); + explicit XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ); + virtual ~XclImpSimpleDffConverter(); protected: /** Returns a color from the Excel color palette. */ @@ -970,42 +978,46 @@ protected: // ---------------------------------------------------------------------------- -class XclImpObjectManager; -class SdrObjList; +/** This is the central instance for converting binary DFF data into shape + objects. Used for all sheet shapes and shapes embedded in chart objects. -/** Derived from SvxMSDffManager and SvxMSConvertOCXControls, contains core - implementation of DFF stream import and OCX form control import. + The class derives from SvxMSDffManager and SvxMSConvertOCXControls and + contains core implementation of DFF stream import and OCX form control + import. */ -class XclImpDffManager : public XclImpSimpleDffManager, protected SvxMSConvertOCXControls +class XclImpDffConverter : public XclImpSimpleDffConverter, private SvxMSConvertOCXControls { public: - explicit XclImpDffManager( - const XclImpRoot& rRoot, - XclImpObjectManager& rObjManager, - SvStream& rDffStrm ); - virtual ~XclImpDffManager(); + explicit XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ); + virtual ~XclImpDffConverter(); /** Initializes the internal progress bar with the passed size and starts it. */ void StartProgressBar( sal_Size nProgressSize ); + /** Increase the progress bar by the passed value. */ + void Progress( sal_Size nDelta = 1 ); + /** Initially called before the objects of the passed drawing manager are converted. */ + void InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ); /** Processes BIFF5 drawing objects without DFF data, inserts into the passed object list. */ - void ProcessObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj ); - /** Processes the leading drawing group container in the DFF stream. */ - void ProcessDrawingGroup( SvStream& rDffStrm ); - /** Processes a drawing container for a sheet in the DFF stream, converts all objects. */ - void ProcessDrawing( SvStream& rDffStrm, sal_Size nStrmPos ); + void ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj ); + /** Processes all objects in the passed list. */ + void ProcessDrawing( const XclImpDrawObjVector& rDrawObjs ); + /** Processes a drawing container in the passed DFF stream, converts all objects. */ + void ProcessDrawing( SvStream& rDffStrm ); + /** Finally called after the objects of the passed drawing manager have been converted. */ + void FinalizeDrawing(); /** Creates the SdrObject for the passed Excel TBX form control object. */ SdrObject* CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect ); /** Creates the SdrObject for the passed Excel OLE object or OCX form control object. */ SdrObject* CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect ); + /** Returns true, if the conversion of OLE objects is supported. */ + bool SupportsOleObjects() const; /** Returns the default text margin in drawing layer units. */ inline sal_Int32 GetDefaultTextMargin() const { return mnDefTextMargin; } - /** Returns the used area in the sheet with the passed index. */ - ScRange GetUsedArea( SCTAB nScTab ) const; -protected: +private: // virtual functions of SvxMSDffManager /** Reads the client anchor from the DFF stream and sets it at the correct object. */ @@ -1036,11 +1048,30 @@ protected: BOOL bFloatingCtrl ); private: + /** Data per registered drawing manager, will be stacked for recursive calls. */ + struct XclImpDffConvData + { + XclImpDrawing& mrDrawing; /// Current drawing container with all drawing objects. + SdrModel& mrSdrModel; /// The SdrModel of the drawing manager. + SdrPage& mrSdrPage; /// The SdrPage of the drawing manager. + XclImpSolverContainer maSolverCont; /// The solver container for connector rules. + ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > + mxCtrlForm; /// Controls form of current drawing page. + sal_Int32 mnLastCtrlIndex; /// Last insertion index of a form control (for macro events). + bool mbHasCtrlForm; /// True = mxCtrlForm is initialized (but maybe still null). + + explicit XclImpDffConvData( XclImpDrawing& rDrawing, + SdrModel& rSdrModel, SdrPage& rSdrPage ); + }; + + /** Returns the current drawing manager data struct from top of the stack. */ + XclImpDffConvData& GetConvData(); + /** Returns the current drawing manager data struct from top of the stack. */ + const XclImpDffConvData& GetConvData() const; + /** Reads contents of a hyperlink property and returns the extracted URL. */ String ReadHlinkProperty( SvStream& rDffStrm ) const; - /** Processes a drawing group container (global drawing data). */ - void ProcessDggContainer( SvStream& rDffStrm, const DffRecordHeader& rDggHeader ); /** Processes a drawing container (all drawing data of a sheet). */ void ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader ); /** Processes the global shape group container (all shapes of a sheet). */ @@ -1051,87 +1082,71 @@ private: void ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader ); /** Inserts the passed SdrObject into the document. This function takes ownership of pSdrObj! */ - void InsertSdrObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ); - /** Stores the standard controls form for the passed sheet in mxCurrForm member. */ - void SetCurrentForm( SCTAB nScTab ); - - /** Updates the used area of a sheet with the position and size of the passed object. */ - void UpdateUsedArea( const XclImpDrawObjBase& rDrawObj ); + void InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ); + /** Initializes the mxCtrlForm referring to the standard controls form. */ + void InitControlForm(); private: - typedef ::std::map< SCTAB, ScRange > ScRangeMap; - typedef ScfRef< ScfProgressBar > ScfProgressBarRef; + typedef ScfRef< ScfProgressBar > ScfProgressBarRef; + typedef ScfRef< XclImpDffConvData > XclImpDffConvDataRef; + typedef ::std::vector< XclImpDffConvDataRef > XclImpDffConvDataStack; - XclImpObjectManager& mrObjManager; /// The Excel object manager. - XclImpSolverContainer maSolverCont; /// The solver container for connector rules. + const ::rtl::OUString maStdFormName; /// Standard name of control forms. SotStorageStreamRef mxCtlsStrm; /// The 'Ctls' stream for OCX form controls. - ScRangeMap maUsedAreaMap; /// Used ranges for all sheets. ScfProgressBarRef mxProgress; /// The progress bar used in ProcessObj(). - ::com::sun::star::uno::Reference< ::com::sun::star::form::XForm > - mxCurrForm; /// Controls form of current sheet (needed in virtual functions). + XclImpDffConvDataStack maDataStack; /// Stack for registered drawing managers. sal_uInt32 mnOleImpFlags; /// Application OLE import settings. sal_Int32 mnDefTextMargin; /// Default margin in text boxes. - sal_Int32 mnLastCtrlIndex; /// Last insertion index of a form control (for macro events). - SCTAB mnCurrFormScTab; /// Sheet index of form stored in mxCurrForm. }; -// The object manager ========================================================= +// Drawing manager ============================================================ -/** Stores all drawing and OLE objects and additional data related to these objects. */ -class XclImpObjectManager : protected XclImpRoot +/** Base class for a container for all objects on a drawing (spreadsheet or + embedded chart object). */ +class XclImpDrawing : protected XclImpRoot { public: - explicit XclImpObjectManager( const XclImpRoot& rRoot ); - virtual ~XclImpObjectManager(); - - // *** Read Excel records *** --------------------------------------------- + explicit XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ); + virtual ~XclImpDrawing(); /** Reads and returns a bitmap from the IMGDATA record. */ - static Graphic ReadImgData( XclImpStream& rStrm ); + static Graphic ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads a plain OBJ record (without leading DFF data). */ void ReadObj( XclImpStream& rStrm ); - /** Reads the MSODRAWINGGROUP record. */ - void ReadMsoDrawingGroup( XclImpStream& rStrm ); /** Reads the MSODRAWING or MSODRAWINGSELECTION record. */ void ReadMsoDrawing( XclImpStream& rStrm ); - /** Reads the NOTE record. */ - void ReadNote( XclImpStream& rStrm ); - - /** Inserts a new chart object and reads the chart substream (BOF/EOF block). - @descr Used to import chart sheets, which do not have a corresponding OBJ record. */ - void ReadTabChart( XclImpStream& rStrm ); - - // *** Drawing objects *** ------------------------------------------------ + /** Returns true, if the conversion of OLE objects is supported. */ + inline bool SupportsOleObjects() const { return mbOleObjs; } /** Finds the OBJ record data related to the DFF shape at the passed position. */ XclImpDrawObjRef FindDrawObj( const DffRecordHeader& rHeader ) const; /** Finds the OBJ record data specified by the passed object identifier. */ - XclImpDrawObjRef FindDrawObj( const XclObjId& rObjId ) const; + XclImpDrawObjRef FindDrawObj( sal_uInt16 nObjId ) const; /** Finds the textbox data related to the DFF shape at the passed position. */ const XclImpObjTextData* FindTextData( const DffRecordHeader& rHeader ) const; /** Sets the object with the passed identification to be skipped on import. */ - void SetSkipObj( SCTAB nScTab, sal_uInt16 nObjId ); - - // *** Drawing object conversion *** -------------------------------------- + void SetSkipObj( sal_uInt16 nObjId ); + /** Returns the size of the progress bar shown while processing all objects. */ + sal_Size GetProgressSize() const; - /** Returns the DFF manager (DFF stream converter). Don't call before the DFF stream is read. */ - XclImpDffManager& GetDffManager(); - /** Inserts all objects into the Calc document. */ - void ConvertObjects(); + /** Derived classes calculate the resulting rectangle of the passed anchor. */ + virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const = 0; + /** Called whenever an object has been inserted into the draw page. */ + virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj ) = 0; - /** Returns the default name for the passed object. */ - String GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const; - /** Returns the used area in the sheet with the passed index. */ - ScRange GetUsedArea( SCTAB nScTab ) const; +protected: + /** Appends a new drawing object to the list of raw objects (without DFF data). */ + void AppendRawObject( const XclImpDrawObjRef& rxDrawObj ); + /** Converts all objects and inserts them into the current drawing page. */ + void ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage ); - // ------------------------------------------------------------------------ private: /** Reads and returns a bitmap from WMF/PICT format. */ - static void ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ); + static void ReadWmf( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads and returns a bitmap from BMP format. */ - static void ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ); + static void ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ); /** Reads contents of an DFF record and append data to internal DFF stream. */ void ReadDffRecord( XclImpStream& rStrm ); @@ -1140,36 +1155,86 @@ private: /** Reads the TXO record and following CONTINUE records containing string and formatting. */ void ReadTxo( XclImpStream& rStrm ); +private: + typedef ::std::map< sal_Size, XclImpDrawObjRef > XclImpObjMap; + typedef ::std::map< sal_uInt16, XclImpDrawObjRef > XclImpObjMapById; + typedef ScfRef< XclImpObjTextData > XclImpObjTextRef; + typedef ::std::map< sal_Size, XclImpObjTextRef > XclImpObjTextMap; + + XclImpDrawObjVector maRawObjs; /// BIFF5 objects without DFF data. + SvMemoryStream maDffStrm; /// Copy of the DFF page stream in memory. + XclImpObjMap maObjMap; /// Maps BIFF8 drawing objects to DFF stream position. + XclImpObjMapById maObjMapId; /// Maps BIFF8 drawing objects to object ID. + XclImpObjTextMap maTextMap; /// Maps BIFF8 TXO textbox data to DFF stream position. + ScfUInt16Vec maSkipObjs; /// IDs of all objects to be skipped. + bool mbOleObjs; /// True = draw model supports OLE objects. +}; + +// ---------------------------------------------------------------------------- + +/** Drawing manager of a single sheet. */ +class XclImpSheetDrawing : public XclImpDrawing +{ +public: + explicit XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab ); + + /** Reads the NOTE record. */ + void ReadNote( XclImpStream& rStrm ); + /** Inserts a new chart object and reads the chart substream (BOF/EOF block). + @descr Used to import chart sheets, which do not have a corresponding OBJ record. */ + void ReadTabChart( XclImpStream& rStrm ); + + /** Returns the total cell range covered by any shapes in the sheet. */ + inline const ScRange& GetUsedArea() const { return maScUsedArea; } + /** Converts all objects and inserts them into the sheet drawing page. */ + void ConvertObjects( XclImpDffConverter& rDffConv ); + + /** Calculate the resulting rectangle of the passed anchor. */ + virtual Rectangle CalcAnchorRect( const XclObjAnchor& rAnchor, bool bDffAnchor ) const; + /** On call, updates the used area of the sheet. */ + virtual void OnObjectInserted( const XclImpDrawObjBase& rDrawObj ); + +private: /** Reads a BIFF3-BIFF5 NOTE record. */ void ReadNote3( XclImpStream& rStrm ); /** Reads a BIFF8 NOTE record. */ void ReadNote8( XclImpStream& rStrm ); - /** Returns the size of the progress bar shown while processing all objects. */ - sal_Size GetProgressSize() const; +private: + ScRange maScUsedArea; /// Sheet index and used area in this sheet. +}; + +// The object manager ========================================================= + +/** Stores all drawing and OLE objects and additional data related to these objects. */ +class XclImpObjectManager : protected XclImpRoot +{ +public: + explicit XclImpObjectManager( const XclImpRoot& rRoot ); + virtual ~XclImpObjectManager(); + + /** Reads the MSODRAWINGGROUP record. */ + void ReadMsoDrawingGroup( XclImpStream& rStrm ); + + /** Returns (initially creates) the drawing manager of the specified sheet. */ + XclImpSheetDrawing& GetSheetDrawing( SCTAB nScTab ); + /** Inserts all objects into the Calc document. */ + void ConvertObjects(); + + /** Returns the default name for the passed object. */ + String GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const; + /** Returns the used area in the sheet with the passed index. */ + ScRange GetUsedArea( SCTAB nScTab ) const; // ------------------------------------------------------------------------ private: - typedef ::std::map< sal_Size, XclImpDrawObjRef > XclImpObjMap; - typedef ::std::map< XclObjId, XclImpDrawObjRef > XclImpObjMapById; - typedef ScfRef< XclImpObjTextData > XclImpObjTextRef; - typedef ::std::map< sal_Size, XclImpObjTextRef > XclImpObjTextMap; - typedef ::std::vector< XclObjId > XclObjIdVec; - typedef ::std::map< sal_uInt16, String > DefObjNameMap; - typedef ::std::vector< sal_Size > StreamPosVec; - typedef ScfRef< XclImpDffManager > XclImpDffMgrRef; - - XclImpDrawObjVector maRawObjs; /// BIFF5 objects without DFF data. - XclImpObjMap maObjMap; /// Maps BIFF8 drawing objects to DFF stream position. - XclImpObjMapById maObjMapId; /// Maps BIFF8 drawing objects to sheet index and object ID. - XclImpObjTextMap maTextMap; /// Maps BIFF8 TXO textbox data to DFF stream position. - XclObjIdVec maSkipObjs; /// All objects to be skipped. + typedef ScfRef< XclImpSheetDrawing > XclImpSheetDrawingRef; + typedef ::std::map< SCTAB, XclImpSheetDrawingRef > XclImpSheetDrawingMap; DefObjNameMap maDefObjNames; /// Default base names for all object types. - SvMemoryStream maDffStrm; /// Copy of DFF stream in memory. - StreamPosVec maTabStrmPos; /// Start positions of DFF stream fragments for all sheets. - XclImpDffMgrRef mxDffManager; /// The DFF stream converter. + SvMemoryStream maDggStrm; /// Copy of global DFF data (DGG container) in memory. + XclImpSheetDrawingMap maSheetDrawings; /// Drawing managers of all sheets. }; // DFF property set helper ==================================================== @@ -1197,8 +1262,8 @@ public: private: typedef ::std::auto_ptr< SvMemoryStream > SvMemoryStreamPtr; - SvMemoryStream maDummyStrm; /// Dummy stream for DFF manager. - XclImpSimpleDffManager maDffManager;/// DFF manager used to resolve palette colors. + SvMemoryStream maDummyStrm; /// Dummy DGG stream for DFF manager. + XclImpSimpleDffConverter maDffConv; /// DFF converter used to resolve palette colors. SvMemoryStreamPtr mxMemStrm; /// Helper stream. }; diff --git a/sc/source/filter/inc/xihelper.hxx b/sc/source/filter/inc/xihelper.hxx index 9a836c8844db..05412c306c0c 100644 --- a/sc/source/filter/inc/xihelper.hxx +++ b/sc/source/filter/inc/xihelper.hxx @@ -320,13 +320,15 @@ public: /** Returns the type of the cached value (EXC_CACHEDVAL_*). */ inline sal_uInt8 GetType() const { return mnType; } /** Returns the cached string value, if this value is a string, else an empty string. */ - inline const String& GetString() const { return mxStr.get() ? *mxStr : EMPTY_STRING; } + inline const String& GetString() const { return mxStr.get() ? *mxStr : EMPTY_STRING; } /** Returns the cached number, if this value has number type, else 0.0. */ inline double GetValue() const { return mfValue; } /** Returns the cached Boolean value, if this value has Boolean type, else false. */ inline bool GetBool() const { return (mnType == EXC_CACHEDVAL_BOOL) && (mnBoolErr != 0); } /** Returns the cached Calc error code, if this value has Error type, else 0. */ - USHORT GetError() const; + inline sal_uInt8 GetXclError() const { return (mnType == EXC_CACHEDVAL_ERROR) ? mnBoolErr : EXC_ERR_NA; } + /** Returns the cached Calc error code, if this value has Error type, else 0. */ + USHORT GetScError() const; /** Returns the token array if this is a Boolean value or error value, else 0. */ inline const ScTokenArray* GetBoolErrFmla() const { return mxTokArr.get(); } diff --git a/sc/source/filter/inc/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx index 3881adaaf911..0e06b31b650d 100644 --- a/sc/source/filter/inc/xiroot.hxx +++ b/sc/source/filter/inc/xiroot.hxx @@ -51,6 +51,7 @@ class XclImpTabInfo; class XclImpNameManager; class XclImpLinkManager; class XclImpObjectManager; +class XclImpSheetDrawing; class XclImpCondFormatManager; class XclImpAutoFilterBuffer; class XclImpWebQueryBuffer; @@ -176,6 +177,8 @@ public: /** Returns the drawing object manager. */ XclImpObjectManager& GetObjectManager() const; + /** Returns the drawing container of the current sheet. */ + XclImpSheetDrawing& GetCurrSheetDrawing() const; /** Returns the conditional formattings manager. */ XclImpCondFormatManager& GetCondFormatManager() const; /** Returns the filter manager. */ diff --git a/sc/source/filter/inc/xistyle.hxx b/sc/source/filter/inc/xistyle.hxx index 4a347062905c..104002542a17 100644 --- a/sc/source/filter/inc/xistyle.hxx +++ b/sc/source/filter/inc/xistyle.hxx @@ -316,6 +316,9 @@ struct XclImpCellBorder : public XclCellBorder /** Fills this struct with BIFF8 CF (conditional format) record data. */ void FillFromCF8( sal_uInt16 nLineStyle, sal_uInt32 nLineColor, sal_uInt32 nFlags ); + /** Returns true, if any of the outer border lines is visible. */ + bool HasAnyOuterBorder() const; + /** Inserts a box item representing this border style into the item set. @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. */ void FillToItemSet( @@ -423,8 +426,6 @@ private: @descr In cell XFs, a set bit represents "used", in style XFs it is a cleared bit. Therefore mbCellXF must be set correctly before calling this method. */ void SetUsedFlags( sal_uInt8 nUsedFlags ); - /** Sets own "attribute used" flags, if attributes are different from passed parent XF. */ - void UpdateUsedFlags( const XclImpXF& rParentXF ); private: typedef ::std::auto_ptr< ScPatternAttr > ScPatternAttrPtr; diff --git a/sc/source/filter/inc/xlchart.hxx b/sc/source/filter/inc/xlchart.hxx index 7e5f90fda4a7..f6711211bc13 100644 --- a/sc/source/filter/inc/xlchart.hxx +++ b/sc/source/filter/inc/xlchart.hxx @@ -71,6 +71,7 @@ namespace com { namespace sun { namespace star { #define SERVICE_CHART2_TITLE CREATE_OUSTRING( "com.sun.star.chart2.Title" ) // property names +#define EXC_CHPROP_ADDITIONALSHAPES CREATE_OUSTRING( "AdditionalShapes" ) #define EXC_CHPROP_ARRANGEORDER CREATE_OUSTRING( "ArrangeOrder" ) #define EXC_CHPROP_ATTAXISINDEX CREATE_OUSTRING( "AttachedAxisIndex" ) #define EXC_CHPROP_ATTRIBDATAPOINTS CREATE_OUSTRING( "AttributedDataPoints" ) @@ -168,6 +169,8 @@ const sal_Int32 EXC_CHART_AXESSET_NONE = -1; /// For internal use const sal_Int32 EXC_CHART_AXESSET_PRIMARY = 0; /// API primary axes set index. const sal_Int32 EXC_CHART_AXESSET_SECONDARY = 1; /// API secondary axes set index. +const sal_Int32 EXC_CHART_UNIT = 4000; /// Chart objects are positioned in 1/4000 of chart area. + // (0x0850) CHFRINFO ---------------------------------------------------------- const sal_uInt16 EXC_ID_CHFRINFO = 0x0850; diff --git a/sc/source/filter/inc/xlescher.hxx b/sc/source/filter/inc/xlescher.hxx index f60d6d3a5ee5..33b75af8cd2c 100644 --- a/sc/source/filter/inc/xlescher.hxx +++ b/sc/source/filter/inc/xlescher.hxx @@ -312,18 +312,21 @@ bool operator<( const XclObjId& rL, const XclObjId& rR ); /** Represents the position (anchor) of an object in a Calc document. */ struct XclObjAnchor : public XclRange { - SCTAB mnScTab; /// Calc sheet index. sal_uInt16 mnLX; /// X offset in left column (1/1024 of column width). sal_uInt16 mnTY; /// Y offset in top row (1/256 of row height). sal_uInt16 mnRX; /// X offset in right column (1/1024 of column width). sal_uInt16 mnBY; /// Y offset in bottom row (1/256 of row height). - explicit XclObjAnchor( SCTAB nScTab ); + explicit XclObjAnchor(); /** Calculates a rectangle from the contained coordinates. */ - Rectangle GetRect( ScDocument& rDoc, MapUnit eMapUnit ) const; - /** Initializes the anchor coordinates from a rectangle. */ - void SetRect( ScDocument& rDoc, const Rectangle& rRect, MapUnit eMapUnit ); + Rectangle GetRect( ScDocument& rDoc, SCTAB nScTab, MapUnit eMapUnit ) const; + /** Initializes the anchor coordinates for a sheet. */ + void SetRect( ScDocument& rDoc, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit ); + + /** Initializes the anchor coordinates for an embedded draw page. */ + void SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY, + const Rectangle& rRect, MapUnit eMapUnit, bool bDffAnchor ); }; template< typename StreamType > diff --git a/sc/source/filter/inc/xltools.hxx b/sc/source/filter/inc/xltools.hxx index b2519a51d156..e8ceed8248d6 100644 --- a/sc/source/filter/inc/xltools.hxx +++ b/sc/source/filter/inc/xltools.hxx @@ -121,6 +121,8 @@ public: /** Converts an Excel error code to a Calc error code. */ static USHORT GetScErrorCode( sal_uInt8 nXclError ); + /** Converts the passed BIFF error to a double containing the respective Calc error code. */ + static double ErrorToDouble( sal_uInt8 nXclError ); /** Gets a translated error code or Boolean value from Excel error codes. @param rfDblValue Returns 0.0 for error codes or the value of a Boolean (0.0 or 1.0). @param bErrorOrBool false = nError is a Boolean value; true = is an error value. diff --git a/sc/source/filter/rtf/eeimpars.cxx b/sc/source/filter/rtf/eeimpars.cxx index 756b384b7f11..86a347970ff6 100644 --- a/sc/source/filter/rtf/eeimpars.cxx +++ b/sc/source/filter/rtf/eeimpars.cxx @@ -126,7 +126,7 @@ ULONG ScEEImport::Read( SvStream& rStream, const String& rBaseURL ) } -void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) +void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate ) { ScProgress* pProgress = new ScProgress( mpDoc->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC ), mpParser->Count() ); @@ -147,10 +147,12 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) nLastMergedRow = SCROW_MAX; BOOL bHasGraphics = FALSE; ScEEParseEntry* pE; - SvNumberFormatter* pFormatter = mpDoc->GetFormatTable(); - bool bNumbersEnglishUS = (pFormatter->GetLanguage() != LANGUAGE_ENGLISH_US); - if (bNumbersEnglishUS) + if (!pFormatter) + pFormatter = mpDoc->GetFormatTable(); + bool bNumbersEnglishUS = false; + if (pFormatter->GetLanguage() == LANGUAGE_SYSTEM) { + // Automatic language option selected. Check for the global 'use US English' option. SvxHtmlOptions aOpt; bNumbersEnglishUS = aOpt.IsNumbersEnglishUS(); } @@ -332,7 +334,7 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) else if ( !pE->aSel.HasRange() ) { // maybe ALT text of IMG or similar - mpDoc->SetString( nCol, nRow, nTab, pE->aAltText ); + mpDoc->SetString( nCol, nRow, nTab, pE->aAltText, pFormatter ); // wenn SelRange komplett leer kann nachfolgender Text im gleichen Absatz liegen! } else @@ -377,7 +379,7 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) if (bNumbersEnglishUS && !bEnUsRecognized) mpDoc->PutCell( nCol, nRow, nTab, new ScStringCell( aStr)); else - mpDoc->SetString( nCol, nRow, nTab, aStr ); + mpDoc->SetString( nCol, nRow, nTab, aStr, pFormatter, bConvertDate ); } } else diff --git a/sc/source/filter/xcl97/xcl97esc.cxx b/sc/source/filter/xcl97/xcl97esc.cxx index 2c5a30f085d3..a7c6dee67dc5 100644 --- a/sc/source/filter/xcl97/xcl97esc.cxx +++ b/sc/source/filter/xcl97/xcl97esc.cxx @@ -59,9 +59,11 @@ #include "xechart.hxx" #include "xcl97esc.hxx" +using ::rtl::OUString; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::container::XIndexAccess; @@ -72,24 +74,40 @@ using ::com::sun::star::form::XFormsSupplier; using ::com::sun::star::script::ScriptEventDescriptor; using ::com::sun::star::script::XEventAttacherManager; -// --- class XclEscherEx --------------------------------------------- +// ============================================================================ -XclEscherEx::XclEscherEx( const XclExpRoot& rRoot, SvStream& rStrm, UINT32 nDrawings ) - : - EscherEx( rStrm, nDrawings ), - XclExpRoot( rRoot ), - pPicTempFile( NULL ), - pPicStrm( NULL ), - pCurrXclObj( NULL ), - pCurrAppData( NULL ), - pTheClientData( new XclEscherClientData ), - pAdditionalText( NULL ), - nAdditionalText( 0 ) +XclEscherExGlobal::XclEscherExGlobal( const XclExpRoot& rRoot ) : + XclExpRoot( rRoot ) +{ +} + +SvStream* XclEscherExGlobal::ImplQueryPictureStream() +{ + mxPicTempFile.reset( new ::utl::TempFile ); + if( mxPicTempFile->IsValid() ) + { + mxPicTempFile->EnableKillingFile(); + mxPicStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxPicTempFile->GetURL(), STREAM_STD_READWRITE ) ); + mxPicStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); + } + return mxPicStrm.get(); +} + +// ============================================================================ + +XclEscherEx::XclEscherEx( const XclExpRoot& rRoot, XclExpObjectManager& rObjMgr, SvStream& rStrm, const XclEscherEx* pParent ) : + EscherEx( pParent ? pParent->mxGlobal : EscherExGlobalRef( new XclEscherExGlobal( rRoot ) ), rStrm ), + XclExpRoot( rRoot ), + mrObjMgr( rObjMgr ), + pCurrXclObj( NULL ), + pCurrAppData( NULL ), + pTheClientData( new XclEscherClientData ), + pAdditionalText( NULL ), + nAdditionalText( 0 ), + mnNextKey( 0 ), + mbIsRootDff( pParent == 0 ) { - aOffsetMap.Insert( (void*) 0, LIST_APPEND ); // start of stream - // Xcl forgets OLE objects completely if the Escher object is not EMF and - // the corresponding OLE application is opened and nothing is changed. - SetOleEmf( TRUE ); + InsertPersistOffset( mnNextKey, 0 ); } @@ -98,86 +116,83 @@ XclEscherEx::~XclEscherEx() DBG_ASSERT( !aStack.Count(), "~XclEscherEx: stack not empty" ); DeleteCurrAppData(); delete pTheClientData; - if ( pPicStrm ) - { - delete pPicStrm; - } - if ( pPicTempFile ) - delete pPicTempFile; } -SvStream* XclEscherEx::QueryPicStream() +sal_uInt32 XclEscherEx::InitNextDffFragment() { - if ( !pPicStrm ) - { - if ( !pPicTempFile ) - { - pPicTempFile = new utl::TempFile; - if ( pPicTempFile->IsValid() ) - pPicTempFile->EnableKillingFile(); - else - { - delete pPicTempFile; - pPicTempFile = NULL; - } - } - if ( pPicTempFile ) - { - pPicStrm = utl::UcbStreamHelper::CreateStream( pPicTempFile->GetURL(), STREAM_STD_READWRITE ); - pPicStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - } - } - return pPicStrm; + /* Current value of mnNextKey will be used by caller to refer to the + starting point of the DFF fragment. The key exists already in the + PersistTable (has been inserted by c'tor of previous call of + InitNextDffFragment(), has been updated by UpdateDffFragmentEnd(). */ + sal_uInt32 nPersistKey = mnNextKey; + + /* Prepare the next key that is used by caller as end point of the DFF + fragment. Will be updated by caller when writing to the DFF stream, + using the UpdateDffFragmentEnd() function. This is needed to find DFF + data written by the SVX base class implementation without interaction, + e.g. the solver container that will be written after the last shape. */ + ++mnNextKey; + InsertPersistOffset( mnNextKey, mpOutStrm->Tell() ); + + return nPersistKey; } - -void XclEscherEx::InsertAtCurrentPos( UINT32 nBytes, BOOL bCont ) +void XclEscherEx::UpdateDffFragmentEnd() { - ULONG nPos = GetStreamPos(); - ULONG nCnt = aOffsetMap.Count(); - ULONG j, nOff; - for ( j=0, nOff = (ULONG) aOffsetMap.First(); j<nCnt; - j++, nOff = (ULONG) aOffsetMap.Next() ) - { - if ( nOff >= nPos ) - aOffsetMap.Replace( (void*) (nOff + nBytes) ); - } - EscherEx::InsertAtCurrentPos( nBytes, bCont ); + // update existing fragment key with new stream position + ReplacePersistOffset( mnNextKey, mpOutStrm->Tell() ); } - -ULONG XclEscherEx::AddCurrentOffsetToMap() +sal_uInt32 XclEscherEx::GetDffFragmentPos( sal_uInt32 nFragmentKey ) { - aOffsetMap.Insert( (void*) GetStreamPos(), LIST_APPEND ); - return aOffsetMap.Count() - 1; + /* TODO: this function is non-const because PersistTable::PtGetOffsetByID() + is non-const due to tools/List usage. */ + return GetPersistOffset( nFragmentKey ); } +sal_uInt32 XclEscherEx::GetDffFragmentSize( sal_uInt32 nFragmentKey ) +{ + /* TODO: this function is non-const because PersistTable::PtGetOffsetByID() + is non-const due to tools/List usage. */ + return GetDffFragmentPos( nFragmentKey + 1 ) - GetDffFragmentPos( nFragmentKey ); +} -void XclEscherEx::ReplaceCurrentOffsetInMap( ULONG nPos ) +bool XclEscherEx::HasPendingDffData() { - aOffsetMap.Replace( (void*) GetStreamPos(), nPos ); + /* TODO: this function is non-const because PersistTable::PtGetOffsetByID() + is non-const due to tools/List usage. */ + return GetDffFragmentPos( mnNextKey ) < GetStreamPos(); } -sal_Bool ImplXclEscherExIsFontwork( const SdrObject* pObj ) +XclExpDffAnchorBase* XclEscherEx::CreateDffAnchor( const SdrObject& rSdrObj ) const { - const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) ); + // the object manager creates the correct anchor type according to context + XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor(); + // pass the drawing object, that will calculate the anchor position + pAnchor->SetSdrObject( rSdrObj ); + return pAnchor; +} - sal_Bool bIsFontwork = sal_False; - if ( pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE ) +namespace { + +bool lcl_IsFontwork( const SdrObject* pObj ) +{ + bool bIsFontwork = false; + if( pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE ) { + const OUString aTextPath = CREATE_OUSTRING( "TextPath" ); SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&) pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ); - - com::sun::star::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath ); - if ( pAny ) + if( Any* pAny = rGeometryItem.GetPropertyValueByName( aTextPath, aTextPath ) ) *pAny >>= bIsFontwork; } return bIsFontwork; } -EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Reference< - com::sun::star::drawing::XShape >& rShape ) +} // namespace + +EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape, const Rectangle* pChildAnchor ) { if ( nAdditionalText ) nAdditionalText++; @@ -185,17 +200,17 @@ EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Referen if ( bInGroup ) { // stacked recursive group object if ( !pCurrAppData->IsStackedGroup() ) - { //! UpdateStopPos only once + { //! UpdateDffFragmentEnd only once pCurrAppData->SetStackedGroup( TRUE ); - pCurrXclObj->UpdateStopPos(); + UpdateDffFragmentEnd(); } } aStack.Push( pCurrXclObj ); aStack.Push( pCurrAppData ); pCurrAppData = new XclEscherHostAppData; - SdrObject* pObj = GetSdrObjectFromXShape( rShape ); + SdrObject* pObj = GetSdrObjectFromXShape( rxShape ); if ( !pObj ) - pCurrXclObj = new XclObjAny( GetRoot() ); // just what is it?!? + pCurrXclObj = new XclObjAny( mrObjMgr ); // just what is it?!? else { pCurrXclObj = NULL; @@ -203,38 +218,50 @@ EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Referen if( nObjType == OBJ_OLE2 ) { - //! not-const because GetObjRef may load the OLE object - Reference < XClassifiedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), UNO_QUERY ); - if ( xObj.is() ) + // no OLE objects in embedded drawings (chart shapes) + if( mbIsRootDff ) { - SvGlobalName aObjClsId( xObj->getClassID() ); - if ( SotExchange::IsChart( aObjClsId ) ) - { // yes, it's a chart diagram - GetOldRoot().pObjRecs->Add( new XclExpChartObj( GetRoot(), rShape ) ); - pCurrXclObj = NULL; // no metafile or whatsoever + //! not-const because GetObjRef may load the OLE object + Reference < XClassifiedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), UNO_QUERY ); + if ( xObj.is() ) + { + SvGlobalName aObjClsId( xObj->getClassID() ); + if ( SotExchange::IsChart( aObjClsId ) ) + { // yes, it's a chart diagram + mrObjMgr.AddObj( new XclExpChartObj( mrObjMgr, rxShape, pChildAnchor ) ); + pCurrXclObj = NULL; // no metafile or whatsoever + } + else // metafile and OLE object + pCurrXclObj = new XclObjOle( mrObjMgr, *pObj ); } - else // metafile and OLE object - pCurrXclObj = new XclObjOle( GetRoot(), *pObj ); + else // just a metafile + pCurrXclObj = new XclObjAny( mrObjMgr ); } - else // just a metafile - pCurrXclObj = new XclObjAny( GetRoot() ); + else + pCurrXclObj = new XclObjAny( mrObjMgr ); } else if( nObjType == OBJ_UNO ) { - pCurrXclObj = CreateCtrlObj( rShape ); +#if EXC_EXP_OCX_CTRL + // no ActiveX controls in embedded drawings (chart shapes) + if( mbIsRootDff ) + pCurrXclObj = CreateCtrlObj( rxShape, pChildAnchor ); +#else + pCurrXclObj = CreateCtrlObj( rxShape, pChildAnchor ); +#endif if( !pCurrXclObj ) - pCurrXclObj = new XclObjAny( GetRoot() ); // just a metafile + pCurrXclObj = new XclObjAny( mrObjMgr ); // just a metafile } else if( !ScDrawLayer::IsNoteCaption( pObj ) ) { // #107540# ignore permanent note shapes // #i12190# do not ignore callouts (do not filter by object type ID) - pCurrXclObj = new XclObjAny( GetRoot() ); // just a metafile + pCurrXclObj = new XclObjAny( mrObjMgr ); // just a metafile } } if ( pCurrXclObj ) { - if ( !GetOldRoot().pObjRecs->Add( pCurrXclObj ) ) + if ( !mrObjMgr.AddObj( pCurrXclObj ) ) { // maximum count reached, object got deleted pCurrXclObj = NULL; } @@ -247,14 +274,15 @@ EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Referen { if ( !bInGroup ) { - /* Create a dummy anchor carrying the flags. Real coordinates are - calculated later in WriteData(EscherEx&,const Rectangle&). */ - XclExpDffAnchor* pAnchor = new XclExpDffAnchor( GetRoot() ); + /* Create a dummy anchor carrying the flags. Real + coordinates are calculated later in virtual call of + WriteData(EscherEx&,const Rectangle&). */ + XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor(); pAnchor->SetFlags( *pObj ); pCurrAppData->SetClientAnchor( pAnchor ); } const SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pObj ); - if ( pTextObj && !ImplXclEscherExIsFontwork( pTextObj ) && ( pObj->GetObjIdentifier() != OBJ_CAPTION ) ) + if( pTextObj && !lcl_IsFontwork( pTextObj ) && (pObj->GetObjIdentifier() != OBJ_CAPTION) ) { const OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject(); if( pParaObj ) @@ -265,7 +293,7 @@ EscherExHostAppData* XclEscherEx::StartShape( const com::sun::star::uno::Referen else { if ( !bInGroup ) - pCurrAppData->SetClientAnchor( new XclExpDffAnchor( GetRoot() ) ); + pCurrAppData->SetClientAnchor( mrObjMgr.CreateDffAnchor() ); } } else if ( nAdditionalText == 3 ) @@ -295,13 +323,10 @@ void XclEscherEx::EndShape( UINT16 nShapeType, UINT32 nShapeID ) // escher data of last shape not written? -> delete it from object list if( nShapeID == 0 ) { - XclObj* pLastObj = static_cast< XclObj* >( GetOldRoot().pObjRecs->Last() ); + XclObj* pLastObj = mrObjMgr.RemoveLastObj(); DBG_ASSERT( pLastObj == pCurrXclObj, "XclEscherEx::EndShape - wrong object" ); - if ( pLastObj == pCurrXclObj ) - { - GetOldRoot().pObjRecs->Remove(); - DELETEZ( pCurrXclObj ); - } + DELETEZ( pLastObj ); + pCurrXclObj = 0; } if( pCurrXclObj ) @@ -312,7 +337,7 @@ void XclEscherEx::EndShape( UINT16 nShapeType, UINT32 nShapeID ) else { pCurrXclObj->SetEscherShapeType( nShapeType ); - pCurrXclObj->UpdateStopPos(); + UpdateDffFragmentEnd(); } } } @@ -335,26 +360,18 @@ EscherExHostAppData* XclEscherEx::EnterAdditionalTextGroup() } -void XclEscherEx::DeleteCurrAppData() -{ - if ( pCurrAppData ) - { - delete pCurrAppData->GetClientAnchor(); -// delete pCurrAppData->GetClientData(); - delete pCurrAppData->GetClientTextbox(); - delete pCurrAppData; - } -} - - void XclEscherEx::EndDocument() { - Flush( pPicStrm ); + if( mbIsRootDff ) + Flush( static_cast< XclEscherExGlobal& >( *mxGlobal ).GetPictureStream() ); + + // seek back DFF stream to prepare saving the MSODRAWING[GROUP] records + mpOutStrm->Seek( 0 ); } #if EXC_EXP_OCX_CTRL -XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape ) +XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor ) { ::std::auto_ptr< XclExpOcxControlObj > xOcxCtrl; @@ -375,7 +392,7 @@ XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape ) sal_uInt32 nStrmSize = static_cast< sal_uInt32 >( mxCtlsStrm->Tell() - nStrmStart ); // adjust the class name to "Forms.***.1" aClassName.InsertAscii( "Forms.", 0 ).AppendAscii( ".1" ); - xOcxCtrl.reset( new XclExpOcxControlObj( GetRoot(), xShape, aClassName, nStrmStart, nStrmSize ) ); + xOcxCtrl.reset( new XclExpOcxControlObj( mrObjMgr, xShape, pChildAnchor, aClassName, nStrmStart, nStrmSize ) ); } } } @@ -384,9 +401,9 @@ XclExpOcxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape ) #else -XclExpTbxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape ) +XclExpTbxControlObj* XclEscherEx::CreateCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor ) { - ::std::auto_ptr< XclExpTbxControlObj > xTbxCtrl( new XclExpTbxControlObj( GetRoot(), xShape ) ); + ::std::auto_ptr< XclExpTbxControlObj > xTbxCtrl( new XclExpTbxControlObj( mrObjMgr, xShape, pChildAnchor ) ); if( xTbxCtrl->GetObjType() == EXC_OBJTYPE_UNKNOWN ) xTbxCtrl.reset(); @@ -454,98 +471,17 @@ void XclEscherEx::ConvertTbxMacro( XclExpTbxControlObj& rTbxCtrlObj, Reference< #endif -// --- class XclEscher ----------------------------------------------- - -XclEscher::XclEscher( const XclExpRoot& rRoot, UINT32 nDrawings ) : - XclExpRoot( rRoot ) -{ - pTempFile = new utl::TempFile; - pTempFile->EnableKillingFile(); - pStrm = utl::UcbStreamHelper::CreateStream( pTempFile->GetURL(), STREAM_STD_READWRITE ); - pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - pEx = new XclEscherEx( rRoot, *pStrm, nDrawings ); -} - - -XclEscher::~XclEscher() -{ - delete pEx; - delete pStrm; - delete pTempFile; -} - - -void XclEscher::AddSdrPage() -{ - if( SdrPage* pPage = GetSdrPage( GetCurrScTab() ) ) - pEx->AddSdrPage( *pPage ); - // #106213# the first dummy object may still be open - DBG_ASSERT( pEx->GetGroupLevel() <= 1, "XclEscher::AddSdrPage - still groups open?" ); - while( pEx->GetGroupLevel() ) - pEx->LeaveGroup(); -} - - -// Escher client anchor ======================================================= - -XclExpDffAnchor::XclExpDffAnchor( const XclExpRoot& rRoot, sal_uInt16 nFlags ) : - XclExpRoot( rRoot ), - maAnchor( rRoot.GetCurrScTab() ), - mnFlags( nFlags ) -{ -} - -XclExpDffAnchor::XclExpDffAnchor( const XclExpRoot& rRoot, const SdrObject& rSdrObj ) : - XclExpRoot( rRoot ), - maAnchor( rRoot.GetCurrScTab() ) -{ - SetFlags( rSdrObj ); - maAnchor.SetRect( GetDoc(), rSdrObj.GetCurrentBoundRect(), MAP_100TH_MM ); -} - -void XclExpDffAnchor::SetFlags( const SdrObject& rSdrObj ) -{ - // Special case "page anchor" (X==0,Y==1) -> lock pos and size. - const Point& rPos = rSdrObj.GetAnchorPos(); - mnFlags = ((rPos.X() == 0) && (rPos.Y() == 1)) ? EXC_ESC_ANCHOR_LOCKED : 0; -} - -void XclExpDffAnchor::WriteData( EscherEx& rEx, const Rectangle& rRect ) -{ - // the rectangle is already in twips - maAnchor.SetRect( GetDoc(), rRect, MAP_TWIP ); - WriteData( rEx ); -} - - -void XclExpDffAnchor::WriteData( EscherEx& rEx ) const -{ - rEx.AddAtom( 18, ESCHER_ClientAnchor ); - rEx.GetStream() << mnFlags << maAnchor; -} - - -// ---------------------------------------------------------------------------- - -XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ) : - XclExpDffAnchor( rRoot, EXC_ESC_ANCHOR_SIZELOCKED ) -{ - maAnchor.SetRect( GetDoc(), rRect, MAP_100TH_MM ); -} - - -// ---------------------------------------------------------------------------- - -XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot& rRoot, const ScAddress& rScPos ) : - XclExpDffAnchor( rRoot, EXC_ESC_ANCHOR_POSLOCKED ) +void XclEscherEx::DeleteCurrAppData() { - GetAddressConverter().ConvertAddress( maAnchor.maFirst, rScPos, true ); - maAnchor.maLast.mnCol = maAnchor.maFirst.mnCol + 1; - maAnchor.maLast.mnRow = maAnchor.maFirst.mnRow + 1; - maAnchor.mnLX = maAnchor.mnTY = maAnchor.mnRX = maAnchor.mnBY = 0; + if ( pCurrAppData ) + { + delete pCurrAppData->GetClientAnchor(); +// delete pCurrAppData->GetClientData(); + delete pCurrAppData->GetClientTextbox(); + delete pCurrAppData; + } } - // ============================================================================ // --- class XclEscherClientData ------------------------------------- diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index e4c4443ea56e..67a295ccec8b 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -49,6 +49,7 @@ #include "xcl97esc.hxx" #include "editutil.hxx" #include "xecontent.hxx" +#include "xeescher.hxx" #include "xestyle.hxx" #include "xelink.hxx" @@ -86,158 +87,22 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::drawing::XShape; +// ============================================================================ -//___________________________________________________________________ - -// --- class XclMsodrawing_Base -------------------------------------- - -XclMsodrawing_Base::XclMsodrawing_Base( XclEscher& rEscher, sal_Size nInitialSize ) - : - pEscher( &rEscher ), - nStartPos( rEscher.GetEx()->GetLastOffsetMapPos() ) -{ - // for safety's sake add this now - nStopPos = GetEscherEx()->AddCurrentOffsetToMap(); - (void)nInitialSize; // avoid compiler warning - DBG_ASSERT( GetDataLen() == nInitialSize, "XclMsodrawing_Base ctor: do I really own that data?" ); -} - - -XclMsodrawing_Base::~XclMsodrawing_Base() -{ -} - - -void XclMsodrawing_Base::UpdateStopPos() -{ - if ( nStopPos > 0 ) - GetEscherEx()->ReplaceCurrentOffsetInMap( nStopPos ); - else - nStopPos = GetEscherEx()->AddCurrentOffsetToMap(); -} - - -sal_Size XclMsodrawing_Base::GetDataLen() const -{ - if ( nStartPos < nStopPos ) - { - XclEscherEx* pEx = GetEscherEx(); - return pEx->GetOffsetFromMap( nStopPos ) - pEx->GetOffsetFromMap( nStartPos ); - } - DBG_ERRORFILE( "XclMsodrawing_Base::GetDataLen: position mismatch" ); - return 0; -} - - - -// --- class XclMsodrawinggroup -------------------------------------- - -XclMsodrawinggroup::XclMsodrawinggroup( RootData& rRoot, UINT16 nEscherType ) : - XclMsodrawing_Base( *rRoot.pEscher ), - XclExpRecord(0x00EB, 2) // bogus record size since we don't know the actual size yet. -{ - if ( nEscherType ) - { - XclEscherEx* pEx = GetEscherEx(); - SvStream& rOut = pEx->GetStream(); - switch ( nEscherType ) - { - case ESCHER_DggContainer : - { // per-document data - pEx->OpenContainer( nEscherType ); -//2do: stuff it with our own document defaults? -#if 0 - pEx->BeginCount(); - pEx->AddOpt( ... ); - pEx->EndCount( ESCHER_OPT, 3 ); -#else - BYTE pDummyOPT[] = { - 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01, - 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00, - 0x00, 0x08 - }; - pEx->AddAtom( sizeof(pDummyOPT), ESCHER_OPT, 3, 3 ); - rOut.Write( pDummyOPT, sizeof(pDummyOPT) ); -#endif - BYTE pDummySplitMenuColors[] = { - 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08, - 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10 - }; - pEx->AddAtom( sizeof(pDummySplitMenuColors), ESCHER_SplitMenuColors, 0, 4 ); - rOut.Write( pDummySplitMenuColors, sizeof(pDummySplitMenuColors) ); - pEx->CloseContainer(); // ESCHER_DggContainer - } - break; - } - UpdateStopPos(); - } -} - - -XclMsodrawinggroup::~XclMsodrawinggroup() -{ -} - - -void XclMsodrawinggroup::WriteBody( XclExpStream& rStrm ) -{ - DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ), - "XclMsodrawinggroup::SaveCont: Escher stream position mismatch" ); - rStrm.CopyFromStream( pEscher->GetStrm(), GetDataLen() ); -} - - -// --- class XclMsodrawing -------------------------------------- - -XclMsodrawing::XclMsodrawing( const XclExpRoot& rRoot, UINT16 nEscherType, sal_Size nInitialSize ) : - XclMsodrawing_Base( *rRoot.GetOldRoot().pEscher, nInitialSize ), - XclExpRecord( 0x00EC, nInitialSize ) -{ - if ( nEscherType ) - { - XclEscherEx* pEx = GetEscherEx(); - switch ( nEscherType ) - { - case ESCHER_DgContainer : - { // per-sheet data - pEx->OpenContainer( nEscherType ); - // open group shape container - Rectangle aRect( 0, 0, 0, 0 ); - pEx->EnterGroup( &aRect ); - } - break; - } - UpdateStopPos(); - } -} - - -XclMsodrawing::~XclMsodrawing() -{ -} - - -void XclMsodrawing::WriteBody( XclExpStream& rStrm ) -{ - DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ), - "XclMsodrawing::SaveCont: Escher stream position mismatch" ); - rStrm.CopyFromStream( pEscher->GetStrm(), GetDataLen() ); -} - - - - -// --- class XclObjList ---------------------------------------------- - -XclObjList::XclObjList( const XclExpRoot& rRoot ) : +XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ) : XclExpRoot( rRoot ), - pMsodrawingPerSheet( new XclMsodrawing( rRoot, ESCHER_DgContainer ) ), - pSolverContainer( NULL ) + mrEscherEx( rEscherEx ), + pSolverContainer( 0 ) { + pMsodrawingPerSheet = new XclExpMsoDrawing( rEscherEx ); + // open the DGCONTAINER and the patriarch group shape + mrEscherEx.OpenContainer( ESCHER_DgContainer ); + Rectangle aRect( 0, 0, 0, 0 ); + mrEscherEx.EnterGroup( &aRect ); + mrEscherEx.UpdateDffFragmentEnd(); } - -XclObjList::~XclObjList() +XclExpObjList::~XclExpObjList() { for ( XclObj* p = First(); p; p = Next() ) delete p; @@ -245,10 +110,9 @@ XclObjList::~XclObjList() delete pSolverContainer; } - -UINT16 XclObjList::Add( XclObj* pObj ) +UINT16 XclExpObjList::Add( XclObj* pObj ) { - DBG_ASSERT( Count() < 0xFFFF, "XclObjList::Add: too much for Xcl" ); + DBG_ASSERT( Count() < 0xFFFF, "XclExpObjList::Add: too much for Xcl" ); if ( Count() < 0xFFFF ) { Insert( pObj, LIST_APPEND ); @@ -263,22 +127,17 @@ UINT16 XclObjList::Add( XclObj* pObj ) } } - -void XclObjList::EndSheet() +void XclExpObjList::EndSheet() { - XclEscherEx* pEx = pMsodrawingPerSheet->GetEscherEx(); - // Is there still something in the stream? -> The solver container - sal_Size nSolverSize = pEx->GetStreamPos() - pEx->GetOffsetFromMap( pEx->GetLastOffsetMapPos() ); - if( nSolverSize > 0 ) - pSolverContainer = new XclMsodrawing( GetRoot(), ESCHER_SolverContainer, nSolverSize ); + if( mrEscherEx.HasPendingDffData() ) + pSolverContainer = new XclExpMsoDrawing( mrEscherEx ); - //! close ESCHER_DgContainer created by XclObjList ctor MSODRAWING - pEx->CloseContainer(); + // close the DGCONTAINER created by XclExpObjList ctor MSODRAWING + mrEscherEx.CloseContainer(); } - -void XclObjList::Save( XclExpStream& rStrm ) +void XclExpObjList::Save( XclExpStream& rStrm ) { //! Escher must be written, even if there are no objects pMsodrawingPerSheet->Save( rStrm ); @@ -290,28 +149,26 @@ void XclObjList::Save( XclExpStream& rStrm ) pSolverContainer->Save( rStrm ); } - - // --- class XclObj -------------------------------------------------- -XclObj::XclObj( const XclExpRoot& rRoot, sal_uInt16 nObjType, bool bOwnEscher ) : +XclObj::XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher ) : XclExpRecord( EXC_ID_OBJ, 26 ), + mrEscherEx( rObjMgr.GetEscherEx() ), pClientTextbox( NULL ), pTxo( NULL ), mnObjType( nObjType ), nObjId(0), nGrbit( 0x6011 ), // AutoLine, AutoFill, Printable, Locked - bFirstOnSheet( rRoot.GetOldRoot().pObjRecs->Count() == 0 ), + bFirstOnSheet( !rObjMgr.HasObj() ), mbOwnEscher( bOwnEscher ) { //! first object continues the first MSODRAWING record if ( bFirstOnSheet ) - pMsodrawing = rRoot.GetOldRoot().pObjRecs->GetMsodrawingPerSheet(); + pMsodrawing = rObjMgr.GetMsodrawingPerSheet(); else - pMsodrawing = new XclMsodrawing( rRoot ); + pMsodrawing = new XclExpMsoDrawing( mrEscherEx ); } - XclObj::~XclObj() { if ( !bFirstOnSheet ) @@ -320,6 +177,18 @@ XclObj::~XclObj() delete pTxo; } +void XclObj::ImplWriteAnchor( const XclExpRoot& /*rRoot*/, const SdrObject* pSdrObj, const Rectangle* pChildAnchor ) +{ + if( pChildAnchor ) + { + mrEscherEx.AddChildAnchor( *pChildAnchor ); + } + else if( pSdrObj ) + { + ::std::auto_ptr< XclExpDffAnchorBase > xDffAnchor( mrEscherEx.CreateDffAnchor( *pSdrObj ) ); + xDffAnchor->WriteDffData( mrEscherEx ); + } +} void XclObj::SetEscherShapeType( UINT16 nType ) { @@ -350,21 +219,19 @@ void XclObj::SetEscherShapeType( UINT16 nType ) } } - void XclObj::SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj ) { DBG_ASSERT( !pClientTextbox, "XclObj::SetText: already set" ); if ( !pClientTextbox ) { - pMsodrawing->UpdateStopPos(); - pClientTextbox = new XclMsodrawing( rRoot ); - pClientTextbox->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox ); // TXO record - pClientTextbox->UpdateStopPos(); + mrEscherEx.UpdateDffFragmentEnd(); + pClientTextbox = new XclExpMsoDrawing( mrEscherEx ); + mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record + mrEscherEx.UpdateDffFragmentEnd(); pTxo = new XclTxo( rRoot, rObj ); } } - void XclObj::WriteBody( XclExpStream& rStrm ) { DBG_ASSERT( mnObjType != EXC_OBJTYPE_UNKNOWN, "XclObj::WriteBody - unknown type" ); @@ -392,7 +259,6 @@ void XclObj::WriteBody( XclExpStream& rStrm ) rStrm.CopyFromStream( aMemStrm ); } - void XclObj::Save( XclExpStream& rStrm ) { // MSODRAWING record (msofbtSpContainer) @@ -406,7 +272,6 @@ void XclObj::Save( XclExpStream& rStrm ) SaveTextRecs( rStrm ); } - void XclObj::WriteSubRecs( XclExpStream& /*rStrm*/ ) { } @@ -421,17 +286,14 @@ void XclObj::SaveTextRecs( XclExpStream& rStrm ) pTxo->Save( rStrm ); } - // --- class XclObjComment ------------------------------------------- - -XclObjComment::XclObjComment( const XclExpRoot& rRoot, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible ) - : - XclObj( rRoot, EXC_OBJTYPE_NOTE, true ) +XclObjComment::XclObjComment( XclExpObjectManager& rObjMgr, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible ) : + XclObj( rObjMgr, EXC_OBJTYPE_NOTE, true ) { - ProcessEscherObj(rRoot, rRect, pCaption, bVisible); + ProcessEscherObj( rObjMgr.GetRoot(), rRect, pCaption, bVisible); // TXO - pTxo = new XclTxo( rRoot, rEditObj, pCaption ); + pTxo = new XclTxo( rObjMgr.GetRoot(), rEditObj, pCaption ); } void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& rRect, SdrObject* pCaption, const bool bVisible ) @@ -482,66 +344,62 @@ void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& } nGrbit = 0; // all off: AutoLine, AutoFill, Printable, Locked - XclEscherEx* pEx = pMsodrawing->GetEscherEx(); - pEx->OpenContainer( ESCHER_SpContainer ); - pEx->AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); sal_uInt32 nFlags = 0x000A0000; ::set_flag( nFlags, sal_uInt32(2), !bVisible ); aPropOpt.AddOpt( ESCHER_Prop_fPrint, nFlags ); // bool field - aPropOpt.Commit( pEx->GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); - XclExpDffNoteAnchor( rRoot, rRect ).WriteData( *pEx); + XclExpDffNoteAnchor( rRoot, rRect ).WriteDffData( mrEscherEx ); + + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record + mrEscherEx.UpdateDffFragmentEnd(); - pEx->AddAtom( 0, ESCHER_ClientData ); // OBJ record - pMsodrawing->UpdateStopPos(); //! Be sure to construct the MSODRAWING ClientTextbox record _after_ the //! base OBJ's MSODRAWING record Escher data is completed. - pClientTextbox = new XclMsodrawing( rRoot ); - pClientTextbox->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox ); // TXO record - pClientTextbox->UpdateStopPos(); - pEx->CloseContainer(); // ESCHER_SpContainer + pClientTextbox = new XclExpMsoDrawing( mrEscherEx ); + mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record + mrEscherEx.UpdateDffFragmentEnd(); + mrEscherEx.CloseContainer(); // ESCHER_SpContainer } - XclObjComment::~XclObjComment() { } - void XclObjComment::Save( XclExpStream& rStrm ) { // content of this record XclObj::Save( rStrm ); } - // --- class XclObjDropDown ------------------------------------------ -XclObjDropDown::XclObjDropDown( const XclExpRoot& rRoot, const ScAddress& rPos, BOOL bFilt ) : - XclObj( rRoot, EXC_OBJTYPE_DROPDOWN, true ), - bIsFiltered( bFilt ) +XclObjDropDown::XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, BOOL bFilt ) : + XclObj( rObjMgr, EXC_OBJTYPE_DROPDOWN, true ), + bIsFiltered( bFilt ) { SetLocked( TRUE ); SetPrintable( FALSE ); SetAutoFill( TRUE ); SetAutoLine( FALSE ); nGrbit |= 0x0100; // undocumented - XclEscherEx* pEx = pMsodrawing->GetEscherEx(); - pEx->OpenContainer( ESCHER_SpContainer ); - pEx->AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); + mrEscherEx.OpenContainer( ESCHER_SpContainer ); + mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT ); EscherPropertyContainer aPropOpt; aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00010000 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x000A0000 ); // bool field - aPropOpt.Commit( pEx->GetStream() ); + aPropOpt.Commit( mrEscherEx.GetStream() ); - XclExpDffDropDownAnchor( rRoot, rPos ).WriteData( *pEx ); + XclExpDffDropDownAnchor( rObjMgr.GetRoot(), rPos ).WriteDffData( mrEscherEx ); - pEx->AddAtom( 0, ESCHER_ClientData ); // OBJ record - pMsodrawing->UpdateStopPos(); - pEx->CloseContainer(); // ESCHER_SpContainer + mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record + mrEscherEx.UpdateDffFragmentEnd(); + mrEscherEx.CloseContainer(); // ESCHER_SpContainer // old size + ftSbs + ftLbsData AddRecSize( 24 + 20 ); @@ -568,7 +426,6 @@ void XclObjDropDown::WriteSubRecs( XclExpStream& rStrm ) rStrm.EndRecord(); } - // --- class XclTxo -------------------------------------------------- sal_uInt8 lcl_GetHorAlignFromItemSet( const SfxItemSet& rItemSet ) @@ -725,22 +582,19 @@ sal_Size XclTxo::GetLen() const return 18; } - // --- class XclObjOle ------------------------------------------- -XclObjOle::XclObjOle( const XclExpRoot& rRoot, const SdrObject& rObj ) : - XclObj( rRoot, EXC_OBJTYPE_PICTURE ), +XclObjOle::XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ) : + XclObj( rObjMgr, EXC_OBJTYPE_PICTURE ), rOleObj( rObj ), - pRootStorage( rRoot.GetRootStorage() ) + pRootStorage( rObjMgr.GetRoot().GetRootStorage() ) { } - XclObjOle::~XclObjOle() { } - void XclObjOle::WriteSubRecs( XclExpStream& rStrm ) { // write only as embedded, not linked @@ -810,18 +664,16 @@ void XclObjOle::WriteSubRecs( XclExpStream& rStrm ) } } - void XclObjOle::Save( XclExpStream& rStrm ) { // content of this record XclObj::Save( rStrm ); } - // --- class XclObjAny ------------------------------------------- -XclObjAny::XclObjAny( const XclExpRoot& rRoot ) : - XclObj( rRoot, EXC_OBJTYPE_UNKNOWN ) +XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr ) : + XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN ) { } @@ -846,7 +698,6 @@ void XclObjAny::Save( XclExpStream& rStrm ) XclObj::Save( rStrm ); } - // --- class ExcBof8_Base -------------------------------------------- ExcBof8_Base::ExcBof8_Base() diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 580dd2ee0791..93e529c4ceca 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -428,7 +428,7 @@ void ScXMLDataPilotTableContext::EndElement() break; case SERVICE : { - ScDPServiceDesc aServiceDesk(sServiceName, sServiceSourceObject, sServiceSourceName, + ScDPServiceDesc aServiceDesk(sServiceName, sServiceSourceName, sServiceSourceObject, sServiceUsername, sServicePassword); pDPObject->SetServiceData(aServiceDesk); } @@ -1453,6 +1453,7 @@ ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImpo pDataPilotSubTotals->AddFunction( sal::static_int_cast<sal_Int16>( ScXMLConverter::GetFunctionFromString( sValue ) ) ); } + break; case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME: case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT: pDataPilotSubTotals->SetDisplayName(sValue); diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx index 1c1126e07640..4c65632fb45e 100644 --- a/sc/source/ui/Accessibility/AccessibleDocument.cxx +++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx @@ -963,18 +963,14 @@ void ScChildrenShapes::FillSelectionSupplier() const SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY); + if (xSelectionSupplier.is()) { - xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pFrame->GetController(), uno::UNO_QUERY); - if (xSelectionSupplier.is()) - { - if (mpAccessibleDocument) - xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument); - uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY); - if (xShapes.is()) - mnShapesSelected = xShapes->getCount(); - } + if (mpAccessibleDocument) + xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument); + uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY); + if (xShapes.is()) + mnShapesSelected = xShapes->getCount(); } } } diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx index 5ea8c4d78e0f..f6fc2cb27b71 100644 --- a/sc/source/ui/app/inputwin.cxx +++ b/sc/source/ui/app/inputwin.cxx @@ -768,8 +768,9 @@ __EXPORT ScTextWnd::~ScTextWnd() { delete pEditView; delete pEditEngine; - for( AccTextDataVector::reverse_iterator aIt = maAccTextDatas.rbegin(), aEnd = maAccTextDatas.rend(); aIt != aEnd; ++aIt ) - (*aIt)->Dispose(); + while (!maAccTextDatas.empty()) { + maAccTextDatas.back()->Dispose(); + } } void __EXPORT ScTextWnd::Paint( const Rectangle& rRec ) diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx index ff42e379be13..0af2c30d628f 100644 --- a/sc/source/ui/attrdlg/scdlgfact.cxx +++ b/sc/source/ui/attrdlg/scdlgfact.cxx @@ -71,6 +71,7 @@ #include "validate.hxx" //add for ScValidationDlg #include "validate.hrc" //add for ScValidationDlg #include "sortdlg.hxx" //add for ScSortDlg +#include "textimportoptions.hxx" #include "opredlin.hxx" //add for ScRedlineOptionsTabPage #include "tpcalc.hxx" //add for ScTpCalcOptions #include "tpprint.hxx" //add for ScTpPrintOptions @@ -112,6 +113,7 @@ IMPL_ABSTDLG_BASE(AbstractScNewScenarioDlg_Impl); //add for ScNewScenarioDlg IMPL_ABSTDLG_BASE(AbstractScShowTabDlg_Impl); //add for ScShowTabDlg IMPL_ABSTDLG_BASE(AbstractScStringInputDlg_Impl); //add for ScStringInputDlg IMPL_ABSTDLG_BASE(AbstractScImportOptionsDlg_Impl); //add for ScImportOptionsDlg +IMPL_ABSTDLG_BASE(AbstractScTextImportOptionsDlg_Impl); IMPL_ABSTDLG_BASE(AbstractTabDialog_Impl); //add for ScAttrDlg, ScHFEditDlg, ScStyleDlg, ScSubTotalDlg,ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg // AbstractTabDialog_Impl begin @@ -193,6 +195,11 @@ void AbstractScImportAsciiDlg_Impl::SetTextToColumnsMode() pDlg->SetTextToColumnsMode(); } +void AbstractScImportAsciiDlg_Impl::SaveParameters() +{ + pDlg->SaveParameters(); +} + // AbstractScImportAsciiDlg_Impl end //AbstractScAutoFormatDlg_Impl begin @@ -617,6 +624,20 @@ void AbstractScImportOptionsDlg_Impl::GetImportOptions( ScImportOptions& rOption pDlg->GetImportOptions(rOptions); } // add for AbstractScImportOptionsDlg_Impl end + +//add for AbstractScLangChooserDlg_Impl begin +LanguageType AbstractScTextImportOptionsDlg_Impl::GetLanguageType() const +{ + return pDlg->getLanguageType(); +} + +bool AbstractScTextImportOptionsDlg_Impl::IsDateConversionSet() const +{ + return pDlg->isDateConversionSet(); +} + +//add for AbstractScLangChooserDlg_Impl end + // =========================Factories for createdialog =================== //add for ScImportAsciiDlg begin @@ -639,6 +660,21 @@ AbstractScImportAsciiDlg * ScAbstractDialogFactory_Impl::CreateScImportAsciiDlg } // ScImportAsciiDlg end +AbstractScTextImportOptionsDlg * ScAbstractDialogFactory_Impl::CreateScTextImportOptionsDlg( Window* pParent, int nId ) +{ + ScTextImportOptionsDlg* pDlg = NULL; + switch (nId) + { + case RID_SCDLG_TEXT_IMPORT_OPTIONS: + pDlg = new ScTextImportOptionsDlg(pParent); + break; + default: + ; + } + + return pDlg ? new AbstractScTextImportOptionsDlg_Impl(pDlg) : NULL; +} + //add for ScAutoFormatDlg begin AbstractScAutoFormatDlg * ScAbstractDialogFactory_Impl::CreateScAutoFormatDlg( Window* pParent, //add for ScAutoFormatDlg diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx index 7a9b03217655..d9752c83da9a 100644 --- a/sc/source/ui/attrdlg/scdlgfact.hxx +++ b/sc/source/ui/attrdlg/scdlgfact.hxx @@ -61,6 +61,7 @@ class ScStringInputDlg; class ScImportOptionsDlg; class SfxTabDialog; class ScSortWarningDlg; +class ScTextImportOptionsDlg; #define DECL_ABSTDLG_BASE(Class,DialogClass) \ DialogClass* pDlg; \ @@ -116,6 +117,7 @@ class AbstractScImportAsciiDlg_Impl : public AbstractScImportAsciiDlg //add for DECL_ABSTDLG_BASE(AbstractScImportAsciiDlg_Impl, ScImportAsciiDlg) virtual void GetOptions( ScAsciiOptions& rOpt ); virtual void SetTextToColumnsMode(); + virtual void SaveParameters(); }; class AbstractScAutoFormatDlg_Impl : public AbstractScAutoFormatDlg //add for ScAutoFormatDlg @@ -340,6 +342,13 @@ class AbstractScImportOptionsDlg_Impl : public AbstractScImportOptionsDlg //add virtual void GetImportOptions( ScImportOptions& rOptions ) const; }; +class AbstractScTextImportOptionsDlg_Impl : public AbstractScTextImportOptionsDlg +{ + DECL_ABSTDLG_BASE( AbstractScTextImportOptionsDlg_Impl, ScTextImportOptionsDlg) + virtual LanguageType GetLanguageType() const; + virtual bool IsDateConversionSet() const; +}; + //add for ScAttrDlg , ScHFEditDlg, ScStyleDlg, ScSubTotalDlg, ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg class AbstractTabDialog_Impl : public SfxAbstractTabDialog { @@ -381,6 +390,8 @@ public: SvStream* pInStream, int nId, sal_Unicode cSep = '\t'); + virtual AbstractScTextImportOptionsDlg * CreateScTextImportOptionsDlg( Window* pParent, int nId ); + virtual AbstractScAutoFormatDlg * CreateScAutoFormatDlg( Window* pParent, //add for ScAutoFormatDlg ScAutoFormat* pAutoFormat, const ScAutoFormatData* pSelFormatData, diff --git a/sc/source/ui/dbgui/asciiopt.cxx b/sc/source/ui/dbgui/asciiopt.cxx index a40a5fb994ea..cd1f85fb99cc 100644 --- a/sc/source/ui/dbgui/asciiopt.cxx +++ b/sc/source/ui/dbgui/asciiopt.cxx @@ -53,8 +53,11 @@ ScAsciiOptions::ScAsciiOptions() : bFixedLen ( FALSE ), aFieldSeps ( ';' ), bMergeFieldSeps ( FALSE ), + bQuotedFieldAsText(false), + bDetectSpecialNumber(false), cTextSep ( cDefaultTextSep ), eCharSet ( gsl_getSystemTextEncoding() ), + eLang ( LANGUAGE_SYSTEM ), bCharSetSystem ( FALSE ), nStartRow ( 1 ), nInfoCount ( 0 ), @@ -68,8 +71,11 @@ ScAsciiOptions::ScAsciiOptions(const ScAsciiOptions& rOpt) : bFixedLen ( rOpt.bFixedLen ), aFieldSeps ( rOpt.aFieldSeps ), bMergeFieldSeps ( rOpt.bMergeFieldSeps ), + bQuotedFieldAsText(rOpt.bQuotedFieldAsText), + bDetectSpecialNumber(rOpt.bDetectSpecialNumber), cTextSep ( rOpt.cTextSep ), eCharSet ( rOpt.eCharSet ), + eLang ( rOpt.eLang ), bCharSetSystem ( rOpt.bCharSetSystem ), nStartRow ( rOpt.nStartRow ), nInfoCount ( rOpt.nInfoCount ) @@ -152,6 +158,7 @@ ScAsciiOptions& ScAsciiOptions::operator=( const ScAsciiOptions& rCpy ) bFixedLen = rCpy.bFixedLen; aFieldSeps = rCpy.aFieldSeps; bMergeFieldSeps = rCpy.bMergeFieldSeps; + bQuotedFieldAsText = rCpy.bQuotedFieldAsText; cTextSep = rCpy.cTextSep; eCharSet = rCpy.eCharSet; bCharSetSystem = rCpy.bCharSetSystem; @@ -166,6 +173,7 @@ BOOL ScAsciiOptions::operator==( const ScAsciiOptions& rCmp ) const if ( bFixedLen == rCmp.bFixedLen && aFieldSeps == rCmp.aFieldSeps && bMergeFieldSeps == rCmp.bMergeFieldSeps && + bQuotedFieldAsText == rCmp.bQuotedFieldAsText && cTextSep == rCmp.cTextSep && eCharSet == rCmp.eCharSet && bCharSetSystem == rCmp.bCharSetSystem && @@ -245,13 +253,20 @@ void ScAsciiOptions::ReadFromString( const String& rString ) eCharSet = ScGlobal::GetCharsetValue( aToken ); } + // Language + if (nCount >= 4) + { + aToken = rString.GetToken(3, ','); + eLang = static_cast<LanguageType>(aToken.ToInt32()); + } + // // Startzeile // - if ( nCount >= 4 ) + if ( nCount >= 5 ) { - aToken = rString.GetToken(3,','); + aToken = rString.GetToken(4,','); nStartRow = aToken.ToInt32(); } @@ -259,12 +274,12 @@ void ScAsciiOptions::ReadFromString( const String& rString ) // Spalten-Infos // - if ( nCount >= 5 ) + if ( nCount >= 6 ) { delete[] pColStart; delete[] pColFormat; - aToken = rString.GetToken(4,','); + aToken = rString.GetToken(5,','); nSub = aToken.GetTokenCount('/'); nInfoCount = nSub / 2; if (nInfoCount) @@ -283,6 +298,20 @@ void ScAsciiOptions::ReadFromString( const String& rString ) pColFormat = NULL; } } + + // Import quoted field as text. + if (nCount >= 7) + { + aToken = rString.GetToken(6, ','); + bQuotedFieldAsText = aToken.EqualsAscii("true") ? true : false; + } + + // Detect special nubmers. + if (nCount >= 8) + { + aToken = rString.GetToken(7, ','); + bDetectSpecialNumber = aToken.EqualsAscii("true") ? true : false; + } } @@ -333,6 +362,10 @@ String ScAsciiOptions::WriteToString() const aOutStr += ScGlobal::GetCharsetString( eCharSet ); aOutStr += ','; // Token-Ende + // Language + aOutStr += String::CreateFromInt32(eLang); + aOutStr += ','; + // // Startzeile // @@ -354,6 +387,15 @@ String ScAsciiOptions::WriteToString() const aOutStr += String::CreateFromInt32(pColFormat[nInfo]); } + aOutStr += ','; + + // Import quoted field as text. + aOutStr += String::CreateFromAscii(bQuotedFieldAsText ? "true" : "false"); + aOutStr += ','; + + // Detect special nubmers. + aOutStr += String::CreateFromAscii(bDetectSpecialNumber ? "true" : "false"); + return aOutStr; } diff --git a/sc/source/ui/dbgui/asciiopt.hrc b/sc/source/ui/dbgui/asciiopt.hrc index 275de80f5972..7bf6d42d6e2f 100644 --- a/sc/source/ui/dbgui/asciiopt.hrc +++ b/sc/source/ui/dbgui/asciiopt.hrc @@ -26,31 +26,46 @@ ************************************************************************/ #include "sc.hrc" //#define RID_SCDLG_ASCII 256 -#define RB_SEPARATED 1 -#define RB_FIXED 2 -#define FT_CHARSET 3 -#define LB_CHARSET 4 -#define FL_SEPOPT 5 -#define FT_FIELDSEP 6 -#define CB_FIELDSEP 7 -#define FT_TEXTSEP 8 -#define CB_TEXTSEP 9 -#define FL_FIELDOPT 10 -#define FT_TYPE 12 -#define FT_PREVIEW 13 -#define LB_TYPE1 23 -#define FL_WIDTH 30 -#define BTN_OK 31 -#define BTN_CANCEL 32 -#define BTN_HELP 33 -#define CTR_TABLEBOX 41 -#define CKB_TAB 51 -#define CKB_SPACE 52 -#define CKB_SEMICOLON 53 -#define CKB_COMMA 54 -#define CKB_OTHER 55 -#define ED_OTHER 56 -#define FT_AT_ROW 59 -#define NF_AT_ROW 60 -#define CB_ASONCE 90 -#define STR_TEXTTOCOLUMNS 100 +#define BTN_OK 1 +#define BTN_CANCEL 2 +#define BTN_HELP 3 + +#define FL_FIELDOPT 4 +#define FT_CHARSET 5 +#define LB_CHARSET 6 +#define FT_CUSTOMLANG 7 +#define LB_CUSTOMLANG 8 +#define FT_AT_ROW 9 +#define NF_AT_ROW 10 + +#define FL_SEPOPT 11 +#define RB_FIXED 12 +#define RB_SEPARATED 13 +#define CKB_TAB 14 +#define CKB_COMMA 15 +#define CKB_OTHER 16 +#define ED_OTHER 17 +#define CKB_SEMICOLON 18 +#define CKB_SPACE 19 +#define CB_ASONCE 20 +#define CB_TEXTSEP 21 +#define FT_TEXTSEP 22 + +#define FL_OTHER_OPTIONS 23 +#define CB_QUOTED_AS_TEXT 24 +#define CB_DETECT_SPECIAL_NUMBER 25 + +#define FL_WIDTH 26 +#define FT_TYPE 27 +#define LB_TYPE1 28 +#define CTR_TABLEBOX 29 +#define STR_TEXTTOCOLUMNS 30 + + + + + + + + + diff --git a/sc/source/ui/dbgui/asciiopt.src b/sc/source/ui/dbgui/asciiopt.src index b527719cb6de..9efbfe0f557f 100644 --- a/sc/source/ui/dbgui/asciiopt.src +++ b/sc/source/ui/dbgui/asciiopt.src @@ -31,55 +31,44 @@ ModalDialog RID_SCDLG_ASCII { OutputSize = TRUE ; SVLook = TRUE ; - Size = MAP_APPFONT ( 320 , 247 ) ; + Size = MAP_APPFONT ( 320 , 305 ) ; Text [ en-US ] = "Text Import" ; Moveable = TRUE ; - FixedLine FL_WIDTH - { - Pos = MAP_APPFONT ( 6 , 132 ) ; - Size = MAP_APPFONT ( 252 , 8 ) ; - Text [ en-US ] = "Fields" ; - }; - FixedText FT_TYPE - { - Pos = MAP_APPFONT ( 12 , 145 ) ; - Size = MAP_APPFONT ( 60 , 8 ) ; - Text [ en-US ] = "Column t~ype"; - }; - ListBox LB_TYPE1 + + OKButton BTN_OK { - Pos = MAP_APPFONT ( 76 , 143 ) ; - Size = MAP_APPFONT ( 60 , 68 ) ; + Pos = MAP_APPFONT ( 264 , 6 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; - DropDown = TRUE ; + DefButton = TRUE ; }; - FixedLine FL_SEPOPT + CancelButton BTN_CANCEL { - Pos = MAP_APPFONT ( 6 , 48 ) ; - Size = MAP_APPFONT ( 252 , 8 ) ; - Text [ en-US ] = "Separator options" ; + Pos = MAP_APPFONT ( 264 , 23 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; }; - RadioButton RB_FIXED + HelpButton BTN_HELP { - Pos = MAP_APPFONT ( 12 , 59 ) ; - Size = MAP_APPFONT ( 243 , 10 ) ; - Text [ en-US ] = "~Fixed width" ; + Pos = MAP_APPFONT ( 264 , 43 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; }; - RadioButton RB_SEPARATED + + FixedLine FL_FIELDOPT { - Pos = MAP_APPFONT ( 12 , 73 ) ; - Size = MAP_APPFONT ( 243 , 10 ) ; - Text [ en-US ] = "~Separated by" ; - TabStop = TRUE ; - Check = TRUE ; + Pos = MAP_APPFONT ( 6 , 3 ) ; + Size = MAP_APPFONT ( 252 , 8 ) ; + Text [ en-US ] = "Import" ; }; + FixedText FT_CHARSET { Pos = MAP_APPFONT ( 12 , 16 ) ; Size = MAP_APPFONT ( 60 , 8 ) ; Text [ en-US ] = "Ch~aracter set" ; }; + ListBox LB_CHARSET { Pos = MAP_APPFONT ( 76 , 14 ) ; @@ -88,119 +77,182 @@ ModalDialog RID_SCDLG_ASCII DropDown = TRUE ; Sort = TRUE; }; - FixedLine FL_FIELDOPT - { - Pos = MAP_APPFONT ( 6 , 3 ) ; - Size = MAP_APPFONT ( 252 , 8 ) ; - Text [ en-US ] = "Import" ; - }; - FixedText FT_TEXTSEP + + FixedText FT_CUSTOMLANG { - Pos = MAP_APPFONT ( 156 , 114 ) ; + Pos = MAP_APPFONT ( 12 , 32 ) ; Size = MAP_APPFONT ( 60 , 8 ) ; - Text [ en-US ] = "Te~xt delimiter" ; + Text [ en-US ] = "Language" ; }; - ComboBox CB_TEXTSEP + + ListBox LB_CUSTOMLANG { - Pos = MAP_APPFONT ( 218 , 112 ) ; - Size = MAP_APPFONT ( 37 , 94 ) ; + Pos = MAP_APPFONT ( 76 , 30 ) ; + Size = MAP_APPFONT ( 130 , 61 ) ; TabStop = TRUE ; DropDown = TRUE ; + Sort = TRUE; }; - OKButton BTN_OK + + FixedText FT_AT_ROW { - Pos = MAP_APPFONT ( 264 , 6 ) ; - Size = MAP_APPFONT ( 50 , 14 ) ; + Pos = MAP_APPFONT ( 12 , 48 ) ; + Size = MAP_APPFONT ( 60 , 8 ) ; + Text [ en-US ] = "From ro~w" ; + }; + + NumericField NF_AT_ROW + { + Border = TRUE ; + SVLook = TRUE ; + Pos = MAP_APPFONT ( 76 , 46 ) ; + Size = MAP_APPFONT ( 30 , 12 ) ; TabStop = TRUE ; - DefButton = TRUE ; + Spin = TRUE ; + Repeat = TRUE ; + Minimum = 1 ; }; - CancelButton BTN_CANCEL + + FixedLine FL_SEPOPT { - Pos = MAP_APPFONT ( 264 , 23 ) ; - Size = MAP_APPFONT ( 50 , 14 ) ; + Pos = MAP_APPFONT ( 6 , 63 ) ; + Size = MAP_APPFONT ( 252 , 8 ) ; + Text [ en-US ] = "Separator options" ; + }; + RadioButton RB_FIXED + { + Pos = MAP_APPFONT ( 12 , 75 ) ; + Size = MAP_APPFONT ( 243 , 10 ) ; + Text [ en-US ] = "~Fixed width" ; TabStop = TRUE ; }; - HelpButton BTN_HELP + RadioButton RB_SEPARATED { - Pos = MAP_APPFONT ( 264 , 43 ) ; - Size = MAP_APPFONT ( 50 , 14 ) ; + Pos = MAP_APPFONT ( 12 , 89 ) ; + Size = MAP_APPFONT ( 243 , 10 ) ; + Text [ en-US ] = "~Separated by" ; TabStop = TRUE ; + Check = TRUE ; }; + CheckBox CKB_TAB { - Pos = MAP_APPFONT ( 20 , 86 ) ; + Pos = MAP_APPFONT ( 20 , 102 ) ; Size = MAP_APPFONT ( 68 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "~Tab" ; }; - CheckBox CKB_SEMICOLON + CheckBox CKB_COMMA { - Pos = MAP_APPFONT ( 20 , 99 ) ; + Pos = MAP_APPFONT ( 92 , 102 ) ; Size = MAP_APPFONT ( 68 , 10 ) ; TabStop = TRUE ; - Text [ en-US ] = "S~emicolon" ; + Text [ en-US ] = "~Comma" ; }; - CheckBox CKB_COMMA + CheckBox CKB_OTHER + { + Pos = MAP_APPFONT ( 164 , 102 ) ; + Size = MAP_APPFONT ( 50 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "~Other" ; + }; + Edit ED_OTHER + { + Border = TRUE ; + Pos = MAP_APPFONT ( 218 , 100 ) ; + Size = MAP_APPFONT ( 37 , 12 ) ; + TabStop = TRUE ; + MaxTextLength = 10 ; + }; + + CheckBox CKB_SEMICOLON { - Pos = MAP_APPFONT ( 92 , 86 ) ; + Pos = MAP_APPFONT ( 20 , 115 ) ; Size = MAP_APPFONT ( 68 , 10 ) ; TabStop = TRUE ; - Text [ en-US ] = "~Comma" ; + Text [ en-US ] = "S~emicolon" ; }; CheckBox CKB_SPACE { - Pos = MAP_APPFONT ( 92 , 99 ) ; + Pos = MAP_APPFONT ( 92 , 115 ) ; Size = MAP_APPFONT ( 68 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "S~pace" ; }; - CheckBox CKB_OTHER + + CheckBox CB_ASONCE { - Pos = MAP_APPFONT ( 164 , 86 ) ; - Size = MAP_APPFONT ( 50 , 10 ) ; + Pos = MAP_APPFONT ( 20 , 130 ) ; + Size = MAP_APPFONT ( 130 , 10 ) ; TabStop = TRUE ; - Text [ en-US ] = "~Other" ; + Text [ en-US ] = "Merge ~delimiters" ; }; - Edit ED_OTHER + + ComboBox CB_TEXTSEP { - Border = TRUE ; - Pos = MAP_APPFONT ( 218 , 84 ) ; - Size = MAP_APPFONT ( 37 , 12 ) ; + Pos = MAP_APPFONT ( 218 , 128 ) ; + Size = MAP_APPFONT ( 37 , 94 ) ; TabStop = TRUE ; - MaxTextLength = 10 ; + DropDown = TRUE ; }; - FixedText FT_AT_ROW + FixedText FT_TEXTSEP { - Pos = MAP_APPFONT ( 12 , 32 ) ; + Pos = MAP_APPFONT ( 156 , 130 ) ; Size = MAP_APPFONT ( 60 , 8 ) ; - Text [ en-US ] = "From ro~w" ; + Text [ en-US ] = "Te~xt delimiter" ; }; - NumericField NF_AT_ROW + + FixedLine FL_OTHER_OPTIONS { - Border = TRUE ; - SVLook = TRUE ; - Pos = MAP_APPFONT ( 76 , 30 ) ; - Size = MAP_APPFONT ( 30 , 12 ) ; + Pos = MAP_APPFONT ( 6 , 146 ) ; + Size = MAP_APPFONT ( 252 , 8 ) ; + Text [ en-US ] = "Other options" ; + }; + + CheckBox CB_QUOTED_AS_TEXT + { + Pos = MAP_APPFONT ( 12 , 158 ) ; + Size = MAP_APPFONT ( 130 , 10 ) ; TabStop = TRUE ; - Spin = TRUE ; - Repeat = TRUE ; - Minimum = 1 ; + Text [ en-US ] = "~Quoted field as text" ; + }; + + CheckBox CB_DETECT_SPECIAL_NUMBER + { + Pos = MAP_APPFONT ( 12 , 171 ) ; + Size = MAP_APPFONT ( 130 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Detect special numbers" ; + }; + + FixedLine FL_WIDTH + { + Pos = MAP_APPFONT ( 6 , 187 ) ; + Size = MAP_APPFONT ( 252 , 8 ) ; + Text [ en-US ] = "Fields" ; + }; + FixedText FT_TYPE + { + Pos = MAP_APPFONT ( 12 , 200 ) ; + Size = MAP_APPFONT ( 60 , 8 ) ; + Text [ en-US ] = "Column t~ype"; + }; + ListBox LB_TYPE1 + { + Pos = MAP_APPFONT ( 76 , 198 ) ; + Size = MAP_APPFONT ( 60 , 68 ) ; + TabStop = TRUE ; + DropDown = TRUE ; }; Control CTR_TABLEBOX { HelpId = HID_SC_ASCII_TABCTR ; Border = TRUE ; DialogControl = TRUE ; - Pos = MAP_APPFONT ( 12 , 159 ) ; + Pos = MAP_APPFONT ( 12 , 216 ) ; Size = MAP_APPFONT ( 243 , 82 ) ; }; - CheckBox CB_ASONCE - { - Pos = MAP_APPFONT ( 20 , 114 ) ; - Size = MAP_APPFONT ( 130 , 10 ) ; - TabStop = TRUE ; - Text [ en-US ] = "Merge ~delimiters" ; - }; + String STR_TEXTTOCOLUMNS { Text [ en-US ] = "Text to Columns" ; diff --git a/sc/source/ui/dbgui/csvgrid.cxx b/sc/source/ui/dbgui/csvgrid.cxx index 2ec05af2f72e..d271022a987c 100644 --- a/sc/source/ui/dbgui/csvgrid.cxx +++ b/sc/source/ui/dbgui/csvgrid.cxx @@ -734,7 +734,8 @@ void ScCsvGrid::ImplSetTextLineSep( while( *pChar && (nColIx < sal::static_int_cast<sal_uInt32>(CSV_MAXCOLCOUNT)) ) { // scan for next cell text - pChar = ScImportExport::ScanNextFieldFromString( pChar, aCellText, cTextSep, pSepChars, bMergeSep ); + bool bIsQuoted = false; + pChar = ScImportExport::ScanNextFieldFromString( pChar, aCellText, cTextSep, pSepChars, bMergeSep, bIsQuoted ); // update column width sal_Int32 nWidth = Max( CSV_MINCOLWIDTH, aCellText.Len() + sal_Int32( 1 ) ); diff --git a/sc/source/ui/dbgui/csvruler.cxx b/sc/source/ui/dbgui/csvruler.cxx index d84c938bfd14..56aa2a50a835 100644 --- a/sc/source/ui/dbgui/csvruler.cxx +++ b/sc/source/ui/dbgui/csvruler.cxx @@ -34,8 +34,77 @@ #include "AccessibleCsvControl.hxx" +#include <optutil.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include "miscuno.hxx" + +using namespace rtl; +using namespace com::sun::star::uno; + + + +// ============================================================================ +#define SEP_PATH "Office.Calc/Dialogs/CSVImport" +#define FIXED_WIDTH_LIST "FixedWidthList" + + // ============================================================================ +static void load_FixedWidthList(ScCsvSplits &aSplits) +{ + String sSplits; + OUString sFixedWidthLists; + + Sequence<Any>aValues; + const Any *pProperties; + Sequence<OUString> aNames(1); + OUString* pNames = aNames.getArray(); + ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) ); + + pNames[0] = OUString::createFromAscii( FIXED_WIDTH_LIST ); + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getConstArray(); + + if( pProperties[0].hasValue() ) + { + aSplits.Clear(); + pProperties[0] >>= sFixedWidthLists; + + sSplits = String( sFixedWidthLists ); + + // String ends with a semi-colon so there is no 'int' after the last one. + xub_StrLen n = sSplits.GetTokenCount() - 1; + for (xub_StrLen i = 0; i < n; ++i) + aSplits.Insert( sSplits.GetToken(i).ToInt32() ); + } +} +static void save_FixedWidthList(ScCsvSplits aSplits) +{ + String sSplits; + // Create a semi-colon separated string to save the splits + sal_uInt32 n = aSplits.Count(); + for (sal_uInt32 i = 0; i < n; ++i) + { + sSplits.Append( String::CreateFromInt32( aSplits[i] ) ); + sSplits.Append((char)';'); + } + + OUString sFixedWidthLists = OUString( sSplits ); + Sequence<Any> aValues; + Any *pProperties; + Sequence<OUString> aNames(1); + OUString* pNames = aNames.getArray(); + ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) ); + + pNames[0] = OUString::createFromAscii( FIXED_WIDTH_LIST ); + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getArray(); + pProperties[0] <<= sFixedWidthLists; + + aItem.PutProperties(aNames, aValues); +} + ScCsvRuler::ScCsvRuler( ScCsvControl& rParent ) : ScCsvControl( rParent ), mnPosCursorLast( 1 ) @@ -45,6 +114,13 @@ ScCsvRuler::ScCsvRuler( ScCsvControl& rParent ) : InitSizeData(); maBackgrDev.SetFont( GetFont() ); maRulerDev.SetFont( GetFont() ); + + load_FixedWidthList( maSplits ); +} + +ScCsvRuler::~ScCsvRuler() +{ + save_FixedWidthList( maSplits ); } diff --git a/sc/source/ui/dbgui/dapidata.cxx b/sc/source/ui/dbgui/dapidata.cxx index 87de71767a17..976e0ae23039 100644 --- a/sc/source/ui/dbgui/dapidata.cxx +++ b/sc/source/ui/dbgui/dapidata.cxx @@ -56,7 +56,7 @@ using namespace com::sun::star; //------------------------------------------------------------------------- #define DP_SERVICE_DBCONTEXT "com.sun.star.sdb.DatabaseContext" -#define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler" +#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler" // entries in the "type" ListBox #define DP_TYPELIST_TABLE 0 diff --git a/sc/source/ui/dbgui/makefile.mk b/sc/source/ui/dbgui/makefile.mk index ee855d22aef1..2d4fa71f690e 100644 --- a/sc/source/ui/dbgui/makefile.mk +++ b/sc/source/ui/dbgui/makefile.mk @@ -49,6 +49,7 @@ SLOFILES = \ $(SLO)$/pfiltdlg.obj \ $(SLO)$/dbnamdlg.obj \ $(SLO)$/expftext.obj \ + $(SLO)$/textimportoptions.obj \ $(SLO)$/subtdlg.obj \ $(SLO)$/tpsubt.obj \ $(SLO)$/fieldwnd.obj \ @@ -83,6 +84,7 @@ EXCEPTIONSFILES= \ SRS1NAME=$(TARGET) SRC1FILES = \ + textimportoptions.src \ pivot.src \ pvfundlg.src \ dpgroupdlg.src \ diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index 8609bfcbfb0a..03de0b8914a3 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -739,9 +739,12 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0; if ( !pDimension || (pDimension->GetOrientation() != nOrient) ) { - const OUString* pLayoutName = pDimension->GetLayoutName(); - if (pLayoutName) - aName = *pLayoutName; + if (pDimension) + { + const OUString* pLayoutName = pDimension->GetLayoutName(); + if (pLayoutName) + aName = *pLayoutName; + } maLbDims.InsertEntry( aName ); maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim)); } diff --git a/sc/source/ui/dbgui/pvfundlg.src b/sc/source/ui/dbgui/pvfundlg.src index 70bce3ed30e9..ed00f6a65fa5 100644 --- a/sc/source/ui/dbgui/pvfundlg.src +++ b/sc/source/ui/dbgui/pvfundlg.src @@ -227,8 +227,8 @@ ModalDialog RID_SCDLG_PIVOTSUBT }; CheckBox CB_SHOWALL { - Pos = MAP_APPFONT ( 12 , 127 ) ; - Size = MAP_APPFONT ( 140 , 10 ) ; + Pos = MAP_APPFONT ( 6 , 127 ) ; + Size = MAP_APPFONT ( 152 , 10 ) ; Text [ en-US ] = "Show it~ems without data"; TabStop = TRUE ; }; diff --git a/sc/source/ui/dbgui/scuiasciiopt.cxx b/sc/source/ui/dbgui/scuiasciiopt.cxx index e4e568e00882..171daa0ca882 100644 --- a/sc/source/ui/dbgui/scuiasciiopt.cxx +++ b/sc/source/ui/dbgui/scuiasciiopt.cxx @@ -41,6 +41,12 @@ // ause #include "editutil.hxx" +#include <optutil.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include "miscuno.hxx" + + //! TODO make dynamic #ifdef WIN const SCSIZE ASCIIDLG_MAXROWS = 10000; @@ -48,6 +54,22 @@ const SCSIZE ASCIIDLG_MAXROWS = 10000; const SCSIZE ASCIIDLG_MAXROWS = MAXROWCOUNT; #endif + +using namespace rtl; +using namespace com::sun::star::uno; + +// Defines - CSV Import Preserve Options +#define FIXED_WIDTH "FixedWidth" +#define FROM_ROW "FromRow" +#define CHAR_SET "CharSet" +#define SEPARATORS "Separators" +#define TEXT_SEPARATORS "TextSeparators" +#define MERGE_DELIMITERS "MergeDelimiters" +#define QUOTED_AS_TEXT "QuotedFieldAsText" +#define DETECT_SPECIAL_NUM "DetectSpecialNumbers" +#define LANGUAGE "Language" +#define SEP_PATH "Office.Calc/Dialogs/CSVImport" + // ============================================================================ void lcl_FillCombo( ComboBox& rCombo, const String& rList, sal_Unicode cSelect ) @@ -95,11 +117,96 @@ sal_Unicode lcl_CharFromCombo( ComboBox& rCombo, const String& rList ) return c; } +static void load_Separators( OUString &sFieldSeparators, OUString &sTextSeparators, + bool &bMergeDelimiters, bool& bQuotedAsText, bool& bDetectSpecialNum, + bool &bFixedWidth, sal_Int32 &nFromRow, sal_Int32 &nCharSet, + sal_Int32& nLanguage ) +{ + Sequence<Any>aValues; + const Any *pProperties; + Sequence<OUString> aNames(9); + OUString* pNames = aNames.getArray(); + ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) ); + + pNames[0] = OUString::createFromAscii( MERGE_DELIMITERS ); + pNames[1] = OUString::createFromAscii( SEPARATORS ); + pNames[2] = OUString::createFromAscii( TEXT_SEPARATORS ); + pNames[3] = OUString::createFromAscii( FIXED_WIDTH ); + pNames[4] = OUString::createFromAscii( FROM_ROW ); + pNames[5] = OUString::createFromAscii( CHAR_SET ); + pNames[6] = OUString::createFromAscii( QUOTED_AS_TEXT ); + pNames[7] = OUString::createFromAscii( DETECT_SPECIAL_NUM ); + pNames[8] = OUString::createFromAscii( LANGUAGE ); + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getConstArray(); + if( pProperties[1].hasValue() ) + pProperties[1] >>= sFieldSeparators; + + if( pProperties[2].hasValue() ) + pProperties[2] >>= sTextSeparators; + + if( pProperties[0].hasValue() ) + bMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny( pProperties[0] ); + + if( pProperties[3].hasValue() ) + bFixedWidth = ScUnoHelpFunctions::GetBoolFromAny( pProperties[3] ); + + if( pProperties[4].hasValue() ) + pProperties[4] >>= nFromRow; + + if( pProperties[5].hasValue() ) + pProperties[5] >>= nCharSet; + + if ( pProperties[6].hasValue() ) + pProperties[6] >>= bQuotedAsText; + + if ( pProperties[7].hasValue() ) + pProperties[7] >>= bDetectSpecialNum; + + if ( pProperties[8].hasValue() ) + pProperties[8] >>= nLanguage; +} + +static void save_Separators( + String maSeparators, String maTxtSep, bool bMergeDelimiters, bool bQuotedAsText, + bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow, sal_Int32 nCharSet, sal_Int32 nLanguage ) +{ + OUString sFieldSeparators = OUString( maSeparators ); + OUString sTextSeparators = OUString( maTxtSep ); + Sequence<Any> aValues; + Any *pProperties; + Sequence<OUString> aNames(9); + OUString* pNames = aNames.getArray(); + ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) ); + + pNames[0] = OUString::createFromAscii( MERGE_DELIMITERS ); + pNames[1] = OUString::createFromAscii( SEPARATORS ); + pNames[2] = OUString::createFromAscii( TEXT_SEPARATORS ); + pNames[3] = OUString::createFromAscii( FIXED_WIDTH ); + pNames[4] = OUString::createFromAscii( FROM_ROW ); + pNames[5] = OUString::createFromAscii( CHAR_SET ); + pNames[6] = OUString::createFromAscii( QUOTED_AS_TEXT ); + pNames[7] = OUString::createFromAscii( DETECT_SPECIAL_NUM ); + pNames[8] = OUString::createFromAscii( LANGUAGE ); + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getArray(); + pProperties[1] <<= sFieldSeparators; + pProperties[2] <<= sTextSeparators; + ScUnoHelpFunctions::SetBoolInAny( pProperties[0], bMergeDelimiters ); + ScUnoHelpFunctions::SetBoolInAny( pProperties[3], bFixedWidth ); + pProperties[4] <<= nFromRow; + pProperties[5] <<= nCharSet; + pProperties[6] <<= static_cast<sal_Bool>(bQuotedAsText); + pProperties[7] <<= static_cast<sal_Bool>(bDetectSpecialNum); + pProperties[8] <<= nLanguage; + + aItem.PutProperties(aNames, aValues); +} // ---------------------------------------------------------------------------- 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 ), @@ -110,6 +217,8 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aFlFieldOpt ( this, ScResId( FL_FIELDOPT ) ), aFtCharSet ( this, ScResId( FT_CHARSET ) ), aLbCharSet ( this, ScResId( LB_CHARSET ) ), + aFtCustomLang( this, ScResId( FT_CUSTOMLANG ) ), + aLbCustomLang( this, ScResId( LB_CUSTOMLANG ) ), aFtRow ( this, ScResId( FT_AT_ROW ) ), aNfRow ( this, ScResId( NF_AT_ROW ) ), @@ -125,9 +234,14 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aCkbOther ( this, ScResId( CKB_OTHER ) ), aEdOther ( this, ScResId( ED_OTHER ) ), aCkbAsOnce ( this, ScResId( CB_ASONCE) ), + aFlOtherOpt ( this, ScResId( FL_OTHER_OPTIONS ) ), + aFtTextSep ( this, ScResId( FT_TEXTSEP ) ), aCbTextSep ( this, ScResId( CB_TEXTSEP ) ), + aCkbQuotedAsText( this, ScResId(CB_QUOTED_AS_TEXT) ), + aCkbDetectNumber( this, ScResId(CB_DETECT_SPECIAL_NUMBER) ), + aFlWidth ( this, ScResId( FL_WIDTH ) ), aFtType ( this, ScResId( FT_TYPE ) ), aLbType ( this, ScResId( LB_TYPE1 ) ), @@ -143,14 +257,15 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aFldSepList ( ScResId( SCSTR_FIELDSEP ) ), aTextSepList( ScResId( SCSTR_TEXTSEP ) ), mcTextSep ( ScAsciiOptions::cDefaultTextSep ), - maStrTextToColumns( ScResId( STR_TEXTTOCOLUMNS ) ) + maStrTextToColumns( ScResId( STR_TEXTTOCOLUMNS ) ), + mbFileImport(true) { FreeResource(); + mbFileImport = aDatName.Len() > 0; String aName = GetText(); // aDatName is empty if invoked during paste from clipboard. - BOOL bClipboard = (aDatName.Len() == 0); - if (!bClipboard) + if (mbFileImport) { aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" - [")); aName += aDatName; @@ -158,20 +273,55 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, } SetText( aName ); - switch(cSep) + + OUString sFieldSeparators; + OUString sTextSeparators; + bool bMergeDelimiters = false; + bool bFixedWidth = false; + bool bQuotedFieldAsText = true; + bool bDetectSpecialNum = false; + sal_Int32 nFromRow = 1; + sal_Int32 nCharSet = -1; + sal_Int32 nLanguage = 0; + if (mbFileImport) + // load separators only when importing csv files. + load_Separators (sFieldSeparators, sTextSeparators, bMergeDelimiters, + bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow, nCharSet, nLanguage); + maFieldSeparators = String(sFieldSeparators); + + if( bMergeDelimiters ) + aCkbAsOnce.Check(); + if (bQuotedFieldAsText) + aCkbQuotedAsText.Check(); + if (bDetectSpecialNum) + aCkbDetectNumber.Check(); + if( bFixedWidth ) + aRbFixed.Check(); + if( nFromRow != 1 ) + aNfRow.SetValue( nFromRow ); + + ByteString bString(maFieldSeparators,RTL_TEXTENCODING_MS_1252); + const sal_Char *aSep = bString.GetBuffer(); + int len = maFieldSeparators.Len(); + for (int i = 0; i < len; ++i) { - case '\t': aCkbTab.Check(); break; - case ';': aCkbSemicolon.Check(); break; - case ',': aCkbComma.Check(); break; - case ' ': aCkbSpace.Check(); break; - default: - aCkbOther.Check(); - aEdOther.SetText( cSep ); + switch( aSep[i] ) + { + case '\t': aCkbTab.Check(); break; + case ';': aCkbSemicolon.Check(); break; + case ',': aCkbComma.Check(); break; + case ' ': aCkbSpace.Check(); break; + default: + aCkbOther.Check(); + aEdOther.SetText( aEdOther.GetText() + OUString( aSep[i] ) ); + } } + + // Get Separators from the dialog maFieldSeparators = GetSeparators(); // Clipboard is always Unicode, else detect. - BOOL bPreselectUnicode = bClipboard; + bool bPreselectUnicode = !mbFileImport; // Sniff for Unicode / not if( !bPreselectUnicode && mpDatStream ) { @@ -207,6 +357,7 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, // *** Separator characters *** lcl_FillCombo( aCbTextSep, aTextSepList, mcTextSep ); + aCbTextSep.SetText( sTextSeparators ); Link aSeparatorHdl =LINK( this, ScImportAsciiDlg, SeparatorHdl ); aCbTextSep.SetSelectHdl( aSeparatorHdl ); @@ -215,6 +366,8 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aCkbSemicolon.SetClickHdl( aSeparatorHdl ); aCkbComma.SetClickHdl( aSeparatorHdl ); aCkbAsOnce.SetClickHdl( aSeparatorHdl ); + aCkbQuotedAsText.SetClickHdl( aSeparatorHdl ); + aCkbDetectNumber.SetClickHdl( aSeparatorHdl ); aCkbSpace.SetClickHdl( aSeparatorHdl ); aCkbOther.SetClickHdl( aSeparatorHdl ); aEdOther.SetModifyHdl( aSeparatorHdl ); @@ -227,9 +380,18 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aLbCharSet.InsertTextEncoding( RTL_TEXTENCODING_DONTKNOW, aCharSetUser ); aLbCharSet.SelectTextEncoding( bPreselectUnicode ? RTL_TEXTENCODING_UNICODE : gsl_getSystemTextEncoding() ); + + if( nCharSet >= 0 ) + aLbCharSet.SelectEntryPos( static_cast<USHORT>(nCharSet) ); + SetSelectedCharSet(); aLbCharSet.SetSelectHdl( LINK( this, ScImportAsciiDlg, CharSetHdl ) ); + aLbCustomLang.SetLanguageList( + LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, false, false); + aLbCustomLang.InsertLanguage(LANGUAGE_SYSTEM); + aLbCustomLang.SelectLanguage(static_cast<LanguageType>(nLanguage), true); + // *** column type ListBox *** xub_StrLen nCount = aColumnUser.GetTokenCount(); for (xub_StrLen i=0; i<nCount; i++) @@ -336,6 +498,7 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt ) { rOpt.SetCharSet( meCharSet ); rOpt.SetCharSetSystem( mbCharSetSystem ); + rOpt.SetLanguage(aLbCustomLang.GetSelectLanguage()); rOpt.SetFixedLen( aRbFixed.IsChecked() ); rOpt.SetStartRow( (long)aNfRow.GetValue() ); maTableBox.FillColumnData( rOpt ); @@ -345,6 +508,9 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt ) rOpt.SetMergeSeps( aCkbAsOnce.IsChecked() ); rOpt.SetTextSep( lcl_CharFromCombo( aCbTextSep, aTextSepList ) ); } + + rOpt.SetQuotedAsText(aCkbQuotedAsText.IsChecked()); + rOpt.SetDetectSpecialNumber(aCkbDetectNumber.IsChecked()); } void ScImportAsciiDlg::SetTextToColumnsMode() @@ -352,8 +518,33 @@ void ScImportAsciiDlg::SetTextToColumnsMode() SetText( maStrTextToColumns ); aFtCharSet.Disable(); aLbCharSet.Disable(); + aFtCustomLang.Disable(); + aLbCustomLang.SelectLanguage(LANGUAGE_SYSTEM); + aLbCustomLang.Disable(); aFtRow.Disable(); aNfRow.Disable(); + + // Quoted field as text option is not used for text-to-columns mode. + aCkbQuotedAsText.Check(false); + aCkbQuotedAsText.Disable(); + + // Always detect special numbers for text-to-columns mode. + aCkbDetectNumber.Check(); + aCkbDetectNumber.Disable(); +} + +void ScImportAsciiDlg::SaveParameters() +{ + if (!mbFileImport) + // We save parameters only for file import. + return; + + save_Separators( maFieldSeparators, aCbTextSep.GetText(), aCkbAsOnce.IsChecked(), + aCkbQuotedAsText.IsChecked(), aCkbDetectNumber.IsChecked(), + aRbFixed.IsChecked(), + static_cast<sal_Int32>(aNfRow.GetValue()), + static_cast<sal_Int32>(aLbCharSet.GetSelectEntryPos()), + static_cast<sal_Int32>(aLbCustomLang.GetSelectLanguage()) ); } void ScImportAsciiDlg::SetSelectedCharSet() diff --git a/sc/source/ui/dbgui/textimportoptions.cxx b/sc/source/ui/dbgui/textimportoptions.cxx new file mode 100644 index 000000000000..be918d2a0fbd --- /dev/null +++ b/sc/source/ui/dbgui/textimportoptions.cxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: langbox.hxx,v $ + * $Revision: 1.4.242.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#undef SC_DLLIMPLEMENTATION + +//------------------------------------------------------------------------ + +#include "textimportoptions.hxx" +#include "textimportoptions.hrc" + +#include "scresid.hxx" +#include "vcl/window.hxx" +#include "vcl/msgbox.hxx" +#include "vcl/svapp.hxx" + +ScTextImportOptionsDlg::ScTextImportOptionsDlg(Window* pParent) : + ModalDialog(pParent, ScResId(RID_SCDLG_TEXT_IMPORT_OPTIONS)), + + maBtnOk(this, ScResId(BTN_OK)), + maBtnCancel(this, ScResId(BTN_CANCEL)), + maBtnHelp(this, ScResId(BTN_HELP)), + maFlChooseLang(this, ScResId(FL_CHOOSE_LANG)), + maRbAutomatic(this, ScResId(RB_AUTOMATIC)), + maRbCustom(this, ScResId(RB_CUSTOM)), + maLbCustomLang(this, ScResId(LB_CUSTOM_LANG)), + maFlOption(this, ScResId(FL_OPTION)), + maBtnConvertDate(this, ScResId(BTN_CONVERT_DATE)) +{ + FreeResource(); + init(); +} + +ScTextImportOptionsDlg::~ScTextImportOptionsDlg() +{ +} + +short ScTextImportOptionsDlg::Execute() +{ + return ModalDialog::Execute(); +} + +LanguageType ScTextImportOptionsDlg::getLanguageType() const +{ + if (maRbAutomatic.IsChecked()) + return LANGUAGE_SYSTEM; + + return maLbCustomLang.GetSelectLanguage(); +} + +bool ScTextImportOptionsDlg::isDateConversionSet() const +{ + return maBtnConvertDate.IsChecked(); +} + +void ScTextImportOptionsDlg::init() +{ + Link aLink = LINK( this, ScTextImportOptionsDlg, OKHdl ); + maBtnOk.SetClickHdl(aLink); + aLink = LINK( this, ScTextImportOptionsDlg, RadioHdl ); + maRbAutomatic.SetClickHdl(aLink); + maRbCustom.SetClickHdl(aLink); + + maRbAutomatic.Check(true); + + maLbCustomLang.SetLanguageList( + LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, false, false); + + LanguageType eLang = Application::GetSettings().GetLanguage(); + maLbCustomLang.SelectLanguage(eLang); + maLbCustomLang.Disable(); +} + +IMPL_LINK( ScTextImportOptionsDlg, OKHdl, OKButton*, EMPTYARG ) +{ + EndDialog(RET_OK); + return 0; +} + +IMPL_LINK( ScTextImportOptionsDlg, RadioHdl, RadioButton*, pBtn ) +{ + if (pBtn == &maRbAutomatic) + { + maLbCustomLang.Disable(); + } + else if (pBtn == &maRbCustom) + { + maLbCustomLang.Enable(); + } + return 0; +} + diff --git a/sc/source/ui/dbgui/textimportoptions.src b/sc/source/ui/dbgui/textimportoptions.src new file mode 100644 index 000000000000..fff3c4b40749 --- /dev/null +++ b/sc/source/ui/dbgui/textimportoptions.src @@ -0,0 +1,112 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: retypepassdlg.src,v $ + * $Revision: 1.1.2.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "textimportoptions.hrc" + +ModalDialog RID_SCDLG_TEXT_IMPORT_OPTIONS +{ + Text [ en-US ] = "Import Options" ; + Size = MAP_APPFONT ( 190 , 101 ) ; + Moveable = TRUE ; + Closeable = TRUE ; + OutputSize = TRUE ; + + OKButton BTN_OK + { + Pos = MAP_APPFONT ( 135, 6 ) ; + Size = MAP_APPFONT ( 50, 14 ) ; + DefButton = TRUE ; + }; + + CancelButton BTN_CANCEL + { + Pos = MAP_APPFONT ( 135, 23 ) ; + Size = MAP_APPFONT ( 50, 14 ) ; + }; + + HelpButton BTN_HELP + { + Pos = MAP_APPFONT ( 135, 43 ) ; + Size = MAP_APPFONT ( 50, 14 ) ; + }; + + FixedLine FL_CHOOSE_LANG + { + Pos = MAP_APPFONT( 6, 3 ) ; + Size = MAP_APPFONT( 125, 14 ) ; + + Text [ en-US ] = "Select the language to use for import" ; + }; + + RadioButton RB_AUTOMATIC + { + Pos = MAP_APPFONT( 12, 20 ) ; + Size = MAP_APPFONT( 50, 10 ) ; + TabStop = TRUE ; + + Text [ en-US ] = "Automatic" ; + }; + + RadioButton RB_CUSTOM + { + Pos = MAP_APPFONT( 12, 34 ) ; + Size = MAP_APPFONT( 50, 10 ) ; + TabStop = TRUE ; + + Text [ en-US ] = "Custom" ; + }; + + ListBox LB_CUSTOM_LANG + { + Pos = MAP_APPFONT( 20, 50 ) ; + Size = MAP_APPFONT( 100, 55 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + Sort = TRUE ; + }; + + FixedLine FL_OPTION + { + Pos = MAP_APPFONT( 6, 70 ); + Size = MAP_APPFONT( 125, 14 ); + + Text [ en-US ] = "Options" ; + }; + + CheckBox BTN_CONVERT_DATE + { + Pos = MAP_APPFONT( 12, 86 ); + Size = MAP_APPFONT( 125, 10 ); + TabStop = TRUE ; + + Text [ en-US ] = "Detect special numbers (such as dates)." ; + }; +}; + diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 1633af000b51..9895f0f43610 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -56,6 +56,7 @@ #include "attrib.hxx" #include "drwlayer.hxx" #include "dpshttab.hxx" +#include "hints.hxx" // ----------------------------------------------------------------- @@ -592,7 +593,7 @@ BOOL ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam, if (pDestData) pNewData = pDestData; // Bereich vorhanden -> anpassen else // Bereich ab Cursor/Markierung wird angelegt - pNewData = rDocShell.GetDBData(aDestPos, SC_DB_MAKE, TRUE ); + pNewData = rDocShell.GetDBData(aDestPos, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); if (pNewData) { pNewData->SetArea( nTab, @@ -919,7 +920,7 @@ BOOL ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& rQueryParam, pNewData = rDocShell.GetDBData( ScRange( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab, aLocalParam.nCol2, aLocalParam.nRow2, nDestTab ), - SC_DB_MAKE, TRUE ); + SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); if (pNewData) { @@ -1403,7 +1404,12 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb delete pUndoDPObj; if (bDone) + { + // notify API objects + if (pDestObj) + pDoc->BroadcastUno( ScDataPilotModifiedHint( pDestObj->GetName() ) ); aModificator.SetDocumentModified(); + } if ( nErrId && !bApi ) rDocShell.ErrorMessage( nErrId ); diff --git a/sc/source/ui/docshell/dbdocimp.cxx b/sc/source/ui/docshell/dbdocimp.cxx index 17b07099a491..a073e50d105c 100644 --- a/sc/source/ui/docshell/dbdocimp.cxx +++ b/sc/source/ui/docshell/dbdocimp.cxx @@ -69,7 +69,7 @@ using namespace com::sun::star; #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet" -#define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler" +#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler" //! move to a header file? #define SC_DBPROP_DATASOURCENAME "DataSourceName" @@ -86,7 +86,7 @@ void ScDBDocFunc::ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFram if ( !pFrame || !rParam.bImport ) return; - uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame()->GetFrameInterface(); + uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface(); uno::Reference<frame::XDispatchProvider> xDP(xFrame, uno::UNO_QUERY); uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame( @@ -189,7 +189,7 @@ BOOL ScDBDocFunc::DoImportUno( const ScAddress& rPos, // create database range //! merge this with SID_SBA_IMPORT execute in docsh4.cxx - ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, FALSE ); + ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, SC_DBSEL_KEEP ); DBG_ASSERT(pDBData, "can't create DB data"); String sTarget = pDBData->GetName(); diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 1b4f9b677f81..821b2a6ad880 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -57,7 +57,6 @@ #include <sfx2/fcontnr.hxx> #include <sfx2/evntconf.hxx> #include <sfx2/sfx.hrc> -#include <sfx2/topfrm.hxx> #include <sfx2/objface.hxx> #include <svl/srchitem.hxx> #include <unotools/fltrcfg.hxx> @@ -127,6 +126,8 @@ #include <basic/sbstar.hxx> #include <basic/basmgr.hxx> using namespace com::sun::star; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; // STATIC DATA ----------------------------------------------------------- @@ -817,6 +818,34 @@ BOOL __EXPORT ScDocShell::LoadFrom( SfxMedium& rMedium ) return bRet; } +static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert) +{ + OUStringBuffer aBuf; + OUString aTokens[2]; + sal_Int32 n = rOption.getLength(); + const sal_Unicode* p = rOption.getStr(); + sal_Int32 nTokenId = 0; + for (sal_Int32 i = 0; i < n; ++i) + { + const sal_Unicode c = p[i]; + if (c == sal_Unicode(' ')) + { + if (aBuf.getLength()) + aTokens[nTokenId++] = aBuf.makeStringAndClear(); + } + else + aBuf.append(c); + + if (nTokenId >= 2) + break; + } + + if (aBuf.getLength()) + aTokens[nTokenId] = aBuf.makeStringAndClear(); + + rLang = static_cast<LanguageType>(aTokens[0].toInt32()); + rDateConvert = static_cast<bool>(aTokens[1].toInt32()); +} BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium ) { @@ -1190,12 +1219,24 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium ) SvStream* pInStream = rMedium.GetInStream(); if (pInStream) { + LanguageType eLang = LANGUAGE_SYSTEM; + bool bDateConvert = false; + SfxItemSet* pSet = rMedium.GetItemSet(); + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + String aFilterOption = (static_cast<const SfxStringItem*>(pItem))->GetValue(); + lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert); + } + pInStream->Seek( 0 ); ScRange aRange; // HTML macht eigenes ColWidth/RowHeight CalcOutputFactor(); + SvNumberFormatter aNumFormatter(aDocument.GetServiceManager(), eLang); eError = ScFormatFilter::Get().ScImportHTML( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange, - GetOutputFactor(), !bWebQuery ); + GetOutputFactor(), !bWebQuery, &aNumFormatter, bDateConvert ); if (eError != eERR_OK) { if (!GetError()) @@ -2114,7 +2155,7 @@ USHORT __EXPORT ScDocShell::PrepareClose( BOOL bUI, BOOL bForBrowsing ) { if(SC_MOD()->GetCurRefDlgId()>0) { - SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, TYPE(SfxTopViewFrame) ); + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); if( pFrame ) { SfxViewShell* p = pFrame->GetViewShell(); @@ -2162,6 +2203,11 @@ String ScDocShell::GetOwnFilterName() // static return String::CreateFromAscii(pFilterSc50); } +String ScDocShell::GetHtmlFilterName() +{ + return String::CreateFromAscii(pFilterHtml); +} + String ScDocShell::GetWebQueryFilterName() // static { return String::CreateFromAscii(pFilterHtmlWebQ); @@ -2261,22 +2307,19 @@ ScDocShell::ScDocShell( const ScDocShell& rShell ) //------------------------------------------------------------------ -ScDocShell::ScDocShell( SfxObjectCreateMode eMode, const bool _bScriptSupport ) - : SfxObjectShell( eMode ), - __SCDOCSHELL_INIT +ScDocShell::ScDocShell( const sal_uInt64 i_nSfxCreationFlags ) + : SfxObjectShell( i_nSfxCreationFlags ) + , __SCDOCSHELL_INIT { RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" ); SetPool( &SC_MOD()->GetPool() ); - bIsInplace = (eMode == SFX_CREATE_MODE_EMBEDDED); + bIsInplace = (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED); // wird zurueckgesetzt, wenn nicht inplace pDocFunc = new ScDocFunc(*this); - if ( !_bScriptSupport ) - SetHasNoBasic(); - // SetBaseModel needs exception handling ScModelObj::CreateAndSet( this ); diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx index 7ff714c2cbdd..4709a065792f 100644 --- a/sc/source/ui/docshell/docsh3.cxx +++ b/sc/source/ui/docshell/docsh3.cxx @@ -1088,6 +1088,16 @@ void ScDocShell::MergeDocument( ScDocument& rOtherDoc, bool bShared, bool bCheck { aSourceRange = pDel->GetOverAllRange().MakeRange(); GetDocFunc().DeleteCells( aSourceRange, NULL, DEL_DELROWS, TRUE, FALSE ); + + // #i101099# [Collaboration] Changes are not correctly shown + if ( bShared ) + { + ScChangeAction* pAct = pThisTrack->GetLast(); + if ( pAct && pAct->GetType() == eSourceType && pAct->IsDeletedIn() && !pSourceAction->IsDeletedIn() ) + { + pAct->RemoveAllDeletedIn(); + } + } } } break; diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 97403008915d..157b98497e83 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -53,7 +53,6 @@ using namespace ::com::sun::star; #include <sfx2/printer.hxx> #include <sfx2/request.hxx> #include <svtools/sfxecode.hxx> -#include <sfx2/topfrm.hxx> #include <svx/ofaitem.hxx> #include <sot/formats.hxx> #include <svtools/printdlg.hxx> @@ -265,7 +264,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) GetUndoManager()->EnterListAction( aStrImport, aStrImport ); } - ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, FALSE ); + ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, SC_DBSEL_KEEP ); DBG_ASSERT(pDBData, "kann DB-Daten nicht anlegen"); sTarget = pDBData->GetName(); } @@ -2561,7 +2560,7 @@ ScTabViewShell* ScDocShell::GetBestViewShell( BOOL bOnlyVisible ) if( !pViewSh ) { // 1. ViewShell suchen - SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, TYPE(SfxTopViewFrame), bOnlyVisible ); + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, bOnlyVisible ); if( pFrame ) { SfxViewShell* p = pFrame->GetViewShell(); diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx index 6fa6a5ac7863..1bbf9437bc1c 100644 --- a/sc/source/ui/docshell/docsh5.cxx +++ b/sc/source/ui/docshell/docsh5.cxx @@ -148,7 +148,7 @@ ScDBData* lcl_GetDBNearCursor( ScDBCollection* pColl, SCCOL nCol, SCROW nRow, SC return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden } -ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, BOOL bForceMark ) +ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, ScGetDBSelection eSel ) { SCCOL nCol = rMarked.aStart.Col(); SCROW nRow = rMarked.aStart.Row(); @@ -169,7 +169,9 @@ ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, BOOL if (!pData) pData = lcl_GetDBNearCursor( aDocument.GetDBCollection(), nCol, nRow, nTab ); - BOOL bSelected = ( bForceMark || rMarked.aStart != rMarked.aEnd ); + BOOL bSelected = ( eSel == SC_DBSEL_FORCE_MARK || + (rMarked.aStart != rMarked.aEnd && eSel != SC_DBSEL_ROW_DOWN) ); + bool bOnlyDown = (!bSelected && eSel == SC_DBSEL_ROW_DOWN && rMarked.aStart.Row() == rMarked.aEnd.Row()); BOOL bUseThis = FALSE; if (pData) @@ -189,12 +191,21 @@ ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, BOOL bUseThis = TRUE; if ( bIsNoName && eMode == SC_DB_MAKE ) { - // wenn nichts markiert, "unbenannt" auf zusammenhaengenden Bereich anpassen + // If nothing marked or only one row marked, adapt + // "unbenannt"/"unnamed" to contiguous area. nStartCol = nCol; nStartRow = nRow; - nEndCol = nStartCol; - nEndRow = nStartRow; - aDocument.GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE ); + if (bOnlyDown) + { + nEndCol = rMarked.aEnd.Col(); + nEndRow = rMarked.aEnd.Row(); + } + else + { + nEndCol = nStartCol; + nEndRow = nStartRow; + } + aDocument.GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE, bOnlyDown ); if ( nOldCol1 != nStartCol || nOldCol2 != nEndCol || nOldRow1 != nStartRow ) bUseThis = FALSE; // passt gar nicht else if ( nOldRow2 != nEndRow ) @@ -242,9 +253,17 @@ ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, BOOL { // zusammenhaengender Bereich nStartCol = nCol; nStartRow = nRow; - nEndCol = nStartCol; - nEndRow = nStartRow; - aDocument.GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE ); + if (bOnlyDown) + { + nEndCol = rMarked.aEnd.Col(); + nEndRow = rMarked.aEnd.Row(); + } + else + { + nEndCol = nStartCol; + nEndRow = nStartRow; + } + aDocument.GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE, bOnlyDown ); } BOOL bHasHeader = aDocument.HasColHeader( nStartCol,nStartRow, nEndCol,nEndRow, nTab ); diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index a095c8d036fa..0569e95605b1 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -306,6 +306,26 @@ void ScExternalRefCache::Table::getAllRows(vector<SCROW>& rRows, SCROW nLow, SCR rRows.swap(aRows); } +::std::pair< SCROW, SCROW > ScExternalRefCache::Table::getRowRange() const +{ + ::std::pair< SCROW, SCROW > aRange( 0, 0 ); + if( !maRows.empty() ) + { + // iterate over entire container (hash map is not sorted by key) + RowsDataType::const_iterator itr = maRows.begin(), itrEnd = maRows.end(); + aRange.first = itr->first; + aRange.second = itr->first + 1; + while( ++itr != itrEnd ) + { + if( itr->first < aRange.first ) + aRange.first = itr->first; + else if( itr->first >= aRange.second ) + aRange.second = itr->first + 1; + } + } + return aRange; +} + void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols, SCCOL nLow, SCCOL nHigh) const { RowsDataType::const_iterator itrRow = maRows.find(nRow); @@ -326,6 +346,33 @@ void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols, SCC rCols.swap(aCols); } +::std::pair< SCCOL, SCCOL > ScExternalRefCache::Table::getColRange( SCROW nRow ) const +{ + ::std::pair< SCCOL, SCCOL > aRange( 0, 0 ); + + RowsDataType::const_iterator itrRow = maRows.find( nRow ); + if (itrRow == maRows.end()) + // this table doesn't have the specified row. + return aRange; + + const RowDataType& rRowData = itrRow->second; + if( !rRowData.empty() ) + { + // iterate over entire container (hash map is not sorted by key) + RowDataType::const_iterator itr = rRowData.begin(), itrEnd = rRowData.end(); + aRange.first = itr->first; + aRange.second = itr->first + 1; + while( ++itr != itrEnd ) + { + if( itr->first < aRange.first ) + aRange.first = itr->first; + else if( itr->first >= aRange.second ) + aRange.second = itr->first + 1; + } + } + return aRange; +} + void ScExternalRefCache::Table::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const { RowsDataType::const_iterator itrRow = maRows.begin(), itrRowEnd = maRows.end(); @@ -2000,6 +2047,9 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, Stri if (aOptions.Len()) pSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, aOptions)); + // make medium hidden to prevent assertion from progress bar + pSet->Put( SfxBoolItem( SID_HIDDEN, TRUE ) ); + auto_ptr<SfxMedium> pMedium(new SfxMedium(aFile, STREAM_STD_READ, false, pFilter, pSet)); if (pMedium->GetError() != ERRCODE_NONE) return NULL; diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx index 8fc49696ba59..46b6b7af3a63 100644 --- a/sc/source/ui/docshell/impex.cxx +++ b/sc/source/ui/docshell/impex.cxx @@ -902,12 +902,11 @@ BOOL ScImportExport::Text2Doc( SvStream& rStrm ) // -bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, - const String& rStr, BYTE nColFormat, - ::utl::TransliterationWrapper& rTransliteration, - CalendarWrapper& rCalendar, - ::utl::TransliterationWrapper* pSecondTransliteration, - CalendarWrapper* pSecondCalendar ) +static bool lcl_PutString( + ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rStr, BYTE nColFormat, + SvNumberFormatter* pFormatter, bool bDetectNumFormat, + ::utl::TransliterationWrapper& rTransliteration, CalendarWrapper& rCalendar, + ::utl::TransliterationWrapper* pSecondTransliteration, CalendarWrapper* pSecondCalendar ) { bool bMultiLine = false; if ( nColFormat == SC_COL_SKIP || !rStr.Len() || !ValidCol(nCol) || !ValidRow(nRow) ) @@ -923,10 +922,10 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, { //! SetString mit Extra-Flag ??? - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); - sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US); + SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable(); + sal_uInt32 nEnglish = pDocFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US); double fVal; - if ( pFormatter->IsNumberFormat( rStr, nEnglish, fVal ) ) + if ( pDocFormatter->IsNumberFormat( rStr, nEnglish, fVal ) ) { // Zahlformat wird nicht auf englisch gesetzt pDoc->SetValue( nCol, nRow, nTab, fVal ); @@ -1062,9 +1061,9 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, } } - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable(); if ( nYear < 100 ) - nYear = pFormatter->ExpandTwoDigitYear( nYear ); + nYear = pDocFormatter->ExpandTwoDigitYear( nYear ); CalendarWrapper* pCalendar = (bSecondCal ? pSecondCalendar : &rCalendar); sal_Int16 nNumMonths = pCalendar->getNumberOfMonthsInYear(); @@ -1100,7 +1099,7 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, pCalendar->setValue( i18n::CalendarFieldIndex::MILLISECOND, nMilli ); if ( pCalendar->isValid() ) { - double fDiff = DateTime(*pFormatter->GetNullDate()) - + double fDiff = DateTime(*pDocFormatter->GetNullDate()) - pCalendar->getEpochStart(); // #i14974# must use getLocalDateTime to get the same // date values as set above @@ -1112,10 +1111,10 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, LanguageType eDocLang = eLatin; //! which language for date formats? short nType = (nFound > 3 ? NUMBERFORMAT_DATETIME : NUMBERFORMAT_DATE); - ULONG nFormat = pFormatter->GetStandardFormat( nType, eDocLang ); + ULONG nFormat = pDocFormatter->GetStandardFormat( nType, eDocLang ); // maybe there is a special format including seconds or milliseconds if (nFound > 5) - nFormat = pFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang); + nFormat = pDocFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang); pDoc->PutCell( nCol, nRow, nTab, new ScValueCell(fDays), nFormat, FALSE ); @@ -1127,7 +1126,7 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, // Standard or date not determined -> SetString / EditCell if( rStr.Search( _LF ) == STRING_NOTFOUND ) - pDoc->SetString( nCol, nRow, nTab, rStr ); + pDoc->SetString( nCol, nRow, nTab, rStr, pFormatter, bDetectNumFormat ); else { bMultiLine = true; @@ -1137,7 +1136,7 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, } -String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext ) +String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext, bool& rbIsQuoted ) { xub_StrLen nLen = rLine.Len(); if (nNext > nLen) @@ -1151,7 +1150,11 @@ String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext ) while ( nSpace > nStart && pStr[nSpace-1] == ' ' ) --nSpace; - return rLine.Copy( nStart, nSpace-nStart ); + rbIsQuoted = (pStr[nStart] == sal_Unicode('"') && pStr[nSpace-1] == sal_Unicode('"')); + if (rbIsQuoted) + return rLine.Copy(nStart+1, nSpace-nStart-2); + else + return rLine.Copy(nStart, nSpace-nStart); } BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) @@ -1184,9 +1187,9 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) const BYTE* pColFormat = pExtOptions->GetColFormat(); long nSkipLines = pExtOptions->GetStartRow(); - LanguageType eLatin, eCjk, eCtl; - pDoc->GetLanguage( eLatin, eCjk, eCtl ); - LanguageType eDocLang = eLatin; //! which language for date formats? + LanguageType eDocLang = pExtOptions->GetLanguage(); + SvNumberFormatter aNumFormatter(pDoc->GetServiceManager(), eDocLang); + bool bDetectNumFormat = pExtOptions->IsDetectSpecialNumber(); // For date recognition ::utl::TransliterationWrapper aTransliteration( @@ -1228,6 +1231,8 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) // survives the toggle of bDetermineRange down at the end of the do{} loop. bool bRangeIsDetermined = bDetermineRange; + bool bQuotedAsText = pExtOptions && pExtOptions->IsQuotedAsText(); + ULONG nOriginalStreamPos = rStrm.Tell(); do @@ -1249,7 +1254,8 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) // SC_COL_SKIP. for ( i=0; i<nInfoCount && nCol <= MAXCOL+1; i++ ) { - if ( pColFormat[i] != SC_COL_SKIP ) // sonst auch nCol nicht hochzaehlen + BYTE nFmt = pColFormat[i]; + if (nFmt != SC_COL_SKIP) // sonst auch nCol nicht hochzaehlen { if (nCol > MAXCOL) bOverflow = TRUE; // display warning on import @@ -1257,11 +1263,15 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) { xub_StrLen nStart = pColStart[i]; xub_StrLen nNext = ( i+1 < nInfoCount ) ? pColStart[i+1] : nLineLen; - aCell = lcl_GetFixed( aLine, nStart, nNext ); - bMultiLine |= lcl_PutString( pDoc, nCol, nRow, - nTab, aCell, pColFormat[i], - aTransliteration, aCalendar, - pEnglishTransliteration, pEnglishCalendar); + bool bIsQuoted = false; + aCell = lcl_GetFixed( aLine, nStart, nNext, bIsQuoted ); + if (bIsQuoted && bQuotedAsText) + nFmt = SC_COL_TEXT; + + bMultiLine |= lcl_PutString( + pDoc, nCol, nRow, nTab, aCell, nFmt, + &aNumFormatter, bDetectNumFormat, aTransliteration, aCalendar, + pEnglishTransliteration, pEnglishCalendar); } ++nCol; } @@ -1278,7 +1288,8 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) // SC_COL_SKIP. while (*p && nCol <= MAXCOL+1) { - p = ScImportExport::ScanNextFieldFromString( p, aCell, cStr, pSeps, bMerge ); + bool bIsQuoted = false; + p = ScImportExport::ScanNextFieldFromString( p, aCell, cStr, pSeps, bMerge, bIsQuoted ); BYTE nFmt = SC_COL_STANDARD; for ( i=nInfoStart; i<nInfoCount; i++ ) @@ -1295,10 +1306,15 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) if (nCol > MAXCOL) bOverflow = TRUE; // display warning on import else if (!bDetermineRange) - bMultiLine |= lcl_PutString( pDoc, nCol, nRow, - nTab, aCell, nFmt, aTransliteration, - aCalendar, pEnglishTransliteration, - pEnglishCalendar); + { + if (bIsQuoted && bQuotedAsText) + nFmt = SC_COL_TEXT; + + bMultiLine |= lcl_PutString( + pDoc, nCol, nRow, nTab, aCell, nFmt, + &aNumFormatter, bDetectNumFormat, aTransliteration, + aCalendar, pEnglishTransliteration, pEnglishCalendar); + } ++nCol; } @@ -1372,11 +1388,13 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) // static const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p, - String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, BOOL bMergeSeps ) + String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted ) { + rbIsQuoted = false; rField.Erase(); if ( *p == cStr ) // String in Anfuehrungszeichen { + rbIsQuoted = true; const sal_Unicode* p1; p1 = p = lcl_ScanString( p, rField, cStr, DQM_ESCAPE ); while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) ) @@ -2035,7 +2053,7 @@ class ScFormatFilterMissing : public ScFormatFilterPlugin { virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress&, const CharSet, UINT32 ) RETURN_ERROR virtual FltError ScImportRTF( SvStream&, const String&, ScDocument*, ScRange& ) RETURN_ERROR - virtual FltError ScImportHTML( SvStream&, const String&, ScDocument*, ScRange&, double, BOOL ) RETURN_ERROR + virtual FltError ScImportHTML( SvStream&, const String&, ScDocument*, ScRange&, double, BOOL, SvNumberFormatter*, bool ) RETURN_ERROR virtual ScEEAbsImport *CreateRTFImport( ScDocument*, const ScRange& ) { return NULL; } virtual ScEEAbsImport *CreateHTMLImport( ScDocument*, const String&, const ScRange&, BOOL ) { return NULL; } diff --git a/sc/source/ui/drawfunc/drawsh.cxx b/sc/source/ui/drawfunc/drawsh.cxx index b44c396f4e0c..e2f70432d679 100644 --- a/sc/source/ui/drawfunc/drawsh.cxx +++ b/sc/source/ui/drawfunc/drawsh.cxx @@ -335,7 +335,7 @@ void ScDrawShell::ExecuteMacroAssign( SdrObject* pObj, Window* pWin ) com::sun::star::uno::Reference < com::sun::star::frame::XFrame > xFrame; if (GetViewShell()) - xFrame = GetViewShell()->GetViewFrame()->GetFrame()->GetFrameInterface(); + xFrame = GetViewShell()->GetViewFrame()->GetFrame().GetFrameInterface(); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); SfxAbstractDialog* pMacroDlg = pFact->CreateSfxDialog( pWin, *pItemSet, xFrame, SID_EVENTCONFIG ); diff --git a/sc/source/ui/drawfunc/fudraw.cxx b/sc/source/ui/drawfunc/fudraw.cxx index 3a3fc833a515..bad23bf26ed1 100644 --- a/sc/source/ui/drawfunc/fudraw.cxx +++ b/sc/source/ui/drawfunc/fudraw.cxx @@ -310,7 +310,7 @@ BOOL __EXPORT FuDraw::KeyInput(const KeyEvent& rKEvt) const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() ) { - BOOL bOle = pViewShell->GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = pViewShell->GetViewFrame()->GetFrame().IsInPlace(); SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj(); if( pObj && pObj->ISA( SdrOle2Obj ) && !bOle ) { diff --git a/sc/source/ui/drawfunc/fuins2.cxx b/sc/source/ui/drawfunc/fuins2.cxx index e0721fc47f50..f648a1484e8e 100644 --- a/sc/source/ui/drawfunc/fuins2.cxx +++ b/sc/source/ui/drawfunc/fuins2.cxx @@ -526,7 +526,8 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* ScRangeList aRanges; aMultiMark.FillRangeListWithMarks( &aRanges, FALSE ); String aStr; - aRanges.Format( aStr, SCR_ABS_3D, pViewSh->GetViewData()->GetDocument() ); + ScDocument* pDocument = pViewSh->GetViewData()->GetDocument(); + aRanges.Format( aStr, SCR_ABS_3D, pDocument, pDocument->GetAddressConvention() ); aRangeString = aStr; // get "total" range for positioning diff --git a/sc/source/ui/drawfunc/fusel.cxx b/sc/source/ui/drawfunc/fusel.cxx index 213169b8b9fd..4a456522003c 100644 --- a/sc/source/ui/drawfunc/fusel.cxx +++ b/sc/source/ui/drawfunc/fusel.cxx @@ -390,7 +390,7 @@ BOOL __EXPORT FuSelection::MouseButtonUp(const MouseEvent& rMEvt) BOOL bReturn = FuDraw::MouseButtonUp(rMEvt); // BOOL bOle = pViewShell->GetViewData()->IsOle(); - BOOL bOle = pViewShell->GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = pViewShell->GetViewFrame()->GetFrame().IsInPlace(); if (aDragTimer.IsActive() ) { diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx index d9add14952a4..2d9cdef1b54e 100644 --- a/sc/source/ui/formdlg/formula.cxx +++ b/sc/source/ui/formdlg/formula.cxx @@ -40,7 +40,6 @@ #include <svl/stritem.hxx> #include <svtools/svtreebx.hxx> #include <sfx2/viewfrm.hxx> -#include <sfx2/topfrm.hxx> #include <vcl/svapp.hxx> #include <vcl/mnemonic.hxx> #include <unotools/charclass.hxx> @@ -308,7 +307,7 @@ ScInputHandler* ScFormulaDlg::GetNextInputHandler(ScDocShell* pDocShell,PtrTabVi { ScInputHandler* pHdl=NULL; - SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell, TYPE(SfxTopViewFrame) ); + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell ); while( pFrame && pHdl==NULL) { SfxViewShell* p = pFrame->GetViewShell(); @@ -318,7 +317,7 @@ ScInputHandler* ScFormulaDlg::GetNextInputHandler(ScDocShell* pDocShell,PtrTabVi pHdl=pViewSh->GetInputHandler(); if(ppViewSh!=NULL) *ppViewSh=pViewSh; } - pFrame = SfxViewFrame::GetNext(*pFrame,pDocShell, TYPE(SfxTopViewFrame) ); + pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ); } diff --git a/sc/source/ui/inc/asciiopt.hxx b/sc/source/ui/inc/asciiopt.hxx index aee63d682a26..a5c7a2b554b4 100644 --- a/sc/source/ui/inc/asciiopt.hxx +++ b/sc/source/ui/inc/asciiopt.hxx @@ -52,7 +52,7 @@ #include <tools/stream.hxx> #include <svx/txencbox.hxx> #include "csvtablebox.hxx" - +#include "i18npool/lang.h" // ============================================================================ @@ -62,8 +62,11 @@ private: BOOL bFixedLen; String aFieldSeps; BOOL bMergeFieldSeps; + bool bQuotedFieldAsText; + bool bDetectSpecialNumber; sal_Unicode cTextSep; CharSet eCharSet; + LanguageType eLang; BOOL bCharSetSystem; long nStartRow; USHORT nInfoCount; @@ -90,20 +93,26 @@ public: BOOL GetCharSetSystem() const { return bCharSetSystem; } const String& GetFieldSeps() const { return aFieldSeps; } BOOL IsMergeSeps() const { return bMergeFieldSeps; } + bool IsQuotedAsText() const { return bQuotedFieldAsText; } + bool IsDetectSpecialNumber() const { return bDetectSpecialNumber; } sal_Unicode GetTextSep() const { return cTextSep; } BOOL IsFixedLen() const { return bFixedLen; } USHORT GetInfoCount() const { return nInfoCount; } const xub_StrLen* GetColStart() const { return pColStart; } const BYTE* GetColFormat() const { return pColFormat; } long GetStartRow() const { return nStartRow; } + LanguageType GetLanguage() const { return eLang; } void SetCharSet( CharSet eNew ) { eCharSet = eNew; } void SetCharSetSystem( BOOL bSet ) { bCharSetSystem = bSet; } void SetFixedLen( BOOL bSet ) { bFixedLen = bSet; } void SetFieldSeps( const String& rStr ) { aFieldSeps = rStr; } void SetMergeSeps( BOOL bSet ) { bMergeFieldSeps = bSet; } + void SetQuotedAsText(bool bSet) { bQuotedFieldAsText = bSet; } + void SetDetectSpecialNumber(bool bSet) { bDetectSpecialNumber = bSet; } void SetTextSep( sal_Unicode c ) { cTextSep = c; } void SetStartRow( long nRow) { nStartRow= nRow; } + void SetLanguage(LanguageType e) { eLang = e; } void SetColInfo( USHORT nCount, const xub_StrLen* pStart, const BYTE* pFormat ); void SetColumnInfo( const ScCsvExpDataVec& rDataVec ); diff --git a/sc/source/ui/inc/csvruler.hxx b/sc/source/ui/inc/csvruler.hxx index 5ddeb1f1ceba..52be4b4ebd8c 100644 --- a/sc/source/ui/inc/csvruler.hxx +++ b/sc/source/ui/inc/csvruler.hxx @@ -68,6 +68,7 @@ private: // ------------------------------------------------------------------------ public: explicit ScCsvRuler( ScCsvControl& rParent ); + ~ScCsvRuler(); // common ruler handling -------------------------------------------------- public: diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx index 87df03b8ecd9..baadae0a64dc 100644 --- a/sc/source/ui/inc/dbfunc.hxx +++ b/sc/source/ui/inc/dbfunc.hxx @@ -53,7 +53,7 @@ private: public: ScDBFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ); //UNUSED2008-05 ScDBFunc( Window* pParent, const ScDBFunc& rDBFunc, ScTabViewShell* pViewShell ); - ~ScDBFunc(); + virtual ~ScDBFunc(); // nur UISort wiederholt bei Bedarf die Teilergebnisse @@ -77,7 +77,7 @@ public: void GotoDBArea( const String& rDBName ); // DB-Bereich vom Cursor - ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE, bool bShrinkToData = false ); + ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE, ScGetDBSelection eSel = SC_DBSEL_KEEP ); void NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList ); @@ -86,8 +86,10 @@ public: bool MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable, const ScDPObject& rSource, BOOL bApi = FALSE ); void DeletePivotTable(); - void RecalcPivotTable(); - + // Wang Xu Ming -- 2009-6-17 + // DataPilot Migration + ULONG RecalcPivotTable(); + // End Comments BOOL HasSelectionForDateGroup( ScDPNumGroupInfo& rOldInfo, sal_Int32& rParts ); BOOL HasSelectionForNumGroup( ScDPNumGroupInfo& rOldInfo ); void GroupDataPilot(); diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index da5e5e7ffbff..09d34c661995 100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -31,10 +31,8 @@ #include <sfx2/objsh.hxx> -//REMOVE #ifndef _SFX_INTERNO_HXX //autogen -//REMOVE #include <sfx2/interno.hxx> -//REMOVE #endif #include <sfx2/docfac.hxx> +#include <sfx2/sfxmodelfactory.hxx> #include <sfx2/viewsh.hxx> #include "scdllapi.h" @@ -179,7 +177,7 @@ public: SFX_DECL_OBJECTFACTORY(); ScDocShell( const ScDocShell& rDocShell ); - ScDocShell( SfxObjectCreateMode eMode = SFX_CREATE_MODE_EMBEDDED, const bool _bScriptSupport = true ); + ScDocShell( const sal_uInt64 i_nSfxCreationFlags = SFXMODEL_EMBEDDED_OBJECT ); ~ScDocShell(); using SotObject::GetInterface; @@ -315,7 +313,7 @@ public: BOOL IsOle(); void DBAreaDeleted( SCTAB nTab, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 ); - ScDBData* GetDBData( const ScRange& rMarked, ScGetDBMode eMode, BOOL bForceMark ); + ScDBData* GetDBData( const ScRange& rMarked, ScGetDBMode eMode, ScGetDBSelection eSel ); ScDBData* GetOldAutoDBRange(); // has to be deleted by caller! void CancelAutoDBRange(); // called when dialog is cancelled @@ -399,6 +397,7 @@ public: static ScDocShell* GetShellByNum( USHORT nDocNo ); static String GetOwnFilterName(); + static String GetHtmlFilterName(); static String GetWebQueryFilterName(); static String GetAsciiFilterName(); static String GetLotusFilterName(); diff --git a/sc/source/ui/inc/fieldwnd.hxx b/sc/source/ui/inc/fieldwnd.hxx index 45a573e72157..539dbe54e275 100644..100755 --- a/sc/source/ui/inc/fieldwnd.hxx +++ b/sc/source/ui/inc/fieldwnd.hxx @@ -34,7 +34,6 @@ #include <vcl/fixed.hxx> #include <cppuhelper/weakref.hxx> -#define MAX_LABELS 256 #define PAGE_SIZE 16 // count of visible fields for scrollbar #define LINE_SIZE 8 // count of fields per column for scrollbar #define MAX_FIELDS 8 // maximum count of fields for row/col/data area diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 0f8e479f6e54..149498a8314d 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -273,7 +273,7 @@ private: void PasteSelection( const Point& rPosPixel ); - void SelectForContextMenu( const Point& rPosPixel ); + void SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY ); void GetSelectionRects( ::std::vector< Rectangle >& rPixelRects ); diff --git a/sc/source/ui/inc/hdrcont.hxx b/sc/source/ui/inc/hdrcont.hxx index 02a4df09afd2..ec4dd49705d1 100644 --- a/sc/source/ui/inc/hdrcont.hxx +++ b/sc/source/ui/inc/hdrcont.hxx @@ -77,7 +77,7 @@ private: long GetScrPos( SCCOLROW nEntryNo ); SCCOLROW GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder ); - + bool IsSelectionAllowed(SCCOLROW nPos) const; void ShowDragHelp(); void DoPaint( SCCOLROW nStart, SCCOLROW nEnd ); diff --git a/sc/source/ui/inc/impex.hxx b/sc/source/ui/inc/impex.hxx index fe4177df7cae..86a91216edcc 100644 --- a/sc/source/ui/inc/impex.hxx +++ b/sc/source/ui/inc/impex.hxx @@ -107,7 +107,7 @@ public: static BOOL IsFormatSupported( ULONG nFormat ); static const sal_Unicode* ScanNextFieldFromString( const sal_Unicode* p, - String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, BOOL bMergeSeps ); + String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted ); static void WriteUnicodeOrByteString( SvStream& rStrm, const String& rString, BOOL bZero = FALSE ); static void WriteUnicodeOrByteEndl( SvStream& rStrm ); static inline BOOL IsEndianSwap( const SvStream& rStrm ); diff --git a/sc/source/ui/inc/scuiasciiopt.hxx b/sc/source/ui/inc/scuiasciiopt.hxx index a1f73458c3a0..3e1a7db38fb2 100644 --- a/sc/source/ui/inc/scuiasciiopt.hxx +++ b/sc/source/ui/inc/scuiasciiopt.hxx @@ -32,6 +32,8 @@ #include "asciiopt.hxx" +#include "svx/langbox.hxx" + // ============================================================================ class ScImportAsciiDlg : public ModalDialog @@ -46,6 +48,8 @@ class ScImportAsciiDlg : public ModalDialog FixedLine aFlFieldOpt; FixedText aFtCharSet; SvxTextEncodingBox aLbCharSet; + FixedText aFtCustomLang; + SvxLanguageBox aLbCustomLang; FixedText aFtRow; NumericField aNfRow; @@ -61,9 +65,15 @@ class ScImportAsciiDlg : public ModalDialog CheckBox aCkbOther; Edit aEdOther; CheckBox aCkbAsOnce; + + FixedLine aFlOtherOpt; + FixedText aFtTextSep; ComboBox aCbTextSep; + CheckBox aCkbQuotedAsText; + CheckBox aCkbDetectNumber; + FixedLine aFlWidth; FixedText aFtType; ListBox aLbType; @@ -84,6 +94,7 @@ class ScImportAsciiDlg : public ModalDialog CharSet meCharSet; /// Selected char set. bool mbCharSetSystem; /// Is System char set selected? + bool mbFileImport; /// Is this dialog involked for csv file import ? public: ScImportAsciiDlg( @@ -93,6 +104,7 @@ public: void GetOptions( ScAsciiOptions& rOpt ); void SetTextToColumnsMode(); + void SaveParameters(); private: /** Sets the selected char set data to meCharSet and mbCharSetSystem. */ diff --git a/sc/inc/eetext.hxx b/sc/source/ui/inc/textimportoptions.hrc index 28ee0d5f09b2..93c554ef5c45 100644 --- a/sc/inc/eetext.hxx +++ b/sc/source/ui/inc/textimportoptions.hrc @@ -2,10 +2,13 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * + * $RCSfile: retypepassdlg.src,v $ + * $Revision: 1.1.2.3 $ + * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -25,9 +28,15 @@ * ************************************************************************/ -#ifndef SC_EETEXT_HXX -#define SC_EETEXT_HXX - -#endif +#include <sc.hrc> +#define BTN_OK 1 +#define BTN_CANCEL 2 +#define BTN_HELP 3 +#define FL_CHOOSE_LANG 4 +#define RB_AUTOMATIC 5 +#define RB_CUSTOM 6 +#define LB_CUSTOM_LANG 7 +#define FL_OPTION 8 +#define BTN_CONVERT_DATE 9 diff --git a/sc/source/ui/inc/textimportoptions.hxx b/sc/source/ui/inc/textimportoptions.hxx new file mode 100644 index 000000000000..bbb2bf6ebf09 --- /dev/null +++ b/sc/source/ui/inc/textimportoptions.hxx @@ -0,0 +1,76 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: langbox.hxx,v $ + * $Revision: 1.4.242.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_UI_IMPORTOPTIONS_HXX +#define SC_UI_IMPORTOPTIONS_HXX + +#include "vcl/dialog.hxx" +#include "vcl/button.hxx" +#include "vcl/fixed.hxx" +#include "i18npool/lang.h" +#include "svx/langbox.hxx" + +class ScTextImportOptionsDlg : public ModalDialog +{ +public: + ScTextImportOptionsDlg(Window* pParent); + virtual ~ScTextImportOptionsDlg(); + + virtual short Execute(); + + LanguageType getLanguageType() const; + bool isDateConversionSet() const; + +private: + void init(); + +private: + OKButton maBtnOk; + CancelButton maBtnCancel; + HelpButton maBtnHelp; + + FixedLine maFlChooseLang; + + RadioButton maRbAutomatic; + RadioButton maRbCustom; + + SvxLanguageBox maLbCustomLang; + + FixedLine maFlOption; + + CheckBox maBtnConvertDate; + + DECL_LINK( OKHdl, OKButton* ); + + DECL_LINK( RadioHdl, RadioButton* ); +}; + + +#endif diff --git a/sc/source/ui/inc/ui_pch.hxx b/sc/source/ui/inc/ui_pch.hxx index ba0cd9dbd3ce..1ef2f02d405b 100644 --- a/sc/source/ui/inc/ui_pch.hxx +++ b/sc/source/ui/inc/ui_pch.hxx @@ -171,7 +171,6 @@ #include <svl/inethist.hxx> #include <svl/inetdef.hxx> #include <sfx2/sfxdefs.hxx> -#include <svl/cancel.hxx> #include <svtools/compat.hxx> #include <svl/inetmsg.hxx> #include <sfx2/app.hxx> diff --git a/sc/source/ui/miscdlgs/anyrefdg.cxx b/sc/source/ui/miscdlgs/anyrefdg.cxx index 30e34def4620..32b3376da9a7 100644 --- a/sc/source/ui/miscdlgs/anyrefdg.cxx +++ b/sc/source/ui/miscdlgs/anyrefdg.cxx @@ -39,7 +39,6 @@ #include <vcl/mnemonic.hxx> #include <tools/shl.hxx> #include <svtools/taskbar.hxx> -#include <sfx2/topfrm.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> @@ -103,7 +102,7 @@ void ScFormulaReferenceHelper::enableInput( BOOL bEnable ) while( pFrame ) { // #71577# enable everything except InPlace, including bean frames - if ( !pFrame->GetFrame()->IsInPlace() ) + if ( !pFrame->GetFrame().IsInPlace() ) { SfxViewShell* p = pFrame->GetViewShell(); ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); @@ -602,7 +601,7 @@ void ScFormulaReferenceHelper::EnableSpreadsheets(BOOL bFlag, BOOL bChilds) while( pFrame ) { // #71577# enable everything except InPlace, including bean frames - if ( !pFrame->GetFrame()->IsInPlace() ) + if ( !pFrame->GetFrame().IsInPlace() ) { SfxViewShell* p = pFrame->GetViewShell(); ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); @@ -642,7 +641,7 @@ void lcl_InvalidateWindows() while( pFrame ) { // #71577# enable everything except InPlace, including bean frames - if ( !pFrame->GetFrame()->IsInPlace() ) + if ( !pFrame->GetFrame().IsInPlace() ) { SfxViewShell* p = pFrame->GetViewShell(); ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); diff --git a/sc/source/ui/miscdlgs/autofmt.cxx b/sc/source/ui/miscdlgs/autofmt.cxx index 78e5ea066c7d..940856775c07 100644 --- a/sc/source/ui/miscdlgs/autofmt.cxx +++ b/sc/source/ui/miscdlgs/autofmt.cxx @@ -44,10 +44,10 @@ #include <editeng/shdditem.hxx> #include <editeng/udlnitem.hxx> #include <editeng/wghtitem.hxx> -#include <sfx2/topfrm.hxx> #include <vcl/svapp.hxx> #include <svl/zforlist.hxx> #include <vcl/msgbox.hxx> +#include <sfx2/viewfrm.hxx> #include <comphelper/processfactory.hxx> #include "sc.hrc" diff --git a/sc/source/ui/miscdlgs/scuiautofmt.cxx b/sc/source/ui/miscdlgs/scuiautofmt.cxx index 79d7c502921f..b2f837db4cb4 100644 --- a/sc/source/ui/miscdlgs/scuiautofmt.cxx +++ b/sc/source/ui/miscdlgs/scuiautofmt.cxx @@ -369,7 +369,7 @@ IMPL_LINK( ScAutoFormatDlg, RenameHdl, void *, EMPTYARG ) aStrRename, aStrLabel, aFormatName, - HID_SC_RENAME_AUTOFMT ); + HID_SC_REN_AFMT_DLG ); if( pDlg->Execute() == RET_OK ) { BOOL bFmtRenamed = FALSE; diff --git a/sc/source/ui/miscdlgs/strindlg.cxx b/sc/source/ui/miscdlgs/strindlg.cxx index aa6db3075b64..b8dc2e13538e 100644 --- a/sc/source/ui/miscdlgs/strindlg.cxx +++ b/sc/source/ui/miscdlgs/strindlg.cxx @@ -72,25 +72,21 @@ ScStringInputDlg::ScStringInputDlg( Window* pParent, // HelpId for Edit different for different uses - DBG_ASSERT( nHelpId == FID_TAB_APPEND || nHelpId == FID_TAB_RENAME || - nHelpId == HID_SC_ADD_AUTOFMT || nHelpId == HID_SC_RENAME_AUTOFMT || - nHelpId == SID_RENAME_OBJECT || - // #i68101# - nHelpId == SID_TITLE_DESCRIPTION_OBJECT, - "unknown ID" ); if ( nHelpId == FID_TAB_APPEND ) aEdInput.SetHelpId( HID_SC_APPEND_NAME ); else if ( nHelpId == FID_TAB_RENAME ) aEdInput.SetHelpId( HID_SC_RENAME_NAME ); else if ( nHelpId == HID_SC_ADD_AUTOFMT ) aEdInput.SetHelpId( HID_SC_AUTOFMT_NAME ); - else if ( nHelpId == HID_SC_RENAME_AUTOFMT ) + else if ( nHelpId == HID_SC_REN_AFMT_DLG ) aEdInput.SetHelpId( HID_SC_REN_AFMT_NAME ); else if ( nHelpId == SID_RENAME_OBJECT ) aEdInput.SetHelpId( HID_SC_RENAME_OBJECT ); // #i68101# else if ( nHelpId == SID_TITLE_DESCRIPTION_OBJECT ) aEdInput.SetHelpId( HID_SC_TITLE_DESCRIPTION_OBJECT ); + else + DBG_ERRORFILE( "unknown ID" ); //------------- FreeResource(); diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src index edb2165daf32..1cc66ca13af6 100644 --- a/sc/source/ui/src/globstr.src +++ b/sc/source/ui/src/globstr.src @@ -1021,7 +1021,7 @@ Resource RID_GLOBSTR }; String STR_QUERY_DELTAB { - Text [ en-US ] = "Are you sure you want to permanently delete the current sheet(s)?" ; + Text [ en-US ] = "Are you sure you want to delete the selected sheet(s)?" ; }; String STR_QUERY_DELSCENARIO { @@ -1722,5 +1722,17 @@ Resource RID_GLOBSTR { Text [ en-US ] = "Page Styles"; }; + String STR_ERR_DATAPILOTSOURCE + { + Text [ en-US ] = "DataPilot source data is invalid."; + }; + String STR_PIVOT_FIRSTROWEMPTYERR + { + Text [ en-US ] = "The field name cannot be empty. Check the first row of data source to make sure there are no empty cells." ; + }; + String STR_PIVOT_ONLYONEROWERR + { + Text [ en-US ] = "DataPilot table needs at least two rows of data to create or refresh." ; + }; }; diff --git a/sc/source/ui/src/miscdlgs.src b/sc/source/ui/src/miscdlgs.src index d4aa01d436ce..8c9279a602c1 100644 --- a/sc/source/ui/src/miscdlgs.src +++ b/sc/source/ui/src/miscdlgs.src @@ -233,7 +233,7 @@ ModalDialog RID_SCDLG_DELCONT { Pos = MAP_APPFONT ( 12 , 86 ) ; Size = MAP_APPFONT ( 83 , 10 ) ; - Text [ en-US ] = "Not~es" ; + Text [ en-US ] = "~Comments" ; TabStop = TRUE ; }; CheckBox BTN_DELOBJECTS @@ -326,14 +326,14 @@ ModalDialog RID_SCDLG_INSCONT { Pos = MAP_APPFONT ( 12 , 114 ) ; Size = MAP_APPFONT ( 84 , 10 ) ; - Text [ en-US ] = "O~bjects" ; + Text [ en-US ] = "~Objects" ; TabStop = TRUE ; }; CheckBox BTN_INSNOTES { Pos = MAP_APPFONT ( 12 , 86 ) ; Size = MAP_APPFONT ( 84 , 10 ) ; - Text [ en-US ] = "N~otes" ; + Text [ en-US ] = "~Comments" ; TabStop = TRUE ; }; FixedLine FL_FRAME @@ -358,7 +358,7 @@ ModalDialog RID_SCDLG_INSCONT { Pos = MAP_APPFONT ( 111 , 44 ) ; Size = MAP_APPFONT ( 83 , 10 ) ; - Text [ en-US ] = "S~ubtract" ; + Text [ en-US ] = "~Subtract" ; }; RadioButton BTN_OP_MUL { diff --git a/sc/source/ui/undo/makefile.mk b/sc/source/ui/undo/makefile.mk index 168130c022ea..01edd92f8553 100644 --- a/sc/source/ui/undo/makefile.mk +++ b/sc/source/ui/undo/makefile.mk @@ -74,6 +74,8 @@ SLOFILES = \ $(SLO)$/undotab.obj EXCEPTIONSFILES= \ + $(SLO)$/undoblk3.obj \ + $(SLO)$/undocell.obj \ $(SLO)$/undostyl.obj # --- Tagets ------------------------------------------------------- diff --git a/sc/source/ui/undo/undodat.cxx b/sc/source/ui/undo/undodat.cxx index 2ed65d5db6f5..d550d54f1aea 100644 --- a/sc/source/ui/undo/undodat.cxx +++ b/sc/source/ui/undo/undodat.cxx @@ -50,6 +50,7 @@ #include "olinefun.hxx" #include "dpobject.hxx" #include "attrib.hxx" +#include "hints.hxx" #include "sc.hrc" // ----------------------------------------------------------------------- @@ -1902,6 +1903,12 @@ void __EXPORT ScUndoDataPilot::Undo() //! set current sheet } + if (pNewDPObject) + { + // notify API objects + pDoc->BroadcastUno( ScDataPilotModifiedHint( pNewDPObject->GetName() ) ); + } + EndUndo(); } diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index fb7625f4cd0b..ad100dba707c 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -5517,7 +5517,7 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createSortDescripto if ( pDocSh ) { // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich - ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, TRUE ); + ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK ); if (pData) { pData->GetSortParam(aParam); @@ -5548,7 +5548,7 @@ void SAL_CALL ScCellRangeObj::sort( const uno::Sequence<beans::PropertyValue>& a { USHORT i; ScSortParam aParam; - ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_MAKE, TRUE ); // ggf. Bereich anlegen + ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen if (pData) { // alten Einstellungen holen, falls nicht alles neu gesetzt wird @@ -5577,7 +5577,7 @@ void SAL_CALL ScCellRangeObj::sort( const uno::Sequence<beans::PropertyValue>& a aParam.nCol2 = aRange.aEnd.Col(); aParam.nRow2 = aRange.aEnd.Row(); - pDocSh->GetDBData( aRange, SC_DB_MAKE, TRUE ); // ggf. Bereich anlegen + pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen ScDBDocFunc aFunc(*pDocSh); // Bereich muss angelegt sein aFunc.Sort( nTab, aParam, TRUE, TRUE, TRUE ); @@ -5595,7 +5595,7 @@ uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFil if ( !bEmpty && pDocSh ) { // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich - ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, TRUE ); + ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK ); if (pData) { ScQueryParam aParam; @@ -5677,7 +5677,7 @@ void SAL_CALL ScCellRangeObj::filter( const uno::Reference<sheet::XSheetFilterDe aParam.nCol2 = aRange.aEnd.Col(); aParam.nRow2 = aRange.aEnd.Row(); - pDocSh->GetDBData( aRange, SC_DB_MAKE, TRUE ); // ggf. Bereich anlegen + pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen //! keep source range in filter descriptor //! if created by createFilterDescriptorByObject ??? @@ -5764,7 +5764,7 @@ uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL ScCellRangeObj::createSubTot if ( !bEmpty && pDocSh ) { // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich - ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, TRUE ); + ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK ); if (pData) { ScSubTotalParam aParam; @@ -5827,7 +5827,7 @@ void SAL_CALL ScCellRangeObj::applySubTotals( aParam.nCol2 = aRange.aEnd.Col(); aParam.nRow2 = aRange.aEnd.Row(); - pDocSh->GetDBData( aRange, SC_DB_MAKE, TRUE ); // ggf. Bereich anlegen + pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen ScDBDocFunc aFunc(*pDocSh); aFunc.DoSubTotals( nTab, aParam, NULL, TRUE, TRUE ); // Bereich muss angelegt sein @@ -5842,7 +5842,7 @@ void SAL_CALL ScCellRangeObj::removeSubTotals() throw(uno::RuntimeException) if (pDocSh) { ScSubTotalParam aParam; - ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, TRUE ); + ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK ); if (pData) pData->GetSubTotalParam(aParam); // auch bei Remove die Feld-Eintraege behalten @@ -5854,7 +5854,7 @@ void SAL_CALL ScCellRangeObj::removeSubTotals() throw(uno::RuntimeException) aParam.nCol2 = aRange.aEnd.Col(); aParam.nRow2 = aRange.aEnd.Row(); - pDocSh->GetDBData( aRange, SC_DB_MAKE, TRUE ); // ggf. Bereich anlegen + pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen ScDBDocFunc aFunc(*pDocSh); aFunc.DoSubTotals( nTab, aParam, NULL, TRUE, TRUE ); // Bereich muss angelegt sein @@ -5870,7 +5870,7 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createImportDescrip if ( !bEmpty && pDocSh ) { // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich - ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, TRUE ); + ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK ); if (pData) pData->GetImportParam(aParam); } @@ -5899,7 +5899,7 @@ void SAL_CALL ScCellRangeObj::doImport( const uno::Sequence<beans::PropertyValue //! TODO: could we get passed a valid result set by any means? uno::Reference< sdbc::XResultSet > xResultSet; - pDocSh->GetDBData( aRange, SC_DB_MAKE, TRUE ); // ggf. Bereich anlegen + 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, TRUE, FALSE ); //! Api-Flag als Parameter diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx index b8a751669e6f..8654de8a429e 100644 --- a/sc/source/ui/unoobj/chart2uno.cxx +++ b/sc/source/ui/unoobj/chart2uno.cxx @@ -118,61 +118,6 @@ template< typename T > return aResult; } -::std::vector< ::rtl::OUString > lcl_getRangeRepresentationsFromDataSource( - const uno::Reference< chart2::data::XDataSource > & xDataSource ) -{ - ::std::vector< ::rtl::OUString > aResult; - if( xDataSource.is()) - { - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences( - xDataSource->getDataSequences()); - const sal_Int32 nCount( aSequences.getLength()); - for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx ) - { - if( aSequences[nIdx].is() ) - { - // first: label - uno::Reference< chart2::data::XDataSequence > xSeq( aSequences[nIdx]->getLabel()); - if( xSeq.is()) - aResult.push_back( xSeq->getSourceRangeRepresentation()); - // then: values - xSeq.set( aSequences[nIdx]->getValues()); - if( xSeq.is()) - aResult.push_back( xSeq->getSourceRangeRepresentation()); - } - } - } - return aResult; -} - -uno::Reference< chart2::data::XLabeledDataSequence > lcl_getCategoriesFromDataSource( - const uno::Reference< chart2::data::XDataSource > & xDataSource ) -{ - uno::Reference< chart2::data::XLabeledDataSequence > xResult; - if( xDataSource.is()) - { - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences( - xDataSource->getDataSequences()); - const sal_Int32 nCount( aSequences.getLength()); - for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx ) - { - if( aSequences[nIdx].is() ) - { - uno::Reference< beans::XPropertySet > xSeqProp( aSequences[nIdx]->getValues(), uno::UNO_QUERY ); - ::rtl::OUString aRole; - if( xSeqProp.is() && - (xSeqProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Role"))) >>= aRole) && - aRole.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("categories")) ) - { - xResult.set( aSequences[nIdx] ); - break; - } - } - } - } - return xResult; -} - struct lcl_appendTableNumber : public ::std::unary_function< SCTAB, void > { lcl_appendTableNumber( ::rtl::OUStringBuffer & rBuffer ) : @@ -214,173 +159,290 @@ uno::Reference< sheet::XSpreadsheetDocument > lcl_GetSpreadSheetDocument( ScDocu // ============================================================================ -class Chart2PositionMap +namespace { + +struct DeleteInstance : public unary_function<FormulaToken*, void> { -public: - Chart2PositionMap(SCCOL nColCount, SCROW nRowCount, - bool bColAdd, bool bRowAdd, Table& rCols); - ~Chart2PositionMap(); + void operator() (FormulaToken* p) const + { + delete p; + } +}; - SCCOL getColCount() const { return static_cast<SCCOL>(maColHeaders.size()); } - SCROW getRowCount() const { return static_cast<SCROW>(maRowHeaders.size()); } +} - const FormulaToken* getColHeaderPosition(SCCOL nChartCol) const; - const FormulaToken* getRowHeaderPosition(SCROW nChartRow) const; +struct TokenTable +{ + SCROW mnRowCount; + SCCOL mnColCount; + vector<FormulaToken*> maTokens; - vector<ScSharedTokenRef>* getColRanges(SCCOL nCol) const; - vector<ScSharedTokenRef>* getRowRanges(SCROW nRow) const; + void init( SCCOL nColCount, SCROW nRowCount ) + { + mnColCount = nColCount; + mnRowCount = nRowCount; + maTokens.reserve(mnColCount*mnRowCount); + } + void clear() + { + for_each(maTokens.begin(), maTokens.end(), DeleteInstance()); + } + void push_back( FormulaToken* pToken ) + { + maTokens.push_back( pToken ); + DBG_ASSERT( maTokens.size()<= static_cast<sal_uInt32>( mnColCount*mnRowCount ), "too much tokens" ); + } -private: sal_uInt32 getIndex(SCCOL nCol, SCROW nRow) const { - return static_cast<sal_uInt32>(nCol*getRowCount() + nRow); + DBG_ASSERT( nCol<mnColCount, "wrong column index" ); + DBG_ASSERT( nRow<mnRowCount, "wrong row index" ); + sal_uInt32 nRet = static_cast<sal_uInt32>(nCol*mnRowCount + nRow); + DBG_ASSERT( maTokens.size()>= static_cast<sal_uInt32>( mnColCount*mnRowCount ), "too few tokens" ); + return nRet; } -private: - vector<FormulaToken*> maRowHeaders; - vector<FormulaToken*> maColHeaders; - vector<FormulaToken*> maData; + vector<ScSharedTokenRef>* getColRanges(SCCOL nCol) const; + vector<ScSharedTokenRef>* getRowRanges(SCROW nRow) const; + vector<ScSharedTokenRef>* getAllRanges() const; }; -Chart2PositionMap::Chart2PositionMap(SCCOL nColCount, SCROW nRowCount, - bool bColAdd, bool bRowAdd, Table& rCols) +vector<ScSharedTokenRef>* TokenTable::getColRanges(SCCOL nCol) const { - // bColAdd is true when the first column serves as a row header. Likewise, - // when bRowAdd is true the first row serves as a column header. + if (nCol >= mnColCount) + return NULL; + if( mnRowCount<=0 ) + return NULL; - maColHeaders.reserve(nColCount); - maRowHeaders.reserve(nRowCount); - maData.reserve(nColCount*nRowCount); + auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>); + sal_uInt32 nLast = getIndex(nCol, mnRowCount-1); + for (sal_uInt32 i = getIndex(nCol, 0); i <= nLast; ++i) + { + FormulaToken* p = maTokens[i]; + if (!p) + continue; - Table* pCol = static_cast<Table*>(rCols.First()); - FormulaToken* pPos = static_cast<FormulaToken*>(pCol->First()); + ScSharedTokenRef pCopy(static_cast<ScToken*>(p->Clone())); + ScRefTokenHelper::join(*pTokens, pCopy); + } + return pTokens.release(); +} - if (bRowAdd) - pPos = static_cast<FormulaToken*>(pCol->Next()); +vector<ScSharedTokenRef>* TokenTable::getRowRanges(SCROW nRow) const +{ + if (nRow >= mnRowCount) + return NULL; + if( mnColCount<=0 ) + return NULL; - if (bColAdd) + auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>); + sal_uInt32 nLast = getIndex(mnColCount-1, nRow); + for (sal_uInt32 i = getIndex(0, nRow); i <= nLast; i += mnRowCount) { - // 1st column as a row header. - for (SCROW nRow = 0; nRow < nRowCount; ++nRow) - { - maRowHeaders.push_back(pPos); - pPos = static_cast<FormulaToken*>(pCol->Next()); - } - pCol = static_cast<Table*>(rCols.Next()); // move to the next column. + FormulaToken* p = maTokens[i]; + if (!p) + continue; + + ScSharedTokenRef p2(static_cast<ScToken*>(p->Clone())); + ScRefTokenHelper::join(*pTokens, p2); } - else + return pTokens.release(); +} + +vector<ScSharedTokenRef>* TokenTable::getAllRanges() const +{ + auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>); + sal_uInt32 nStop = mnColCount*mnRowCount; + for (sal_uInt32 i = 0; i < nStop; i++) { - for (SCROW nRow = 0; nRow < nRowCount; ++nRow) - { - // Make a copy. - maRowHeaders.push_back(pPos ? pPos->Clone() : NULL); - pPos = static_cast<FormulaToken*>(pCol->Next()); - } + FormulaToken* p = maTokens[i]; + if (!p) + continue; + + ScSharedTokenRef p2(static_cast<ScToken*>(p->Clone())); + ScRefTokenHelper::join(*pTokens, p2); } + return pTokens.release(); +} + +// ============================================================================ + +class Chart2PositionMap +{ +public: + Chart2PositionMap(SCCOL nColCount, SCROW nRowCount, + bool bFillRowHeader, bool bFillColumnHeader, Table& rCols, + ScDocument* pDoc ); + ~Chart2PositionMap(); + + SCCOL getDataColCount() const { return mnDataColCount; } + SCROW getDataRowCount() const { return mnDataRowCount; } + + vector<ScSharedTokenRef>* getLeftUpperCornerRanges() const; + vector<ScSharedTokenRef>* getAllColHeaderRanges() const; + vector<ScSharedTokenRef>* getAllRowHeaderRanges() const; + + vector<ScSharedTokenRef>* getColHeaderRanges(SCCOL nChartCol) const; + vector<ScSharedTokenRef>* getRowHeaderRanges(SCROW nChartRow) const; + + vector<ScSharedTokenRef>* getDataColRanges(SCCOL nCol) const; + vector<ScSharedTokenRef>* getDataRowRanges(SCROW nRow) const; - // Data in columns and in column headers. - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) +private: + SCCOL mnDataColCount; + SCROW mnDataRowCount; + + TokenTable maLeftUpperCorner; //nHeaderColCount*nHeaderRowCount + TokenTable maColHeaders; //mnDataColCount*nHeaderRowCount + TokenTable maRowHeaders; //nHeaderColCount*mnDataRowCount + TokenTable maData;//mnDataColCount*mnDataRowCount +}; + +Chart2PositionMap::Chart2PositionMap(SCCOL nAllColCount, SCROW nAllRowCount, + bool bFillRowHeader, bool bFillColumnHeader, Table& rCols, ScDocument* pDoc) +{ + // if bFillRowHeader is true, at least the first column serves as a row header. + // If more than one column is pure text all the first pure text columns are used as header. + // Likewise, if bFillColumnHeader is true, at least the first row serves as a column header. + // If more than one row is pure text all the first pure text rows are used as header. + + SCROW nHeaderRowCount = (bFillColumnHeader && nAllColCount && nAllRowCount) ? 1 : 0; + SCCOL nHeaderColCount = (bFillRowHeader && nAllColCount && nAllRowCount) ? 1 : 0; + + if( nHeaderColCount || nHeaderRowCount ) { - if (pCol) + const SCCOL nInitialHeaderColCount = nHeaderColCount; + //check whether there is more than one text column or row that should be added to the headers + SCROW nSmallestValueRowIndex = nAllRowCount; + bool bFoundValues = false; + bool bFoundAnything = false; + Table* pCol = static_cast<Table*>(rCols.First()); + for (SCCOL nCol = 0; !bFoundValues && nCol < nAllColCount; ++nCol) { - pPos = static_cast<FormulaToken*>(pCol->First()); - if (bRowAdd) - { - // 1st row as a column header. - maColHeaders.push_back(pPos); - pPos = static_cast<FormulaToken*>(pCol->Next()); - } - else - // Duplicate the 1st cell as a column header. - maColHeaders.push_back(pPos ? pPos->Clone() : NULL); - - for (SCROW nRow = 0; nRow < nRowCount; ++nRow) + if (pCol && nCol>=nHeaderColCount) { - maData.push_back(pPos); - pPos = static_cast<FormulaToken*>(pCol->Next()); + ScToken* pToken = static_cast<ScToken*>(pCol->First()); + for (SCROW nRow = 0; !bFoundValues && nRow < nSmallestValueRowIndex; ++nRow) + { + if (pToken && nRow>=nHeaderRowCount) + { + ScRange aRange; + bool bExternal = false; + StackVar eType = pToken->GetType(); + if( eType==svExternal || eType==svExternalSingleRef || eType==svExternalDoubleRef || eType==svExternalName ) + bExternal = true;//lllll todo correct? + ScSharedTokenRef pSharedToken(static_cast<ScToken*>(pToken->Clone())); + ScRefTokenHelper::getRangeFromToken(aRange, pSharedToken, bExternal ); + SCCOL nCol1=0, nCol2=0; + SCROW nRow1=0, nRow2=0; + SCTAB nTab1=0, nTab2=0; + aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + if (pDoc && pDoc->HasValueData( nCol1, nRow1, nTab1 )) + { + bFoundValues = bFoundAnything = true; + nSmallestValueRowIndex = std::min( nSmallestValueRowIndex, nRow ); + } + if( !bFoundAnything ) + { + if (pDoc && pDoc->HasData( nCol1, nRow1, nTab1 ) ) + bFoundAnything = true; + } + } + pToken = static_cast<ScToken*>(pCol->Next()); + } + if(!bFoundValues && nHeaderColCount>0) + nHeaderColCount++; } + pCol = static_cast<Table*>(rCols.Next()); } - else + if( bFoundAnything ) { - // the entire column is empty. - maColHeaders.push_back(NULL); - for (SCROW nRow = 0; nRow < nRowCount; ++nRow) - maData.push_back(NULL); + if(nHeaderRowCount>0) + { + if( bFoundValues ) + nHeaderRowCount = nSmallestValueRowIndex; + else if( nAllRowCount>1 ) + nHeaderRowCount = nAllRowCount-1; + } } - pCol = static_cast<Table*>(rCols.Next()); + else //if the cells are completely empty, just use single header rows and columns + nHeaderColCount = nInitialHeaderColCount; } -} -namespace { + mnDataColCount = nAllColCount - nHeaderColCount; + mnDataRowCount = nAllRowCount - nHeaderRowCount; -struct DeleteInstance : public unary_function<FormulaToken*, void> -{ - void operator() (FormulaToken* p) const + maLeftUpperCorner.init(nHeaderColCount,nHeaderRowCount); + maColHeaders.init(mnDataColCount,nHeaderRowCount); + maRowHeaders.init(nHeaderColCount,mnDataRowCount); + maData.init(mnDataColCount,mnDataRowCount); + + Table* pCol = static_cast<Table*>(rCols.First()); + FormulaToken* pToken = static_cast<FormulaToken*>(pCol->First()); + for (SCCOL nCol = 0; nCol < nAllColCount; ++nCol) { - delete p; - } -}; + if (pCol) + { + pToken = static_cast<FormulaToken*>(pCol->First()); + for (SCROW nRow = 0; nRow < nAllRowCount; ++nRow) + { + if( nCol < nHeaderColCount ) + { + if( nRow < nHeaderRowCount ) + maLeftUpperCorner.push_back(pToken); + else + maRowHeaders.push_back(pToken); + } + else if( nRow < nHeaderRowCount ) + maColHeaders.push_back(pToken); + else + maData.push_back(pToken); + pToken = static_cast<FormulaToken*>(pCol->Next()); + } + } + pCol = static_cast<Table*>(rCols.Next()); + } } Chart2PositionMap::~Chart2PositionMap() { - for_each(maColHeaders.begin(), maColHeaders.end(), DeleteInstance()); - for_each(maRowHeaders.begin(), maRowHeaders.end(), DeleteInstance()); - for_each(maData.begin(), maData.end(), DeleteInstance()); + maLeftUpperCorner.clear(); + maColHeaders.clear(); + maRowHeaders.clear(); + maData.clear(); } -const FormulaToken* Chart2PositionMap::getColHeaderPosition(SCCOL nCol) const +vector<ScSharedTokenRef>* Chart2PositionMap::getLeftUpperCornerRanges() const { - if (nCol < getColCount()) - return maColHeaders[nCol]; - return NULL; + return maLeftUpperCorner.getAllRanges(); } -const FormulaToken* Chart2PositionMap::getRowHeaderPosition(SCROW nRow) const +vector<ScSharedTokenRef>* Chart2PositionMap::getAllColHeaderRanges() const { - if (nRow < getRowCount()) - return maRowHeaders[nRow]; - return NULL; + return maColHeaders.getAllRanges(); } - -vector<ScSharedTokenRef>* Chart2PositionMap::getColRanges(SCCOL nCol) const +vector<ScSharedTokenRef>* Chart2PositionMap::getAllRowHeaderRanges() const { - if (nCol >= getColCount()) - return NULL; - - auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>); - sal_uInt32 nStop = getIndex(nCol, getRowCount()); - for (sal_uInt32 i = getIndex(nCol, 0); i < nStop; ++i) - { - FormulaToken* p = maData[i]; - if (!p) - continue; - - ScSharedTokenRef pCopy(static_cast<ScToken*>(p->Clone())); - ScRefTokenHelper::join(*pTokens, pCopy); - } - return pTokens.release(); + return maRowHeaders.getAllRanges(); } - -vector<ScSharedTokenRef>* Chart2PositionMap::getRowRanges(SCROW nRow) const +vector<ScSharedTokenRef>* Chart2PositionMap::getColHeaderRanges(SCCOL nCol) const { - SCROW nRowCount = getRowCount(); - if (nRow >= nRowCount) - return NULL; + return maColHeaders.getColRanges( nCol); +} +vector<ScSharedTokenRef>* Chart2PositionMap::getRowHeaderRanges(SCROW nRow) const +{ + return maRowHeaders.getRowRanges( nRow); +} - auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>); - sal_uInt32 nStop = getIndex(getColCount(), nRow); - for (sal_uInt32 i = getIndex(0, nRow); i < nStop; i += nRowCount) - { - FormulaToken* p = maData[i]; - if (!p) - continue; +vector<ScSharedTokenRef>* Chart2PositionMap::getDataColRanges(SCCOL nCol) const +{ + return maData.getColRanges( nCol); +} - ScSharedTokenRef p2(static_cast<ScToken*>(p->Clone())); - ScRefTokenHelper::join(*pTokens, p2); - } - return pTokens.release(); +vector<ScSharedTokenRef>* Chart2PositionMap::getDataRowRanges(SCROW nRow) const +{ + return maData.getRowRanges( nRow); } // ---------------------------------------------------------------------------- @@ -730,55 +792,20 @@ void Chart2Positioner::createPositionMap() pNewAddress.reset(NULL); pNewRowTable.reset(NULL); - bool bColAdd = mbRowHeaders; - bool bRowAdd = mbColHeaders; + bool bFillRowHeader = mbRowHeaders; + bool bFillColumnHeader = mbColHeaders; - SCSIZE nColCount = static_cast<SCSIZE>(pCols->Count()); - SCSIZE nRowCount = 0; + SCSIZE nAllColCount = static_cast<SCSIZE>(pCols->Count()); + SCSIZE nAllRowCount = 0; pCol = static_cast<Table*>(pCols->First()); if (pCol) { if (mbDummyUpperLeft) pCol->Insert(0, NULL); // Dummy fuer Beschriftung - nRowCount = static_cast<SCSIZE>(pCol->Count()); + nAllRowCount = static_cast<SCSIZE>(pCol->Count()); } - else - nRowCount = 0; - if (nColCount > 0 && bColAdd) - nColCount -= 1; - if (nRowCount > 0 && bRowAdd) - nRowCount -= 1; - - if (nColCount == 0 || nRowCount == 0) - { - ScComplexRefData aData; - ScRefTokenHelper::getDoubleRefDataFromToken(aData, mpRefTokens->front()); - if (pCols->Count() > 0) - pCol = static_cast<Table*>(pCols->First()); - else - { - pCol = new Table; - pCols->Insert(0, pCol); - } - nColCount = 1; - if (pCol->Count() > 0) - { - FormulaToken* pPos = static_cast<FormulaToken*>(pCol->First()); - if (pPos) - { - delete pPos; - pCol->Replace(pCol->GetCurKey(), NULL); - } - } - else - pCol->Insert(0, NULL); - - nRowCount = 1; - bColAdd = false; - bRowAdd = false; - } - else + if( nAllColCount!=0 && nAllRowCount!=0 ) { if (bNoGlue) { @@ -796,8 +823,8 @@ void Chart2Positioner::createPositionMap() } mpPositionMap.reset( new Chart2PositionMap( - static_cast<SCCOL>(nColCount), static_cast<SCROW>(nRowCount), - bColAdd, bRowAdd, *pCols)); + static_cast<SCCOL>(nAllColCount), static_cast<SCROW>(nAllRowCount), + bFillRowHeader, bFillColumnHeader, *pCols, mpDoc)); // Destroy all column instances. for (pCol = static_cast<Table*>(pCols->First()); pCol; pCol = static_cast<Table*>(pCols->Next())) @@ -1021,639 +1048,44 @@ void ScChart2DataProvider::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint return !aTokens.empty(); } -namespace { - -class RemoveHeaderFromRanges : public unary_function<ScSharedTokenRef, void> -{ -public: - RemoveHeaderFromRanges(const ScSharedTokenRef& rHeaderCell, bool bOrientCol) : - mpTokens(new vector<ScSharedTokenRef>), - mpHeaderCell(rHeaderCell), - mbOrientCol(bOrientCol) - { - } - - RemoveHeaderFromRanges(const RemoveHeaderFromRanges& r) : - mpTokens(r.mpTokens), - mpHeaderCell(r.mpHeaderCell), - mbOrientCol(r.mbOrientCol) - { - } - - void operator() (const ScSharedTokenRef& pRange) - { - if (!isContained(pRange)) - { - // header cell is not part of this range. Just add it to the - // range list and move on. - ScRefTokenHelper::join(*mpTokens, pRange); - return; - } - - // This range contains the header cell. - - ScComplexRefData aRange; - ScRefTokenHelper::getDoubleRefDataFromToken(aRange, pRange); - const ScSingleRefData& s = aRange.Ref1; - const ScSingleRefData& e = aRange.Ref2; - const ScSingleRefData& h = mpHeaderCell->GetSingleRef(); - - if (equals(s, e)) - // This range *only* contains the header cell. Skip it. - return; - - if (s.nTab != e.nTab) - // 3D range has no business being here.... - return; - - if (mbOrientCol) - { - // column major - - if (s.nCol == e.nCol) - { - // single column range. - splitSingleColRange(pRange, s, e); - } - else - { - if (s.nCol == h.nCol) - { - // header cell is in the first column. - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.InitAddress(s.nCol, e.nRow, s.nTab); - splitSingleColRange(pNew, r.Ref1, r.Ref2); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(s.nCol + 1, s.nRow, s.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - } - else if (e.nCol == h.nCol) - { - // header cell is in the last column. - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(e.nCol, s.nRow, s.nTab); - splitSingleColRange(pNew, r.Ref1, r.Ref2); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.InitAddress(e.nCol - 1, e.nRow, e.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - } - else - { - // header cell is somewhere between the first and last columns. - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.InitAddress(h.nCol - 1, e.nRow, h.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(h.nCol, s.nRow, s.nTab); - r.Ref2.InitAddress(h.nCol, e.nRow, e.nTab); - splitSingleColRange(pNew, r.Ref1, r.Ref2); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(h.nCol + 1, s.nRow, h.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - } - } - } - else - { - // row major - - if (s.nRow == e.nRow) - { - // Single row range. - splitSingleRowRange(pRange, s, e); - } - else - { - if (s.nRow == h.nRow) - { - // header cell is in the first row. - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.InitAddress(e.nCol, s.nRow, s.nTab); - splitSingleRowRange(pNew, r.Ref1, r.Ref2); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(s.nCol, s.nRow + 1, s.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - } - else if (e.nRow == h.nRow) - { - // header cell is in the last row. - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(s.nCol, e.nRow, s.nTab); - splitSingleRowRange(pNew, r.Ref1, r.Ref2); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.InitAddress(e.nCol, e.nRow - 1, e.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - } - else - { - // header cell is somewhere between the 1st and last rows. - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.InitAddress(e.nCol, h.nRow - 1, h.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(s.nCol, h.nRow, s.nTab); - r.Ref2.InitAddress(e.nCol, h.nRow, e.nTab); - splitSingleRowRange(pNew, r.Ref1, r.Ref2); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(s.nCol, h.nRow + 1, h.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - } - } - } - } - - void getNewTokens(vector<ScSharedTokenRef>& rTokens) - { - mpTokens->swap(rTokens); - } - -private: - - void splitSingleColRange(const ScSharedTokenRef& pRange, const ScSingleRefData& s, const ScSingleRefData& e) - { - const ScSingleRefData& h = mpHeaderCell->GetSingleRef(); - - if (equals(s, h)) - { - // header is at the top. - - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.nRow += 1; - ScRefTokenHelper::join(*mpTokens, pNew); - } - else if (equals(e, h)) - { - // header is at the bottom. - - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.nRow -= 1; - ScRefTokenHelper::join(*mpTokens, pNew); - } - else - { - // header is somewhere in the middle. - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.InitAddress(h.nCol, h.nRow - 1, h.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(h.nCol, h.nRow + 1, h.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - } - } - - void splitSingleRowRange(const ScSharedTokenRef& pRange, const ScSingleRefData& s, const ScSingleRefData& e) - { - const ScSingleRefData& h = mpHeaderCell->GetSingleRef(); - - if (equals(s, h)) - { - // header is at the top. - - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.nCol += 1; - ScRefTokenHelper::join(*mpTokens, pNew); - } - else if (equals(e, h)) - { - // header is at the bottom. - - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.nCol -= 1; - ScRefTokenHelper::join(*mpTokens, pNew); - } - else - { - // header is somewhere in the middle. - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref2.InitAddress(h.nCol - 1, h.nRow, h.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - - { - ScSharedTokenRef pNew(static_cast<ScToken*>(pRange->Clone())); - ScComplexRefData& r = pNew->GetDoubleRef(); - r.Ref1.InitAddress(h.nCol + 1, h.nRow, h.nTab); - ScRefTokenHelper::join(*mpTokens, pNew); - } - } - } - - /** - * Compare two single ref data for equality, but only compare their - * absolute cell addresses while ignoring flags and relative addresses. - */ - bool equals(const ScSingleRefData& r1, const ScSingleRefData& r2) const - { - return (r1.nCol == r2.nCol) && (r1.nRow == r2.nRow) && (r1.nTab == r2.nTab); - } - - bool isContained(const ScSharedTokenRef& pRange) - { - bool bExternal = ScRefTokenHelper::isExternalRef(mpHeaderCell); - if (bExternal != ScRefTokenHelper::isExternalRef(pRange)) - // internal vs external. - return false; - - if (bExternal) - { - if (pRange->GetIndex() != mpHeaderCell->GetIndex()) - // different external files. - return false; - - if (pRange->GetString() != mpHeaderCell->GetString()) - // different table. - return false; - } - - ScComplexRefData aRange; - ScRefTokenHelper::getDoubleRefDataFromToken(aRange, pRange); - const ScSingleRefData& rCell = mpHeaderCell->GetSingleRef(); - - bool bRowContained = (aRange.Ref1.nRow <= rCell.nRow) && (rCell.nRow <= aRange.Ref2.nRow); - bool bColContained = (aRange.Ref1.nCol <= rCell.nCol) && (rCell.nCol <= aRange.Ref2.nCol); - bool bTabContained = (aRange.Ref1.nTab <= rCell.nTab) && (rCell.nTab <= aRange.Ref2.nTab); - - return (bRowContained && bColContained && bTabContained); - } - -private: - shared_ptr< vector<ScSharedTokenRef> > mpTokens; - - /** - * Stores header cell position. Must be a single ref token i.e. either - * ScSingleRefToken or ScExternalSingleRefToken. - */ - ScSharedTokenRef mpHeaderCell; - - bool mbOrientCol; -}; - -} - -static void lcl_removeHeaderFromRanges(vector<ScSharedTokenRef>& rTokens, const ScSharedTokenRef& rHeaderCell, bool bOrientCol) -{ - RemoveHeaderFromRanges func(rHeaderCell, bOrientCol); - func = for_each(rTokens.begin(), rTokens.end(), func); - func.getNewTokens(rTokens); -} - -uno::Reference< chart2::data::XDataSource> SAL_CALL -ScChart2DataProvider::createDataSource( - const uno::Sequence< beans::PropertyValue >& aArguments ) - throw( lang::IllegalArgumentException, uno::RuntimeException) -{ - ScUnoGuard aGuard; - if ( ! m_pDocument ) - throw uno::RuntimeException(); - - uno::Reference< chart2::data::XDataSource> xResult; - bool bLabel = true; - bool bOrientCol = true; - ::rtl::OUString aRangeRepresentation; - uno::Sequence< sal_Int32 > aSequenceMapping; - for(sal_Int32 i = 0; i < aArguments.getLength(); ++i) - { - rtl::OUString sName(aArguments[i].Name); - if (aArguments[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataRowSource"))) - { - chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS; - if( ! (aArguments[i].Value >>= eSource)) - { - sal_Int32 nSource(0); - if( aArguments[i].Value >>= nSource ) - eSource = (static_cast< chart::ChartDataRowSource >( nSource )); - } - bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS); - } - else if (aArguments[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstCellAsLabel"))) - { - bLabel = ::cppu::any2bool(aArguments[i].Value); - } - else if (aArguments[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation"))) - { - aArguments[i].Value >>= aRangeRepresentation; - } - else if (aArguments[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SequenceMapping"))) - { - aArguments[i].Value >>= aSequenceMapping; - } - } - - vector<ScSharedTokenRef> aRefTokens; - ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar()); - if (aRefTokens.empty()) - // Invalid range representation. Bail out. - throw lang::IllegalArgumentException(); - - if (bLabel) - addUpperLeftCornerIfMissing(aRefTokens); - - bool bColHeaders = (bOrientCol ? bLabel : false ); - bool bRowHeaders = (bOrientCol ? false : bLabel ); - - Chart2Positioner aChPositioner(m_pDocument, aRefTokens); - aChPositioner.setHeaders(bColHeaders, bRowHeaders); - - const Chart2PositionMap* pChartMap = aChPositioner.getPositionMap(); - if (!pChartMap) - // No chart position map instance. Bail out. - return xResult; - - ScChart2DataSource* pDS = NULL; - std::list < ScChart2LabeledDataSequence* > aSeqs; - - // Fill Categories - - ScChart2LabeledDataSequence* pHeader = NULL; - if (bOrientCol ? aChPositioner.hasRowHeaders() : aChPositioner.hasColHeaders()) - { - pHeader = new ScChart2LabeledDataSequence(m_pDocument); - sal_Int32 nCount = static_cast< sal_Int32 >( bOrientCol ? pChartMap->getRowCount() : pChartMap->getColCount() ); - vector<ScSharedTokenRef> aRefTokens2; - ScSharedTokenRef pLabelToken; - for (sal_Int32 i = 0; i < nCount; ++i) - { - const FormulaToken* pPos = bOrientCol ? - pChartMap->getRowHeaderPosition(static_cast<SCROW>(i)) : - pChartMap->getColHeaderPosition(static_cast<SCCOL>(i)); - if (pPos) - { - ScSharedTokenRef p(static_cast<ScToken*>(pPos->Clone())); - ScRefTokenHelper::join(aRefTokens2, p); - if (!pLabelToken) - { - pLabelToken = p; - StackVar eType = pLabelToken->GetType(); - if (eType == svSingleRef || eType == svExternalSingleRef) - { - ScSingleRefData& r = pLabelToken->GetSingleRef(); - if (bOrientCol) - r.nRow -= 1; - else - r.nCol -= 1; - } - } - } - } - if (pLabelToken) - { - if (bLabel) - { - auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>); - pTokens->push_back(pLabelToken); - Reference < chart2::data::XDataSequence > xLabelSeq(new ScChart2DataSequence(m_pDocument, this, pTokens.release(), m_bIncludeHiddenCells)); - Reference< beans::XPropertySet > xLabelProps(xLabelSeq, uno::UNO_QUERY); - if (xLabelProps.is()) - xLabelProps->setPropertyValue( - OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ROLE)), - uno::makeAny(OUString(RTL_CONSTASCII_USTRINGPARAM("label")))); - pHeader->setLabel(xLabelSeq); - } - else - ScRefTokenHelper::join(aRefTokens2, pLabelToken); - } - auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>); - pTokens->swap(aRefTokens2); - uno::Reference< chart2::data::XDataSequence > xSeq( new ScChart2DataSequence( m_pDocument, this, pTokens.release(), m_bIncludeHiddenCells) ); - pHeader->setValues(xSeq); - } - if (pHeader) - aSeqs.push_back(pHeader); - - // Fill Serieses with Labels - - sal_Int32 nCount = bOrientCol ? pChartMap->getColCount() : pChartMap->getRowCount(); - for (sal_Int32 i = 0; i < nCount; ++i) - { - ScChart2LabeledDataSequence* pLabeled = new ScChart2LabeledDataSequence(m_pDocument); - uno::Reference < chart2::data::XDataSequence > xLabelSeq; - auto_ptr< vector<ScSharedTokenRef> > pRanges(NULL); - if (bOrientCol) - pRanges.reset(pChartMap->getColRanges(static_cast<SCCOL>(i))); - else - pRanges.reset(pChartMap->getRowRanges(static_cast<SCROW>(i))); - - ScSharedTokenRef pHeaderCell; - if (bOrientCol) - { - const FormulaToken* p = pChartMap->getColHeaderPosition(static_cast<SCCOL>(i)); - if (p) - pHeaderCell.reset(static_cast<ScToken*>(p->Clone())); - } - else - { - const FormulaToken* p = pChartMap->getRowHeaderPosition(static_cast<SCROW>(i)); - if (p) - pHeaderCell.reset(static_cast<ScToken*>(p->Clone())); - } - - if (bLabel) - { - if (!pHeaderCell && pRanges.get() && !pRanges->empty()) - { - const ScSharedTokenRef& p = pRanges->front(); - if (p && ScRefTokenHelper::isRef(p)) - { - // Take the first cell in the range as the header position. - ScSingleRefData aData = p->GetSingleRef(); - bool bExternal = ScRefTokenHelper::isExternalRef(p); - if (bExternal) - { - sal_uInt16 nFileId = p->GetIndex(); - const String& rTabName = p->GetString(); - pHeaderCell.reset(new ScExternalSingleRefToken(nFileId, rTabName, aData)); - } - else - pHeaderCell.reset(new ScSingleRefToken(aData)); - } - } - if (pHeaderCell) - { - auto_ptr< vector<ScSharedTokenRef> > pTokens(new vector<ScSharedTokenRef>); - pTokens->reserve(1); - pTokens->push_back(pHeaderCell); - xLabelSeq.set(new ScChart2DataSequence(m_pDocument, this, pTokens.release(), m_bIncludeHiddenCells)); - uno::Reference< beans::XPropertySet > xLabelProps(xLabelSeq, uno::UNO_QUERY); - if (xLabelProps.is()) - xLabelProps->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ROLE)), uno::makeAny(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("label")))); - - // remove Header from Ranges - lcl_removeHeaderFromRanges(*pRanges, pHeaderCell, bOrientCol); - } - } - else - { - if (pHeaderCell) - ScRefTokenHelper::join(*pRanges, pHeaderCell); - } - - // FIXME: if there are no labels the column or row name should be taken - - uno::Reference < chart2::data::XDataSequence > xSeq(new ScChart2DataSequence(m_pDocument, this, pRanges.release(), m_bIncludeHiddenCells)); - - pLabeled->setValues(xSeq); - pLabeled->setLabel(xLabelSeq); - - aSeqs.push_back(pLabeled); - } - - pDS = new ScChart2DataSource(m_pDocument); - std::list < ScChart2LabeledDataSequence* >::iterator aItr(aSeqs.begin()); - std::list < ScChart2LabeledDataSequence* >::iterator aEndItr(aSeqs.end()); - - //reorder labeled sequences according to aSequenceMapping - std::vector< ScChart2LabeledDataSequence* > aSeqVector; - while(aItr != aEndItr) - { - aSeqVector.push_back(*aItr); - ++aItr; - } - - std::map< sal_Int32, ScChart2LabeledDataSequence* > aSequenceMap; - for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ ) - { - // note: assuming that the values in the sequence mapping are always non-negative - std::vector< ScChart2LabeledDataSequence* >::size_type nOldIndex( static_cast< sal_uInt32 >( aSequenceMapping[nNewIndex] )); - if( nOldIndex < aSeqVector.size() ) - { - pDS->AddLabeledSequence( aSeqVector[nOldIndex] ); - aSeqVector[nOldIndex] = 0; - } - - } - - std::vector< ScChart2LabeledDataSequence* >::iterator aVectorItr(aSeqVector.begin()); - std::vector< ScChart2LabeledDataSequence* >::iterator aVectorEndItr(aSeqVector.end()); - while(aVectorItr != aVectorEndItr) - { - if(*aVectorItr) - pDS->AddLabeledSequence(*aVectorItr); - ++aVectorItr; - } - - xResult.set( pDS ); - return xResult; -} - namespace { -bool lcl_HasCategories( - const uno::Reference< chart2::data::XDataSource >& xDataSource, - bool & rOutHasCategories ) +ScChart2LabeledDataSequence* lcl_createScChart2DataSequenceFromTokens( auto_ptr< vector<ScSharedTokenRef> > pValueTokens, auto_ptr< vector<ScSharedTokenRef> > pLabelTokens, + ScDocument* pDoc, const uno::Reference < chart2::data::XDataProvider >& xDP, bool bIncludeHiddenCells ) { - bool bResult = false; - uno::Reference< chart2::data::XLabeledDataSequence > xCategories( - lcl_getCategoriesFromDataSource( xDataSource )); - if( xCategories.is()) + ScChart2LabeledDataSequence* pRet = 0; + bool bHasValues = pValueTokens.get() && !pValueTokens->empty(); + bool bHasLabel = pLabelTokens.get() && !pLabelTokens->empty(); + if( bHasValues || bHasLabel ) { - uno::Reference< lang::XServiceInfo > xValues( xCategories->getValues(), uno::UNO_QUERY ); - if (xValues.is()) + pRet = new ScChart2LabeledDataSequence(pDoc); + if(bHasValues) { - rOutHasCategories = xValues->getImplementationName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ScChart2DataSequence")); - bResult = true; + uno::Reference < chart2::data::XDataSequence > xSeq(new ScChart2DataSequence(pDoc, xDP, pValueTokens.release(), bIncludeHiddenCells)); + pRet->setValues(xSeq); } - } - return bResult; -} - -bool lcl_HasFirstCellAsLabel( - const uno::Reference< chart2::data::XDataSource >& xDataSource, - bool & rOutHasFirstCellAsLabel ) -{ - bool bResult = false; - if( xDataSource.is()) - { - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences( - xDataSource->getDataSequences()); - const sal_Int32 nCount( aSequences.getLength()); - if (nCount > 0 && aSequences[nCount - 1].is() ) + if(bHasLabel) { - uno::Reference< lang::XServiceInfo > xLabel( aSequences[nCount - 1]->getLabel(), uno::UNO_QUERY ); // take the last sequence, because the first has no label if it is also created - if (xLabel.is()) - { - rOutHasFirstCellAsLabel = xLabel->getImplementationName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ScChart2DataSequence")); - bResult = true; - } + uno::Reference < chart2::data::XDataSequence > xLabelSeq(new ScChart2DataSequence(pDoc, xDP, pLabelTokens.release(), bIncludeHiddenCells)); + pRet->setLabel(xLabelSeq); } } - return bResult; + return pRet; } -} // anonymous namespace - -bool ScChart2DataProvider::addUpperLeftCornerIfMissing(vector<ScSharedTokenRef>& rRefTokens) +//---------------------------------------------------- +/** + * Check the current list of reference tokens, and add the upper left + * corner of the minimum range that encloses all ranges if certain + * conditions are met. + * + * @param rRefTokens list of reference tokens + * + * @return true if the corner was added, false otherwise. + */ +bool lcl_addUpperLeftCornerIfMissing(vector<ScSharedTokenRef>& rRefTokens, + SCROW nCornerRowCount=1, SCCOL nCornerColumnCount=1) { using ::std::max; using ::std::min; @@ -1834,13 +1266,13 @@ bool ScChart2DataProvider::addUpperLeftCornerIfMissing(vector<ScSharedTokenRef>& // The corner cell is contained. return false; - if (rData.nCol == nMinCol+1 && rData.nRow == nMinRow) + if (rData.nCol == nMinCol+nCornerColumnCount && rData.nRow == nMinRow) bRight = true; - if (rData.nCol == nMinCol && rData.nRow == nMinRow+1) + if (rData.nCol == nMinCol && rData.nRow == nMinRow+nCornerRowCount) bBottom = true; - if (rData.nCol == nMinCol+1 && rData.nRow == nMinRow+1) + if (rData.nCol == nMinCol+nCornerColumnCount && rData.nRow == nMinRow+nCornerRowCount) bDiagonal = true; } break; @@ -1855,16 +1287,16 @@ bool ScChart2DataProvider::addUpperLeftCornerIfMissing(vector<ScSharedTokenRef>& // The corner cell is contained. return false; - if (r1.nCol <= nMinCol+1 && nMinCol+1 <= r2.nCol && + if (r1.nCol <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.nCol && r1.nRow <= nMinRow && nMinRow <= r2.nRow) bRight = true; if (r1.nCol <= nMinCol && nMinCol <= r2.nCol && - r1.nRow <= nMinRow+1 && nMinRow+1 <= r2.nRow) + r1.nRow <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.nRow) bBottom = true; - if (r1.nCol <= nMinCol+1 && nMinCol+1 <= r2.nCol && - r1.nRow <= nMinRow+1 && nMinRow+1 <= r2.nRow) + if (r1.nCol <= nMinCol+nCornerColumnCount && nMinCol+nCornerColumnCount <= r2.nCol && + r1.nRow <= nMinRow+nCornerRowCount && nMinRow+nCornerRowCount <= r2.nRow) bDiagonal = true; } break; @@ -1934,22 +1366,194 @@ bool ScChart2DataProvider::addUpperLeftCornerIfMissing(vector<ScSharedTokenRef>& aData.nRow = nMinRow; aData.nTab = nTab; - if (bExternal) + if( nCornerRowCount==1 && nCornerColumnCount==1 ) { - ScSharedTokenRef pCorner( - new ScExternalSingleRefToken(nFileId, aExtTabName, aData)); - ScRefTokenHelper::join(rRefTokens, pCorner); + if (bExternal) + { + ScSharedTokenRef pCorner( + new ScExternalSingleRefToken(nFileId, aExtTabName, aData)); + ScRefTokenHelper::join(rRefTokens, pCorner); + } + else + { + ScSharedTokenRef pCorner(new ScSingleRefToken(aData)); + ScRefTokenHelper::join(rRefTokens, pCorner); + } } else { - ScSharedTokenRef pCorner(new ScSingleRefToken(aData)); - ScRefTokenHelper::join(rRefTokens, pCorner); + ScSingleRefData aDataEnd(aData); + aDataEnd.nCol += (nCornerColumnCount-1); + aDataEnd.nRow += (nCornerRowCount-1); + ScComplexRefData r; + r.Ref1=aData; + r.Ref2=aDataEnd; + if (bExternal) + { + ScSharedTokenRef pCorner( + new ScExternalDoubleRefToken(nFileId, aExtTabName, r)); + ScRefTokenHelper::join(rRefTokens, pCorner); + } + else + { + ScSharedTokenRef pCorner(new ScDoubleRefToken(r)); + ScRefTokenHelper::join(rRefTokens, pCorner); + } } return true; } -namespace { +} + +uno::Reference< chart2::data::XDataSource> SAL_CALL +ScChart2DataProvider::createDataSource( + const uno::Sequence< beans::PropertyValue >& aArguments ) + throw( lang::IllegalArgumentException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + if ( ! m_pDocument ) + throw uno::RuntimeException(); + + uno::Reference< chart2::data::XDataSource> xResult; + bool bLabel = true; + bool bCategories = false; + bool bOrientCol = true; + ::rtl::OUString aRangeRepresentation; + uno::Sequence< sal_Int32 > aSequenceMapping; + for(sal_Int32 i = 0; i < aArguments.getLength(); ++i) + { + rtl::OUString sName(aArguments[i].Name); + if (aArguments[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataRowSource"))) + { + chart::ChartDataRowSource eSource = chart::ChartDataRowSource_COLUMNS; + if( ! (aArguments[i].Value >>= eSource)) + { + sal_Int32 nSource(0); + if( aArguments[i].Value >>= nSource ) + eSource = (static_cast< chart::ChartDataRowSource >( nSource )); + } + bOrientCol = (eSource == chart::ChartDataRowSource_COLUMNS); + } + else if (aArguments[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstCellAsLabel"))) + { + bLabel = ::cppu::any2bool(aArguments[i].Value); + } + else if (aArguments[i].Name == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasCategories"))) + { + bCategories = ::cppu::any2bool(aArguments[i].Value); + } + else if (aArguments[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CellRangeRepresentation"))) + { + aArguments[i].Value >>= aRangeRepresentation; + } + else if (aArguments[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SequenceMapping"))) + { + aArguments[i].Value >>= aSequenceMapping; + } + } + + vector<ScSharedTokenRef> aRefTokens; + ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument, m_pDocument->GetGrammar()); + if (aRefTokens.empty()) + // Invalid range representation. Bail out. + throw lang::IllegalArgumentException(); + + if (bLabel) + lcl_addUpperLeftCornerIfMissing(aRefTokens); //#i90669# + + bool bColHeaders = (bOrientCol ? bLabel : bCategories ); + bool bRowHeaders = (bOrientCol ? bCategories : bLabel ); + + Chart2Positioner aChPositioner(m_pDocument, aRefTokens); + aChPositioner.setHeaders(bColHeaders, bRowHeaders); + + const Chart2PositionMap* pChartMap = aChPositioner.getPositionMap(); + if (!pChartMap) + // No chart position map instance. Bail out. + return xResult; + + ScChart2DataSource* pDS = NULL; + std::list < ScChart2LabeledDataSequence* > aSeqs; + + // Fill Categories + if( bCategories ) + { + auto_ptr< vector<ScSharedTokenRef> > pValueTokens(NULL); + if (bOrientCol) + pValueTokens.reset(pChartMap->getAllRowHeaderRanges()); + else + pValueTokens.reset(pChartMap->getAllColHeaderRanges()); + + auto_ptr< vector<ScSharedTokenRef> > pLabelTokens(NULL); + pLabelTokens.reset(pChartMap->getLeftUpperCornerRanges()); + + ScChart2LabeledDataSequence* pCategories = lcl_createScChart2DataSequenceFromTokens( pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells );//ownership of pointers is transfered! + if( pCategories ) + aSeqs.push_back(pCategories); + } + + // Fill Serieses (values and label) + sal_Int32 nCount = bOrientCol ? pChartMap->getDataColCount() : pChartMap->getDataRowCount(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + auto_ptr< vector<ScSharedTokenRef> > pValueTokens(NULL); + auto_ptr< vector<ScSharedTokenRef> > pLabelTokens(NULL); + if (bOrientCol) + { + pValueTokens.reset(pChartMap->getDataColRanges(static_cast<SCCOL>(i))); + pLabelTokens.reset(pChartMap->getColHeaderRanges(static_cast<SCCOL>(i))); + } + else + { + pValueTokens.reset(pChartMap->getDataRowRanges(static_cast<SCROW>(i))); + pLabelTokens.reset(pChartMap->getRowHeaderRanges(static_cast<SCROW>(i))); + } + ScChart2LabeledDataSequence* pChartSeries = lcl_createScChart2DataSequenceFromTokens( pValueTokens, pLabelTokens, m_pDocument, this, m_bIncludeHiddenCells ); //ownership of pointers is transfered! + if( pChartSeries ) + aSeqs.push_back(pChartSeries); + } + + pDS = new ScChart2DataSource(m_pDocument); + std::list < ScChart2LabeledDataSequence* >::iterator aItr(aSeqs.begin()); + std::list < ScChart2LabeledDataSequence* >::iterator aEndItr(aSeqs.end()); + + //reorder labeled sequences according to aSequenceMapping + std::vector< ScChart2LabeledDataSequence* > aSeqVector; + while(aItr != aEndItr) + { + aSeqVector.push_back(*aItr); + ++aItr; + } + + std::map< sal_Int32, ScChart2LabeledDataSequence* > aSequenceMap; + for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ ) + { + // note: assuming that the values in the sequence mapping are always non-negative + std::vector< ScChart2LabeledDataSequence* >::size_type nOldIndex( static_cast< sal_uInt32 >( aSequenceMapping[nNewIndex] )); + if( nOldIndex < aSeqVector.size() ) + { + pDS->AddLabeledSequence( aSeqVector[nOldIndex] ); + aSeqVector[nOldIndex] = 0; + } + + } + + std::vector< ScChart2LabeledDataSequence* >::iterator aVectorItr(aSeqVector.begin()); + std::vector< ScChart2LabeledDataSequence* >::iterator aVectorEndItr(aSeqVector.end()); + while(aVectorItr != aVectorEndItr) + { + if(*aVectorItr) + pDS->AddLabeledSequence(*aVectorItr); + ++aVectorItr; + } + + xResult.set( pDS ); + return xResult; +} + +namespace +{ /** * Function object to create a list of table numbers from a token list. @@ -1984,8 +1588,134 @@ private: shared_ptr< list<SCTAB> > mpTabNumList; }; +class RangeAnalyzer +{ +public: + RangeAnalyzer(); + void initRangeAnalyzer( const vector<ScSharedTokenRef>& rTokens ); + void analyzeRange( sal_Int32& rnDataInRows, sal_Int32& rnDataInCols, + bool& rbRowSourceAmbiguous ) const; + bool inSameSingleRow( RangeAnalyzer& rOther ); + bool inSameSingleColumn( RangeAnalyzer& rOther ); + SCROW getRowCount() { return mnRowCount; } + SCCOL getColumnCount() { return mnColumnCount; } + +private: + bool mbEmpty; + bool mbAmbiguous; + SCROW mnRowCount; + SCCOL mnColumnCount; + + SCCOL mnStartColumn; + SCROW mnStartRow; +}; + +RangeAnalyzer::RangeAnalyzer() + : mbEmpty(true) + , mbAmbiguous(false) + , mnRowCount(0) + , mnColumnCount(0) + , mnStartColumn(-1) + , mnStartRow(-1) +{ } +void RangeAnalyzer::initRangeAnalyzer( const vector<ScSharedTokenRef>& rTokens ) +{ + mnRowCount=0; + mnColumnCount=0; + mnStartColumn = -1; + mnStartRow = -1; + mbAmbiguous=false; + if( rTokens.empty() ) + { + mbEmpty=true; + return; + } + mbEmpty=false; + + vector<ScSharedTokenRef>::const_iterator itr = rTokens.begin(), itrEnd = rTokens.end(); + for (; itr != itrEnd ; ++itr) + { + ScSharedTokenRef aRefToken = *itr; + StackVar eVar = aRefToken->GetType(); + if (eVar == svDoubleRef || eVar == svExternalDoubleRef) + { + const ScComplexRefData& r = aRefToken->GetDoubleRef(); + if (r.Ref1.nTab == r.Ref2.nTab) + { + mnColumnCount = std::max<SCCOL>( mnColumnCount, static_cast<SCCOL>(abs(r.Ref2.nCol - r.Ref1.nCol)+1) ); + mnRowCount = std::max<SCROW>( mnRowCount, static_cast<SCROW>(abs(r.Ref2.nRow - r.Ref1.nRow)+1) ); + if( mnStartColumn == -1 ) + { + mnStartColumn = r.Ref1.nCol; + mnStartRow = r.Ref1.nRow; + } + else + { + if( mnStartColumn != r.Ref1.nCol && mnStartRow != r.Ref1.nRow ) + mbAmbiguous=true; + } + } + else + mbAmbiguous=true; + } + else if (eVar == svSingleRef || eVar == svExternalSingleRef) + { + const ScSingleRefData& r = aRefToken->GetSingleRef(); + mnColumnCount = std::max<SCCOL>( mnColumnCount, 1); + mnRowCount = std::max<SCROW>( mnRowCount, 1); + if( mnStartColumn == -1 ) + { + mnStartColumn = r.nCol; + mnStartRow = r.nRow; + } + else + { + if( mnStartColumn != r.nCol && mnStartRow != r.nRow ) + mbAmbiguous=true; + } + } + else + mbAmbiguous=true; + } +} + +void RangeAnalyzer::analyzeRange( sal_Int32& rnDataInRows, + sal_Int32& rnDataInCols, + bool& rbRowSourceAmbiguous ) const +{ + if(!mbEmpty && !mbAmbiguous) + { + if( mnRowCount==1 && mnColumnCount>1 ) + ++rnDataInRows; + else if( mnColumnCount==1 && mnRowCount>1 ) + ++rnDataInCols; + else if( mnRowCount>1 && mnColumnCount>1 ) + rbRowSourceAmbiguous = true; + } + else if( !mbEmpty ) + rbRowSourceAmbiguous = true; +} + +bool RangeAnalyzer::inSameSingleRow( RangeAnalyzer& rOther ) +{ + if( mnStartRow==rOther.mnStartRow && + mnRowCount==1 && rOther.mnRowCount==1 ) + return true; + return false; +} + +bool RangeAnalyzer::inSameSingleColumn( RangeAnalyzer& rOther ) +{ + if( mnStartColumn==rOther.mnStartColumn && + mnColumnCount==1 && rOther.mnColumnCount==1 ) + return true; + return false; +} + +} //end anonymous namespace + uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArguments( const uno::Reference< chart2::data::XDataSource >& xDataSource ) throw (uno::RuntimeException) @@ -1993,28 +1723,137 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum ::std::vector< beans::PropertyValue > aResult; bool bRowSourceDetected = false; bool bFirstCellAsLabel = false; - bool bHasCategories = true; + bool bHasCategories = false; ::rtl::OUString sRangeRep; + bool bHasCategoriesLabels = false; + vector<ScSharedTokenRef> aAllCategoriesValuesTokens; + vector<ScSharedTokenRef> aAllSeriesLabelTokens; + chart::ChartDataRowSource eRowSource = chart::ChartDataRowSource_COLUMNS; - vector<ScSharedTokenRef> aTokens; + vector<ScSharedTokenRef> aAllTokens; - // CellRangeRepresentation + // parse given data source and collect infos { ScUnoGuard aGuard; DBG_ASSERT( m_pDocument, "No Document -> no detectArguments" ); - if(!m_pDocument) + if(!m_pDocument ||!xDataSource.is()) return lcl_VectorToSequence( aResult ); - detectRangesFromDataSource(aTokens, eRowSource, bRowSourceDetected, xDataSource); + sal_Int32 nDataInRows = 0; + sal_Int32 nDataInCols = 0; + bool bRowSourceAmbiguous = false; + + Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences( xDataSource->getDataSequences()); + const sal_Int32 nCount( aSequences.getLength()); + RangeAnalyzer aPrevLabel,aPrevValues; + for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx ) + { + Reference< chart2::data::XLabeledDataSequence > xLS(aSequences[nIdx]); + if( xLS.is() ) + { + bool bThisIsCategories = false; + if(!bHasCategories) + { + Reference< beans::XPropertySet > xSeqProp( xLS->getValues(), uno::UNO_QUERY ); + ::rtl::OUString aRole; + if( xSeqProp.is() && (xSeqProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Role"))) >>= aRole) && + aRole.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("categories")) ) + bThisIsCategories = bHasCategories = true; + } + + RangeAnalyzer aLabel,aValues; + // label + Reference< chart2::data::XDataSequence > xLabel( xLS->getLabel()); + if( xLabel.is()) + { + bFirstCellAsLabel = true; + vector<ScSharedTokenRef> aTokens; + ScRefTokenHelper::compileRangeRepresentation( aTokens, xLabel->getSourceRangeRepresentation(), m_pDocument, m_pDocument->GetGrammar() ); + aLabel.initRangeAnalyzer(aTokens); + vector<ScSharedTokenRef>::const_iterator itr = aTokens.begin(), itrEnd = aTokens.end(); + for (; itr != itrEnd; ++itr) + { + ScRefTokenHelper::join(aAllTokens, *itr); + if(!bThisIsCategories) + ScRefTokenHelper::join(aAllSeriesLabelTokens, *itr); + } + if(bThisIsCategories) + bHasCategoriesLabels=true; + } + // values + Reference< chart2::data::XDataSequence > xValues( xLS->getValues()); + if( xValues.is()) + { + vector<ScSharedTokenRef> aTokens; + ScRefTokenHelper::compileRangeRepresentation( aTokens, xValues->getSourceRangeRepresentation(), m_pDocument, m_pDocument->GetGrammar() ); + aValues.initRangeAnalyzer(aTokens); + vector<ScSharedTokenRef>::const_iterator itr = aTokens.begin(), itrEnd = aTokens.end(); + for (; itr != itrEnd; ++itr) + { + ScRefTokenHelper::join(aAllTokens, *itr); + if(bThisIsCategories) + ScRefTokenHelper::join(aAllCategoriesValuesTokens, *itr); + } + } + //detect row source + if(!bThisIsCategories || nCount==1) //categories might span multiple rows *and* columns, so they should be used for detection only if nothing else is available + { + if (!bRowSourceAmbiguous) + { + aValues.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous); + aLabel.analyzeRange(nDataInRows,nDataInCols,bRowSourceAmbiguous); + if (nDataInRows > 1 && nDataInCols > 1) + bRowSourceAmbiguous = true; + else if( !bRowSourceAmbiguous && !nDataInRows && !nDataInCols ) + { + if( aValues.inSameSingleColumn( aLabel ) ) + nDataInCols++; + else if( aValues.inSameSingleRow( aLabel ) ) + nDataInRows++; + else + { + //#i86188# also detect a single column split into rows correctly + if( aValues.inSameSingleColumn( aPrevValues ) ) + nDataInRows++; + else if( aValues.inSameSingleRow( aPrevValues ) ) + nDataInCols++; + else if( aLabel.inSameSingleColumn( aPrevLabel ) ) + nDataInRows++; + else if( aLabel.inSameSingleRow( aPrevLabel ) ) + nDataInCols++; + } + } + } + } + aPrevValues=aValues; + aPrevLabel=aLabel; + } + } + + if (!bRowSourceAmbiguous) + { + bRowSourceDetected = true; + eRowSource = ( nDataInRows > 0 + ? chart::ChartDataRowSource_ROWS + : chart::ChartDataRowSource_COLUMNS ); + } + else + { + // set DataRowSource to the better of the two ambiguities + eRowSource = ( nDataInRows > nDataInCols + ? chart::ChartDataRowSource_ROWS + : chart::ChartDataRowSource_COLUMNS ); + } + } // TableNumberList { list<SCTAB> aTableNumList; InsertTabNumber func; - func = for_each(aTokens.begin(), aTokens.end(), func); + func = for_each(aAllTokens.begin(), aAllTokens.end(), func); func.getList(aTableNumList); aResult.push_back( beans::PropertyValue( ::rtl::OUString::createFromAscii("TableNumberList"), -1, @@ -2033,29 +1872,38 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum // HasCategories if( bRowSourceDetected ) { - if( lcl_HasCategories( xDataSource, bHasCategories )) - { - aResult.push_back( - beans::PropertyValue( ::rtl::OUString::createFromAscii("HasCategories"), -1, - uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE )); - } + aResult.push_back( + beans::PropertyValue( ::rtl::OUString::createFromAscii("HasCategories"), -1, + uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE )); } // FirstCellAsLabel if( bRowSourceDetected ) { - lcl_HasFirstCellAsLabel( xDataSource, bFirstCellAsLabel ); aResult.push_back( beans::PropertyValue( ::rtl::OUString::createFromAscii("FirstCellAsLabel"), -1, uno::makeAny( bFirstCellAsLabel ), beans::PropertyState_DIRECT_VALUE )); } // Add the left upper corner to the range if it is missing. - if (bRowSourceDetected && bFirstCellAsLabel && bHasCategories) - addUpperLeftCornerIfMissing(aTokens); + if (bRowSourceDetected && bFirstCellAsLabel && bHasCategories && !bHasCategoriesLabels ) + { + RangeAnalyzer aTop,aLeft; + if( eRowSource==chart::ChartDataRowSource_COLUMNS ) + { + aTop.initRangeAnalyzer(aAllSeriesLabelTokens); + aLeft.initRangeAnalyzer(aAllCategoriesValuesTokens); + } + else + { + aTop.initRangeAnalyzer(aAllCategoriesValuesTokens); + aLeft.initRangeAnalyzer(aAllSeriesLabelTokens); + } + lcl_addUpperLeftCornerIfMissing(aAllTokens, aTop.getRowCount(), aLeft.getColumnCount());//e.g. #i91212# + } // Get range string. - lcl_convertTokensToString(sRangeRep, aTokens, m_pDocument); + lcl_convertTokensToString(sRangeRep, aAllTokens, m_pDocument); // add cell range property aResult.push_back( @@ -2270,91 +2118,6 @@ rtl::OUString SAL_CALL ScChart2DataProvider::convertRangeFromXML( const rtl::OUS return aRet; } -namespace { - -class CollectRefTokens : public ::std::unary_function<ScSharedTokenRef, void> -{ -public: - CollectRefTokens() : - mpRefTokens(new vector<ScSharedTokenRef>()), - mnDataInRows(0), - mnDataInCols(0), - mbRowSourceAmbiguous(false) - { - } - - CollectRefTokens(const CollectRefTokens& r) : - mpRefTokens(r.mpRefTokens), - mnDataInRows(r.mnDataInRows), - mnDataInCols(r.mnDataInCols), - mbRowSourceAmbiguous(r.mbRowSourceAmbiguous) - { - } - - void operator() (const ScSharedTokenRef& rRefToken) - { - if (!mbRowSourceAmbiguous) - { - StackVar eVar = rRefToken->GetType(); - if (eVar == svDoubleRef || eVar == svExternalDoubleRef) - { - const ScComplexRefData& r = rRefToken->GetDoubleRef(); - mbRowSourceAmbiguous = r.Ref1.nTab != r.Ref2.nTab; - if (!mbRowSourceAmbiguous) - { - bool bColDiff = (r.Ref2.nCol - r.Ref1.nCol) != 0; - bool bRowDiff = (r.Ref2.nRow - r.Ref1.nRow) != 0; - - if (bColDiff && !bRowDiff) - ++mnDataInRows; - else if (bRowDiff && !bColDiff) - ++mnDataInCols; - else if (bRowDiff && bColDiff) - mbRowSourceAmbiguous = true; - - if (mnDataInRows > 0 && mnDataInCols > 0) - mbRowSourceAmbiguous = true; - } - } - } - - mpRefTokens->push_back(rRefToken); - } - - void appendTokens(vector<ScSharedTokenRef>& rTokens) - { - vector<ScSharedTokenRef> aNewTokens = rTokens; - vector<ScSharedTokenRef>::const_iterator itr = mpRefTokens->begin(), itrEnd = mpRefTokens->end(); - for (; itr != itrEnd; ++itr) - ScRefTokenHelper::join(aNewTokens, *itr); - - rTokens.swap(aNewTokens); - } - - bool isRowSourceAmbiguous() const - { - return mbRowSourceAmbiguous; - } - - sal_uInt32 getDataInRows() const - { - return mnDataInRows; - } - - sal_uInt32 getDataInCols() const - { - return mnDataInCols; - } - -private: - shared_ptr< vector<ScSharedTokenRef> > mpRefTokens; - sal_uInt32 mnDataInRows; - sal_uInt32 mnDataInCols; - bool mbRowSourceAmbiguous; -}; - -} - // DataProvider XPropertySet ------------------------------------------------- uno::Reference< beans::XPropertySetInfo> SAL_CALL @@ -2437,53 +2200,6 @@ void SAL_CALL ScChart2DataProvider::removeVetoableChangeListener( OSL_ENSURE( false, "Not yet implemented" ); } -void ScChart2DataProvider::detectRangesFromDataSource(vector<ScSharedTokenRef>& rRefTokens, - chart::ChartDataRowSource& rRowSource, - bool& rRowSourceDetected, - const Reference<chart2::data::XDataSource>& xDataSource) -{ - if (!m_pDocument) - return; - - sal_Int32 nDataInRows = 0; - sal_Int32 nDataInCols = 0; - bool bRowSourceAmbiguous = false; - - vector<OUString> aRangeReps = lcl_getRangeRepresentationsFromDataSource(xDataSource); - for (vector<OUString>::const_iterator itr = aRangeReps.begin(), itrEnd = aRangeReps.end(); - itr != itrEnd; ++itr) - { - const OUString& rRangeRep = *itr; - vector<ScSharedTokenRef> aTokens; - ScRefTokenHelper::compileRangeRepresentation(aTokens, rRangeRep, m_pDocument, m_pDocument->GetGrammar()); - - CollectRefTokens func; - func = for_each(aTokens.begin(), aTokens.end(), func); - func.appendTokens(rRefTokens); - bRowSourceAmbiguous = bRowSourceAmbiguous || func.isRowSourceAmbiguous(); - if (!bRowSourceAmbiguous) - { - nDataInRows += func.getDataInRows(); - nDataInCols += func.getDataInCols(); - } - } - - if (!bRowSourceAmbiguous) - { - rRowSourceDetected = true; - rRowSource = ( nDataInRows > 0 - ? chart::ChartDataRowSource_ROWS - : chart::ChartDataRowSource_COLUMNS ); - } - else - { - // set DataRowSource to the better of the two ambiguities - rRowSource = ( nDataInRows > nDataInCols - ? chart::ChartDataRowSource_ROWS - : chart::ChartDataRowSource_COLUMNS ); - } -} - // DataSource ================================================================ ScChart2DataSource::ScChart2DataSource( ScDocument* pDoc) diff --git a/sc/source/ui/unoobj/chartuno.cxx b/sc/source/ui/unoobj/chartuno.cxx index 5feabe72207d..201c411ea45c 100644 --- a/sc/source/ui/unoobj/chartuno.cxx +++ b/sc/source/ui/unoobj/chartuno.cxx @@ -480,20 +480,15 @@ void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& { bool bFound = false; ScDocument* pDoc = (pDocShell? pDocShell->GetDocument(): 0); - uno::Reference< embed::XEmbeddedObject > xIPObj; + if( pDoc ) - xIPObj.set( pDoc->FindOleObjectByName( aChartName ), uno::UNO_QUERY ); - if( xIPObj.is()) { - //make sure that the chart is loaded - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - uno::Reference< chart2::XChartDocument > xChartDoc( xIPObj->getComponent(), uno::UNO_QUERY ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); - if( xReceiver.is() ) + uno::Reference< chart2::XChartDocument > xChartDoc( pDoc->GetChartByName( aChartName ) ); + if( xChartDoc.is() ) { + uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); - if( xProvider.is() ) + if( xReceiver.is() && xProvider.is() ) { uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xReceiver->getUsedData() ) ); diff --git a/sc/source/ui/unoobj/cursuno.cxx b/sc/source/ui/unoobj/cursuno.cxx index 39ed859aa574..daf075964a3a 100644 --- a/sc/source/ui/unoobj/cursuno.cxx +++ b/sc/source/ui/unoobj/cursuno.cxx @@ -133,7 +133,7 @@ void SAL_CALL ScCellCursorObj::collapseToCurrentRegion() throw(uno::RuntimeExcep SCTAB nTab = aOneRange.aStart.Tab(); pDocSh->GetDocument()->GetDataArea( - nTab, nStartCol, nStartRow, nEndCol, nEndRow, TRUE ); + nTab, nStartCol, nStartRow, nEndCol, nEndRow, TRUE, false ); ScRange aNew( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ); SetNewRange( aNew ); @@ -331,7 +331,7 @@ void SAL_CALL ScCellCursorObj::gotoStart() throw(uno::RuntimeException) SCTAB nTab = aOneRange.aStart.Tab(); pDocSh->GetDocument()->GetDataArea( - nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE ); + nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE, false ); ScRange aNew( nStartCol, nStartRow, nTab ); SetNewRange( aNew ); @@ -359,7 +359,7 @@ void SAL_CALL ScCellCursorObj::gotoEnd() throw(uno::RuntimeException) SCTAB nTab = aOneRange.aStart.Tab(); pDocSh->GetDocument()->GetDataArea( - nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE ); + nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE, false ); ScRange aNew( nEndCol, nEndRow, nTab ); SetNewRange( aNew ); diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index a921d1e125f2..7e23d6b2f9f5 100644..100755 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -43,15 +43,19 @@ #include "unoguard.hxx" #include "dpobject.hxx" #include "dpshttab.hxx" +#include "dpsdbtab.hxx" #include "dpsave.hxx" #include "dbdocfun.hxx" #include "unonames.hxx" #include "dpgroup.hxx" #include "dpdimsave.hxx" +#include "hints.hxx" + #include <com/sun/star/sheet/XHierarchiesSupplier.hpp> #include <com/sun/star/sheet/XLevelsSupplier.hpp> #include <com/sun/star/sheet/XMembersSupplier.hpp> #include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/sheet/DataImportMode.hpp> #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> #include <com/sun/star/sheet/DataPilotOutputRangeType.hpp> @@ -105,9 +109,12 @@ 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_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 }, {MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_SERVICEARG), 0, &getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNO_SHOWFILT), 0, &getBooleanCppuType(), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_SOURCESERV), 0, &getCppuType((rtl::OUString*)0), 0, 0 }, {0,0,0,0,0,0} }; return aDataPilotDescriptorBaseMap_Impl; @@ -261,8 +268,7 @@ ScDPObject* lcl_GetDPObject( ScDocShell* pDocShell, SCTAB nTab, const String& rN for (USHORT i=0; i<nCount; i++) { ScDPObject* pDPObj = (*pColl)[i]; - if ( pDPObj->IsSheetData() && - pDPObj->GetOutRange().aStart.Tab() == nTab && + if ( pDPObj->GetOutRange().aStart.Tab() == nTab && pDPObj->GetName() == rName ) return pDPObj; } @@ -344,7 +350,7 @@ ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nInd for (USHORT i=0; i<nCount; i++) { ScDPObject* pDPObj = (*pColl)[i]; - if ( pDPObj->IsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab ) + if ( pDPObj->GetOutRange().aStart.Tab() == nTab ) { if ( nFound == nIndex ) { @@ -496,7 +502,7 @@ sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException) for (USHORT i=0; i<nCount; i++) { ScDPObject* pDPObj = (*pColl)[i]; - if ( pDPObj->IsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab ) + if ( pDPObj->GetOutRange().aStart.Tab() == nTab ) ++nFound; } return nFound; @@ -560,7 +566,7 @@ Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames() for (i=0; i<nCount; i++) { ScDPObject* pDPObj = (*pColl)[i]; - if ( pDPObj->IsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab ) + if ( pDPObj->GetOutRange().aStart.Tab() == nTab ) ++nFound; } @@ -570,7 +576,7 @@ Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames() for (i=0; i<nCount; i++) { ScDPObject* pDPObj = (*pColl)[i]; - if ( pDPObj->IsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab ) + if ( pDPObj->GetOutRange().aStart.Tab() == nTab ) pAry[nPos++] = pDPObj->GetName(); } @@ -598,8 +604,7 @@ sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName ) //! allow all data sources!!! ScDPObject* pDPObj = (*pColl)[i]; - if ( pDPObj->IsSheetData() && - pDPObj->GetOutRange().aStart.Tab() == nTab && + if ( pDPObj->GetOutRange().aStart.Tab() == nTab && pDPObj->GetName() == aNamStr ) return TRUE; } @@ -696,11 +701,12 @@ CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange() ScUnoGuard aGuard; ScDPObject* pDPObject(GetDPObject()); - if (!pDPObject || !pDPObject->IsSheetData()) + if (!pDPObject) throw RuntimeException(); CellRangeAddress aRet; - ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->aSourceRange ); + if (pDPObject->IsSheetData()) + ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->aSourceRange ); return aRet; } @@ -818,6 +824,99 @@ void SAL_CALL ScDataPilotDescriptorBase::setPropertyValue( const OUString& aProp { aNewData.SetDrillDown(::cppu::any2bool( aValue )); } + else if ( aNameString.EqualsAscii( SC_UNO_IMPORTDESC ) ) + { + uno::Sequence<beans::PropertyValue> aArgSeq; + if ( aValue >>= aArgSeq ) + { + ScImportSourceDesc aImportDesc; + + const ScImportSourceDesc* pOldDesc = pDPObject->GetImportSourceDesc(); + if (pOldDesc) + aImportDesc = *pOldDesc; + + ScImportParam aParam; + ScImportDescriptor::FillImportParam( aParam, aArgSeq ); + + USHORT nNewType = sheet::DataImportMode_NONE; + if ( aParam.bImport ) + { + if ( aParam.bSql ) + nNewType = sheet::DataImportMode_SQL; + else if ( aParam.nType == ScDbQuery ) + nNewType = sheet::DataImportMode_QUERY; + else + nNewType = sheet::DataImportMode_TABLE; + } + aImportDesc.nType = nNewType; + aImportDesc.aDBName = aParam.aDBName; + aImportDesc.aObject = aParam.aStatement; + aImportDesc.bNative = aParam.bNative; + + pDPObject->SetImportDesc( aImportDesc ); + } + } + else if ( aNameString.EqualsAscii( SC_UNO_SOURCESERV ) ) + { + rtl::OUString aStrVal; + if ( aValue >>= aStrVal ) + { + String aEmpty; + ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty); + + const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc(); + if (pOldDesc) + aServiceDesc = *pOldDesc; + + aServiceDesc.aServiceName = aStrVal; + + pDPObject->SetServiceData( aServiceDesc ); + } + } + else if ( aNameString.EqualsAscii( SC_UNO_SERVICEARG ) ) + { + uno::Sequence<beans::PropertyValue> aArgSeq; + if ( aValue >>= aArgSeq ) + { + String aEmpty; + ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty); + + const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc(); + if (pOldDesc) + aServiceDesc = *pOldDesc; + + rtl::OUString aStrVal; + sal_Int32 nArgs = aArgSeq.getLength(); + for (sal_Int32 nArgPos=0; nArgPos<nArgs; ++nArgPos) + { + const beans::PropertyValue& rProp = aArgSeq[nArgPos]; + String aPropName(rProp.Name); + + if (aPropName.EqualsAscii( SC_UNO_SOURCENAME )) + { + if ( rProp.Value >>= aStrVal ) + aServiceDesc.aParSource = aStrVal; + } + else if (aPropName.EqualsAscii( SC_UNO_OBJECTNAME )) + { + if ( rProp.Value >>= aStrVal ) + aServiceDesc.aParName = aStrVal; + } + else if (aPropName.EqualsAscii( SC_UNO_USERNAME )) + { + if ( rProp.Value >>= aStrVal ) + aServiceDesc.aParUser = aStrVal; + } + else if (aPropName.EqualsAscii( SC_UNO_PASSWORD )) + { + if ( rProp.Value >>= aStrVal ) + aServiceDesc.aParPass = aStrVal; + } + } + + pDPObject->SetServiceData( aServiceDesc ); + } + } else throw UnknownPropertyException(); @@ -868,6 +967,63 @@ Any SAL_CALL ScDataPilotDescriptorBase::getPropertyValue( const OUString& aPrope { aRet = ::cppu::bool2any( aNewData.GetDrillDown() ); } + else if ( aNameString.EqualsAscii( SC_UNO_IMPORTDESC ) ) + { + const ScImportSourceDesc* pImportDesc = pDPObject->GetImportSourceDesc(); + if ( pImportDesc ) + { + // fill ScImportParam so ScImportDescriptor::FillProperties can be used + ScImportParam aParam; + aParam.bImport = ( pImportDesc->nType != sheet::DataImportMode_NONE ); + aParam.aDBName = pImportDesc->aDBName; + aParam.aStatement = pImportDesc->aObject; + aParam.bNative = pImportDesc->bNative; + aParam.bSql = ( pImportDesc->nType == sheet::DataImportMode_SQL ); + aParam.nType = static_cast<BYTE>(( pImportDesc->nType == sheet::DataImportMode_QUERY ) ? ScDbQuery : ScDbTable); + + uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() ); + ScImportDescriptor::FillProperties( aSeq, aParam ); + aRet <<= aSeq; + } + else + { + // empty sequence + uno::Sequence<beans::PropertyValue> aEmpty(0); + aRet <<= aEmpty; + } + } + else if ( aNameString.EqualsAscii( SC_UNO_SOURCESERV ) ) + { + rtl::OUString aServiceName; + const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc(); + if (pServiceDesc) + aServiceName = pServiceDesc->aServiceName; + aRet <<= aServiceName; // empty string if no ServiceDesc set + } + else if ( aNameString.EqualsAscii( SC_UNO_SERVICEARG ) ) + { + const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc(); + if (pServiceDesc) + { + uno::Sequence<beans::PropertyValue> aSeq( 4 ); + beans::PropertyValue* pArray = aSeq.getArray(); + pArray[0].Name = rtl::OUString::createFromAscii( SC_UNO_SOURCENAME ); + pArray[0].Value <<= rtl::OUString( pServiceDesc->aParSource ); + pArray[1].Name = rtl::OUString::createFromAscii( SC_UNO_OBJECTNAME ); + pArray[1].Value <<= rtl::OUString( pServiceDesc->aParName ); + pArray[2].Name = rtl::OUString::createFromAscii( SC_UNO_USERNAME ); + pArray[2].Value <<= rtl::OUString( pServiceDesc->aParUser ); + pArray[3].Name = rtl::OUString::createFromAscii( SC_UNO_PASSWORD ); + pArray[3].Value <<= rtl::OUString( pServiceDesc->aParPass ); + aRet <<= aSeq; + } + else + { + // empty sequence + uno::Sequence<beans::PropertyValue> aEmpty(0); + aRet <<= aEmpty; + } + } else throw UnknownPropertyException(); } @@ -966,7 +1122,8 @@ ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation( ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) : ScDataPilotDescriptorBase( pDocSh ), nTab( nT ), - aName( rN ) + aName( rN ), + aModifyListeners( 0 ) { } @@ -981,6 +1138,7 @@ Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType ) // we also need to do the same for XDataPilotTable SC_QUERYINTERFACE( XDataPilotTable ) SC_QUERYINTERFACE( XDataPilotTable2 ) + SC_QUERYINTERFACE( XModifyBroadcaster ) return ScDataPilotDescriptorBase::queryInterface( rType ); } @@ -1004,12 +1162,13 @@ Sequence< uno::Type > SAL_CALL ScDataPilotTableObj::getTypes() throw(RuntimeExce sal_Int32 nParentLen = aParentTypes.getLength(); const uno::Type* pParentPtr = aParentTypes.getConstArray(); - aTypes.realloc( nParentLen + 1 ); + aTypes.realloc( nParentLen + 2 ); uno::Type* pPtr = aTypes.getArray(); for (sal_Int32 i = 0; i < nParentLen; ++i) pPtr[ i ] = pParentPtr[ i ]; // parent types first pPtr[ nParentLen ] = getCppuType( (const Reference< XDataPilotTable2 >*)0 ); + pPtr[ nParentLen+1 ] = getCppuType( (const Reference< XModifyBroadcaster >*)0 ); } return aTypes; } @@ -1115,17 +1274,21 @@ CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeExc return aRet; } +ULONG RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, BOOL bRecord, BOOL bApi ); + void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException) { ScUnoGuard aGuard; - ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); - if (pDPObj) - { - ScDPObject* pNew = new ScDPObject(*pDPObj); - ScDBDocFunc aFunc(*GetDocShell()); - aFunc.DataPilotUpdate( pDPObj, pNew, TRUE, TRUE ); - delete pNew; // DataPilotUpdate copies settings from "new" object - } + if( ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName) ) + RefreshDPObject( pDPObj, NULL, GetDocShell(), TRUE, TRUE ); + //if (pDPObj) + //{ + // ScDPObject* pNew = new ScDPObject(*pDPObj); + // ScDBDocFunc aFunc(*GetDocShell()); + // aFunc.DataPilotUpdate( pDPObj, pNew, TRUE, TRUE ); + // delete pNew; // DataPilotUpdate copies settings from "new" object + //} + } Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr) @@ -1183,6 +1346,70 @@ CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 n return aRet; } +void SAL_CALL ScDataPilotTableObj::addModifyListener( const uno::Reference<util::XModifyListener>& aListener ) + throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + + uno::Reference<util::XModifyListener> *pObj = new uno::Reference<util::XModifyListener>( aListener ); + aModifyListeners.Insert( pObj, aModifyListeners.Count() ); + + if ( aModifyListeners.Count() == 1 ) + { + acquire(); // don't lose this object (one ref for all listeners) + } +} + +void SAL_CALL ScDataPilotTableObj::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener ) + throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + + acquire(); // in case the listeners have the last ref - released below + + USHORT nCount = aModifyListeners.Count(); + for ( USHORT n=nCount; n--; ) + { + uno::Reference<util::XModifyListener> *pObj = aModifyListeners[n]; + if ( *pObj == aListener ) + { + aModifyListeners.DeleteAndDestroy( n ); + + if ( aModifyListeners.Count() == 0 ) + { + release(); // release the ref for the listeners + } + + break; + } + } + + release(); // might delete this object +} + +void ScDataPilotTableObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + if ( rHint.ISA(ScDataPilotModifiedHint) && + static_cast<const ScDataPilotModifiedHint&>(rHint).GetName() == aName ) + { + Refreshed_Impl(); + } + + ScDataPilotDescriptorBase::Notify( rBC, rHint ); +} + +void ScDataPilotTableObj::Refreshed_Impl() +{ + lang::EventObject aEvent; + aEvent.Source.set((cppu::OWeakObject*)this); + + // the EventObject holds a Ref to this object until after the listener calls + + ScDocument* pDoc = GetDocShell()->GetDocument(); + for ( USHORT n=0; n<aModifyListeners.Count(); n++ ) + pDoc->AddUnoListenerCall( *aModifyListeners[n], aEvent ); +} + // ============================================================================ ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) : diff --git a/sc/source/ui/unoobj/dispuno.cxx b/sc/source/ui/unoobj/dispuno.cxx index cff547ce2652..6c82871d02da 100644 --- a/sc/source/ui/unoobj/dispuno.cxx +++ b/sc/source/ui/unoobj/dispuno.cxx @@ -65,9 +65,7 @@ uno::Reference<view::XSelectionSupplier> lcl_GetSelectionSupplier( SfxViewShell* SfxViewFrame* pViewFrame = pViewShell->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) - return uno::Reference<view::XSelectionSupplier>( pFrame->GetController(), uno::UNO_QUERY ); + return uno::Reference<view::XSelectionSupplier>( pViewFrame->GetFrame().GetController(), uno::UNO_QUERY ); } } return uno::Reference<view::XSelectionSupplier>(); @@ -81,8 +79,7 @@ ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell* pVi { if ( pViewShell ) { - SfxFrame* pFrame = pViewShell->GetViewFrame()->GetFrame(); - m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pFrame->GetFrameInterface(), uno::UNO_QUERY)); + m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY)); if (m_xIntercepted.is()) { comphelper::increment( m_refCount ); diff --git a/sc/source/ui/unoobj/filtuno.cxx b/sc/source/ui/unoobj/filtuno.cxx index 837d34544b60..8591f2fc0801 100644 --- a/sc/source/ui/unoobj/filtuno.cxx +++ b/sc/source/ui/unoobj/filtuno.cxx @@ -48,7 +48,12 @@ #include "sc.hrc" //CHINA001 #include "scabstdlg.hxx" //CHINA001 +#include "i18npool/lang.h" + +#include <memory> + using namespace ::com::sun::star; +using ::rtl::OUStringBuffer; //------------------------------------------------------------------------ @@ -143,6 +148,10 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() throw(uno::RuntimeException) sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL; String aFilterString( aFilterName ); + + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + DBG_ASSERT(pFact, "ScAbstractFactory create fail!"); + if ( !bExport && aFilterString == ScDocShell::GetAsciiFilterName() ) { // ascii import is special... @@ -161,20 +170,40 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() throw(uno::RuntimeException) pInStream = utl::UcbStreamHelper::CreateStream( xInputStream ); //CHINA001 ScImportAsciiDlg* pDlg = new ScImportAsciiDlg( NULL, aPrivDatName, pInStream, cAsciiDel ); - ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); - DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001 AbstractScImportAsciiDlg* pDlg = pFact->CreateScImportAsciiDlg( NULL, aPrivDatName, pInStream, RID_SCDLG_ASCII, cAsciiDel); DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001 if ( pDlg->Execute() == RET_OK ) { ScAsciiOptions aOptions; pDlg->GetOptions( aOptions ); + pDlg->SaveParameters(); aFilterOptions = aOptions.WriteToString(); nRet = ui::dialogs::ExecutableDialogResults::OK; } delete pDlg; delete pInStream; } + else if ( aFilterString == ScDocShell::GetWebQueryFilterName() || aFilterString == ScDocShell::GetHtmlFilterName() ) + { + if (!bExport) + { + // HTML import. + ::std::auto_ptr<AbstractScTextImportOptionsDlg> pDlg( + pFact->CreateScTextImportOptionsDlg(NULL, RID_SCDLG_TEXT_IMPORT_OPTIONS)); + + if (pDlg->Execute() == RET_OK) + { + LanguageType eLang = pDlg->GetLanguageType(); + OUStringBuffer aBuf; + + aBuf.append(String::CreateFromInt32(static_cast<sal_Int32>(eLang))); + aBuf.append(sal_Unicode(' ')); + aBuf.append(pDlg->IsDateConversionSet() ? sal_Unicode('1') : sal_Unicode('0')); + aFilterOptions = aBuf.makeStringAndClear(); + nRet = ui::dialogs::ExecutableDialogResults::OK; + } + } + } else { sal_Bool bMultiByte = sal_True; @@ -246,8 +275,6 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() throw(uno::RuntimeException) //CHINA001 &aOptions, &aTitle, bMultiByte, bDBEnc, //CHINA001 !bExport ); //CHINA001 - ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); - DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001 AbstractScImportOptionsDlg* pDlg = pFact->CreateScImportOptionsDlg( NULL, RID_SCDLG_IMPORTOPT, bAscii, &aOptions, &aTitle, bMultiByte, bDBEnc, diff --git a/sc/source/ui/unoobj/unodoc.cxx b/sc/source/ui/unoobj/unodoc.cxx index 9673db411ea0..d3d755e8b495 100644 --- a/sc/source/ui/unoobj/unodoc.cxx +++ b/sc/source/ui/unoobj/unodoc.cxx @@ -60,9 +60,7 @@ uno::Reference< uno::XInterface > SAL_CALL ScDocument_createInstance( { ::vos::OGuard aGuard( Application::GetSolarMutex() ); ScDLL::Init(); - const SfxObjectCreateMode eCreateMode = ( _nCreationFlags & SFXMODEL_EMBEDDED_OBJECT ) ? SFX_CREATE_MODE_EMBEDDED : SFX_CREATE_MODE_STANDARD; - const bool bScriptSupport = ( _nCreationFlags & SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) == 0; - SfxObjectShell* pShell = new ScDocShell( eCreateMode, bScriptSupport ); + SfxObjectShell* pShell = new ScDocShell( _nCreationFlags ); return uno::Reference< uno::XInterface >( pShell->GetModel() ); } diff --git a/sc/source/ui/vba/vbahelper.cxx b/sc/source/ui/vba/vbahelper.cxx index ca3b7825b232..4bc57e150c8f 100644 --- a/sc/source/ui/vba/vbahelper.cxx +++ b/sc/source/ui/vba/vbahelper.cxx @@ -518,7 +518,7 @@ void PrintOutHelper( const uno::Any& From, const uno::Any& To, const uno::Any& C { if ( bPreview ) { - if ( !pViewFrame->GetFrame()->IsInPlace() ) + if ( !pViewFrame->GetFrame().IsInPlace() ) { SC_MOD()->InputEnterHandler(); pViewFrame->GetDispatcher()->Execute( SID_VIEWSHELL1, SFX_CALLMODE_SYNCHRON ); diff --git a/sc/source/ui/vba/vbawindow.cxx b/sc/source/ui/vba/vbawindow.cxx index 0416b99abcb3..f0aafe83908b 100644 --- a/sc/source/ui/vba/vbawindow.cxx +++ b/sc/source/ui/vba/vbawindow.cxx @@ -48,7 +48,7 @@ #include <sc.hrc> #include <hash_map> #include <sfx2/viewfrm.hxx> -#include <sfx2/topfrm.hxx> +#include <vcl/wrkwin.hxx> #include "unonames.hxx" using namespace ::com::sun::star; @@ -400,17 +400,13 @@ ScVbaWindow::getWindowState() throw (uno::RuntimeException) sal_Int32 nwindowState = xlNormal; ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame(); - SfxTopViewFrame *pTop= PTR_CAST( SfxTopViewFrame, pViewFrame -> GetTopViewFrame() ); - if ( pTop ) + WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow(); + if ( pWork ) { - WorkWindow* pWork = (WorkWindow*) pTop->GetTopFrame_Impl()->GetSystemWindow(); - if ( pWork ) - { - if ( pWork -> IsMaximized()) - nwindowState = xlMaximized; - else if (pWork -> IsMinimized()) - nwindowState = xlMinimized; - } + if ( pWork -> IsMaximized()) + nwindowState = xlMaximized; + else if (pWork -> IsMinimized()) + nwindowState = xlMinimized; } return uno::makeAny( nwindowState ); } @@ -422,21 +418,17 @@ ScVbaWindow::setWindowState( const uno::Any& _windowstate ) throw (uno::RuntimeE _windowstate >>= nwindowState; ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame(); - SfxTopViewFrame *pTop= PTR_CAST( SfxTopViewFrame, pViewFrame -> GetTopViewFrame() ); - if ( pTop ) + WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow(); + if ( pWork ) { - WorkWindow* pWork = (WorkWindow*) pTop->GetTopFrame_Impl()->GetSystemWindow(); - if ( pWork ) - { - if ( nwindowState == xlMaximized) - pWork -> Maximize(); - else if (nwindowState == xlMinimized) - pWork -> Minimize(); - else if (nwindowState == xlNormal) - pWork -> Restore(); - else - throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Invalid Parameter" ) ), uno::Reference< uno::XInterface >() ); - } + if ( nwindowState == xlMaximized) + pWork -> Maximize(); + else if (nwindowState == xlMinimized) + pWork -> Minimize(); + else if (nwindowState == xlNormal) + pWork -> Restore(); + else + throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Invalid Parameter" ) ), uno::Reference< uno::XInterface >() ); } } diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index 916e670ec5b1..a461c54f255e 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -42,6 +42,7 @@ #include <svx/hlnkitem.hxx> #include <sfx2/app.hxx> #include <sfx2/bindings.hxx> +#include <sfx2/childwin.hxx> #include <sfx2/objface.hxx> #include <sfx2/request.hxx> #include <sfx2/viewfrm.hxx> @@ -518,7 +519,7 @@ void ScCellShell::GetState(SfxItemSet &rSet) // removed: SID_BORDER_OBJECT (old Basic) ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); -// BOOL bOle = pTabViewShell->GetViewFrame()->GetFrame()->IsInPlace(); +// BOOL bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace(); // BOOL bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo()); ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScViewData* pData = GetViewData(); @@ -970,6 +971,29 @@ void ScCellShell::GetState(SfxItemSet &rSet) } break; + case SID_SPELL_DIALOG: + { + if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) ) + { + bool bVisible = false; + SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL ); + if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) ) + { + SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich ); + Window* pWin = ( pChild ? pChild->GetWindow() : NULL ); + if ( pWin && pWin->IsVisible() ) + { + bVisible = true; + } + } + if ( !bVisible ) + { + rSet.DisableItem( nWhich ); + } + } + } + break; + } // switch ( nWitch ) nWhich = aIter.NextWhich(); } // while ( nWitch ) diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index aec15fceef9e..95d86032ef56 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -1944,7 +1944,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) aSet.Put( SvxFontItem( aCurFont.GetFamily(), aCurFont.GetName(), aCurFont.GetStyleName(), aCurFont.GetPitch(), aCurFont.GetCharSet(), GetPool().GetWhich(SID_ATTR_CHAR_FONT) ) ); SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( pTabViewShell->GetDialogParent(), aSet, - pTabViewShell->GetViewFrame()->GetFrame()->GetFrameInterface(), RID_SVXDLG_CHARMAP ); + pTabViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP ); if ( pDlg->Execute() == RET_OK ) { diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx index 95ceffc5dc59..086160263739 100644 --- a/sc/source/ui/view/cellsh2.cxx +++ b/sc/source/ui/view/cellsh2.cxx @@ -161,7 +161,7 @@ BOOL lcl_GetSortParam( const ScViewData* pData, ScSortParam& rSortParam ) SCCOL nStartCol = aExternalRange.aStart.Col(); SCROW nEndRow = aExternalRange.aEnd.Row(); SCCOL nEndCol = aExternalRange.aEnd.Col(); - pDoc->GetDataArea( aExternalRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow, FALSE ); + pDoc->GetDataArea( aExternalRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow, FALSE, false ); aExternalRange.aStart.SetRow( nStartRow ); aExternalRange.aStart.SetCol( nStartCol ); aExternalRange.aEnd.SetRow( nEndRow ); @@ -242,7 +242,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq ) SfxViewFrame* pViewFrame = pTabViewShell->GetViewFrame(); BOOL bWasOpen = FALSE; { - uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame()->GetFrameInterface(); + uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface(); uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame( rtl::OUString::createFromAscii("_beamer"), frame::FrameSearchFlag::CHILDREN); diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx index 2cc42635b9b0..ed391f154892 100644 --- a/sc/source/ui/view/cellsh3.cxx +++ b/sc/source/ui/view/cellsh3.cxx @@ -88,7 +88,7 @@ void ScCellShell::Execute( SfxRequest& rReq ) case SID_OPENDLG_FUNCTION: // #53318# inplace macht die EditShell Aerger... //! kann nicht immer umgeschaltet werden ???? - if (!pTabViewShell->GetViewFrame()->GetFrame()->IsInPlace()) + if (!pTabViewShell->GetViewFrame()->GetFrame().IsInPlace()) pTabViewShell->SetDontSwitch(TRUE); // EditShell nicht abschalten // kein break @@ -244,7 +244,7 @@ void ScCellShell::Execute( SfxRequest& rReq ) { if (nSlot == FID_INPUTLINE_BLOCK) { - pTabViewShell->EnterBlock( String(), pData ); + pTabViewShell->EnterBlock( aString, pData ); } else if ( aString.Len() > 0 && ( aString.GetChar(0) == '=' || aString.GetChar(0) == '+' || aString.GetChar(0) == '-' ) ) { diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx index 02dfd77f7460..1e5a6b9da4ae 100644 --- a/sc/source/ui/view/dbfunc.cxx +++ b/sc/source/ui/view/dbfunc.cxx @@ -104,7 +104,7 @@ void ScDBFunc::GotoDBArea( const String& rDBName ) // aktuellen Datenbereich fuer Sortieren / Filtern suchen -ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode, bool bShrinkToData ) +ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode, ScGetDBSelection eSel ) { ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDBData* pData = NULL; @@ -112,27 +112,72 @@ ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode, bool bShrinkToData ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange); if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED ) { - if (bShrinkToData) + bool bShrinkColumnsOnly = false; + if (eSel == SC_DBSEL_ROW_DOWN) { - // Shrink the range to only include data area. - ScDocument* pDoc = pDocSh->GetDocument(); - SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col(); - SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row(); - if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2)) + // Don't alter row range, additional rows may have been selected on + // purpose to append data, or to have a fake header row. + bShrinkColumnsOnly = true; + // Select further rows only if only one row or a portion thereof is + // selected. + if (aRange.aStart.Row() != aRange.aEnd.Row()) + { + // If an area is selected shrink that to the actual used + // columns, don't draw filter buttons for empty columns. + eSel = SC_DBSEL_SHRINK_TO_USED_DATA; + } + else if (aRange.aStart.Col() == aRange.aEnd.Col()) { - aRange.aStart.SetCol(nCol1); - aRange.aEnd.SetCol(nCol2); - aRange.aStart.SetRow(nRow1); - aRange.aEnd.SetRow(nRow2); + // One cell only, if it is not marked obtain entire used data + // area. + const ScMarkData& rMarkData = GetViewData()->GetMarkData(); + if (!(rMarkData.IsMarked() || rMarkData.IsMultiMarked())) + eSel = SC_DBSEL_KEEP; } } - pData = pDocSh->GetDBData( aRange, eMode, FALSE ); + switch (eSel) + { + case SC_DBSEL_SHRINK_TO_SHEET_DATA: + { + // Shrink the selection to sheet data area. + ScDocument* pDoc = pDocSh->GetDocument(); + SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col(); + SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row(); + if (pDoc->ShrinkToDataArea( aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2)) + { + aRange.aStart.SetCol(nCol1); + aRange.aEnd.SetCol(nCol2); + aRange.aStart.SetRow(nRow1); + aRange.aEnd.SetRow(nRow2); + } + } + break; + case SC_DBSEL_SHRINK_TO_USED_DATA: + case SC_DBSEL_ROW_DOWN: + { + // Shrink the selection to actual used area. + ScDocument* pDoc = pDocSh->GetDocument(); + SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col(); + SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row(); + if (pDoc->ShrinkToUsedDataArea( aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2, bShrinkColumnsOnly)) + { + aRange.aStart.SetCol(nCol1); + aRange.aEnd.SetCol(nCol2); + aRange.aStart.SetRow(nRow1); + aRange.aEnd.SetRow(nRow2); + } + } + break; + default: + ; // nothing + } + pData = pDocSh->GetDBData( aRange, eMode, eSel ); } else if ( eMode != SC_DB_OLD ) pData = pDocSh->GetDBData( ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() ), - eMode, FALSE ); + eMode, SC_DBSEL_KEEP ); if ( pData && bMark ) { @@ -290,7 +335,7 @@ void ScDBFunc::ToggleAutoFilter() ScQueryParam aParam; ScDocument* pDoc = GetViewData()->GetDocument(); - ScDBData* pDBData = GetDBData( FALSE ); + ScDBData* pDBData = GetDBData( FALSE, SC_DB_MAKE, SC_DBSEL_ROW_DOWN ); pDBData->SetByRow( TRUE ); //! Undo, vorher abfragen ?? pDBData->GetQueryParam( aParam ); diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 2ef65f596c34..406fdab9c824 100644..100755 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -689,8 +689,41 @@ void ScDBFunc::DeletePivotTable() else ErrorMessage(STR_PIVOT_NOTFOUND); } +ULONG RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, BOOL bRecord, BOOL bApi ) +{ + if( !pDPObj ) + return STR_PIVOT_NOTFOUND; + + if( !pDoc ) + return static_cast<ULONG>(-1); + + if( !pDocSh && ( pDocSh = PTR_CAST( ScDocShell, pDoc->GetDocumentShell() ) ) == NULL ) + return static_cast<ULONG>(-1); + + if( ULONG nErrId = pDPObj->RefreshCache() ) + return nErrId; + else if ( nErrId == 0 ) + { + //Refresh all dpobjects + ScDPCollection* pDPCollection = pDoc->GetDPCollection(); + USHORT nCount = pDPCollection->GetCount(); + for (USHORT i=0; i<nCount; i++) + { + if ( (*pDPCollection)[i]->GetCacheId() == pDPObj->GetCacheId() ) + { + ScDBDocFunc aFunc( * pDocSh ); + if ( !aFunc.DataPilotUpdate( (*pDPCollection)[i], (*pDPCollection)[i], bRecord, bApi ) ) + break; + } + } -void ScDBFunc::RecalcPivotTable() + return nErrId; + } + + return 0U; +} + +ULONG ScDBFunc::RecalcPivotTable() { ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDocument* pDoc = GetViewData()->GetDocument(); @@ -702,12 +735,26 @@ void ScDBFunc::RecalcPivotTable() GetViewData()->GetTabNo() ); if ( pDPObj ) { - ScDBDocFunc aFunc( *pDocSh ); - aFunc.DataPilotUpdate( pDPObj, pDPObj, TRUE, FALSE ); - CursorPosChanged(); // shells may be switched + // Wang Xu Ming -- 2009-6-17 + // DataPilot Migration + //ScDBDocFunc aFunc( *pDocSh ); + //aFunc.DataPilotUpdate( pDPObj, pDPObj, TRUE, FALSE ); + //CursorPosChanged(); // shells may be switched + ULONG nErrId = RefreshDPObject( pDPObj, pDoc, pDocSh, TRUE, FALSE );//pDPObj->RefreshCache(); + if ( nErrId == 0 ) + { + // There is no undo for the refresh of the cache table, but the undo history for cell changes + // remains valid and should be preserved, so the history isn't cleared here. + //GetViewData()->GetDocShell()->GetUndoManager()->Clear(); + } + else if (nErrId <= USHRT_MAX) + ErrorMessage(static_cast<USHORT>(nErrId)); + return nErrId; + // End Comments } else ErrorMessage(STR_PIVOT_NOTFOUND); + return STR_PIVOT_NOTFOUND; } void ScDBFunc::GetSelectedMemberList( ScStrCollection& rEntries, long& rDimension ) diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 837cee2698b3..311bcf8c24b2 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -529,7 +529,7 @@ void ScDrawView::MarkListHasChanged() // Verben anpassen SfxViewFrame* pViewFrame = pViewSh->GetViewFrame(); - BOOL bOle = pViewSh->GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = pViewSh->GetViewFrame()->GetFrame().IsInPlace(); if ( pOle2Obj && !bOle ) { uno::Reference < embed::XEmbeddedObject > xObj = pOle2Obj->GetObjRef(); @@ -570,16 +570,13 @@ void ScDrawView::MarkListHasChanged() if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + SfxFrame& rFrame = pViewFrame->GetFrame(); + uno::Reference<frame::XController> xController = rFrame.GetController(); + if (xController.is()) { - uno::Reference<frame::XController> xController = pFrame->GetController(); - if (xController.is()) - { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp) - pImp->SelectionChanged(); - } + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->SelectionChanged(); } } diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index cd55e4f72c34..b8eeb868809e 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -2407,24 +2407,20 @@ long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController(); + if (xController.is()) { - com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pFrame->GetController(); - if (xController.is()) + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp && pImp->IsMouseListening()) { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp && pImp->IsMouseListening()) - { - ::com::sun::star::awt::MouseEvent aEvent; - lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() ); - if ( rNEvt.GetWindow() ) - aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); - if ( nType == EVENT_MOUSEBUTTONDOWN) - pImp->MousePressed( aEvent ); - else - pImp->MouseReleased( aEvent ); - } + ::com::sun::star::awt::MouseEvent aEvent; + lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() ); + if ( rNEvt.GetWindow() ) + aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); + if ( nType == EVENT_MOUSEBUTTONDOWN) + pImp->MousePressed( aEvent ); + else + pImp->MouseReleased( aEvent ); } } } @@ -2689,9 +2685,32 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) if ( bMouse ) { + SCsCOL nCellX = -1; + SCsROW nCellY = -1; + pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY); + ScDocument* pDoc = pViewData->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab); + bool bSelectAllowed = true; + if ( pProtect && pProtect->isProtected() ) + { + // This sheet is protected. Check if a context menu is allowed on this cell. + bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED); + bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); + bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); + + if (bCellProtected) + bSelectAllowed = bSelProtected; + else + bSelectAllowed = bSelUnprotected; + } + if (!bSelectAllowed) + // Selecting this cell is not allowed, neither is context menu. + return; + // #i18735# First select the item under the mouse pointer. // This can change the selection, and the view state (edit mode, etc). - SelectForContextMenu( aPosPixel ); + SelectForContextMenu( aPosPixel, nCellX, nCellY ); } BOOL bDone = FALSE; @@ -2786,15 +2805,12 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) } } -void ScGridWindow::SelectForContextMenu( const Point& rPosPixel ) +void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY ) { // #i18735# if the click was outside of the current selection, // the cursor is moved or an object at the click position selected. // (see SwEditWin::SelectMenuPosition in Writer) - SCsCOL nCellX; - SCsROW nCellY; - pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nCellX, nCellY ); ScTabView* pView = pViewData->GetView(); ScDrawView* pDrawView = pView->GetScDrawView(); diff --git a/sc/source/ui/view/hdrcont.cxx b/sc/source/ui/view/hdrcont.cxx index 511463db8a10..6c389d496b73 100644 --- a/sc/source/ui/view/hdrcont.cxx +++ b/sc/source/ui/view/hdrcont.cxx @@ -44,6 +44,7 @@ #include "scmod.hxx" // Optionen #include "inputopt.hxx" // Optionen #include "gridmerg.hxx" +#include "document.hxx" // ----------------------------------------------------------------------- @@ -120,7 +121,7 @@ void ScHeaderControl::SetWidth( long nNew ) } } -__EXPORT ScHeaderControl::~ScHeaderControl() +ScHeaderControl::~ScHeaderControl() { } @@ -262,7 +263,7 @@ void ScHeaderControl::DrawShadedRect( long nStart, long nEnd, const Color& rBase // Paint // -void __EXPORT ScHeaderControl::Paint( const Rectangle& rRect ) +void ScHeaderControl::Paint( const Rectangle& rRect ) { // fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren // Linien zusammengefasst @@ -652,7 +653,46 @@ SCCOLROW ScHeaderControl::GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder ) return nHitNo; } -void __EXPORT ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) +bool ScHeaderControl::IsSelectionAllowed(SCCOLROW nPos) const +{ + ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()); + if (!pViewSh) + return false; + + ScViewData* pViewData = pViewSh->GetViewData(); + USHORT nTab = pViewData->GetTabNo(); + ScDocument* pDoc = pViewData->GetDocument(); + const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab); + bool bSelectAllowed = true; + if ( pProtect && pProtect->isProtected() ) + { + // This sheet is protected. Check if a context menu is allowed on this cell. + bool bCellsProtected = false; + if (bVertical) + { + // row header + SCROW nRPos = static_cast<SCROW>(nPos); + bCellsProtected = pDoc->HasAttrib(0, nRPos, nTab, MAXCOL, nRPos, nTab, HASATTR_PROTECTED); + } + else + { + // column header + SCCOL nCPos = static_cast<SCCOL>(nPos); + bCellsProtected = pDoc->HasAttrib(nCPos, 0, nTab, nCPos, MAXROW, nTab, HASATTR_PROTECTED); + } + + bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); + bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); + + if (bCellsProtected) + bSelectAllowed = bSelProtected; + else + bSelectAllowed = bSelUnprotected; + } + return bSelectAllowed; +} + +void ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) { if (IsDisabled()) return; @@ -662,6 +702,8 @@ void __EXPORT ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) BOOL bFound; SCCOLROW nHitNo = GetMousePos( rMEvt, bFound ); + if (!IsSelectionAllowed(nHitNo)) + return; if ( bFound && rMEvt.IsLeft() && ResizeAllowed() ) { @@ -717,7 +759,7 @@ void __EXPORT ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) } } -void __EXPORT ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt ) +void ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt ) { if ( IsDisabled() ) return; @@ -770,7 +812,7 @@ void __EXPORT ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt ) } } -void __EXPORT ScHeaderControl::MouseMove( const MouseEvent& rMEvt ) +void ScHeaderControl::MouseMove( const MouseEvent& rMEvt ) { if ( IsDisabled() ) { @@ -820,7 +862,7 @@ void ScHeaderControl::Tracking( const TrackingEvent& rTEvt ) MouseMove( rTEvt.GetMouseEvent() ); } -void __EXPORT ScHeaderControl::Command( const CommandEvent& rCEvt ) +void ScHeaderControl::Command( const CommandEvent& rCEvt ) { USHORT nCmd = rCEvt.GetCommand(); if ( nCmd == COMMAND_CONTEXTMENU ) @@ -845,8 +887,11 @@ void __EXPORT ScHeaderControl::Command( const CommandEvent& rCEvt ) MouseEvent aMEvt( rCEvt.GetMousePosPixel() ); BOOL bBorder; SCCOLROW nPos = GetMousePos( aMEvt, bBorder ); - USHORT nTab = pViewData->GetTabNo(); + if (!IsSelectionAllowed(nPos)) + // Selecting this cell is not allowed, neither is context menu. + return; + SCTAB nTab = pViewData->GetTabNo(); ScRange aNewRange; if ( bVertical ) aNewRange = ScRange( 0, sal::static_int_cast<SCROW>(nPos), nTab, @@ -935,7 +980,7 @@ void ScHeaderControl::ShowDragHelp() } } -void __EXPORT ScHeaderControl::RequestHelp( const HelpEvent& rHEvt ) +void ScHeaderControl::RequestHelp( const HelpEvent& rHEvt ) { // Wenn eigene QuickHelp angezeigt wird, nicht durch RequestHelp // wieder wegnehmen lassen diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk index e40d6da5c09d..feeacc865fba 100644 --- a/sc/source/ui/view/makefile.mk +++ b/sc/source/ui/view/makefile.mk @@ -156,6 +156,9 @@ EXCEPTIONSFILES= \ $(SLO)$/scextopt.obj \ $(SLO)$/tabvwshb.obj \ $(SLO)$/viewdata.obj \ + $(SLO)$/viewfunc.obj \ + $(SLO)$/viewfun2.obj \ + $(SLO)$/viewfun3.obj \ $(SLO)$/viewfun5.obj \ $(SLO)$/viewfun7.obj \ $(SLO)$/reffact.obj diff --git a/sc/source/ui/view/prevwsh.cxx b/sc/source/ui/view/prevwsh.cxx index f4b976b00e4d..38d5144274c5 100644 --- a/sc/source/ui/view/prevwsh.cxx +++ b/sc/source/ui/view/prevwsh.cxx @@ -44,7 +44,6 @@ #include <sfx2/dispatch.hxx> #include <sfx2/objface.hxx> #include <sfx2/request.hxx> -#include <sfx2/topfrm.hxx> #include <svtools/printdlg.hxx> #include <svl/stritem.hxx> #include <svl/whiter.hxx> @@ -151,7 +150,7 @@ void ScPreviewShell::Construct( Window* pParent ) ScPreviewShell::ScPreviewShell( SfxViewFrame* pViewFrame, SfxViewShell* pOldSh ) : - SfxViewShell( pViewFrame, SFX_VIEW_MAXIMIZE_FIRST | SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ), + SfxViewShell( pViewFrame, SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ), pDocShell( (ScDocShell*)pViewFrame->GetObjectShell() ), nSourceDesignMode( SC_FORCEMODE_NONE ), pAccessibilityBroadcaster( NULL ) diff --git a/sc/source/ui/view/spelldialog.cxx b/sc/source/ui/view/spelldialog.cxx index 8ff816263b4f..a178b0a0ada6 100644 --- a/sc/source/ui/view/spelldialog.cxx +++ b/sc/source/ui/view/spelldialog.cxx @@ -200,7 +200,12 @@ void ScSpellDialogChildWindow::Init() ScEditableTester aTester( mpDoc, rMarkData ); if( !aTester.IsEditable() ) { - mpViewShell->ErrorMessage( aTester.GetMessageId() ); + // #i85751# Don't show a ErrorMessage here, because the vcl + // parent of the InfoBox is not fully initialized yet. + // This leads to problems in the modality behaviour of the + // ScSpellDialogChildWindow. + + //mpViewShell->ErrorMessage( aTester.GetMessageId() ); return; } } diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index b8656e1e25a0..4938defa437d 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -1169,7 +1169,7 @@ BOOL ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos ) const CommandWheelData* pData = rCEvt.GetWheelData(); if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM ) { - if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame()->IsInPlace() ) + if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() ) { // for ole inplace editing, the scale is defined by the visarea and client size // and can't be changed directly @@ -1626,7 +1626,7 @@ void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY return; SCROW nEndPos = MAXROW; - if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame()->IsInPlace() ) + if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() ) { // fuer OLE Inplace immer MAXROW @@ -2455,16 +2455,13 @@ void ScTabView::SetNewVisArea() SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + SfxFrame& rFrame = pViewFrame->GetFrame(); + com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController(); + if (xController.is()) { - com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pFrame->GetController(); - if (xController.is()) - { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp) - pImp->VisAreaChanged(); - } + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->VisAreaChanged(); } } if (aViewData.GetViewShell()->HasAccessibilityObjects()) diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index b61c3ade64f4..750e49ec2334 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -367,16 +367,12 @@ void ScTabView::SelectionChanged() SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController(); + if (xController.is()) { - uno::Reference<frame::XController> xController = pFrame->GetController(); - if (xController.is()) - { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp) - pImp->SelectionChanged(); - } + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->SelectionChanged(); } } @@ -1427,7 +1423,7 @@ void ScTabView::MarkDataArea( BOOL bIncludeCursor ) SCCOL nEndCol = nStartCol; SCROW nEndRow = nStartRow; - pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor ); + pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false ); HideAllCursors(); DoneBlockMode(); diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx index 460f31b07175..bc5c94c271e2 100644 --- a/sc/source/ui/view/tabview5.cxx +++ b/sc/source/ui/view/tabview5.cxx @@ -334,16 +334,12 @@ void ScTabView::TabChanged() SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController(); + if (xController.is()) { - uno::Reference<frame::XController> xController = pFrame->GetController(); - if (xController.is()) - { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp) - pImp->SheetChanged(); - } + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->SheetChanged(); } } } diff --git a/sc/source/ui/view/tabvwsh2.cxx b/sc/source/ui/view/tabvwsh2.cxx index ab0dae319105..ca47535ad2cf 100644 --- a/sc/source/ui/view/tabvwsh2.cxx +++ b/sc/source/ui/view/tabvwsh2.cxx @@ -451,7 +451,7 @@ void ScTabViewShell::GetDrawState(SfxItemSet &rSet) case SID_DRAW_CHART: { - BOOL bOle = GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = GetViewFrame()->GetFrame().IsInPlace(); if ( bOle || !SvtModuleOptions().IsChart() ) rSet.DisableItem( nWhich ); } diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx index 493760d7a6ba..c291d01d71c2 100644 --- a/sc/source/ui/view/tabvwsh3.cxx +++ b/sc/source/ui/view/tabvwsh3.cxx @@ -41,7 +41,6 @@ #include <sfx2/dispatch.hxx> #include <sfx2/passwd.hxx> #include <sfx2/request.hxx> -#include <sfx2/topfrm.hxx> #include <svl/ptitem.hxx> #include <svl/stritem.hxx> #include <tools/urlobj.hxx> @@ -482,7 +481,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) { if ( pDocSh->GetTitle() == aStrDocName ) { - pViewFrame = SfxViewFrame::GetFirst( pDocSh, TYPE(SfxTopViewFrame) ); + pViewFrame = SfxViewFrame::GetFirst( pDocSh ); bFound = ( NULL != pViewFrame ); } @@ -490,8 +489,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) } if ( bFound ) - if ( pViewFrame->ISA(SfxTopViewFrame) ) - pViewFrame->GetFrame()->Appear(); + pViewFrame->GetFrame().Appear(); rReq.Ignore();//XXX wird von SFX erledigt } @@ -502,7 +500,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) case SID_PRINTPREVIEW: { - if ( !pThisFrame->GetFrame()->IsInPlace() ) // nicht bei OLE + if ( !pThisFrame->GetFrame().IsInPlace() ) // nicht bei OLE { // print preview is now always in the same frame as the tab view // -> always switch this frame back to normal view diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index d7a0e2b080b0..ed09ec85ee8c 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -32,7 +32,6 @@ // INCLUDE --------------------------------------------------------------- -#include <sfx2/topfrm.hxx> #include "scitems.hxx" #include <editeng/eeitem.hxx> @@ -263,7 +262,7 @@ void __EXPORT ScTabViewShell::Deactivate(BOOL bMDI) DeActivateOlk( GetViewData() ); ActivateView( FALSE, FALSE ); - if ( GetViewFrame()->GetFrame()->IsInPlace() ) // inplace + if ( GetViewFrame()->GetFrame().IsInPlace() ) // inplace GetViewData()->GetDocShell()->UpdateOle(GetViewData(),TRUE); if ( pHdl ) @@ -291,8 +290,7 @@ void ScTabViewShell::SetActive() #if 0 SfxViewFrame* pFrame = GetViewFrame(); - if ( pFrame->ISA(SfxTopViewFrame) ) - pFrame->GetFrame()->Appear(); + pFrame->GetFrame().Appear(); SFX_APP()->SetViewFrame( pFrame ); // immer erst Appear, dann SetViewFrame (#29290#) #endif @@ -390,7 +388,7 @@ void __EXPORT ScTabViewShell::AdjustPosSizePixel( const Point &rPos, const Size void __EXPORT ScTabViewShell::InnerResizePixel( const Point &rOfs, const Size &rSize ) { Size aNewSize( rSize ); - if ( GetViewFrame()->GetFrame()->IsInPlace() ) + if ( GetViewFrame()->GetFrame().IsInPlace() ) { SvBorder aBorder; GetBorderSize( aBorder, rSize ); @@ -1335,13 +1333,10 @@ ScTabViewObj* lcl_GetViewObj( ScTabViewShell& rShell ) SfxViewFrame* pViewFrame = rShell.GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) - { - uno::Reference<frame::XController> xController = pFrame->GetController(); - if (xController.is()) - pRet = ScTabViewObj::getImplementation( xController ); - } + SfxFrame& rFrame = pViewFrame->GetFrame(); + uno::Reference<frame::XController> xController = rFrame.GetController(); + if (xController.is()) + pRet = ScTabViewObj::getImplementation( xController ); } return pRet; } @@ -1382,8 +1377,7 @@ void ScTabViewShell::StartSimpleRefDialog( // Then the view has to be activated first, the same way as in Execute for SID_CURRENTDOC. // Can't use GrabFocus here, because it needs to take effect immediately. - if ( pViewFrm->ISA(SfxTopViewFrame) ) - pViewFrm->GetFrame()->Appear(); + pViewFrm->GetFrame().Appear(); } USHORT nId = ScSimpleRefDlgWrapper::GetChildWindowId(); @@ -1525,7 +1519,7 @@ BOOL ScTabViewShell::TabKeyInput(const KeyEvent& rKEvt) // container app and are executed during Window::KeyInput. // -> don't pass keys to input handler that would be used there // but should call slots instead. - BOOL bParent = ( GetViewFrame()->GetFrame()->IsInPlace() && eFunc != KEYFUNC_DONTKNOW ); + BOOL bParent = ( GetViewFrame()->GetFrame().IsInPlace() && eFunc != KEYFUNC_DONTKNOW ); if( !bUsed && !bDraw && nCode != KEY_RETURN && !bParent ) bUsed = pScMod->InputKeyEvent( rKEvt, TRUE ); // Eingabe @@ -1645,8 +1639,6 @@ FASTBOOL __EXPORT ScTabViewShell::KeyInput( const KeyEvent &rKeyEvent ) //------------------------------------------------------------------ -// SfxViewShell( pViewFrame, SFX_VIEW_MAXIMIZE_FIRST | SFX_VIEW_DISABLE_ACCELS ), - #define __INIT_ScTabViewShell \ eCurOST(OST_NONE), \ nDrawSfxId(0), \ @@ -1736,7 +1728,7 @@ void ScTabViewShell::Construct( BYTE nForceDesignMode ) // show the right cells GetViewData()->SetScreenPos( bNegativePage ? aVisArea.TopRight() : aVisArea.TopLeft() ); - if ( GetViewFrame()->GetFrame()->IsInPlace() ) // inplace + if ( GetViewFrame()->GetFrame().IsInPlace() ) // inplace { pDocSh->SetInplace( TRUE ); // schon so initialisiert if (pDoc->IsEmbedded()) @@ -1876,7 +1868,7 @@ void ScTabViewShell::Construct( BYTE nForceDesignMode ) // #105575#; update only in the first creation of the ViewShell pDocSh->SetUpdateEnabled(FALSE); - if ( GetViewFrame()->GetFrame()->IsInPlace() ) + if ( GetViewFrame()->GetFrame().IsInPlace() ) UpdateHeaderWidth(); // The implace activation requires headers to be calculated SvBorder aBorder; @@ -1898,7 +1890,7 @@ void ScTabViewShell::Construct( BYTE nForceDesignMode ) //UNUSED2008-05 //UNUSED2008-05 UpdatePageBreakData(); //UNUSED2008-05 -//UNUSED2008-05 /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame()->GetFrameInterface(); +//UNUSED2008-05 /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface(); //UNUSED2008-05 if (xFrame.is()) //UNUSED2008-05 xFrame->setComponent( uno::Reference<awt::XWindow>(), new ScTabViewObj( this ) );*/ //UNUSED2008-05 // make Controller known to SFX @@ -1914,7 +1906,7 @@ void ScTabViewShell::Construct( BYTE nForceDesignMode ) ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame, SfxViewShell* pOldSh ) : - SfxViewShell( pViewFrame, SFX_VIEW_MAXIMIZE_FIRST | SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ), + SfxViewShell( pViewFrame, SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ), ScDBFunc( &pViewFrame->GetWindow(), (ScDocShell&)*pViewFrame->GetObjectShell(), this ), __INIT_ScTabViewShell { @@ -1950,7 +1942,7 @@ ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame, SetZoomType( rAppOpt.GetZoomType(), TRUE ); } - /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame()->GetFrameInterface(); + /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface(); if (xFrame.is()) xFrame->setComponent( uno::Reference<awt::XWindow>(), new ScTabViewObj( this ) );*/ // make Controller known to SFX diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx index 5940b2a3b950..7734f3e24ff8 100644 --- a/sc/source/ui/view/tabvwsha.cxx +++ b/sc/source/ui/view/tabvwsha.cxx @@ -174,7 +174,7 @@ void __EXPORT ScTabViewShell::GetState( SfxItemSet& rSet ) USHORT nMyId = 0; SfxViewFrame* pThisFrame = GetViewFrame(); - BOOL bOle = GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = GetViewFrame()->GetFrame().IsInPlace(); SCTAB nTabCount = pDoc->GetTableCount(); SCTAB nTabSelCount = rMark.GetSelectCount(); diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx index 5e69e5c9bf99..8f4a203ea14d 100644 --- a/sc/source/ui/view/tabvwshb.cxx +++ b/sc/source/ui/view/tabvwshb.cxx @@ -432,7 +432,7 @@ void ScTabViewShell::ExecDrawIns(SfxRequest& rReq) void ScTabViewShell::GetDrawInsState(SfxItemSet &rSet) { - BOOL bOle = GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = GetViewFrame()->GetFrame().IsInPlace(); BOOL bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo()); ScDocShell* pDocShell = ( GetViewData() ? GetViewData()->GetDocShell() : NULL ); bool bShared = ( pDocShell ? pDocShell->IsDocShared() : false ); diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx index 74a824a709d6..7d1cbb05761b 100644 --- a/sc/source/ui/view/tabvwshc.cxx +++ b/sc/source/ui/view/tabvwshc.cxx @@ -175,7 +175,7 @@ SfxModelessDialog* ScTabViewShell::CreateRefDialog( SCITEM_QUERYDATA, SCITEM_QUERYDATA ); - ScDBData* pDBData = GetDBData(); + ScDBData* pDBData = GetDBData( TRUE, SC_DB_MAKE, SC_DBSEL_ROW_DOWN); pDBData->GetQueryParam( aQueryParam ); ScQueryItem aItem( SCITEM_QUERYDATA, GetViewData(), &aQueryParam ); @@ -200,7 +200,7 @@ SfxModelessDialog* ScTabViewShell::CreateRefDialog( SCITEM_QUERYDATA, SCITEM_QUERYDATA ); - ScDBData* pDBData = GetDBData(); + ScDBData* pDBData = GetDBData( TRUE, SC_DB_MAKE, SC_DBSEL_ROW_DOWN); pDBData->GetQueryParam( aQueryParam ); aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA, diff --git a/sc/source/ui/view/tabvwshd.cxx b/sc/source/ui/view/tabvwshd.cxx index 6074d03a67aa..4ef5186a25a0 100644 --- a/sc/source/ui/view/tabvwshd.cxx +++ b/sc/source/ui/view/tabvwshd.cxx @@ -40,7 +40,7 @@ #include <sfx2/childwin.hxx> #include <sfx2/request.hxx> -#include <sfx2/topfrm.hxx> +#include <sfx2/viewfrm.hxx> #include <vcl/svapp.hxx> #include <vcl/wrkwin.hxx> diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 627f214c4ec6..5fcd094acffc 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -85,6 +85,7 @@ #include "inputwin.hxx" #include "funcdesc.hxx" #include "docuno.hxx" +#include "charthelper.hxx" // STATIC DATA --------------------------------------------------------------- @@ -2800,6 +2801,10 @@ void ScViewFunc::MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy ) nNewTab--; SetTabNo( nNewTab, TRUE ); + + //#i29848# adjust references to data on the copied sheet + if( bCopy ) + ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab ); } } diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx index 794ee488afed..9697cae3a57e 100644 --- a/sc/source/ui/view/viewfun5.cxx +++ b/sc/source/ui/view/viewfun5.cxx @@ -387,7 +387,7 @@ BOOL ScViewFunc::PasteDataFormat( ULONG nFormatId, // Creation of database area "Import1" isn't here, but in the DocShell // slot execute, so it can be added to the undo action - ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, FALSE ); + ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, SC_DBSEL_KEEP ); String sTarget; if (pDBData) sTarget = pDBData->GetName(); diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx index c348b843cfdc..f73346398ea1 100644 --- a/sc/source/ui/view/viewutil.cxx +++ b/sc/source/ui/view/viewutil.cxx @@ -370,7 +370,7 @@ BOOL ScViewUtil::ExecuteCharMap( const SvxFontItem& rOldFont, SfxAllItemSet aSet( rFrame.GetObjectShell()->GetPool() ); aSet.Put( SfxBoolItem( FN_PARAM_1, FALSE ) ); aSet.Put( SvxFontItem( rOldFont.GetFamily(), rOldFont.GetFamilyName(), rOldFont.GetStyleName(), rOldFont.GetPitch(), rOldFont.GetCharSet(), aSet.GetPool()->GetWhich( SID_ATTR_CHAR_FONT ) ) ); - SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame()->GetFrameInterface(), RID_SVXDLG_CHARMAP ); + SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP ); if ( pDlg->Execute() == RET_OK ) { SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP, FALSE ); diff --git a/sc/util/hidother.src b/sc/util/hidother.src index 48dfebdf5c2c..ffdb5c329399 100644 --- a/sc/util/hidother.src +++ b/sc/util/hidother.src @@ -81,6 +81,7 @@ hidspecial HID_SC_APPEND_NAME { HelpID = HID_SC_APPEND_NAME; }; hidspecial HID_SC_AUTOFMT_NAME { HelpID = HID_SC_AUTOFMT_NAME; }; hidspecial HID_SC_ADD_AUTOFMT { HelpID = HID_SC_ADD_AUTOFMT; }; hidspecial HID_SC_REN_AFMT_NAME { HelpID = HID_SC_REN_AFMT_NAME; }; +hidspecial HID_SC_REN_AFMT_DLG { HelpID = HID_SC_REN_AFMT_DLG; }; hidspecial HID_SC_RENAME_AUTOFMT { HelpID = HID_SC_RENAME_AUTOFMT; }; hidspecial HID_PASSWD_TABLE { HelpID = HID_PASSWD_TABLE; }; hidspecial HID_PASSWD_DOC { HelpID = HID_PASSWD_DOC; }; diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk index 0635ca4732df..275b3d22548a 100644 --- a/sc/util/makefile.mk +++ b/sc/util/makefile.mk @@ -139,7 +139,7 @@ LIB4FILES= \ SHL2TARGET= scd$(DLLPOSTFIX) SHL2IMPLIB= scdimp -SHL2VERSIONMAP= scd.map +SHL2VERSIONMAP=$(SOLARENV)/src/component.map SHL2DEF=$(MISC)$/$(SHL2TARGET).def DEF2NAME= $(SHL2TARGET) @@ -277,6 +277,7 @@ LIB8OBJFILES = \ $(SLO)$/dapidata.obj \ $(SLO)$/crdlg.obj \ $(SLO)$/scuiasciiopt.obj \ + $(SLO)$/textimportoptions.obj \ $(SLO)$/scuiautofmt.obj \ $(SLO)$/dpgroupdlg.obj \ $(SLO)$/editfield.obj @@ -287,7 +288,7 @@ TARGET_VBA=vbaobj SHL9TARGET=$(TARGET_VBA)$(DLLPOSTFIX).uno SHL9IMPLIB= i$(TARGET_VBA) -SHL9VERSIONMAP=$(TARGET_VBA).map +SHL9VERSIONMAP=$(SOLARENV)/src/component.map SHL9DEF=$(MISC)$/$(SHL9TARGET).def DEF9NAME=$(SHL9TARGET) .IF "$(VBA_EXTENSION)"=="YES" diff --git a/sc/util/sc.map b/sc/util/sc.map deleted file mode 100644 index bfd1401a7685..000000000000 --- a/sc/util/sc.map +++ /dev/null @@ -1,8 +0,0 @@ -SC_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/sc/util/scd.map b/sc/util/scd.map deleted file mode 100644 index bfd1401a7685..000000000000 --- a/sc/util/scd.map +++ /dev/null @@ -1,8 +0,0 @@ -SC_1_0 { - global: - component_getImplementationEnvironment; - component_writeInfo; - component_getFactory; - local: - *; -}; diff --git a/sc/util/scfilt.map b/sc/util/scfilt.map index 589736f24eb1..642b8db15088 100644 --- a/sc/util/scfilt.map +++ b/sc/util/scfilt.map @@ -1,4 +1,4 @@ -SCFILT_1_0 { +UDK_3_0_0 { global: ScFilterCreate; local: diff --git a/sc/util/scui.map b/sc/util/scui.map index f40bd255fe1d..ad5e33836c7c 100644 --- a/sc/util/scui.map +++ b/sc/util/scui.map @@ -1,4 +1,4 @@ -SWUI_1_0 { +UDK_3_0_0 { global: CreateDialogFactory; local: diff --git a/sc/util/vbaobj.map b/sc/util/vbaobj.map deleted file mode 100644 index 737cddbfe3df..000000000000 --- a/sc/util/vbaobj.map +++ /dev/null @@ -1,9 +0,0 @@ -OOO_1.1 { - global: - component_getImplementationEnvironment; - component_getFactory; - component_writeInfo; - - local: - *; -}; |