1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #ifndef INCLUDED_SC_INC_DBDATA_HXX 21 #define INCLUDED_SC_INC_DBDATA_HXX 22 23 #include "scdllapi.h" 24 #include "refreshtimer.hxx" 25 #include "address.hxx" 26 #include "global.hxx" 27 #include "rangelst.hxx" 28 29 #include <svl/listener.hxx> 30 31 #include <memory> 32 #include <set> 33 #include <vector> 34 35 class ScDocument; 36 struct ScSortParam; 37 struct ScQueryParam; 38 struct ScSubTotalParam; 39 40 /** Enum used to indicate which portion of the DBArea is to be considered. */ 41 enum class ScDBDataPortion 42 { 43 TOP_LEFT, ///< top left cell of area 44 AREA ///< entire area 45 }; 46 47 /** Container base class to provide selected access for ScDBData. */ 48 class ScDBDataContainerBase 49 { 50 public: ScDBDataContainerBase(ScDocument & rDoc)51 ScDBDataContainerBase( ScDocument& rDoc ) : mrDoc(rDoc) {} ~ScDBDataContainerBase()52 virtual ~ScDBDataContainerBase() {} 53 ScDocument& GetDocument() const; 54 ScRangeList& GetDirtyTableColumnNames(); 55 56 protected: 57 ScDocument& mrDoc; 58 ScRangeList maDirtyTableColumnNames; 59 }; 60 61 class SAL_DLLPUBLIC_RTTI ScDBData final : public SvtListener, public ScRefreshTimer 62 { 63 private: 64 std::unique_ptr<ScSortParam> mpSortParam; 65 std::unique_ptr<ScQueryParam> mpQueryParam; 66 std::unique_ptr<ScSubTotalParam> mpSubTotal; 67 std::unique_ptr<ScImportParam> mpImportParam; 68 69 ScDBDataContainerBase* mpContainer; 70 71 /// DBParam 72 const OUString aName; 73 OUString aUpper; 74 SCTAB nTable; 75 SCCOL nStartCol; 76 SCROW nStartRow; 77 SCCOL nEndCol; 78 SCROW nEndRow; 79 bool bByRow; 80 bool bHasHeader; 81 bool bHasTotals; 82 bool bDoSize; 83 bool bKeepFmt; 84 bool bStripData; 85 86 /// QueryParam 87 bool bIsAdvanced; ///< true if created by advanced filter 88 ScRange aAdvSource; ///< source range 89 90 bool bDBSelection; ///< not in Param: if selection, block update 91 92 sal_uInt16 nIndex; ///< unique index formulas 93 bool bAutoFilter; ///< AutoFilter? (not saved) 94 bool bModified; ///< is set/cleared for/by(?) UpdateReference 95 96 ::std::vector< OUString > maTableColumnNames; ///< names of table columns 97 bool mbTableColumnNamesDirty; 98 SCSIZE nFilteredRowCount; 99 100 using ScRefreshTimer::operator==; 101 102 public: 103 struct less 104 { 105 bool operator() (const std::unique_ptr<ScDBData>& left, const std::unique_ptr<ScDBData>& right) const; 106 }; 107 108 SC_DLLPUBLIC ScDBData(const OUString& rName, 109 SCTAB nTab, 110 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, 111 bool bByR = true, bool bHasH = true, bool bTotals = false); 112 ScDBData(const ScDBData& rData); 113 ScDBData(const OUString& rName, const ScDBData& rData); 114 SC_DLLPUBLIC virtual ~ScDBData() override; 115 116 virtual void Notify( const SfxHint& rHint ) override; 117 118 ScDBData& operator= (const ScDBData& rData) ; 119 120 bool operator== (const ScDBData& rData) const; 121 GetName() const122 const OUString& GetName() const { return aName; } GetUpperName() const123 const OUString& GetUpperName() const { return aUpper; } GetTab() const124 SCTAB GetTab() const { return nTable; } 125 void GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const; 126 SC_DLLPUBLIC void GetArea(ScRange& rRange) const; 127 void SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); 128 void MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); SetByRow(bool bByR)129 void SetByRow(bool bByR) { bByRow = bByR; } HasHeader() const130 bool HasHeader() const { return bHasHeader; } SetHeader(bool bHasH)131 void SetHeader(bool bHasH) { bHasHeader = bHasH; } HasTotals() const132 bool HasTotals() const { return bHasTotals; } SetTotals(bool bTotals)133 void SetTotals(bool bTotals) { bHasTotals = bTotals; } SetIndex(sal_uInt16 nInd)134 void SetIndex(sal_uInt16 nInd) { nIndex = nInd; } GetIndex() const135 sal_uInt16 GetIndex() const { return nIndex; } IsDoSize() const136 bool IsDoSize() const { return bDoSize; } SetDoSize(bool bSet)137 void SetDoSize(bool bSet) { bDoSize = bSet; } IsKeepFmt() const138 bool IsKeepFmt() const { return bKeepFmt; } SetKeepFmt(bool bSet)139 void SetKeepFmt(bool bSet) { bKeepFmt = bSet; } IsStripData() const140 bool IsStripData() const { return bStripData; } SetStripData(bool bSet)141 void SetStripData(bool bSet) { bStripData = bSet; } 142 SetContainer(ScDBDataContainerBase * pContainer)143 void SetContainer( ScDBDataContainerBase* pContainer ) { mpContainer = pContainer; } 144 /** Returns header row range if has headers, else invalid range. */ 145 ScRange GetHeaderArea() const; 146 void StartTableColumnNamesListener(); 147 void EndTableColumnNamesListener(); 148 SC_DLLPUBLIC void SetTableColumnNames( const ::std::vector< OUString >& rNames ); GetTableColumnNames() const149 SC_DLLPUBLIC const ::std::vector< OUString >& GetTableColumnNames() const { return maTableColumnNames; } AreTableColumnNamesDirty() const150 bool AreTableColumnNamesDirty() const { return mbTableColumnNamesDirty; } 151 152 /** Refresh/update the column names with the header row's cell contents. */ 153 SC_DLLPUBLIC void RefreshTableColumnNames( ScDocument* pDoc ); 154 155 /** Refresh/update the column names with the header row's cell contents 156 within the given range. */ 157 void RefreshTableColumnNames( ScDocument* pDoc, const ScRange& rRange ); 158 159 /** Finds the column named rName and returns the corresponding offset 160 within the table. 161 @returns -1 if not found. 162 163 XXX NOTE: there is no refresh of names or anything implemented yet, use 164 this only during document load time. 165 */ 166 sal_Int32 GetColumnNameOffset( const OUString& rName ) const; 167 168 /** Returns table column name if nCol is within column range and name 169 is stored, else empty string. */ 170 const OUString& GetTableColumnName( SCCOL nCol ) const; 171 172 OUString GetSourceString() const; 173 OUString GetOperations() const; 174 175 SC_DLLPUBLIC void GetSortParam(ScSortParam& rSortParam) const; 176 SC_DLLPUBLIC void SetSortParam(const ScSortParam& rSortParam); 177 178 /** Remember some more settings of ScSortParam, only to be called at 179 anonymous DB ranges as it at least overwrites bHasHeader. */ 180 void UpdateFromSortParam( const ScSortParam& rSortParam ); 181 182 SC_DLLPUBLIC void GetQueryParam(ScQueryParam& rQueryParam) const; 183 SC_DLLPUBLIC void SetQueryParam(const ScQueryParam& rQueryParam); 184 SC_DLLPUBLIC bool GetAdvancedQuerySource(ScRange& rSource) const; 185 SC_DLLPUBLIC void SetAdvancedQuerySource(const ScRange* pSource); 186 187 void GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const; 188 void SetSubTotalParam(const ScSubTotalParam& rSubTotalParam); 189 190 void GetImportParam(ScImportParam& rImportParam) const; 191 void SetImportParam(const ScImportParam& rImportParam); 192 193 bool IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const; 194 bool IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; 195 196 bool HasImportParam() const; 197 SC_DLLPUBLIC bool HasQueryParam() const; 198 bool HasSortParam() const; 199 bool HasSubTotalParam() const; 200 HasImportSelection() const201 bool HasImportSelection() const { return bDBSelection; } SetImportSelection(bool bSet)202 void SetImportSelection(bool bSet) { bDBSelection = bSet; } 203 HasAutoFilter() const204 bool HasAutoFilter() const { return bAutoFilter; } SetAutoFilter(bool bSet)205 void SetAutoFilter(bool bSet) { bAutoFilter = bSet; } 206 IsModified() const207 bool IsModified() const { return bModified; } SetModified(bool bMod)208 void SetModified(bool bMod) { bModified = bMod; } 209 210 void UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos ); 211 void UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefMode, 212 SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 213 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, 214 SCCOL nDx, SCROW nDy, SCTAB nDz); 215 216 void ExtendDataArea(const ScDocument* pDoc); 217 void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount); 218 void GetFilterSelCount(SCSIZE& nSelected, SCSIZE& nTotal); 219 220 private: 221 222 void AdjustTableColumnNames( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1, 223 SCCOL nOldCol1, SCCOL nOldCol2, SCCOL nNewCol1, SCCOL nNewCol2 ); 224 void InvalidateTableColumnNames( bool bSwapToEmptyNames ); 225 }; 226 227 class SC_DLLPUBLIC ScDBCollection 228 { 229 public: 230 enum RangeType { GlobalNamed, GlobalAnonymous, SheetAnonymous }; 231 232 /** 233 * Stores global named database ranges. 234 */ 235 class SC_DLLPUBLIC NamedDBs final : public ScDBDataContainerBase 236 { 237 friend class ScDBCollection; 238 239 typedef ::std::set<std::unique_ptr<ScDBData>, ScDBData::less> DBsType; 240 DBsType m_DBs; 241 ScDBCollection& mrParent; 242 NamedDBs(ScDBCollection& rParent, ScDocument& rDoc); 243 NamedDBs(const NamedDBs& r, ScDBCollection& rParent); 244 NamedDBs(const NamedDBs&) = delete; 245 virtual ~NamedDBs() override; 246 NamedDBs & operator=(NamedDBs const&) = delete; 247 void initInserted( ScDBData* p ); 248 249 public: 250 typedef DBsType::iterator iterator; 251 typedef DBsType::const_iterator const_iterator; 252 253 iterator begin(); 254 iterator end(); 255 const_iterator begin() const; 256 const_iterator end() const; 257 ScDBData* findByIndex(sal_uInt16 nIndex); 258 ScDBData* findByUpperName(const OUString& rName); 259 iterator findByUpperName2(const OUString& rName); 260 261 /** Takes ownership of p and attempts to insert it into the collection. 262 Deletes p if it could not be inserted, i.e. duplicate name. 263 @return <TRUE/> if inserted, else <FALSE/>. 264 */ 265 bool insert(std::unique_ptr<ScDBData> p); 266 267 void erase(const iterator& itr); 268 bool empty() const; 269 size_t size() const; 270 bool operator== (const NamedDBs& r) const; 271 }; 272 273 /** 274 * Stores global anonymous database ranges. 275 */ 276 class AnonDBs 277 { 278 typedef ::std::vector<std::unique_ptr<ScDBData>> DBsType; 279 DBsType m_DBs; 280 281 AnonDBs& operator=(AnonDBs const&) = delete; 282 283 public: 284 AnonDBs(); 285 AnonDBs(AnonDBs const&); 286 287 typedef DBsType::iterator iterator; 288 typedef DBsType::const_iterator const_iterator; 289 290 iterator begin(); 291 iterator end(); 292 const_iterator begin() const; 293 const_iterator end() const; 294 const ScDBData* findAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const; 295 const ScDBData* findByRange(const ScRange& rRange) const; 296 void deleteOnTab(SCTAB nTab); 297 ScDBData* getByRange(const ScRange& rRange); 298 void insert(ScDBData* p); 299 bool empty() const; 300 bool has( const ScDBData* p ) const; 301 bool operator== (const AnonDBs& r) const; 302 }; 303 304 private: 305 Link<Timer *, void> aRefreshHandler; 306 ScDocument* pDoc; 307 sal_uInt16 nEntryIndex; ///< counter for unique indices 308 NamedDBs maNamedDBs; 309 AnonDBs maAnonDBs; 310 311 public: 312 ScDBCollection(ScDocument* pDocument); 313 ScDBCollection(const ScDBCollection& r); 314 getNamedDBs()315 NamedDBs& getNamedDBs() { return maNamedDBs;} getNamedDBs() const316 const NamedDBs& getNamedDBs() const { return maNamedDBs;} 317 getAnonDBs()318 AnonDBs& getAnonDBs() { return maAnonDBs;} getAnonDBs() const319 const AnonDBs& getAnonDBs() const { return maAnonDBs;} 320 321 const ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const; 322 ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion); 323 const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; 324 ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); 325 ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab ); 326 327 void RefreshDirtyTableColumnNames(); 328 329 void DeleteOnTab( SCTAB nTab ); 330 void UpdateReference(UpdateRefMode eUpdateRefMode, 331 SCCOL nCol1, SCROW nRow1, SCTAB nTab1, 332 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, 333 SCCOL nDx, SCROW nDy, SCTAB nDz); 334 void UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos ); 335 SetRefreshHandler(const Link<Timer *,void> & rLink)336 void SetRefreshHandler( const Link<Timer *, void>& rLink ) 337 { aRefreshHandler = rLink; } GetRefreshHandler() const338 const Link<Timer *, void>& GetRefreshHandler() const { return aRefreshHandler; } 339 340 bool empty() const; 341 bool operator== (const ScDBCollection& r) const; 342 }; 343 344 #endif 345 346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 347