diff options
author | Release Engineers <releng@openoffice.org> | 2008-11-27 15:23:33 +0000 |
---|---|---|
committer | Release Engineers <releng@openoffice.org> | 2008-11-27 15:23:33 +0000 |
commit | 5beec3891e1328a30b6c1fa33c2227ce8381855b (patch) | |
tree | a228838850e863e7659656b49d6da883f3bc0726 /sc | |
parent | 811e7a83cbca79b0779ac2f77fc74b1f99c48439 (diff) |
CWS-TOOLING: integrate CWS koheidatapilot02
2008-11-24 15:34:25 +0100 kohei r264231 : modified ScViewData::IsMultiMarked() to treat simple-filtered areas as simple-marked areas,
for backword compatibility. Simple-filtered areas are not multi-marked areas.
2008-11-07 20:38:51 +0100 kohei r263485 : more unused methods in the header without definitions.
2008-11-07 20:26:25 +0100 kohei r263484 : removed more unused methods.
2008-11-07 19:40:39 +0100 kohei r263481 : removed unused methods based on Caolan's callcatcher output on m35.
2008-11-06 19:32:22 +0100 kohei r263405 : CWS-TOOLING: rebase CWS koheidatapilot02 to trunk@263288 (milestone: DEV300:m35)
2008-10-06 15:18:57 +0200 kohei r262062 : #i94619# allow XDataPilotTable interface to be queried again. Patch submitted by
Noel Power.
2008-10-01 21:49:39 +0200 kohei r262020 : #i90402# don't insert drill-down sheet when the document is in read-only mode.
2008-10-01 03:03:19 +0200 kohei r261982 : #i93918# exclude hidden items and items that are excluded due to
ranks (i.e. top X items).
#i93998# reduce memory consumption of datapilot cache tables by
pooling cache table cell data & use null pointers to represent
empty cells.
2008-09-30 23:35:14 +0200 kohei r261981 : #i92378# keep the layout dialog open when the destination range is not empty
and the user has decided to cancel data pilot creation.
2008-09-30 23:14:55 +0200 kohei r261980 : #i94281# fixed a regression where the data pilot layout dialog fails to
appear on a filtered cell range.
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/dpcachetable.hxx | 87 | ||||
-rw-r--r-- | sc/inc/dpgroup.hxx | 3 | ||||
-rw-r--r-- | sc/inc/dpobject.hxx | 41 | ||||
-rw-r--r-- | sc/inc/dpsave.hxx | 7 | ||||
-rw-r--r-- | sc/inc/dpsdbtab.hxx | 11 | ||||
-rw-r--r-- | sc/inc/dptabdat.hxx | 15 | ||||
-rw-r--r-- | sc/inc/dptabres.hxx | 37 | ||||
-rw-r--r-- | sc/inc/global.hxx | 42 | ||||
-rw-r--r-- | sc/source/core/data/dpcachetable.cxx | 213 | ||||
-rw-r--r-- | sc/source/core/data/dpgroup.cxx | 32 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 111 | ||||
-rw-r--r-- | sc/source/core/data/dpsave.cxx | 93 | ||||
-rw-r--r-- | sc/source/core/data/dpsdbtab.cxx | 16 | ||||
-rw-r--r-- | sc/source/core/data/dpshttab.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/dptabdat.cxx | 38 | ||||
-rw-r--r-- | sc/source/core/data/dptabres.cxx | 116 | ||||
-rw-r--r-- | sc/source/core/data/dptabsrc.cxx | 29 | ||||
-rw-r--r-- | sc/source/core/data/global2.cxx | 86 | ||||
-rw-r--r-- | sc/source/ui/dbgui/pvlaydlg.cxx | 23 | ||||
-rw-r--r-- | sc/source/ui/inc/dbfunc.hxx | 2 | ||||
-rw-r--r-- | sc/source/ui/unoobj/dapiuno.cxx | 3 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh2.cxx | 12 | ||||
-rw-r--r-- | sc/source/ui/view/dbfunc3.cxx | 16 | ||||
-rw-r--r-- | sc/source/ui/view/viewdata.cxx | 3 |
24 files changed, 641 insertions, 406 deletions
diff --git a/sc/inc/dpcachetable.hxx b/sc/inc/dpcachetable.hxx index 4d89dd333979..88451ed748a2 100644 --- a/sc/inc/dpcachetable.hxx +++ b/sc/inc/dpcachetable.hxx @@ -38,8 +38,8 @@ #include "collect.hxx" #include <vector> -#include <set> #include <hash_map> +#include <hash_set> #include <boost/shared_ptr.hpp> #include <com/sun/star/uno/Reference.hxx> @@ -57,62 +57,24 @@ class Date; class ScDocument; class ScRange; class ScDPDimension; +class ScDPCollection; +class ScDPCacheCell; struct ScDPItemData; class Date; // ---------------------------------------------------------------------------- -/** public interface for string-sharing */ -class ScSharedString -{ -public: - static const sal_Int32 EMPTY = 0; - - static const String* getString(sal_Int32 nId); - static sal_Int32 getStringId(const String& aStr); - static 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(); - - private: - typedef ::std::hash_map< String, sal_Int32, ScStringHashCode, ::std::equal_to< String > > SharedStrMap; - - ::std::vector<String> maSharedStrings; - SharedStrMap maSharedStringIds; - sal_Int32 mnStrCount; - }; - - static ::osl::Mutex maStrMutex; - static StringTable maStringTable; -}; - -// ---------------------------------------------------------------------------- - class ScDPCacheTable { public: - /** individual cell within table. */ struct Cell { - SCROW mnCategoryRef; - sal_Int32 mnStrId; - sal_uInt8 mnType; - double mfValue; - bool mbNumeric; + SCROW mnCategoryRef; + ScDPCacheCell* mpContent; Cell(); + ~Cell(); }; /** individual filter item used in SingleFilter and GroupFilter. */ @@ -131,38 +93,47 @@ public: public: /** returns true if the matching condition is met for a single cell value, or false otherwise. */ - virtual bool match(const Cell& rCell) const = 0; + virtual bool match(const ScDPCacheCell& rCell) const = 0; }; /** ordinary single-item filter. */ class SingleFilter : public FilterBase { public: - explicit SingleFilter(); - explicit SingleFilter(sal_Int32 nMatchStrId, double fValue, bool bHasValue); + explicit SingleFilter(ScSimpleSharedString& rSharedString, + sal_Int32 nMatchStrId, double fValue, bool bHasValue); - virtual bool match(const Cell& rCell) const; + virtual bool match(const ScDPCacheCell& rCell) const; - const String getMatchString() const; + const String getMatchString(); double getMatchValue() const; bool hasValue() const; private: + explicit SingleFilter(); + FilterItem maItem; + ScSimpleSharedString mrSharedString; }; /** multi-item (group) filter. */ class GroupFilter : public FilterBase { public: - GroupFilter(); + GroupFilter(ScSimpleSharedString& rSharedString); virtual ~GroupFilter(){} - virtual bool match(const Cell& rCell) const; + virtual bool match(const ScDPCacheCell& rCell) const; + void setMatchIfFound(bool b); void addMatchItem(const String& rStr, double fVal, bool bHasValue); + size_t getMatchItemCount() const; private: + GroupFilter(); + ::std::vector<FilterItem> maItems; + ScSimpleSharedString mrSharedString; + bool mbMatchIfFound; }; /** single filtering criterion. */ @@ -174,10 +145,9 @@ public: Criterion(); }; - ScDPCacheTable(); + ScDPCacheTable(ScDPCollection* pCollection); ~ScDPCacheTable(); - sal_Int32 getHeaderSize() const; sal_Int32 getRowSize() const; sal_Int32 getColSize() const; @@ -203,7 +173,7 @@ 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 ::ScDPCacheTable::Cell* getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty = false) const; + const ScDPCacheCell* getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty = false) const; const String* getFieldName(sal_Int32 nIndex) const; @@ -229,12 +199,14 @@ public: bool empty() const; private: + ScDPCacheTable(); + ScDPCacheTable(const ScDPCacheTable&); + /** * Check if a given row meets all specified criteria. */ bool isRowQualified(sal_Int32 nRow, const ::std::vector<Criterion>& rCriteria, bool bRepeatIfEmpty) const; - void getValueData(ScDocument* pDoc, const ScAddress& rPos, Cell& rCell); - ScDPCacheTable::Cell getSelectedDimension(ScDPDimension* pDim) const; + void getValueData(ScDocument* pDoc, const ScAddress& rPos, ScDPCacheCell& rCell); private: typedef ::boost::shared_ptr<TypedStrCollection> TypedStrCollectionPtr; @@ -251,6 +223,9 @@ private: /** 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; }; diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx index 08a52cd319ff..0fbab349f0a1 100644 --- a/sc/inc/dpgroup.hxx +++ b/sc/inc/dpgroup.hxx @@ -190,13 +190,12 @@ class ScDPGroupTableData : public ScDPTableData void FillGroupValues( ScDPItemData* pItemData, long nCount, const long* pDims ); void CopyFields(const ::std::vector<long>& rFieldDims, ::std::vector<long>& rNewFieldDims); - long* CopyFields( const long* pSourceDims, long nCount ); bool IsNumGroupDimension( long nDimension ) const; void GetNumGroupInfo( long nDimension, ScDPNumGroupInfo& rInfo, bool& rNonInteger, sal_Unicode& rDecimal ); - void ModifyFilterCriteria(::std::vector<ScDPCacheTable::Criterion>& rCriteria) const; + void ModifyFilterCriteria(::std::vector<ScDPCacheTable::Criterion>& rCriteria); public: // takes ownership of pSource diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index e04d4a7750ed..3ba1dfab5e98 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: dpobject.hxx,v $ - * $Revision: 1.14.30.5 $ + * $Revision: 1.15 $ * * This file is part of OpenOffice.org. * @@ -57,10 +57,8 @@ class ScDPSaveData; class ScDPOutput; class ScMultipleReadHeader; class ScMultipleWriteHeader; -#if OLD_PIVOT_IMPLEMENTATION class ScPivot; class ScPivotCollection; -#endif struct ScPivotParam; struct ScImportSourceDesc; struct ScSheetSourceDesc; @@ -186,9 +184,8 @@ public: BOOL FillOldParam(ScPivotParam& rParam, BOOL bForFile) const; BOOL FillLabelData(ScPivotParam& rParam); -#if OLD_PIVOT_IMPLEMENTATION void InitFromOldPivot(const ScPivot& rOld, ScDocument* pDoc, BOOL bSetSource); -#endif + BOOL GetHierarchiesNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xHiers ); BOOL GetHierarchies( sal_Int32 nDim, com::sun::star::uno::Sequence< rtl::OUString >& rHiers ); @@ -242,11 +239,39 @@ 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(); +}; + +// ============================================================================ class ScDPCollection : public Collection { 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); @@ -267,7 +292,11 @@ public: void WriteRefsTo( ScDPCollection& r ) const; String CreateNewName( USHORT nMin = 1 ) const; -//UNUSED2008-05 void EnsureNames(); + + ScSimpleSharedString& GetSharedString(); + + ScDPCacheCell* getCacheCellFromPool(const ScDPCacheCell& rCell); + void clearCacheCellPool(); }; diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index a03ca15f5451..4d1be16e7145 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -45,7 +45,6 @@ namespace com { namespace sun { namespace star { namespace sheet { struct DataPilotFieldLayoutInfo; } } } } -class SvStream; class ScDPDimensionSaveData; // -------------------------------------------------------------------- @@ -64,7 +63,6 @@ private: public: ScDPSaveMember(const String& rName); ScDPSaveMember(const ScDPSaveMember& r); - ScDPSaveMember(SvStream& rStream); ~ScDPSaveMember(); BOOL operator== ( const ScDPSaveMember& r ) const; @@ -82,8 +80,6 @@ public: void WriteToSource( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface>& xMember, sal_Int32 nPosition ); - - void Store( SvStream& rStream ) const; }; @@ -116,7 +112,6 @@ private: public: ScDPSaveDimension(const String& rName, BOOL bDataLayout); ScDPSaveDimension(const ScDPSaveDimension& r); - ScDPSaveDimension(SvStream& rStream); ~ScDPSaveDimension(); BOOL operator== ( const ScDPSaveDimension& r ) const; @@ -170,8 +165,6 @@ public: void WriteToSource( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface>& xDim ); - - void Store( SvStream& rStream ) const; }; diff --git a/sc/inc/dpsdbtab.hxx b/sc/inc/dpsdbtab.hxx index f4874d54263a..84fd36f65ea6 100644 --- a/sc/inc/dpsdbtab.hxx +++ b/sc/inc/dpsdbtab.hxx @@ -33,17 +33,13 @@ #include <com/sun/star/uno/Reference.hxx> -namespace com { namespace sun { namespace star { - namespace lang { - class XMultiServiceFactory; - } -}}} #include "dptabdat.hxx" #include <vector> #include <set> class ScDPCacheTable; +class ScDocument; // -------------------------------------------------------------------- // @@ -74,10 +70,7 @@ private: BOOL OpenDatabase(); public: - ScDatabaseDPData( - ::com::sun::star::uno::Reference< - ::com::sun::star::lang::XMultiServiceFactory > xSMgr, - const ScImportSourceDesc& rImport ); + ScDatabaseDPData(ScDocument* pDoc, const ScImportSourceDesc& rImport); virtual ~ScDatabaseDPData(); virtual long GetColumnCount(); diff --git a/sc/inc/dptabdat.hxx b/sc/inc/dptabdat.hxx index 3545c90ccbee..90953d8c3b4f 100644 --- a/sc/inc/dptabdat.hxx +++ b/sc/inc/dptabdat.hxx @@ -46,6 +46,7 @@ namespace com { namespace sun { namespace star { namespace sheet { }}}} class TypedStrCollection; +class ScSimpleSharedString; // ----------------------------------------------------------------------- @@ -112,6 +113,7 @@ class ScDPDimension; class ScDPLevel; class ScDPInitState; class ScDPResultMember; +class ScDocument; class ScDPTableData { @@ -120,6 +122,7 @@ class ScDPTableData long nLastHier; long nLastLevel; long nLastRet; + ScSimpleSharedString& mrSharedString; public: @@ -146,7 +149,7 @@ public: CalcInfo(); }; - ScDPTableData(); + ScDPTableData(ScDocument* pDoc); virtual ~ScDPTableData(); long GetDatePart( long nDateVal, long nHierarchy, long nLevel ); @@ -165,11 +168,11 @@ public: virtual bool IsRepeatIfEmpty(); - virtual void CreateCacheTable(); - virtual void FilterCacheTable(const ::std::vector<ScDPCacheTable::Criterion>& rCriteria); + virtual void CreateCacheTable() = 0; + virtual void FilterCacheTable(const ::std::vector<ScDPCacheTable::Criterion>& rCriteria) = 0; virtual void GetDrillDownData(const ::std::vector<ScDPCacheTable::Criterion>& rCriteria, - ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rData); - virtual void CalcResults(CalcInfo& rInfo, bool bAutoShow); + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rData) = 0; + virtual void CalcResults(CalcInfo& rInfo, bool bAutoShow) = 0; virtual const ScDPCacheTable& GetCacheTable() const = 0; // overloaded in ScDPGroupTableData: @@ -181,6 +184,8 @@ public: virtual BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex, const ScDPItemData& rSecondData, long nSecondIndex ) const; + ScSimpleSharedString& GetSharedString(); + protected: /** This structure stores vector arrays that hold intermediate data for each row during cache table iteration. */ diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx index df8c2cfe4434..6dfb782b2313 100644 --- a/sc/inc/dptabres.hxx +++ b/sc/inc/dptabres.hxx @@ -31,14 +31,15 @@ #ifndef SC_DPTABRES_HXX #define SC_DPTABRES_HXX -#include <vector> #include <svtools/svarray.hxx> #include <tools/string.hxx> #include <com/sun/star/sheet/MemberResult.hpp> #include <com/sun/star/sheet/DataResult.hpp> #include <com/sun/star/uno/Sequence.hxx> #include "global.hxx" // enum ScSubTotalFunc +#include "dpcachetable.hxx" #include <hash_map> +#include <hash_set> #include <vector> namespace com { namespace sun { namespace star { namespace sheet { @@ -50,10 +51,12 @@ class ScAddress; class ScDocument; class ScDPSource; class ScDPDimension; +class ScDPDimensions; class ScDPLevel; class ScDPMember; class ScDPAggData; class ScDPResultMember; +class ScDPResultVisibilityData; struct ScDPValueData; struct ScDPItemData; @@ -370,6 +373,8 @@ public: const ScDPLevel* GetParentLevel() const { return pParentLevel; } //! Ref ScDPAggData* GetColTotal( long nMeasure ) const; + + void FillVisibilityData(ScDPResultVisibilityData& rData) const; }; class ScDPDataMember @@ -538,6 +543,8 @@ public: long GetAutoCount() const { return nAutoCount; } ScDPResultDimension* GetFirstChildDimension() const; + + void FillVisibilityData(ScDPResultVisibilityData& rData) const; }; class ScDPDataDimension @@ -580,5 +587,33 @@ public: ScDPDataMember* GetMember(long n) const; }; +// ---------------------------------------------------------------------------- + +/** + * This class collects visible members of each dimension and uses that + * information to create filtering criteria (e.g. for drill-down data). + */ +class ScDPResultVisibilityData +{ +public: + ScDPResultVisibilityData(ScSimpleSharedString& rSharedString, ScDPSource* pSource); + ~ScDPResultVisibilityData(); + + void addVisibleMember(const String& rDimName, const ScDPItemData& rMemberItem); + void fillFieldFilters(::std::vector<ScDPCacheTable::Criterion>& rFilters) const; + +private: + struct MemberHash + { + size_t operator()(const ScDPItemData& r) const; + }; + typedef ::std::hash_set<ScDPItemData, MemberHash> VisibleMemberType; + typedef ::std::hash_map<String, VisibleMemberType, ScStringHashCode> DimMemberType; + DimMemberType maDimensions; + + ScSimpleSharedString& mrSharedString; + ScDPSource* mpSource; +}; + #endif diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 6965b2acc8e7..eed8720b0836 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -38,6 +38,8 @@ #include <com/sun/star/uno/Reference.hxx> #include "scdllapi.h" +#include <hash_map> + class ImageList; class Bitmap; class SfxItemSet; @@ -884,6 +886,46 @@ 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/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx index 42fe1a174cf0..53d17894d2c3 100644 --- a/sc/source/core/data/dpcachetable.cxx +++ b/sc/source/core/data/dpcachetable.cxx @@ -37,8 +37,7 @@ #include "cell.hxx" #include "dptabdat.hxx" #include "dptabsrc.hxx" - -#include <stdio.h> +#include "dpobject.hxx" #include <com/sun/star/i18n/LocaleDataItem.hpp> #include <com/sun/star/sdbc/DataType.hpp> @@ -56,7 +55,7 @@ using namespace ::com::sun::star; using ::rtl::OUString; using ::std::vector; -using ::std::set; +using ::std::pair; using ::std::hash_map; using ::std::auto_ptr; using ::com::sun::star::i18n::LocaleDataItem; @@ -76,94 +75,26 @@ static BOOL lcl_HasQueryEntry( const ScQueryParam& rParam ) rParam.GetEntry(0).bDoQuery; } -ScSharedString::StringTable::StringTable() : - mnStrCount(0) -{ - // empty string (ID = 0) - maSharedStrings.push_back(String()); - maSharedStringIds.insert( SharedStrMap::value_type(String(), mnStrCount++) ); -} - -ScSharedString::StringTable::~StringTable() -{ -} - -sal_Int32 ScSharedString::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 ScSharedString::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* ScSharedString::StringTable::getString(sal_Int32 nId) const -{ - if (nId >= mnStrCount) - return NULL; - - return &maSharedStrings[nId]; -} - // ---------------------------------------------------------------------------- -// static -::osl::Mutex ScSharedString::maStrMutex; -ScSharedString::StringTable ScSharedString::maStringTable; - -sal_Int32 ScSharedString::insertString(const String& aStr) -{ - ::osl::MutexGuard aGuard(maStrMutex); - return maStringTable.insertString(aStr); -} - -const String* ScSharedString::getString(sal_Int32 nId) -{ - ::osl::MutexGuard aGuard(maStrMutex); - return maStringTable.getString(nId); -} - -sal_Int32 ScSharedString::getStringId(const String& aStr) -{ - ::osl::MutexGuard aGuard(maStrMutex); - return maStringTable.getStringId(aStr); -} +static ScDPCacheCell EmptyCellContent = ScDPCacheCell(); // ---------------------------------------------------------------------------- ScDPCacheTable::Cell::Cell() : mnCategoryRef(0), - mnStrId(ScSharedString::EMPTY), - mnType(SC_VALTYPE_EMPTY), - mfValue(0.0), - mbNumeric(false) + mpContent(NULL) +{ +} + +ScDPCacheTable::Cell::~Cell() { } // ---------------------------------------------------------------------------- ScDPCacheTable::FilterItem::FilterItem() : - mnMatchStrId(ScSharedString::EMPTY), + mnMatchStrId(ScSimpleSharedString::EMPTY), mfValue(0.0), mbHasValue(false) { @@ -171,18 +102,16 @@ ScDPCacheTable::FilterItem::FilterItem() : // ---------------------------------------------------------------------------- -ScDPCacheTable::SingleFilter::SingleFilter() -{ -} - -ScDPCacheTable::SingleFilter::SingleFilter(sal_Int32 nMatchStrId, double fValue, bool bHasValue) +ScDPCacheTable::SingleFilter::SingleFilter(ScSimpleSharedString& rSharedString, + sal_Int32 nMatchStrId, double fValue, bool bHasValue) : + mrSharedString(rSharedString) { maItem.mnMatchStrId = nMatchStrId; maItem.mfValue = fValue; maItem.mbHasValue = bHasValue; } -bool ScDPCacheTable::SingleFilter::match(const Cell& rCell) const +bool ScDPCacheTable::SingleFilter::match(const ScDPCacheCell& rCell) const { if (rCell.mnStrId != maItem.mnMatchStrId && (!rCell.mbNumeric || rCell.mfValue != maItem.mfValue)) @@ -191,9 +120,9 @@ bool ScDPCacheTable::SingleFilter::match(const Cell& rCell) const return true; } -const String ScDPCacheTable::SingleFilter::getMatchString() const +const String ScDPCacheTable::SingleFilter::getMatchString() { - const String* pStr = ScSharedString::getString(maItem.mnMatchStrId); + const String* pStr = mrSharedString.getString(maItem.mnMatchStrId); if (pStr) return *pStr; @@ -212,11 +141,13 @@ bool ScDPCacheTable::SingleFilter::hasValue() const // ---------------------------------------------------------------------------- -ScDPCacheTable::GroupFilter::GroupFilter() +ScDPCacheTable::GroupFilter::GroupFilter(ScSimpleSharedString& rSharedString) : + mrSharedString(rSharedString), + mbMatchIfFound(true) { } -bool ScDPCacheTable::GroupFilter::match(const Cell& rCell) const +bool ScDPCacheTable::GroupFilter::match(const ScDPCacheCell& rCell) const { vector<FilterItem>::const_iterator itrEnd = maItems.end(); for (vector<FilterItem>::const_iterator itr = maItems.begin(); itr != itrEnd; ++itr) @@ -228,14 +159,19 @@ bool ScDPCacheTable::GroupFilter::match(const Cell& rCell) const bMatch = (itr->mnMatchStrId == rCell.mnStrId); if (bMatch) - return true; + return mbMatchIfFound ? true : false; } - return false; + return mbMatchIfFound ? false : true; +} + +void ScDPCacheTable::GroupFilter::setMatchIfFound(bool b) +{ + mbMatchIfFound = b; } void ScDPCacheTable::GroupFilter::addMatchItem(const String& rStr, double fVal, bool bHasValue) { - sal_Int32 nStrId = ScSharedString::getStringId(rStr); + sal_Int32 nStrId = mrSharedString.getStringId(rStr); FilterItem aItem; aItem.mnMatchStrId = nStrId; aItem.mfValue = fVal; @@ -243,6 +179,11 @@ void ScDPCacheTable::GroupFilter::addMatchItem(const String& rStr, double fVal, maItems.push_back(aItem); } +size_t ScDPCacheTable::GroupFilter::getMatchItemCount() const +{ + return maItems.size(); +} + // ---------------------------------------------------------------------------- ScDPCacheTable::Criterion::Criterion() : @@ -253,7 +194,9 @@ ScDPCacheTable::Criterion::Criterion() : // ---------------------------------------------------------------------------- -ScDPCacheTable::ScDPCacheTable() +ScDPCacheTable::ScDPCacheTable(ScDPCollection* pCollection) : + mrSharedString(pCollection->GetSharedString()), + mpCollection(pCollection) { } @@ -261,11 +204,6 @@ ScDPCacheTable::~ScDPCacheTable() { } -sal_Int32 ScDPCacheTable::getHeaderSize() const -{ - return maHeader.size(); -} - sal_Int32 ScDPCacheTable::getRowSize() const { return maTable.size(); @@ -300,7 +238,7 @@ void ScDPCacheTable::fillTable(ScDocument* pDoc, const ScRange& rRange, const Sc { String aStr; pDoc->GetString(nCol + nStartCol, nStartRow, nTab, aStr); - sal_Int32 nStrId = ScSharedString::insertString(aStr); + sal_Int32 nStrId = mrSharedString.insertString(aStr); maHeader.push_back(nStrId); } @@ -339,24 +277,28 @@ void ScDPCacheTable::fillTable(ScDocument* pDoc, const ScRange& rRange, const Sc Cell& rCell = maTable.back().back(); rCell.mnCategoryRef = maTable.size()-1; - if (nRow == 0 || pDoc->HasData(nStartCol + nCol, nStartRow + nRow, nTab)) + String aCellStr; + bool bReadCell = nRow == 0 || pDoc->HasData(nStartCol + nCol, nStartRow + nRow, nTab); + if (bReadCell) + { 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); + } else rCell.mnCategoryRef = aLastNonEmptyRows[nCol]; - String aStr; - pDoc->GetString(nStartCol + nCol, nStartRow + nRow, nTab, aStr); - rCell.mnStrId = ScSharedString::insertString(aStr); - rCell.mnType = SC_VALTYPE_STRING; - rCell.mbNumeric = false; - ScAddress aPos(nStartCol + nCol, nStartRow + nRow, nTab); - getValueData(pDoc, aPos, rCell); - TypedStrData* pNew; - if (rCell.mbNumeric) - pNew = new TypedStrData(aStr, rCell.mfValue, SC_STRTYPE_VALUE); + if (rCell.mpContent && rCell.mpContent->mbNumeric) + pNew = new TypedStrData(aCellStr, rCell.mpContent->mfValue, SC_STRTYPE_VALUE); else - pNew = new TypedStrData(aStr); + pNew = new TypedStrData(aCellStr); if (!maFieldEntries[nCol]->Insert(pNew)) delete pNew; @@ -365,14 +307,15 @@ void ScDPCacheTable::fillTable(ScDocument* pDoc, const ScRange& rRange, const Sc } void lcl_GetCellValue(const Reference<sdbc::XRow>& xRow, sal_Int32 nType, long nCol, - const Date& rNullDate, ScDPCacheTable::Cell& rCell, String& rStr) + const Date& rNullDate, ScDPCacheCell& rCell, String& rStr, + ScSimpleSharedString& rSharedString) { short nNumType = NUMBERFORMAT_NUMBER; BOOL bEmptyFlag = FALSE; try { rStr = xRow->getString(nCol); - rCell.mnStrId = ScSharedString::getStringId(rStr); + rCell.mnStrId = rSharedString.getStringId(rStr); rCell.mnType = SC_VALTYPE_STRING; switch (nType) @@ -487,7 +430,7 @@ void ScDPCacheTable::fillTable(const Reference<sdbc::XRowSet>& xRowSet, const Da { String aColTitle = xMeta->getColumnLabel(nCol+1); aColTypes[nCol] = xMeta->getColumnType(nCol+1); - maHeader.push_back( ScSharedString::getStringId(aColTitle) ); + maHeader.push_back( mrSharedString.getStringId(aColTitle) ); } // Initialize field entries container. @@ -513,12 +456,14 @@ void ScDPCacheTable::fillTable(const Reference<sdbc::XRowSet>& xRowSet, const Da { maTable.back().push_back( Cell() ); Cell& rCell = maTable.back().back(); + ScDPCacheCell aCellContent; String aStr; - lcl_GetCellValue(xRow, aColTypes[nCol], nCol+1, rNullDate, rCell, aStr); + lcl_GetCellValue(xRow, aColTypes[nCol], nCol+1, rNullDate, aCellContent, aStr, mrSharedString); + rCell.mpContent = mpCollection->getCacheCellFromPool(aCellContent); TypedStrData* pNew; - if (rCell.mbNumeric) - pNew = new TypedStrData(aStr, rCell.mfValue, SC_STRTYPE_VALUE); + if (rCell.mpContent->mbNumeric) + pNew = new TypedStrData(aStr, rCell.mpContent->mfValue, SC_STRTYPE_VALUE); else pNew = new TypedStrData(aStr); @@ -557,20 +502,21 @@ void ScDPCacheTable::filterByPageDimension(const vector<Criterion>& rCriteria, b maRowsVisible[nRow] = isRowQualified(nRow, rCriteria, bRepeatIfEmpty); } -const ::ScDPCacheTable::Cell* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const +const ScDPCacheCell* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const { if ( nRow >= static_cast<SCROW>(maTable.size()) ) return NULL; - const vector<Cell>& rRow = maTable.at(nRow); + const vector<Cell>& rRow = maTable[nRow]; if ( nCol < 0 || static_cast<size_t>(nCol) >= rRow.size() ) return NULL; - const Cell* pCell = &rRow.at(nCol); - if (bRepeatIfEmpty && pCell && pCell->mnType == SC_VALTYPE_EMPTY) - pCell = getCell(nCol, pCell->mnCategoryRef, false); + const Cell& rCell = rRow[nCol]; + const ScDPCacheCell* pCell = rCell.mpContent; + if (bRepeatIfEmpty && !pCell) + pCell = getCell(nCol, rCell.mnCategoryRef, false); - return pCell; + return pCell ? pCell : &EmptyCellContent; } const String* ScDPCacheTable::getFieldName(sal_Int32 nIndex) const @@ -578,12 +524,12 @@ const String* ScDPCacheTable::getFieldName(sal_Int32 nIndex) const if (nIndex >= static_cast<sal_Int32>(maHeader.size())) return NULL; - return ScSharedString::getString(maHeader[nIndex]); + return mrSharedString.getString(maHeader[nIndex]); } sal_Int32 ScDPCacheTable::getFieldIndex(const String& rStr) const { - sal_Int32 nStrId = ScSharedString::getStringId(rStr); + sal_Int32 nStrId = mrSharedString.getStringId(rStr); if (nStrId < 0) // string not found. return nStrId; @@ -628,7 +574,7 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S for (sal_Int32 nCol = 0; nCol < nColSize; ++nCol) { OUString str; - const String* pStr = ScSharedString::getString(maHeader[nCol]); + const String* pStr = mrSharedString.getString(maHeader[nCol]); if (pStr) str = *pStr; @@ -654,7 +600,7 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S for (SCCOL nCol = 0; nCol < nColSize; ++nCol) { Any any; - const Cell* pCell = getCell(nCol, nRow, bRepeatIfEmpty); + const ScDPCacheCell* pCell = getCell(nCol, nRow, bRepeatIfEmpty); if (!pCell) { // This should never happen, but in case this happens, just @@ -670,7 +616,7 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S else { OUString str; - const String* pStr = ScSharedString::getString(pCell->mnStrId); + const String* pStr = mrSharedString.getString(pCell->mnStrId); if (pStr) str = *pStr; any <<= str; @@ -719,7 +665,7 @@ bool ScDPCacheTable::isRowQualified(sal_Int32 nRow, const vector<Criterion>& rCr // use this criterion. continue; - const Cell* pCell = getCell(static_cast<SCCOL>(itr->mnFieldIndex), nRow, bRepeatIfEmpty); + const ScDPCacheCell* pCell = getCell(static_cast<SCCOL>(itr->mnFieldIndex), nRow, bRepeatIfEmpty); if (!pCell) // This should never happen, but just in case... return false; @@ -730,7 +676,7 @@ bool ScDPCacheTable::isRowQualified(sal_Int32 nRow, const vector<Criterion>& rCr return true; } -void ScDPCacheTable::getValueData(ScDocument* pDoc, const ScAddress& rPos, Cell& rCell) +void ScDPCacheTable::getValueData(ScDocument* pDoc, const ScAddress& rPos, ScDPCacheCell& rCell) { ScBaseCell* pCell = pDoc->GetCell(rPos); if (!pCell) @@ -768,12 +714,3 @@ void ScDPCacheTable::getValueData(ScDocument* pDoc, const ScAddress& rPos, Cell& } } -ScDPCacheTable::Cell ScDPCacheTable::getSelectedDimension(ScDPDimension* pDim) const -{ - const ScDPItemData& rData = pDim->GetSelectedData(); - Cell aCell; - aCell.mfValue = rData.fValue; - aCell.mbNumeric = rData.bHasValue; - aCell.mnStrId = ScSharedString::getStringId(rData.aString); - return aCell; -} diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx index 70caeaed2386..b8d512de9b32 100644 --- a/sc/source/core/data/dpgroup.cxx +++ b/sc/source/core/data/dpgroup.cxx @@ -49,6 +49,7 @@ #include "dpcachetable.hxx" #include "dptabsrc.hxx" #include "dptabres.hxx" +#include "dpobject.hxx" #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> @@ -86,7 +87,7 @@ public: ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart, const Date* pNullDate, const ScDPNumGroupInfo* pNumInfo); - virtual bool match(const ScDPCacheTable::Cell &rCell) const; + virtual bool match(const ScDPCacheCell &rCell) const; private: ScDPGroupDateFilter(); // disabled @@ -110,7 +111,7 @@ ScDPGroupDateFilter::ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart // mfMatchValue, mnDatePart); } -bool ScDPGroupDateFilter::match(const ScDPCacheTable::Cell& rCell) const +bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const { using namespace ::com::sun::star::sheet; using ::rtl::math::approxFloor; @@ -977,6 +978,7 @@ String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bo } ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument ) : + ScDPTableData(pDocument), pSourceData( pSource ), pDoc( pDocument ) { @@ -1136,7 +1138,7 @@ void ScDPGroupTableData::CreateCacheTable() pSourceData->CreateCacheTable(); } -void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>& rCriteria) const +void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>& rCriteria) { typedef hash_map<long, const ScDPGroupDimension*> GroupFieldMapType; GroupFieldMapType aGroupFieldIds; @@ -1225,7 +1227,7 @@ void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>& ScDPCacheTable::Criterion aCri; aCri.mnFieldIndex = nSrcDim; - aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter); + aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(GetSharedString())); ScDPCacheTable::GroupFilter* pGrpFilter = static_cast<ScDPCacheTable::GroupFilter*>(aCri.mpFilter.get()); @@ -1317,28 +1319,6 @@ void ScDPGroupTableData::CopyFields(const vector<long>& rFieldDims, vector<long> } } -long* ScDPGroupTableData::CopyFields( const long* pSourceDims, long nCount ) -{ - if (!nCount) - return NULL; - - long nGroupedColumns = aGroups.size(); - - long* pNew = new long[nCount]; - for (long i=0; i<nCount; i++) - if ( pSourceDims[i] >= nSourceCount ) - { - if ( pSourceDims[i] == nSourceCount + nGroupedColumns ) - pNew[i] = nSourceCount; // data layout in source - else - pNew[i] = aGroups[pSourceDims[i] - nSourceCount].GetSourceDim(); // original dimension - } - else - pNew[i] = pSourceDims[i]; - - return pNew; // must be deleted by caller -} - void ScDPGroupTableData::FillGroupValues( ScDPItemData* pItemData, long nCount, const long* pDims ) { long nGroupedColumns = aGroups.size(); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index a2d6365a0336..29963323acfd 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -393,7 +393,7 @@ void ScDPObject::CreateObjects() if ( pImpDesc ) { // database data - pData = new ScDatabaseDPData( pDoc->GetServiceManager(), *pImpDesc ); + pData = new ScDatabaseDPData( pDoc, *pImpDesc ); } else { @@ -2281,7 +2281,49 @@ 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) : pDoc( pDocument ) @@ -2290,12 +2332,15 @@ ScDPCollection::ScDPCollection(ScDocument* pDocument) : ScDPCollection::ScDPCollection(const ScDPCollection& r) : Collection(r), - pDoc(r.pDoc) + pDoc(r.pDoc), + maSharedString(r.maSharedString), + maCacheCellPool(r.maCacheCellPool) { } ScDPCollection::~ScDPCollection() { + clearCacheCellPool(); } DataObject* ScDPCollection::Clone() const @@ -2400,12 +2445,60 @@ String ScDPCollection::CreateNewName( USHORT nMin ) const return String(); // should not happen } -//UNUSED2008-05 void ScDPCollection::EnsureNames() -//UNUSED2008-05 { -//UNUSED2008-05 for (USHORT i=0; i<nCount; i++) -//UNUSED2008-05 if (!((const ScDPObject*)At(i))->GetName().Len()) -//UNUSED2008-05 ((ScDPObject*)At(i))->SetName( CreateNewName() ); -//UNUSED2008-05 } +ScSimpleSharedString& ScDPCollection::GetSharedString() +{ + return maSharedString; +} + +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)); + for_each(ps.begin(), ps.end(), DeleteCacheCells()); + maCacheCellPool.clear(); +} //------------------------------------------------------------------------ // convert old pivot tables into new datapilot tables diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index 56db9b094d2a..007ecb24af33 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -43,7 +43,6 @@ #include "global.hxx" #include <tools/debug.hxx> -#include <tools/stream.hxx> #include <com/sun/star/sheet/GeneralFunction.hpp> #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp> @@ -126,24 +125,6 @@ ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) : { } -ScDPSaveMember::ScDPSaveMember(SvStream& rStream) -{ - rStream.ReadByteString( aName, rStream.GetStreamCharSet() ); - rStream >> nVisibleMode; - rStream >> nShowDetailsMode; - - lcl_SkipExtra( rStream ); // reads at least 1 USHORT -} - -void ScDPSaveMember::Store( SvStream& rStream ) const -{ - rStream.WriteByteString( aName, rStream.GetStreamCharSet() ); - rStream << nVisibleMode; - rStream << nShowDetailsMode; - - rStream << (USHORT) 0; // nExtra -} - ScDPSaveMember::~ScDPSaveMember() { } @@ -294,80 +275,6 @@ ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) : pSelectedPage = NULL; } -ScDPSaveDimension::ScDPSaveDimension(SvStream& rStream) -{ - long i; - - rStream.ReadByteString( aName, rStream.GetStreamCharSet() ); - rStream >> bIsDataLayout; - - rStream >> bDupFlag; - - rStream >> nOrientation; - rStream >> nFunction; // enum GeneralFunction - rStream >> nUsedHierarchy; - - rStream >> nShowEmptyMode; //! at level - - rStream >> bSubTotalDefault; //! at level - rStream >> nSubTotalCount; - if (nSubTotalCount) - { - pSubTotalFuncs = new USHORT[nSubTotalCount]; - for (i=0; i<nSubTotalCount; i++) - rStream >> pSubTotalFuncs[i]; - } - else - pSubTotalFuncs = NULL; - - lcl_SkipExtra( rStream ); // reads at least 1 USHORT - - long nNewCount; - rStream >> nNewCount; - for (i=0; i<nNewCount; i++) - { - ScDPSaveMember* pNew = new ScDPSaveMember( rStream ); - maMemberHash[pNew->GetName()] = pNew; - maMemberList.push_back( pNew ); - } - pReferenceValue = NULL; - pSortInfo = NULL; - pAutoShowInfo = NULL; - pLayoutInfo = NULL; - pLayoutName = NULL; - pSelectedPage = NULL; -} - -void ScDPSaveDimension::Store( SvStream& rStream ) const -{ - long i; - - rStream.WriteByteString( aName, rStream.GetStreamCharSet() ); - rStream << bIsDataLayout; - - rStream << bDupFlag; - - rStream << nOrientation; - rStream << nFunction; // enum GeneralFunction - rStream << nUsedHierarchy; - - rStream << nShowEmptyMode; //! at level - - //! subtotals at level - rStream << bSubTotalDefault; - long nSubCnt = pSubTotalFuncs ? nSubTotalCount : 0; - rStream << nSubCnt; - for (i=0; i<nSubCnt; i++) - rStream << pSubTotalFuncs[i]; - - rStream << (USHORT) 0; // nExtra - - long nCount = maMemberHash.size(); - rStream << nCount; - for (MemberList::const_iterator iter=maMemberList.begin(); iter != maMemberList.end() ; iter++) - (*iter)->Store( rStream ); -} - ScDPSaveDimension::~ScDPSaveDimension() { for (MemberHash::const_iterator i=maMemberHash.begin(); i != maMemberHash.end() ; i++) diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx index b877e09eef4c..1c178e8162cf 100644 --- a/sc/source/core/data/dpsdbtab.cxx +++ b/sc/source/core/data/dpsdbtab.cxx @@ -58,6 +58,8 @@ #include "globstr.hrc" #include "dpcachetable.hxx" #include "dptabres.hxx" +#include "document.hxx" +#include "dpobject.hxx" using namespace com::sun::star; @@ -91,17 +93,21 @@ public: ScDPCacheTable aCacheTable; - ScDatabaseDPData_Impl() {} + ScDatabaseDPData_Impl(ScDPCollection* p) : + aCacheTable(p) + { + } }; // ----------------------------------------------------------------------- ScDatabaseDPData::ScDatabaseDPData( - ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr, - const ScImportSourceDesc& rImport ) + ScDocument* pDoc, + const ScImportSourceDesc& rImport ) : + ScDPTableData(pDoc) { - pImpl = new ScDatabaseDPData_Impl; - pImpl->xServiceManager = xSMgr; + pImpl = new ScDatabaseDPData_Impl(pDoc->GetDPCollection()); + pImpl->xServiceManager = pDoc->GetServiceManager(); pImpl->aDesc = rImport; pImpl->nColCount = 0; pImpl->pTypes = NULL; diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx index 6b83c71b5369..bde7b0e98ecb 100644 --- a/sc/source/core/data/dpshttab.cxx +++ b/sc/source/core/data/dpshttab.cxx @@ -44,6 +44,7 @@ #include "collect.hxx" #include "cell.hxx" #include "dpcachetable.hxx" +#include "dpobject.hxx" #include "globstr.hrc" #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> @@ -74,17 +75,19 @@ public: ScDPCacheTable aCacheTable; - ScSheetDPData_Impl() : - pSpecial(NULL) + ScSheetDPData_Impl(ScDPCollection* p) : + pSpecial(NULL), + aCacheTable(p) { } }; // ----------------------------------------------------------------------- -ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ) +ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ) : + ScDPTableData(pD) { - pImpl = new ScSheetDPData_Impl; + pImpl = new ScSheetDPData_Impl(pD->GetDPCollection()); pImpl->pDoc = pD; pImpl->aRange = rDesc.aSourceRange; pImpl->aQuery = rDesc.aQueryParam; diff --git a/sc/source/core/data/dptabdat.cxx b/sc/source/core/data/dptabdat.cxx index 112b50084dea..70f73ea67579 100644 --- a/sc/source/core/data/dptabdat.cxx +++ b/sc/source/core/data/dptabdat.cxx @@ -48,6 +48,8 @@ #include "global.hxx" #include "dpcachetable.hxx" #include "dptabres.hxx" +#include "document.hxx" +#include "dpobject.hxx" using namespace ::com::sun::star; using ::com::sun::star::uno::Sequence; @@ -125,7 +127,8 @@ ScDPTableData::CalcInfo::CalcInfo() : // --------------------------------------------------------------------------- -ScDPTableData::ScDPTableData() +ScDPTableData::ScDPTableData(ScDocument* pDoc) : + mrSharedString(pDoc->GetDPCollection()->GetSharedString()) { nLastDateVal = nLastHier = nLastLevel = nLastRet = -1; // invalid @@ -186,26 +189,6 @@ bool ScDPTableData::IsRepeatIfEmpty() return false; } -void ScDPTableData::CreateCacheTable() -{ - fprintf(stdout, "ScDPTableData::CreateCacheTable: un-implemented...\n");fflush(stdout); -} - -void ScDPTableData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>&) -{ - fprintf(stdout, "ScDPTableData::FilterCacheTable: un-implemented...\n"); -} - -void ScDPTableData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>&, Sequence< Sequence<Any> >&) -{ - fprintf(stdout, "ScDPTableData::GetDrillDownData: un-implemented...\n");fflush(stdout); -} - -void ScDPTableData::CalcResults(CalcInfo&, bool) -{ - fprintf(stdout, "ScDPTableData::CalcResults: un-implemented...\n");fflush(stdout); -} - UINT32 ScDPTableData::GetNumberFormat(long) { return 0; // default format @@ -240,6 +223,11 @@ BOOL ScDPTableData::HasCommonElement( const ScDPItemData&, long, return FALSE; } +ScSimpleSharedString& ScDPTableData::GetSharedString() +{ + return mrSharedString; +} + void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTable& rCacheTable, const CalcInfo& rInfo, CalcRowData& rData) { @@ -258,7 +246,8 @@ void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTab long nDim = rInfo.aDataSrcCols[i]; rData.aValues.push_back( ScDPValueData() ); ScDPValueData& rVal = rData.aValues.back(); - const ScDPCacheTable::Cell* pCell = rCacheTable.getCell(static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow)); + const ScDPCacheCell* pCell = rCacheTable.getCell( + static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow)); if (pCell) { rVal.fValue = pCell->mbNumeric ? pCell->mfValue : 0.0; @@ -321,11 +310,12 @@ void ScDPTableData::GetItemData(const ScDPCacheTable& rCacheTable, sal_Int32 nRo continue; } - const ScDPCacheTable::Cell* pCell = rCacheTable.getCell(static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty()); + const ScDPCacheCell* pCell = rCacheTable.getCell( + static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty()); if (!pCell || pCell->mnType == SC_VALTYPE_EMPTY) continue; - const String* pString = ScSharedString::getString(pCell->mnStrId); + const String* pString = GetSharedString().getString(pCell->mnStrId); if (!pString) continue; diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index 0a52f12c97c3..398d4d1c7e01 100644 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -51,6 +51,7 @@ #include <math.h> #include <float.h> //! Test !!! #include <algorithm> +#include <hash_map> #include <com/sun/star/sheet/DataResultFlags.hpp> #include <com/sun/star/sheet/MemberResultFlags.hpp> @@ -59,9 +60,13 @@ #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp> #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp> #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp> +#include <com/sun/star/sheet/DataPilotFieldFilter.hpp> using namespace com::sun::star; using ::std::vector; +using ::std::pair; +using ::std::hash_map; +using ::com::sun::star::uno::Sequence; // ----------------------------------------------------------------------- @@ -1577,6 +1582,12 @@ ScDPAggData* ScDPResultMember::GetColTotal( long nMeasure ) const return lcl_GetChildTotal( const_cast<ScDPAggData*>(&aColTotal), nMeasure ); } +void ScDPResultMember::FillVisibilityData(ScDPResultVisibilityData& rData) const +{ + if (pChildDimension) + pChildDimension->FillVisibilityData(rData); +} + // ----------------------------------------------------------------------- ScDPDataMember::ScDPDataMember( const ScDPResultData* pData, const ScDPResultMember* pRes ) : @@ -3231,6 +3242,26 @@ ScDPResultDimension* ScDPResultDimension::GetFirstChildDimension() const return NULL; } +void ScDPResultDimension::FillVisibilityData(ScDPResultVisibilityData& rData) const +{ + if (IsDataLayout()) + return; + + MemberArray::const_iterator itr = maMemberArray.begin(), itrEnd = maMemberArray.end(); + + for (;itr != itrEnd; ++itr) + { + ScDPResultMember* pMember = *itr; + if (pMember->IsValid()) + { + ScDPItemData aItem; + pMember->FillItemData(aItem); + rData.addVisibleMember(GetName(), aItem); + pMember->FillVisibilityData(rData); + } + } +} + // ----------------------------------------------------------------------- ScDPDataDimension::ScDPDataDimension( const ScDPResultData* pData ) : @@ -3559,3 +3590,88 @@ ScDPDataMember* ScDPDataDimension::GetMember(long n) const return aMembers[(USHORT)n]; } +// ---------------------------------------------------------------------------- + +ScDPResultVisibilityData::ScDPResultVisibilityData( + ScSimpleSharedString& rSharedString, ScDPSource* pSource) : + mrSharedString(rSharedString), + mpSource(pSource) +{ +} + +ScDPResultVisibilityData::~ScDPResultVisibilityData() +{ +} + +void ScDPResultVisibilityData::addVisibleMember(const String& rDimName, const ScDPItemData& rMemberItem) +{ + DimMemberType::iterator itr = maDimensions.find(rDimName); + if (itr == maDimensions.end()) + { + pair<DimMemberType::iterator, bool> r = maDimensions.insert( + DimMemberType::value_type(rDimName, VisibleMemberType())); + + if (!r.second) + // insertion failed. + return; + + itr = r.first; + } + VisibleMemberType& rMem = itr->second; + VisibleMemberType::iterator itrMem = rMem.find(rMemberItem); + if (itrMem == rMem.end()) + rMem.insert(rMemberItem); +} + +void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion>& rFilters) const +{ + typedef hash_map<String, long, ScStringHashCode> FieldNameMapType; + FieldNameMapType aFieldNames; + ScDPTableData* pData = mpSource->GetData(); + long nColumnCount = pData->GetColumnCount(); + for (long i = 0; i < nColumnCount; ++i) + { + aFieldNames.insert( + FieldNameMapType::value_type(pData->getDimensionName(i), i)); + } + + const ScDPDimensions* pDims = mpSource->GetDimensionsObject(); + for (DimMemberType::const_iterator itr = maDimensions.begin(), itrEnd = maDimensions.end(); + itr != itrEnd; ++itr) + { + const String& rDimName = itr->first; + ScDPCacheTable::Criterion aCri; + FieldNameMapType::const_iterator itrField = aFieldNames.find(rDimName); + if (itrField == aFieldNames.end()) + // This should never happen! + continue; + + long nDimIndex = itrField->second; + aCri.mnFieldIndex = static_cast<sal_Int32>(nDimIndex); + aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(mrSharedString)); + ScDPCacheTable::GroupFilter* pGrpFilter = + static_cast<ScDPCacheTable::GroupFilter*>(aCri.mpFilter.get()); + + const VisibleMemberType& rMem = itr->second; + for (VisibleMemberType::const_iterator itrMem = rMem.begin(), itrMemEnd = rMem.end(); + itrMem != itrMemEnd; ++itrMem) + { + const ScDPItemData& rMemItem = *itrMem; + pGrpFilter->addMatchItem(rMemItem.aString, rMemItem.fValue, rMemItem.bHasValue); + } + + ScDPDimension* pDim = pDims->getByIndex(nDimIndex); + ScDPMembers* pMembers = pDim->GetHierarchiesObject()->getByIndex(0)-> + GetLevelsObject()->getByIndex(0)->GetMembersObject(); + if (pGrpFilter->getMatchItemCount() < static_cast<size_t>(pMembers->getCount())) + rFilters.push_back(aCri); + } +} + +size_t ScDPResultVisibilityData::MemberHash::operator() (const ScDPItemData& r) const +{ + if (r.bHasValue) + return static_cast<size_t>(::rtl::math::approxFloor(r.fValue)); + else + return rtl_ustr_hashCode_WithLength(r.aString.GetBuffer(), r.aString.Len()); +} diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx index 6108fe0ed9df..ca52ea957cef 100644 --- a/sc/source/core/data/dptabsrc.cxx +++ b/sc/source/core/data/dptabsrc.cxx @@ -31,7 +31,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" -#include <stdio.h> + // INCLUDE --------------------------------------------------------------- @@ -68,6 +68,7 @@ #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp> #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp> +#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp> #include <com/sun/star/table/CellAddress.hpp> #include <unotools/collatorwrapper.hxx> @@ -81,6 +82,7 @@ using ::std::hash_map; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Any; +using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo; // ----------------------------------------------------------------------- @@ -422,6 +424,15 @@ 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; + for (long i = 0; i < nColumnCount; ++i) + { + aFieldNames.insert( + FieldNameMapType::value_type(GetData()->getDimensionName(i), i)); + } // collect ScDPItemData for each filtered column vector<ScDPCacheTable::Criterion> aFilterCriteria; @@ -443,15 +454,21 @@ 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 = ScSharedString::getStringId(aItem.aString); + sal_Int32 nMatchStrId = rSharedString.getStringId(aItem.aString); aFilterCriteria.back().mnFieldIndex = nCol; aFilterCriteria.back().mpFilter.reset( - new ScDPCacheTable::SingleFilter(nMatchStrId, aItem.fValue, aItem.bHasValue) ); + new ScDPCacheTable::SingleFilter(rSharedString, nMatchStrId, aItem.fValue, aItem.bHasValue) ); } } } } + // Take into account the visibilities of field members. + ScDPResultVisibilityData aResVisData(rSharedString, this); + pRowResRoot->FillVisibilityData(aResVisData); + pColResRoot->FillVisibilityData(aResVisData); + aResVisData.fillFieldFilters(aFilterCriteria); + Sequence< Sequence<Any> > aTabData; pData->GetDrillDownData(aFilterCriteria, aTabData); return aTabData; @@ -834,6 +851,8 @@ void ScDPSource::CreateRes_Impl() else { { + ScSimpleSharedString& rSharedString = GetData()->GetSharedString(); + // filter table by page dimensions. vector<ScDPCacheTable::Criterion> aCriteria; for (i = 0; i < nPageDimCount; ++i) @@ -847,9 +866,9 @@ void ScDPSource::CreateRes_Impl() aCriteria.push_back(ScDPCacheTable::Criterion()); ScDPCacheTable::Criterion& r = aCriteria.back(); r.mnFieldIndex = static_cast<sal_Int32>(nField); - sal_Int32 nStrId = ScSharedString::getStringId(rData.aString); + sal_Int32 nStrId = rSharedString.getStringId(rData.aString); r.mpFilter.reset( - new ScDPCacheTable::SingleFilter(nStrId, rData.fValue, rData.bHasValue)); + new ScDPCacheTable::SingleFilter(rSharedString, nStrId, rData.fValue, rData.bHasValue)); } if (!aCriteria.empty()) pData->FilterCacheTable(aCriteria); diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx index f05a72d863f5..c352dbb550d6 100644 --- a/sc/source/core/data/global2.cxx +++ b/sc/source/core/data/global2.cxx @@ -1161,4 +1161,90 @@ 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/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index 768ebffe2682..5a0321935fe0 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -1464,10 +1464,25 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG ) // #95513# don't hide the dialog before executing the slot, instead it is used as // parent for message boxes in ScTabViewShell::GetDialogParent - GetBindings().GetDispatcher()->Execute( SID_PIVOT_TABLE, - SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, - &aOutItem, 0L, 0L ); - Close(); + const SfxPoolItem* pRet = GetBindings().GetDispatcher()->Execute( + SID_PIVOT_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aOutItem, 0L, 0L ); + + bool bSuccess = true; + if (pRet) + { + const SfxBoolItem* pItem = dynamic_cast<const SfxBoolItem*>(pRet); + if (pItem) + bSuccess = pItem->GetValue(); + } + if (bSuccess) + // Table successfully inserted. + Close(); + else + { + // Table insertion failed. Keep the dialog open. + bRefInputMode = true; + SetDispatcherLock(true); + } } else { diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx index 237aec789b4d..7bf76e41df4c 100644 --- a/sc/source/ui/inc/dbfunc.hxx +++ b/sc/source/ui/inc/dbfunc.hxx @@ -86,7 +86,7 @@ public: void Consolidate( const ScConsolidateParam& rParam, BOOL bRecord = TRUE ); - void MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable, + bool MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable, const ScDPObject& rSource, BOOL bApi = FALSE ); void DeletePivotTable(); void RecalcPivotTable(); diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index 33250725536e..04b250d4523b 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -962,6 +962,9 @@ ScDataPilotTableObj::~ScDataPilotTableObj() uno::Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException) { + // since we manually do resolve the query for XDataPilotTable2 + // we also need to do the same for XDataPilotTable + SC_QUERYINTERFACE( sheet::XDataPilotTable ) SC_QUERYINTERFACE( sheet::XDataPilotTable2 ) return ScDataPilotDescriptorBase::queryInterface( rType ); diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx index 97bec0eb9fcb..b870fdfe64ee 100644 --- a/sc/source/ui/view/cellsh2.cxx +++ b/sc/source/ui/view/cellsh2.cxx @@ -615,11 +615,10 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq ) if ( pDPObject ) { const ScPivotItem* pPItem = (const ScPivotItem*)pItem; - pTabViewShell->MakePivotTable( - pPItem->GetData(), - pPItem->GetDestRange(), - pPItem->IsNewSheet(), - *pDPObject ); + bool bSuccess = pTabViewShell->MakePivotTable( + pPItem->GetData(), pPItem->GetDestRange(), pPItem->IsNewSheet(), *pDPObject ); + SfxBoolItem aRet(0, bSuccess); + rReq.SetReturnValue(aRet); } rReq.Done(); } @@ -710,7 +709,8 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq ) { //! use database ranges (select before type dialog?) ScRange aRange; - if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE ) + ScMarkType eType = GetViewData()->GetSimpleArea(aRange); + if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE ) { BOOL bOK = TRUE; if ( pDoc->HasSubTotalCells( aRange ) ) diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 143039087ae9..fe879999bb95 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -579,7 +579,7 @@ String lcl_MakePivotTabName( const String& rPrefix, SCTAB nNumber ) return aName; } -void ScDBFunc::MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable, +bool ScDBFunc::MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable, const ScDPObject& rSource, BOOL bApi ) { // #70096# error message if no fields are set @@ -588,7 +588,7 @@ void ScDBFunc::MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, if ( rData.IsEmpty() && !bApi ) { ErrorMessage(STR_PIVOT_NODATA); - return; + return false; } ScDocShell* pDocSh = GetViewData()->GetDocShell(); @@ -652,7 +652,7 @@ void ScDBFunc::MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bAllowMove = ( pDPObj != NULL ); // allow re-positioning when editing existing table ScDBDocFunc aFunc( *pDocSh ); - aFunc.DataPilotUpdate( pDPObj, &aObj, TRUE, FALSE, bAllowMove ); + bool bSuccess = aFunc.DataPilotUpdate( pDPObj, &aObj, TRUE, FALSE, bAllowMove ); CursorPosChanged(); // shells may be switched @@ -661,6 +661,8 @@ void ScDBFunc::MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, pDocSh->PostPaintExtras(); SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); } + + return bSuccess; } void ScDBFunc::DeletePivotTable() @@ -1733,6 +1735,13 @@ void ScDBFunc::SetDataPilotDetails( BOOL bShow, const String* pNewDimensionName void ScDBFunc::ShowDataPilotSourceData( ScDPObject& rDPObj, const Sequence<sheet::DataPilotFieldFilter>& rFilters ) { + ScDocument* pDoc = GetViewData()->GetDocument(); + if (pDoc->GetDocumentShell()->IsReadOnly()) + { + ErrorMessage(STR_READONLYERR); + return; + } + Reference<sheet::XDimensionsSupplier> xDimSupplier = rDPObj.GetSource(); Reference<container::XNameAccess> xDims = xDimSupplier->getDimensions(); Reference<sheet::XDrillDownDataSupplier> xDDSupplier(xDimSupplier, UNO_QUERY); @@ -1747,7 +1756,6 @@ void ScDBFunc::ShowDataPilotSourceData( ScDPObject& rDPObj, const Sequence<sheet sal_Int32 nColSize = aTabData[0].getLength(); - ScDocument* pDoc = GetViewData()->GetDocument(); SCTAB nNewTab = GetViewData()->GetTabNo(); auto_ptr<ScDocument> pInsDoc(new ScDocument(SCDOCMODE_CLIP)); diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 051f4e5c9f78..16a6fa47de29 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -793,7 +793,8 @@ BOOL ScViewData::IsMultiMarked() // and taking filtered in simple area marks into account. ScRange aDummy; - return GetSimpleArea( aDummy) != SC_MARK_SIMPLE; + ScMarkType eType = GetSimpleArea(aDummy); + return (eType & SC_MARK_SIMPLE) != SC_MARK_SIMPLE; } void ScViewData::SetFillMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) |