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