/* -*- 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 "dpoutput.hxx" #include "dptypes.hxx" #include "pivot.hxx" #include "calcmacros.hxx" #include #include #include #include #include #include #include namespace com { namespace sun { namespace star { namespace container { class XIndexAccess; } namespace sdbc { class XRowSet; } namespace sheet { struct DataPilotTablePositionData; struct DataPilotTableHeaderData; struct DataPilotFieldFilter; } }}} class Rectangle; class ScDPSaveData; class ScDPOutput; struct ScPivotParam; struct ScImportSourceDesc; class ScSheetSourceDesc; struct ScPivotField; class ScDPTableData; class ScDPDimensionSaveData; class ScRangeList; 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 ScDPSaveData* pSaveData; OUString aTableName; OUString aTableTag; ScRange aOutRange; ScSheetSourceDesc* pSheetDesc; // for sheet data ScImportSourceDesc* pImpDesc; // for database data ScDPServiceDesc* pServDesc; // for external service ::boost::shared_ptr mpTableData; // cached data com::sun::star::uno::Reference xSource; ScDPOutput* pOutput; sal_uInt16 mnAutoFormatIndex; 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 bool FillLabelDataForDimension( const com::sun::star::uno::Reference< com::sun::star::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 ); const ScRange GetOutputRangeByType( sal_Int32 nType ); void SetSaveData(const ScDPSaveData& rData); ScDPSaveData* GetSaveData() const { return pSaveData; } void SetOutRange(const ScRange& rRange); const ScRange& GetOutRange() const { return aOutRange; } void SetHeaderLayout(bool bUseGrid); bool GetHeaderLayout() const; void SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate = false); 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; } const ScImportSourceDesc* GetImportSourceDesc() const { return pImpDesc; } const ScDPServiceDesc* GetDPServiceDesc() const { return pServDesc; } com::sun::star::uno::Reference GetSource(); bool IsSheetData() const; bool IsImportData() const { return(pImpDesc != NULL); } bool IsServiceData() const { return(pServDesc != NULL); } 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 = NULL ); bool IsDuplicated( long nDim ); long GetDimCount(); void GetHeaderPositionData(const ScAddress& rPos, ::com::sun::star::sheet::DataPilotTableHeaderData& rData); long GetHeaderDim( const ScAddress& rPos, sal_uInt16& rOrient ); bool GetHeaderDrag( const ScAddress& rPos, bool bMouseLeft, bool bMouseTop, long nDragDim, Rectangle& rPosRect, sal_uInt16& rOrient, long& rDimPos ); bool IsFilterButton( const ScAddress& rPos ); double GetPivotData( const OUString& rDataFieldName, std::vector& rFilters); bool ParseFilters( OUString& rDataFieldName, std::vector& rFilters, std::vector& rFilterFuncs, const OUString& rFilterList ); void GetMemberResultNames(ScDPUniqueStringSet& rNames, long nDimension); void ToggleDetails(const ::com::sun::star::sheet::DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj); bool FillOldParam(ScPivotParam& rParam) const; bool FillLabelData(sal_Int32 nDim, ScDPLabelData& Labels); bool FillLabelData(ScPivotParam& rParam); 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< OUString >& rHiers ); sal_Int32 GetUsedHierarchy( sal_Int32 nDim ); bool GetMembersNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers ); bool GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers ); bool GetMemberNames( sal_Int32 nDim, ::com::sun::star::uno::Sequence< OUString >& rNames ); bool GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector& rMembers ); void UpdateReference( UpdateRefMode eUpdateRefMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ); bool RefsEqual( const ScDPObject& r ) const; void WriteRefsTo( ScDPObject& r ) const; void GetPositionData(const ScAddress& rPos, ::com::sun::star::sheet::DataPilotTablePositionData& rPosData); bool GetDataFieldPositionData(const ScAddress& rPos, ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::DataPilotFieldFilter >& rFilters); void GetDrillDownData(const ScAddress& rPos, ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::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 com::sun::star::uno::Sequence GetRegisteredSources(); static com::sun::star::uno::Reference CreateSource( const ScDPServiceDesc& rDesc ); static void ConvertOrientation( ScDPSaveData& rSaveData, const ScPivotFieldVector& rFields, sal_uInt16 nOrient, const com::sun::star::uno::Reference< com::sun::star::sheet::XDimensionsSupplier>& xSource, const ScDPLabelDataVector& rLabels, const ScPivotFieldVector* pRefColFields = NULL, const ScPivotFieldVector* pRefRowFields = NULL, const ScPivotFieldVector* pRefPageFields = NULL ); static bool IsOrientationAllowed( sal_uInt16 nOrient, sal_Int32 nDimFlags ); #if DEBUG_PIVOT_TABLE void DumpCache() const; #endif }; class ScDPCollection { friend class ScDPCache; public: /** * Stores and manages all caches from internal sheets. */ class SheetCaches { friend class ScDPCollection; typedef boost::ptr_map CachesType; typedef std::vector RangeIndexType; CachesType maCaches; 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, SCsCOL nDx, SCsROW nDy, SCsTAB nDz); SC_DLLPUBLIC ScDPCache* getExistingCache(const ScRange& rRange); void updateCache(const ScRange& rRange, std::set& rRefs); bool remove(const ScDPCache* p); }; /** * Data caches for range name based source data. */ class NameCaches { friend class ScDPCollection; typedef ::boost::ptr_map CachesType; CachesType maCaches; 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& 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 : public ::std::binary_function { bool operator() (const DBType& left, const DBType& right) const; }; }; /** * Data caches for external database sources. */ class DBCaches { friend class ScDPCollection; typedef ::boost::ptr_map CachesType; CachesType maCaches; 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); com::sun::star::uno::Reference createRowSet( sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand); void updateCache( sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand, std::set& rRefs); bool remove(const ScDPCache* p); }; ScDPCollection(ScDocument* pDocument); ScDPCollection(const ScDPCollection& r); ~ScDPCollection(); sal_uLong ReloadCache(ScDPObject* pDPObj, std::set& rRefs); bool ReloadGroupsInCache(ScDPObject* pDPObj, std::set& rRefs); SC_DLLPUBLIC size_t GetCount() const; SC_DLLPUBLIC ScDPObject* operator[](size_t nIndex); SC_DLLPUBLIC const ScDPObject* operator[](size_t nIndex) const; const ScDPObject* GetByName(const OUString& rName) const; void DeleteOnTab( SCTAB nTab ); void UpdateReference( UpdateRefMode eUpdateRefMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB 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' + , and the nMin * specifies the minimum number allowed. * * @param nMin minimum number allowed. * * @return new name for data pilot object. */ OUString CreateNewName( sal_uInt16 nMin = 1 ) const; void FreeTable(ScDPObject* pDPObj); SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj); SC_DLLPUBLIC SheetCaches& GetSheetCaches(); NameCaches& GetNameCaches(); DBCaches& GetDBCaches(); 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& rRefs) const; void GetAllTables(const OUString& rSrcName, std::set& rRefs) const; void GetAllTables( sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand, std::set& rRefs) const; private: typedef ::boost::ptr_vector 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: */