Avoid potential negative array index access to cached text.
[LibreOffice.git] / sc / inc / dbdata.hxx
blobdf235ec52619b78c2012a914eee480f010c6ad6c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include "scdllapi.h"
23 #include "refreshtimer.hxx"
24 #include "address.hxx"
25 #include "global.hxx"
26 #include "rangelst.hxx"
28 #include <svl/listener.hxx>
30 #include <memory>
31 #include <set>
32 #include <vector>
34 class ScDocument;
35 struct ScSortParam;
36 struct ScQueryParam;
37 struct ScSubTotalParam;
39 /** Enum used to indicate which portion of the DBArea is to be considered. */
40 enum class ScDBDataPortion
42 TOP_LEFT, ///< top left cell of area
43 AREA ///< entire area
46 struct TableColumnAttributes
48 std::optional<OUString> maTotalsFunction = std::nullopt;
51 /** Container base class to provide selected access for ScDBData. */
52 class ScDBDataContainerBase
54 public:
55 ScDBDataContainerBase( ScDocument& rDoc ) : mrDoc(rDoc) {}
56 virtual ~ScDBDataContainerBase() {}
57 ScDocument& GetDocument() const;
58 ScRangeList& GetDirtyTableColumnNames();
60 protected:
61 ScDocument& mrDoc;
62 ScRangeList maDirtyTableColumnNames;
65 class SAL_DLLPUBLIC_RTTI ScDBData final : public SvtListener, public ScRefreshTimer
67 private:
68 std::unique_ptr<ScSortParam> mpSortParam;
69 std::unique_ptr<ScQueryParam> mpQueryParam;
70 std::unique_ptr<ScSubTotalParam> mpSubTotal;
71 std::unique_ptr<ScImportParam> mpImportParam;
73 ScDBDataContainerBase* mpContainer;
75 /// DBParam
76 const OUString aName;
77 OUString aUpper;
78 SCTAB nTable;
79 SCCOL nStartCol;
80 SCROW nStartRow;
81 SCCOL nEndCol;
82 SCROW nEndRow;
83 bool bByRow;
84 bool bHasHeader;
85 bool bHasTotals;
86 bool bDoSize;
87 bool bKeepFmt;
88 bool bStripData;
90 /// QueryParam
91 bool bIsAdvanced; ///< true if created by advanced filter
92 ScRange aAdvSource; ///< source range
94 bool bDBSelection; ///< not in Param: if selection, block update
96 sal_uInt16 nIndex; ///< unique index formulas
97 bool bAutoFilter; ///< AutoFilter? (not saved)
98 bool bModified; ///< is set/cleared for/by(?) UpdateReference
100 ::std::vector< OUString > maTableColumnNames; ///< names of table columns
101 ::std::vector< TableColumnAttributes > maTableColumnAttributes; ///< attributes of table columns
102 bool mbTableColumnNamesDirty;
103 SCSIZE nFilteredRowCount;
105 using ScRefreshTimer::operator==;
107 public:
108 struct less
110 bool operator() (const std::unique_ptr<ScDBData>& left, const std::unique_ptr<ScDBData>& right) const;
113 SC_DLLPUBLIC ScDBData(const OUString& rName,
114 SCTAB nTab,
115 SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
116 bool bByR = true, bool bHasH = true, bool bTotals = false);
117 ScDBData(const ScDBData& rData);
118 ScDBData(const OUString& rName, const ScDBData& rData);
119 SC_DLLPUBLIC virtual ~ScDBData() override;
121 virtual void Notify( const SfxHint& rHint ) override;
123 ScDBData& operator= (const ScDBData& rData) ;
125 bool operator== (const ScDBData& rData) const;
127 const OUString& GetName() const { return aName; }
128 const OUString& GetUpperName() const { return aUpper; }
129 SCTAB GetTab() const { return nTable; }
130 void GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const;
131 SC_DLLPUBLIC void GetArea(ScRange& rRange) const;
132 void SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
133 void MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
134 SCCOL nUpdateCol = -1);
135 void SetByRow(bool bByR) { bByRow = bByR; }
136 bool HasHeader() const { return bHasHeader; }
137 void SetHeader(bool bHasH) { bHasHeader = bHasH; }
138 bool HasTotals() const { return bHasTotals; }
139 void SetTotals(bool bTotals) { bHasTotals = bTotals; }
140 void SetIndex(sal_uInt16 nInd) { nIndex = nInd; }
141 sal_uInt16 GetIndex() const { return nIndex; }
142 bool IsDoSize() const { return bDoSize; }
143 void SetDoSize(bool bSet) { bDoSize = bSet; }
144 bool IsKeepFmt() const { return bKeepFmt; }
145 void SetKeepFmt(bool bSet) { bKeepFmt = bSet; }
146 bool IsStripData() const { return bStripData; }
147 void SetStripData(bool bSet) { bStripData = bSet; }
149 void SetContainer( ScDBDataContainerBase* pContainer ) { mpContainer = pContainer; }
150 /** Returns header row range if has headers, else invalid range. */
151 ScRange GetHeaderArea() const;
152 void StartTableColumnNamesListener();
153 void EndTableColumnNamesListener();
154 SC_DLLPUBLIC void SetTableColumnNames( ::std::vector< OUString >&& rNames );
155 SC_DLLPUBLIC const ::std::vector< OUString >& GetTableColumnNames() const { return maTableColumnNames; }
156 SC_DLLPUBLIC void SetTableColumnAttributes( ::std::vector< TableColumnAttributes >&& rAttributes );
157 SC_DLLPUBLIC const ::std::vector< TableColumnAttributes >& GetTableColumnAttributes() const { return maTableColumnAttributes; }
158 bool AreTableColumnNamesDirty() const { return mbTableColumnNamesDirty; }
160 /** Refresh/update the column names with the header row's cell contents. */
161 SC_DLLPUBLIC void RefreshTableColumnNames( ScDocument* pDoc );
163 /** Refresh/update the column names with the header row's cell contents
164 within the given range. */
165 void RefreshTableColumnNames( ScDocument* pDoc, const ScRange& rRange );
167 /** Finds the column named rName and returns the corresponding offset
168 within the table.
169 @returns -1 if not found.
171 XXX NOTE: there is no refresh of names or anything implemented yet, use
172 this only during document load time.
174 sal_Int32 GetColumnNameOffset( const OUString& rName ) const;
176 /** Returns table column name if nCol is within column range and name
177 is stored, else empty string. */
178 OUString GetTableColumnName( SCCOL nCol ) const;
180 OUString GetSourceString() const;
181 OUString GetOperations() const;
183 SC_DLLPUBLIC void GetSortParam(ScSortParam& rSortParam) const;
184 SC_DLLPUBLIC void SetSortParam(const ScSortParam& rSortParam);
186 /** Remember some more settings of ScSortParam, only to be called at
187 anonymous DB ranges as it at least overwrites bHasHeader. */
188 void UpdateFromSortParam( const ScSortParam& rSortParam );
190 SC_DLLPUBLIC void GetQueryParam(ScQueryParam& rQueryParam) const;
191 SC_DLLPUBLIC void SetQueryParam(const ScQueryParam& rQueryParam);
192 SC_DLLPUBLIC bool GetAdvancedQuerySource(ScRange& rSource) const;
193 SC_DLLPUBLIC void SetAdvancedQuerySource(const ScRange* pSource);
195 void GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const;
196 void SetSubTotalParam(const ScSubTotalParam& rSubTotalParam);
198 void GetImportParam(ScImportParam& rImportParam) const;
199 void SetImportParam(const ScImportParam& rImportParam);
201 bool IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
202 bool IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
204 bool HasImportParam() const;
205 SC_DLLPUBLIC bool HasQueryParam() const;
206 bool HasSortParam() const;
207 bool HasSubTotalParam() const;
209 bool HasImportSelection() const { return bDBSelection; }
210 void SetImportSelection(bool bSet) { bDBSelection = bSet; }
212 bool HasAutoFilter() const { return bAutoFilter; }
213 void SetAutoFilter(bool bSet) { bAutoFilter = bSet; }
215 bool IsModified() const { return bModified; }
216 void SetModified(bool bMod) { bModified = bMod; }
218 void UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
219 bool UpdateReference(const ScDocument* pDoc, UpdateRefMode eUpdateRefMode, SCCOL nCol1,
220 SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
221 SCCOL nDx, SCROW nDy, SCTAB nDz);
223 void ExtendDataArea(const ScDocument& rDoc);
224 void ExtendBackColorArea(const ScDocument& rDoc);
225 void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount);
226 void GetFilterSelCount(SCSIZE& nSelected, SCSIZE& nTotal);
228 private:
230 void AdjustTableColumnAttributes( UpdateRefMode eUpdateRefMode, SCCOL nDx, SCCOL nCol1,
231 SCCOL nOldCol1, SCCOL nOldCol2, SCCOL nNewCol1, SCCOL nNewCol2 );
232 void InvalidateTableColumnNames( bool bSwapToEmptyNames );
235 class SC_DLLPUBLIC ScDBCollection
237 public:
238 enum RangeType { GlobalNamed, GlobalAnonymous, SheetAnonymous };
241 * Stores global named database ranges.
243 class SC_DLLPUBLIC NamedDBs final : public ScDBDataContainerBase
245 friend class ScDBCollection;
247 typedef ::std::set<std::unique_ptr<ScDBData>, ScDBData::less> DBsType;
248 DBsType m_DBs;
249 ScDBCollection& mrParent;
250 NamedDBs(ScDBCollection& rParent, ScDocument& rDoc);
251 NamedDBs(const NamedDBs& r, ScDBCollection& rParent);
252 NamedDBs(const NamedDBs&) = delete;
253 virtual ~NamedDBs() override;
254 NamedDBs & operator=(NamedDBs const&) = delete;
255 void initInserted( ScDBData* p );
257 public:
258 typedef DBsType::iterator iterator;
259 typedef DBsType::const_iterator const_iterator;
261 iterator begin();
262 iterator end();
263 const_iterator begin() const;
264 const_iterator end() const;
265 ScDBData* findByIndex(sal_uInt16 nIndex);
266 ScDBData* findByUpperName(const OUString& rName);
267 iterator findByUpperName2(const OUString& rName);
268 ScDBData* findByName(const OUString& rName);
270 /** Takes ownership of p and attempts to insert it into the collection.
271 Deletes p if it could not be inserted, i.e. duplicate name.
272 @return <TRUE/> if inserted, else <FALSE/>.
274 bool insert(std::unique_ptr<ScDBData> p);
276 iterator erase(const iterator& itr);
277 bool empty() const;
278 size_t size() const;
279 bool operator== (const NamedDBs& r) const;
283 * Stores global anonymous database ranges.
285 class SAL_DLLPRIVATE AnonDBs
287 typedef ::std::vector<std::unique_ptr<ScDBData>> DBsType;
288 DBsType m_DBs;
290 AnonDBs& operator=(AnonDBs const&) = delete;
292 public:
293 AnonDBs();
294 AnonDBs(AnonDBs const&);
296 typedef DBsType::iterator iterator;
297 typedef DBsType::const_iterator const_iterator;
299 iterator begin();
300 iterator end();
301 const_iterator begin() const;
302 const_iterator end() const;
303 const ScDBData* findAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
304 const ScDBData* findByRange(const ScRange& rRange) const;
305 void deleteOnTab(SCTAB nTab);
306 ScDBData* getByRange(const ScRange& rRange);
307 void insert(ScDBData* p);
308 iterator erase(const iterator& itr);
309 bool empty() const;
310 bool has( const ScDBData* p ) const;
311 bool operator== (const AnonDBs& r) const;
314 private:
315 Link<Timer *, void> aRefreshHandler;
316 ScDocument& rDoc;
317 sal_uInt16 nEntryIndex; ///< counter for unique indices
318 NamedDBs maNamedDBs;
319 AnonDBs maAnonDBs;
321 public:
322 ScDBCollection(ScDocument& rDocument);
323 ScDBCollection(const ScDBCollection& r);
325 NamedDBs& getNamedDBs() { return maNamedDBs;}
326 const NamedDBs& getNamedDBs() const { return maNamedDBs;}
328 AnonDBs& getAnonDBs() { return maAnonDBs;}
329 const AnonDBs& getAnonDBs() const { return maAnonDBs;}
331 const ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const;
332 ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion);
333 const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
334 ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
335 ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab );
336 std::vector<ScDBData*> GetAllDBsFromTab(SCTAB nTab);
338 void RefreshDirtyTableColumnNames();
340 void DeleteOnTab( SCTAB nTab );
341 void UpdateReference(UpdateRefMode eUpdateRefMode,
342 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
343 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
344 SCCOL nDx, SCROW nDy, SCTAB nDz);
345 void UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
346 void CopyToTable(SCTAB nOldPos, SCTAB nNewPos);
348 void SetRefreshHandler( const Link<Timer *, void>& rLink )
349 { aRefreshHandler = rLink; }
350 const Link<Timer *, void>& GetRefreshHandler() const { return aRefreshHandler; }
352 bool empty() const;
353 bool operator== (const ScDBCollection& r) const;
356 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */