/* -*- 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_DBDATA_HXX #define INCLUDED_SC_INC_DBDATA_HXX #include "scdllapi.h" #include "refreshtimer.hxx" #include "address.hxx" #include "global.hxx" #include "rangelst.hxx" #include #include #include #include class ScDocument; struct ScSortParam; struct ScQueryParam; struct ScSubTotalParam; /** Enum used to indicate which portion of the DBArea is to be considered. */ enum class ScDBDataPortion { TOP_LEFT, ///< top left cell of area AREA ///< entire area }; /** Container base class to provide selected access for ScDBData. */ class ScDBDataContainerBase { public: ScDBDataContainerBase( ScDocument& rDoc ) : mrDoc(rDoc) {} virtual ~ScDBDataContainerBase() {} ScDocument& GetDocument() const; ScRangeList& GetDirtyTableColumnNames(); protected: ScDocument& mrDoc; ScRangeList maDirtyTableColumnNames; }; class SAL_DLLPUBLIC_RTTI ScDBData final : public SvtListener, public ScRefreshTimer { private: std::unique_ptr mpSortParam; std::unique_ptr mpQueryParam; std::unique_ptr mpSubTotal; std::unique_ptr mpImportParam; ScDBDataContainerBase* mpContainer; /// DBParam const OUString aName; OUString aUpper; SCTAB nTable; SCCOL nStartCol; SCROW nStartRow; SCCOL nEndCol; SCROW nEndRow; bool bByRow; bool bHasHeader; bool bHasTotals; bool bDoSize; bool bKeepFmt; bool bStripData; /// QueryParam bool bIsAdvanced; ///< true if created by advanced filter ScRange aAdvSource; ///< source range bool bDBSelection; ///< not in Param: if selection, block update sal_uInt16 nIndex; ///< unique index formulas bool bAutoFilter; ///< AutoFilter? (not saved) bool bModified; ///< is set/cleared for/by(?) UpdateReference ::std::vector< OUString > maTableColumnNames; ///< names of table columns bool mbTableColumnNamesDirty; SCSIZE nFilteredRowCount; using ScRefreshTimer::operator==; public: struct less { bool operator() (const std::unique_ptr& left, const std::unique_ptr& right) const; }; SC_DLLPUBLIC ScDBData(const OUString& rName, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bByR = true, bool bHasH = true, bool bTotals = false); ScDBData(const ScDBData& rData); ScDBData(const OUString& rName, const ScDBData& rData); SC_DLLPUBLIC virtual ~ScDBData() override; virtual void Notify( const SfxHint& rHint ) override; ScDBData& operator= (const ScDBData& rData) ; bool operator== (const ScDBData& rData) const; const OUString& GetName() const { return aName; } const OUString& GetUpperName() const { return aUpper; } SCTAB GetTab() const { return nTable; } void GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const; SC_DLLPUBLIC void GetArea(ScRange& rRange) const; void SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); void MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); void SetByRow(bool bByR) { bByRow = bByR; } bool HasHeader() const { return bHasHeader; } void SetHeader(bool bHasH) { bHasHeader = bHasH; } bool HasTotals() const { return bHasTotals; } void SetTotals(bool bTotals) { bHasTotals = bTotals; } void SetIndex(sal_uInt16 nInd) { nIndex = nInd; } sal_uInt16 GetIndex() const { return nIndex; } bool IsDoSize() const { return bDoSize; } void SetDoSize(bool bSet) { bDoSize = bSet; } bool IsKeepFmt() const { return bKeepFmt; } void SetKeepFmt(bool bSet) { bKeepFmt = bSet; } bool IsStripData() const { return bStripData; } void SetStripData(bool bSet) { bStripData = bSet; } void SetContainer( ScDBDataContainerBase* pContainer ) { mpContainer = pContainer; } /** Returns header row range if has headers, else invalid range. */ ScRange GetHeaderArea() const; void StartTableColumnNamesListener(); void EndTableColumnNamesListener(); SC_DLLPUBLIC void SetTableColumnNames( const ::std::vector< OUString >& rNames ); SC_DLLPUBLIC const ::std::vector< OUString >& GetTableColumnNames() const { return maTableColumnNames; } bool AreTableColumnNamesDirty() const { return mbTableColumnNamesDirty; } /** Refresh/update the column names with the header row's cell contents. */ SC_DLLPUBLIC void RefreshTableColumnNames( ScDocument* pDoc ); /** Refresh/update the column names with the header row's cell contents within the given range. */ void RefreshTableColumnNames( ScDocument* pDoc, const ScRange& rRange ); /** Finds the column named rName and returns the corresponding offset within the table. @returns -1 if not found. XXX NOTE: there is no refresh of names or anything implemented yet, use this only during document load time. */ sal_Int32 GetColumnNameOffset( const OUString& rName ) const; /** Returns table column name if nCol is within column range and name is stored, else empty string. */ const OUString& GetTableColumnName( SCCOL nCol ) const; OUString GetSourceString() const; OUString GetOperations() const; SC_DLLPUBLIC void GetSortParam(ScSortParam& rSortParam) const; SC_DLLPUBLIC void SetSortParam(const ScSortParam& rSortParam); /** Remember some more settings of ScSortParam, only to be called at anonymous DB ranges as it at least overwrites bHasHeader. */ void UpdateFromSortParam( const ScSortParam& rSortParam ); SC_DLLPUBLIC void GetQueryParam(ScQueryParam& rQueryParam) const; SC_DLLPUBLIC void SetQueryParam(const ScQueryParam& rQueryParam); SC_DLLPUBLIC bool GetAdvancedQuerySource(ScRange& rSource) const; SC_DLLPUBLIC void SetAdvancedQuerySource(const ScRange* pSource); void GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const; void SetSubTotalParam(const ScSubTotalParam& rSubTotalParam); void GetImportParam(ScImportParam& rImportParam) const; void SetImportParam(const ScImportParam& rImportParam); bool IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const; bool IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; bool HasImportParam() const; SC_DLLPUBLIC bool HasQueryParam() const; bool HasSortParam() const; bool HasSubTotalParam() const; bool HasImportSelection() const { return bDBSelection; } void SetImportSelection(bool bSet) { bDBSelection = bSet; } bool HasAutoFilter() const { return bAutoFilter; } void SetAutoFilter(bool bSet) { bAutoFilter = bSet; } bool IsModified() const { return bModified; } void SetModified(bool bMod) { bModified = bMod; } void UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos ); void UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCCOL nDx, SCROW nDy, SCTAB nDz); void ExtendDataArea(const ScDocument& rDoc); void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount); void GetFilterSelCount(SCSIZE& nSelected, SCSIZE& nTotal); private: void AdjustTableColumnNames( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1, SCCOL nOldCol1, SCCOL nOldCol2, SCCOL nNewCol1, SCCOL nNewCol2 ); void InvalidateTableColumnNames( bool bSwapToEmptyNames ); }; class SC_DLLPUBLIC ScDBCollection { public: enum RangeType { GlobalNamed, GlobalAnonymous, SheetAnonymous }; /** * Stores global named database ranges. */ class SC_DLLPUBLIC NamedDBs final : public ScDBDataContainerBase { friend class ScDBCollection; typedef ::std::set, ScDBData::less> DBsType; DBsType m_DBs; ScDBCollection& mrParent; NamedDBs(ScDBCollection& rParent, ScDocument& rDoc); NamedDBs(const NamedDBs& r, ScDBCollection& rParent); NamedDBs(const NamedDBs&) = delete; virtual ~NamedDBs() override; NamedDBs & operator=(NamedDBs const&) = delete; void initInserted( ScDBData* p ); public: typedef DBsType::iterator iterator; typedef DBsType::const_iterator const_iterator; iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; ScDBData* findByIndex(sal_uInt16 nIndex); ScDBData* findByUpperName(const OUString& rName); iterator findByUpperName2(const OUString& rName); /** Takes ownership of p and attempts to insert it into the collection. Deletes p if it could not be inserted, i.e. duplicate name. @return if inserted, else . */ bool insert(std::unique_ptr p); void erase(const iterator& itr); bool empty() const; size_t size() const; bool operator== (const NamedDBs& r) const; }; /** * Stores global anonymous database ranges. */ class SAL_DLLPRIVATE AnonDBs { typedef ::std::vector> DBsType; DBsType m_DBs; AnonDBs& operator=(AnonDBs const&) = delete; public: AnonDBs(); AnonDBs(AnonDBs const&); typedef DBsType::iterator iterator; typedef DBsType::const_iterator const_iterator; iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; const ScDBData* findAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const; const ScDBData* findByRange(const ScRange& rRange) const; void deleteOnTab(SCTAB nTab); ScDBData* getByRange(const ScRange& rRange); void insert(ScDBData* p); bool empty() const; bool has( const ScDBData* p ) const; bool operator== (const AnonDBs& r) const; }; private: Link aRefreshHandler; ScDocument& rDoc; sal_uInt16 nEntryIndex; ///< counter for unique indices NamedDBs maNamedDBs; AnonDBs maAnonDBs; public: ScDBCollection(ScDocument& rDocument); ScDBCollection(const ScDBCollection& r); NamedDBs& getNamedDBs() { return maNamedDBs;} const NamedDBs& getNamedDBs() const { return maNamedDBs;} AnonDBs& getAnonDBs() { return maAnonDBs;} const AnonDBs& getAnonDBs() const { return maAnonDBs;} const ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const; ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion); const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab ); void RefreshDirtyTableColumnNames(); void DeleteOnTab( SCTAB nTab ); void UpdateReference(UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCCOL nDx, SCROW nDy, SCTAB nDz); void UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos ); void SetRefreshHandler( const Link& rLink ) { aRefreshHandler = rLink; } const Link& GetRefreshHandler() const { return aRefreshHandler; } bool empty() const; bool operator== (const ScDBCollection& r) const; }; #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */