diff options
Diffstat (limited to 'sc/inc/dbdata.hxx')
-rw-r--r-- | sc/inc/dbdata.hxx | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx new file mode 100644 index 0000000000..df235ec526 --- /dev/null +++ b/sc/inc/dbdata.hxx @@ -0,0 +1,356 @@ +/* -*- 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 . + */ + +#pragma once + +#include "scdllapi.h" +#include "refreshtimer.hxx" +#include "address.hxx" +#include "global.hxx" +#include "rangelst.hxx" + +#include <svl/listener.hxx> + +#include <memory> +#include <set> +#include <vector> + +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 +}; + +struct TableColumnAttributes +{ + std::optional<OUString> maTotalsFunction = std::nullopt; +}; + +/** 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<ScSortParam> mpSortParam; + std::unique_ptr<ScQueryParam> mpQueryParam; + std::unique_ptr<ScSubTotalParam> mpSubTotal; + std::unique_ptr<ScImportParam> 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 + ::std::vector< TableColumnAttributes > maTableColumnAttributes; ///< attributes of table columns + bool mbTableColumnNamesDirty; + SCSIZE nFilteredRowCount; + + using ScRefreshTimer::operator==; + +public: + struct less + { + bool operator() (const std::unique_ptr<ScDBData>& left, const std::unique_ptr<ScDBData>& 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, + SCCOL nUpdateCol = -1); + 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( ::std::vector< OUString >&& rNames ); + SC_DLLPUBLIC const ::std::vector< OUString >& GetTableColumnNames() const { return maTableColumnNames; } + SC_DLLPUBLIC void SetTableColumnAttributes( ::std::vector< TableColumnAttributes >&& rAttributes ); + SC_DLLPUBLIC const ::std::vector< TableColumnAttributes >& GetTableColumnAttributes() const { return maTableColumnAttributes; } + 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. */ + 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 ); + bool 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 ExtendBackColorArea(const ScDocument& rDoc); + void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount); + void GetFilterSelCount(SCSIZE& nSelected, SCSIZE& nTotal); + +private: + + void AdjustTableColumnAttributes( 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<std::unique_ptr<ScDBData>, 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); + ScDBData* findByName(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 <TRUE/> if inserted, else <FALSE/>. + */ + bool insert(std::unique_ptr<ScDBData> p); + + iterator 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<std::unique_ptr<ScDBData>> 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); + iterator erase(const iterator& itr); + bool empty() const; + bool has( const ScDBData* p ) const; + bool operator== (const AnonDBs& r) const; + }; + +private: + Link<Timer *, void> 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 ); + std::vector<ScDBData*> GetAllDBsFromTab(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 CopyToTable(SCTAB nOldPos, SCTAB nNewPos); + + void SetRefreshHandler( const Link<Timer *, void>& rLink ) + { aRefreshHandler = rLink; } + const Link<Timer *, void>& GetRefreshHandler() const { return aRefreshHandler; } + + bool empty() const; + bool operator== (const ScDBCollection& r) const; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |