diff options
Diffstat (limited to 'sc/inc/dpobject.hxx')
-rw-r--r-- | sc/inc/dpobject.hxx | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx new file mode 100644 index 000000000..a1a2c6e9e --- /dev/null +++ b/sc/inc/dpobject.hxx @@ -0,0 +1,456 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice 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 . + */ + +#ifndef INCLUDED_SC_INC_DPOBJECT_HXX +#define INCLUDED_SC_INC_DPOBJECT_HXX + +#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 <memory> +#include <set> +#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 ScDPSaveData; +class ScDPOutput; +struct ScImportSourceDesc; +class ScSheetSourceDesc; +class ScDPTableData; +class ScDPDimensionSaveData; +class ScRangeList; +class ScDPCache; +class ScDocument; + +struct ScDPServiceDesc +{ + OUString aServiceName; + OUString aParSource; + OUString aParName; + OUString aParUser; + OUString aParPass; + + ScDPServiceDesc( const OUString& rServ, const OUString& rSrc, const OUString& rNam, + const OUString& rUser, const OUString& rPass ); + + bool operator== ( const ScDPServiceDesc& rOther ) const; +}; + +class SC_DLLPUBLIC ScDPObject +{ +private: + ScDocument* pDoc; + // settings + std::unique_ptr<ScDPSaveData> pSaveData; + OUString aTableName; + OUString aTableTag; + ScRange aOutRange; + std::unique_ptr<ScSheetSourceDesc> pSheetDesc; // for sheet data + std::unique_ptr<ScImportSourceDesc> pImpDesc; // for database data + std::unique_ptr<ScDPServiceDesc> pServDesc; // for external service + std::shared_ptr<ScDPTableData> mpTableData; + // cached data + css::uno::Reference<css::sheet::XDimensionsSupplier> xSource; + std::unique_ptr<ScDPOutput> pOutput; + + // name -> sequence of sequences of css::xml::FastAttribute or css::xml::Attribute + // see PivotTable::putToInteropGrabBag in sc/source/filter/oox/pivottablebuffer.cxx for details + std::map<OUString, css::uno::Any> maInteropGrabBag; + + long nHeaderRows; // page fields plus filter button + bool mbHeaderLayout:1; // true : grid, false : standard + bool bAllowMove:1; + bool bSettingsChanged:1; + bool mbEnableGetPivotData:1; + + SAL_DLLPRIVATE ScDPTableData* GetTableData(); + SAL_DLLPRIVATE void CreateObjects(); + SAL_DLLPRIVATE void CreateOutput(); + SAL_DLLPRIVATE void ClearSource(); + SAL_DLLPRIVATE void FillLabelDataForDimension( + const css::uno::Reference< css::container::XIndexAccess>& xDims, + sal_Int32 nDim, ScDPLabelData& rLabelData); + +public: + ScDPObject(ScDocument* pD); + ScDPObject(const ScDPObject& r); + ~ScDPObject(); + + ScDPObject& operator= (const ScDPObject& r); + + void EnableGetPivotData(bool b); + + void SetAllowMove(bool bSet); + + void InvalidateData(); + void Clear(); + void ClearTableData(); + void ReloadGroupTableData(); + + void Output( const ScAddress& rPos ); + ScRange GetNewOutputRange( bool& rOverflow ); + + ScRange GetOutputRangeByType( sal_Int32 nType ); + ScRange GetOutputRangeByType( sal_Int32 nType ) const; + + void SetSaveData(const ScDPSaveData& rData); + ScDPSaveData* GetSaveData() const { return pSaveData.get(); } + + void SetOutRange(const ScRange& rRange); + const ScRange& GetOutRange() const; + + void SetHeaderLayout(bool bUseGrid); + bool GetHeaderLayout() const { return mbHeaderLayout;} + + void SetSheetDesc(const ScSheetSourceDesc& rDesc); + void SetImportDesc(const ScImportSourceDesc& rDesc); + void SetServiceData(const ScDPServiceDesc& rDesc); + + void WriteSourceDataTo( ScDPObject& rDest ) const; + void WriteTempDataTo( ScDPObject& rDest ) const; + + const ScSheetSourceDesc* GetSheetDesc() const { return pSheetDesc.get(); } + const ScImportSourceDesc* GetImportSourceDesc() const { return pImpDesc.get(); } + const ScDPServiceDesc* GetDPServiceDesc() const { return pServDesc.get(); } + + css::uno::Reference<css::sheet::XDimensionsSupplier> const & GetSource(); + + bool IsSheetData() const; + bool IsImportData() const { return(pImpDesc != nullptr); } + bool IsServiceData() const { return(pServDesc != nullptr); } + + void SetName(const OUString& rNew); + const OUString& GetName() const { return aTableName; } + void SetTag(const OUString& rNew); + const OUString& GetTag() const { return aTableTag; } + + /** + * 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(const OUString& rName) const; + OUString GetDimName( long nDim, bool& rIsDataLayout, sal_Int32* pFlags = nullptr ); + bool IsDuplicated( long nDim ); + long GetDimCount(); + void GetHeaderPositionData(const ScAddress& rPos, css::sheet::DataPilotTableHeaderData& rData); + long GetHeaderDim( const ScAddress& rPos, css::sheet::DataPilotFieldOrientation& rOrient ); + bool GetHeaderDrag( const ScAddress& rPos, bool bMouseLeft, bool bMouseTop, + long nDragDim, + tools::Rectangle& rPosRect, css::sheet::DataPilotFieldOrientation& rOrient, long& rDimPos ); + bool IsFilterButton( const ScAddress& rPos ); + + OUString GetFormattedString( const OUString& 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, + const OUString& rFilterList ); + + void GetMemberResultNames(ScDPUniqueStringSet& rNames, 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); + + bool GetHierarchiesNA( sal_Int32 nDim, css::uno::Reference< css::container::XNameAccess >& xHiers ); + void GetHierarchies( sal_Int32 nDim, css::uno::Sequence< OUString >& rHiers ); + + 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 ); + 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 nHeaderRows, without accessing the source + // (button attribute must be present) + void RefreshAfterLoad(); + + void BuildAllDimensionMembers(); + + /** + * Remove in the save data entries for members that don't exist anymore. + * This is called during pivot table refresh. + */ + 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 ); + + static bool IsOrientationAllowed( css::sheet::DataPilotFieldOrientation nOrient, sal_Int32 nDimFlags ); + + void PutInteropGrabBag(std::map<OUString, css::uno::Any>&& val) + { + maInteropGrabBag = std::move(val); + } + std::pair<bool, css::uno::Any> GetInteropGrabBagValue(const OUString& sName) const + { + if (const auto it = maInteropGrabBag.find(sName); it != maInteropGrabBag.end()) + return { true, it->second }; + + return { false, css::uno::Any() }; + } + +#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* mpDoc; + public: + SheetCaches(ScDocument* pDoc); + bool hasCache(const ScRange& rRange) const; + const ScDPCache* getCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData); + 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, std::set<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* mpDoc; + public: + NameCaches(ScDocument* pDoc); + bool hasCache(const OUString& rName) const; + const ScDPCache* getCache( + const OUString& rName, const ScRange& rRange, const ScDPDimensionSaveData* pDimData); + size_t size() const; + private: + ScDPCache* getExistingCache(const OUString& rName); + + void updateCache( + const OUString& rName, const ScRange& rRange, std::set<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, const OUString& rDBName, const OUString& rCommand); + + 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* mpDoc; + public: + DBCaches(ScDocument* pDoc); + 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); + + private: + ScDPCache* getExistingCache( + sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand); + + 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, + std::set<ScDPObject*>& rRefs); + bool remove(const ScDPCache* p); + }; + + ScDPCollection(ScDocument* pDocument); + ScDPCollection(const ScDPCollection& r); + ~ScDPCollection(); + + const char* ReloadCache(const ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs); + bool ReloadGroupsInCache(const ScDPObject* pDPObj, std::set<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; + + ScDPObject* GetByName(const OUString& 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); + 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; + +#if DEBUG_PIVOT_TABLE + void DumpTables() const; +#endif + +private: + /** Only to be called from ScDPCache::RemoveReference(). */ + void RemoveCache(const ScDPCache* pCache); + + void GetAllTables(const ScRange& rSrcRange, std::set<ScDPObject*>& rRefs) const; + void GetAllTables(const OUString& rSrcName, std::set<ScDPObject*>& rRefs) const; + void GetAllTables( + sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand, + std::set<ScDPObject*>& rRefs) const; + +private: + typedef std::vector< std::unique_ptr<ScDPObject> > TablesType; + + ScDocument* mpDoc; + TablesType maTables; + SheetCaches maSheetCaches; + NameCaches maNameCaches; + DBCaches maDBCaches; +}; + +bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |