| /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| /* |
| * This file is part of the Collabora Office project. |
| * |
| * This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| * |
| * This file incorporates work covered by the following license notice: |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed |
| * with this work for additional information regarding copyright |
| * ownership. The ASF licenses this file to you under the Apache |
| * License, Version 2.0 (the "License"); you may not use this file |
| * except in compliance with the License. You may obtain a copy of |
| * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
| */ |
| |
| #pragma once |
| |
| #include "scdllapi.h" |
| #include "global.hxx" |
| #include "address.hxx" |
| #include "dpcache.hxx" |
| #include "dptypes.hxx" |
| #include "pivot.hxx" |
| #include "calcmacros.hxx" |
| |
| #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> |
| #include <o3tl/sorted_vector.hxx> |
| #include <unotools/resmgr.hxx> |
| |
| #include <memory> |
| #include <vector> |
| #include <map> |
| |
| namespace com::sun::star { |
| |
| namespace container { |
| class XIndexAccess; |
| class XNameAccess; |
| } |
| |
| namespace sdbc { |
| class XRowSet; |
| } |
| |
| namespace sheet { |
| class XMembersAccess; |
| class XDimensionsSupplier; |
| struct DataPilotTablePositionData; |
| struct DataPilotTableHeaderData; |
| struct DataPilotFieldFilter; |
| } |
| } |
| |
| namespace tools |
| { |
| class Rectangle; |
| class XmlWriter; |
| } |
| class ScTokenArray; |
| class ScDPSaveData; |
| class ScDPOutput; |
| struct ScImportSourceDesc; |
| class ScSheetSourceDesc; |
| class ScDPTableData; |
| class ScDPDimCalcSaveData; |
| class ScDPDimensionSaveData; |
| class ScRangeList; |
| class ScDocument; |
| |
| struct ScDPServiceDesc |
| { |
| OUString aServiceName; |
| OUString aParSource; |
| OUString aParName; |
| OUString aParUser; |
| OUString aParPass; |
| |
| ScDPServiceDesc( OUString aServ, OUString aSrc, OUString aNam, |
| OUString aUser, OUString aPass ); |
| |
| bool operator== ( const ScDPServiceDesc& rOther ) const; |
| }; |
| |
| namespace sc |
| { |
| |
| /** Stores the style information for a pivot table */ |
| struct PivotTableStyleInfo |
| { |
| // Style name, which is used to determine how the pivot table is styles |
| OUString maName; |
| |
| // Shold headers be styled |
| bool mbShowRowHeaders = false; |
| bool mbShowColHeaders = false; |
| |
| // Should use stripes / bands |
| bool mbShowRowStripes = false; |
| bool mbShowColStripes = false; |
| |
| bool mbShowLastColumn = false; |
| |
| // If no name is set, the style is not used |
| bool isSet() const |
| { |
| return !maName.isEmpty(); |
| } |
| }; |
| |
| } |
| |
| class ScDPObject |
| { |
| private: |
| ScDocument* mpDocument; |
| |
| // Settings |
| std::unique_ptr<ScDPSaveData> mpSaveData; |
| OUString maTableName; |
| OUString maTableTag; |
| ScRange maOutputRange; |
| std::unique_ptr<ScSheetSourceDesc> mpSheetDescription; // for sheet data |
| std::unique_ptr<ScImportSourceDesc> mpImportDescription; // for database data |
| std::unique_ptr<ScDPServiceDesc> mpServiceDescription; // for external service |
| std::shared_ptr<ScDPTableData> mpTableData; // cached data |
| |
| css::uno::Reference<css::sheet::XDimensionsSupplier> mxSource; |
| std::unique_ptr<ScDPOutput> mpOutput; |
| |
| sal_Int32 mnHeaderRows; // page fields plus filter button |
| bool mbHeaderLayout : 1; // true : grid, false : standard |
| bool mbAllowMove : 1; |
| bool mbSettingsChanged : 1; |
| bool mbEnableGetPivotData : 1; |
| bool mbHideHeader : 1 = false; |
| |
| sc::PivotTableStyleInfo maStyleInfo; |
| |
| void CreateObjects(); |
| void CreateOutput(); |
| void ClearSource(); |
| void FillLabelDataForDimension( |
| const css::uno::Reference< css::container::XIndexAccess>& xDims, |
| sal_Int32 nDim, ScDPLabelData& rLabelData); |
| |
| public: |
| SC_DLLPUBLIC ScDPObject(ScDocument* pD); |
| ScDPObject(const ScDPObject& r); |
| SC_DLLPUBLIC ~ScDPObject(); |
| |
| ScDPObject& operator= (const ScDPObject& r); |
| |
| void EnableGetPivotData(bool b); |
| |
| void SetAllowMove(bool bSet); |
| |
| void InvalidateData(); |
| void Clear(); |
| void ClearTableData(); |
| ScDPTableData* GetTableData(); |
| |
| SC_DLLPUBLIC void ReloadGroupTableData(); |
| |
| SC_DLLPUBLIC void Output( const ScAddress& rPos ); |
| ScRange GetNewOutputRange( bool& rOverflow ); |
| |
| SC_DLLPUBLIC ScRange GetOutputRangeByType( sal_Int32 nType ); |
| SC_DLLPUBLIC ScRange GetOutputRangeByType( sal_Int32 nType ) const; |
| |
| SC_DLLPUBLIC void SetSaveData(const ScDPSaveData& rData); |
| ScDPSaveData* GetSaveData() const { return mpSaveData.get(); } |
| |
| SC_DLLPUBLIC void SetOutRange(const ScRange& rRange); |
| SC_DLLPUBLIC const ScRange& GetOutRange() const; |
| |
| SC_DLLPUBLIC void SetHeaderLayout(bool bUseGrid); |
| bool GetHeaderLayout() const { return mbHeaderLayout;} |
| |
| SC_DLLPUBLIC void SetHideHeader(bool bHideHeader); |
| bool GetHideHeader() const { return mbHideHeader; } |
| |
| SC_DLLPUBLIC void SetSheetDesc(const ScSheetSourceDesc& rDesc); |
| void SetImportDesc(const ScImportSourceDesc& rDesc); |
| void SetServiceData(const ScDPServiceDesc& rDesc); |
| |
| void WriteSourceDataTo( ScDPObject& rDest ) const; |
| |
| SC_DLLPUBLIC void InsertCalculatedFieldToCache(sal_Int32 nIndex, const OUString& rFieldName, |
| const std::shared_ptr<ScTokenArray>& pArray); |
| void RemoveCalculatedFieldFromCache(const OUString& rFieldName); |
| |
| const ScSheetSourceDesc* GetSheetDesc() const { return mpSheetDescription.get(); } |
| const ScImportSourceDesc* GetImportSourceDesc() const { return mpImportDescription.get(); } |
| const ScDPServiceDesc* GetDPServiceDesc() const { return mpServiceDescription.get(); } |
| |
| SC_DLLPUBLIC css::uno::Reference<css::sheet::XDimensionsSupplier> const & GetSource(); |
| |
| bool IsSheetData() const; |
| bool IsImportData() const { return mpImportDescription != nullptr; } |
| bool IsServiceData() const { return mpServiceDescription != nullptr; } |
| |
| |
| SC_DLLPUBLIC void SetName(const OUString& rNew); |
| const OUString& GetName() const { return maTableName; } |
| void SetTag(const OUString& rNew); |
| const OUString& GetTag() const { return maTableTag; } |
| |
| /** |
| * Data description cell displays the description of a data dimension if |
| * and only if there is only one data dimension. It's usually located at |
| * the upper-left corner of the table output. |
| */ |
| bool IsDataDescriptionCell(const ScAddress& rPos); |
| |
| bool IsDimNameInUse(std::u16string_view rName) const; |
| SC_DLLPUBLIC OUString GetDimName( tools::Long nDim, bool& rIsDataLayout, sal_Int32* pFlags = nullptr ); |
| SC_DLLPUBLIC bool IsDuplicated( tools::Long nDim ); |
| SC_DLLPUBLIC tools::Long GetDimCount(); |
| void GetHeaderPositionData(const ScAddress& rPos, css::sheet::DataPilotTableHeaderData& rData); |
| SC_DLLPUBLIC tools::Long GetHeaderDim( const ScAddress& rPos, css::sheet::DataPilotFieldOrientation& rOrient ); |
| bool GetHeaderDrag( const ScAddress& rPos, bool bMouseLeft, bool bMouseTop, |
| tools::Long nDragDim, |
| tools::Rectangle& rPosRect, css::sheet::DataPilotFieldOrientation& rOrient, tools::Long& rDimPos ); |
| bool IsFilterButton( const ScAddress& rPos ); |
| |
| static OUString GetFormattedString(const ScDPTableData* pTableData, tools::Long nDimension, const double fValue); |
| SC_DLLPUBLIC OUString GetFormattedString( std::u16string_view rDimName, const double fValue ); |
| |
| double GetPivotData( |
| const OUString& rDataFieldName, |
| std::vector<css::sheet::DataPilotFieldFilter>& rFilters); |
| |
| bool ParseFilters( |
| OUString& rDataFieldName, |
| std::vector<css::sheet::DataPilotFieldFilter>& rFilters, |
| std::vector<sal_Int16>& rFilterFuncs, |
| std::u16string_view rFilterList ); |
| |
| void GetMemberResultNames(ScDPUniqueStringSet& rNames, tools::Long nDimension); |
| |
| void ToggleDetails(const css::sheet::DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj); |
| |
| void FillOldParam(ScPivotParam& rParam) const; |
| void FillLabelData(sal_Int32 nDim, ScDPLabelData& Labels); |
| void FillLabelData(ScPivotParam& rParam); |
| |
| void GetFieldIdsNames(css::sheet::DataPilotFieldOrientation nOrient, std::vector<tools::Long>& rIndices, |
| std::vector<OUString>& rNames); |
| |
| bool GetHierarchiesNA( sal_Int32 nDim, css::uno::Reference< css::container::XNameAccess >& xHiers ); |
| void GetHierarchies( sal_Int32 nDim, css::uno::Sequence< OUString >& rHiers ); |
| |
| SC_DLLPUBLIC sal_Int32 GetUsedHierarchy( sal_Int32 nDim ); |
| |
| bool GetMembersNA( sal_Int32 nDim, css::uno::Reference< css::sheet::XMembersAccess >& xMembers ); |
| bool GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, css::uno::Reference< css::sheet::XMembersAccess >& xMembers ); |
| |
| bool GetMemberNames( sal_Int32 nDim, css::uno::Sequence< OUString >& rNames ); |
| SC_DLLPUBLIC bool GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector<ScDPLabelData::Member>& rMembers ); |
| |
| void UpdateReference( UpdateRefMode eUpdateRefMode, |
| const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz ); |
| bool RefsEqual( const ScDPObject& r ) const; |
| void WriteRefsTo( ScDPObject& r ) const; |
| |
| void GetPositionData(const ScAddress& rPos, css::sheet::DataPilotTablePositionData& rPosData); |
| |
| bool GetDataFieldPositionData(const ScAddress& rPos, |
| css::uno::Sequence< |
| css::sheet::DataPilotFieldFilter >& rFilters); |
| |
| void GetDrillDownData(const ScAddress& rPos, |
| css::uno::Sequence< css::uno::Sequence< css::uno::Any > >& rTableData); |
| |
| // apply drop-down attribute, initialize mnHeaderRows, without accessing the source |
| // (button attribute must be present) |
| void RefreshAfterLoad(); |
| |
| sc::PivotTableStyleInfo const& getStyleInfo() const |
| { |
| return maStyleInfo; |
| } |
| |
| void setStyleInfo(sc::PivotTableStyleInfo const& rStyleInfo) |
| { |
| maStyleInfo = rStyleInfo; |
| } |
| |
| SC_DLLPUBLIC void BuildAllDimensionMembers(); |
| |
| /** |
| * Remove in the save data entries for members that don't exist anymore. |
| * This is called during pivot table refresh. |
| */ |
| SC_DLLPUBLIC bool SyncAllDimensionMembers(); |
| |
| static bool HasRegisteredSources(); |
| static std::vector<OUString> GetRegisteredSources(); |
| static css::uno::Reference<css::sheet::XDimensionsSupplier> |
| CreateSource( const ScDPServiceDesc& rDesc ); |
| |
| static void ConvertOrientation( |
| ScDPSaveData& rSaveData, |
| const ScPivotFieldVector& rFields, css::sheet::DataPilotFieldOrientation nOrient, |
| const css::uno::Reference< css::sheet::XDimensionsSupplier>& xSource, |
| const ScDPLabelDataVector& rLabels, |
| const ScPivotFieldVector* pRefColFields = nullptr, |
| const ScPivotFieldVector* pRefRowFields = nullptr, |
| const ScPivotFieldVector* pRefPageFields = nullptr ); |
| |
| SC_DLLPUBLIC static bool IsOrientationAllowed( css::sheet::DataPilotFieldOrientation nOrient, sal_Int32 nDimFlags ); |
| |
| void dumpAsXml(tools::XmlWriter& rWriter) const; |
| void dumpXmlFile() const; |
| |
| #if DUMP_PIVOT_TABLE |
| void Dump() const; |
| void DumpCache() const; |
| #endif |
| }; |
| |
| class ScDPCollection |
| { |
| friend class ScDPCache; |
| public: |
| |
| /** |
| * Stores and manages all caches from internal sheets. |
| */ |
| class SheetCaches |
| { |
| friend class ScDPCollection; |
| typedef std::map<size_t, std::unique_ptr<ScDPCache>> CachesType; |
| typedef std::vector<ScRange> RangeIndexType; |
| CachesType m_Caches; |
| RangeIndexType maRanges; |
| ScDocument& mrDoc; |
| public: |
| SheetCaches(ScDocument& rDoc); |
| bool hasCache(const ScRange& rRange) const; |
| const ScDPCache* getCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData, const ScDPDimCalcSaveData* pCalculatedDimData); |
| SC_DLLPUBLIC size_t size() const; |
| |
| void updateReference( |
| UpdateRefMode eMode, const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz); |
| |
| SC_DLLPUBLIC ScDPCache* getExistingCache(const ScRange& rRange); |
| SC_DLLPUBLIC const ScDPCache* getExistingCache(const ScRange& rRange) const; |
| |
| void updateCache(const ScRange& rRange, o3tl::sorted_vector<ScDPObject*>& rRefs); |
| bool remove(const ScDPCache* p); |
| |
| SC_DLLPUBLIC const std::vector<ScRange>& getAllRanges() const; |
| }; |
| |
| /** |
| * Data caches for range name based source data. |
| */ |
| class NameCaches |
| { |
| friend class ScDPCollection; |
| typedef ::std::map<OUString, std::unique_ptr<ScDPCache>> CachesType; |
| CachesType m_Caches; |
| ScDocument& mrDoc; |
| public: |
| NameCaches(ScDocument& rDoc); |
| bool hasCache(const OUString& rName) const; |
| const ScDPCache* getCache(const OUString& rName, const ScRange& rRange, |
| const ScDPDimensionSaveData* pDimData, const ScDPDimCalcSaveData* pCalculatedDimData); |
| ScDPCache* getExistingCache(const OUString& rName); |
| size_t size() const; |
| private: |
| |
| void updateCache( |
| const OUString& rName, const ScRange& rRange, o3tl::sorted_vector<ScDPObject*>& rRefs); |
| bool remove(const ScDPCache* p); |
| }; |
| |
| /** |
| * Defines connection type to external data source. Used as a key to look |
| * up database cache. |
| */ |
| struct DBType |
| { |
| sal_Int32 mnSdbType; |
| OUString maDBName; |
| OUString maCommand; |
| DBType(sal_Int32 nSdbType, OUString aDBName, OUString aCommand); |
| |
| struct less |
| { |
| bool operator() (const DBType& left, const DBType& right) const; |
| }; |
| }; |
| |
| /** |
| * Data caches for external database sources. |
| */ |
| class DBCaches |
| { |
| friend class ScDPCollection; |
| typedef ::std::map<DBType, std::unique_ptr<ScDPCache>, DBType::less> CachesType; |
| CachesType m_Caches; |
| ScDocument& mrDoc; |
| public: |
| DBCaches(ScDocument& rDoc); |
| bool hasCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) const; |
| const ScDPCache* getCache( |
| sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand, const ScDPDimensionSaveData* pDimData, const ScDPDimCalcSaveData* pCalculatedDimData); |
| ScDPCache* getExistingCache(sal_Int32 nSdbType, const OUString& rDBName, |
| const OUString& rCommand); |
| |
| private: |
| |
| static css::uno::Reference<css::sdbc::XRowSet> createRowSet( |
| sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand); |
| |
| void updateCache( |
| sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand, |
| o3tl::sorted_vector<ScDPObject*>& rRefs); |
| bool remove(const ScDPCache* p); |
| }; |
| |
| ScDPCollection(ScDocument& rDocument); |
| ScDPCollection(const ScDPCollection& r); |
| ~ScDPCollection(); |
| |
| TranslateId ReloadCache(const ScDPObject* pDPObj, o3tl::sorted_vector<ScDPObject*>& rRefs); |
| bool ReloadGroupsInCache(const ScDPObject* pDPObj, o3tl::sorted_vector<ScDPObject*>& rRefs); |
| SC_DLLPUBLIC bool GetReferenceGroups(const ScDPObject& rDPObj, const ScDPDimensionSaveData** pGroups) const; |
| |
| SC_DLLPUBLIC size_t GetCount() const; |
| SC_DLLPUBLIC ScDPObject& operator[](size_t nIndex); |
| SC_DLLPUBLIC const ScDPObject& operator[](size_t nIndex) const; |
| |
| SC_DLLPUBLIC ScDPObject* GetByName(std::u16string_view rName) const; |
| |
| void DeleteOnTab( SCTAB nTab ); |
| void UpdateReference( UpdateRefMode eUpdateRefMode, |
| const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz ); |
| void CopyToTab( SCTAB nOld, SCTAB nNew ); |
| bool RefsEqual( const ScDPCollection& r ) const; |
| void WriteRefsTo( ScDPCollection& r ) const; |
| |
| /** |
| * Create a new name that's not yet used by any existing data pilot |
| * objects. All data pilot names are 'DataPilot' + <num> |
| * |
| * @return new name for data pilot object. |
| */ |
| OUString CreateNewName() const; |
| |
| void FreeTable(const ScDPObject* pDPObj); |
| |
| /** Deletes all pivot tables on the input tab. */ |
| void DeleteByTab(SCTAB nTab); |
| SC_DLLPUBLIC ScDPObject* InsertNewTable(std::unique_ptr<ScDPObject> pDPObj); |
| SC_DLLPUBLIC bool HasTable(const ScDPObject* pDPObj) const; |
| |
| SC_DLLPUBLIC SheetCaches& GetSheetCaches(); |
| SC_DLLPUBLIC const SheetCaches& GetSheetCaches() const; |
| NameCaches& GetNameCaches(); |
| SC_DLLPUBLIC const NameCaches& GetNameCaches() const; |
| DBCaches& GetDBCaches(); |
| SC_DLLPUBLIC const DBCaches& GetDBCaches() const; |
| |
| ScRangeList GetAllTableRanges( SCTAB nTab ) const; |
| bool IntersectsTableByColumns( SCCOL nCol1, SCCOL nCol2, SCROW nRow, SCTAB nTab ) const; |
| bool IntersectsTableByRows( SCCOL nCol, SCROW nRow1, SCROW nRow2, SCTAB nTab ) const; |
| bool HasTable( const ScRange& rRange ) const; |
| |
| private: |
| /** Only to be called from ScDPCache::RemoveReference(). */ |
| void RemoveCache(const ScDPCache* pCache); |
| |
| void GetAllTables(const ScRange& rSrcRange, o3tl::sorted_vector<ScDPObject*>& rRefs) const; |
| void GetAllTables(std::u16string_view rSrcName, o3tl::sorted_vector<ScDPObject*>& rRefs) const; |
| void GetAllTables( |
| sal_Int32 nSdbType, std::u16string_view rDBName, std::u16string_view rCommand, |
| o3tl::sorted_vector<ScDPObject*>& rRefs) const; |
| |
| private: |
| typedef std::vector< std::unique_ptr<ScDPObject> > TablesType; |
| |
| ScDocument& mrDoc; |
| TablesType maTables; |
| SheetCaches maSheetCaches; |
| NameCaches maNameCaches; |
| DBCaches maDBCaches; |
| }; |
| |
| bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right); |
| |
| /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |