Avoid potential negative array index access to cached text.
[LibreOffice.git] / sc / inc / dpobject.hxx
blob0e4cf882b529d5081efa4245efa66a48b388beda
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 "global.hxx"
24 #include "address.hxx"
25 #include "dpcache.hxx"
26 #include "dptypes.hxx"
27 #include "pivot.hxx"
28 #include "calcmacros.hxx"
30 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
31 #include <o3tl/sorted_vector.hxx>
32 #include <unotools/resmgr.hxx>
34 #include <memory>
35 #include <vector>
36 #include <map>
38 namespace com::sun::star {
40 namespace container {
41 class XIndexAccess;
42 class XNameAccess;
45 namespace sdbc {
46 class XRowSet;
49 namespace sheet {
50 class XMembersAccess;
51 class XDimensionsSupplier;
52 struct DataPilotTablePositionData;
53 struct DataPilotTableHeaderData;
54 struct DataPilotFieldFilter;
58 namespace tools { class Rectangle; }
59 class ScDPSaveData;
60 class ScDPOutput;
61 struct ScImportSourceDesc;
62 class ScSheetSourceDesc;
63 class ScDPTableData;
64 class ScDPDimensionSaveData;
65 class ScRangeList;
66 class ScDPCache;
67 class ScDocument;
69 struct ScDPServiceDesc
71 OUString aServiceName;
72 OUString aParSource;
73 OUString aParName;
74 OUString aParUser;
75 OUString aParPass;
77 ScDPServiceDesc( OUString aServ, OUString aSrc, OUString aNam,
78 OUString aUser, OUString aPass );
80 bool operator== ( const ScDPServiceDesc& rOther ) const;
83 class SC_DLLPUBLIC ScDPObject
85 private:
86 ScDocument* pDoc;
87 // settings
88 std::unique_ptr<ScDPSaveData> pSaveData;
89 OUString aTableName;
90 OUString aTableTag;
91 ScRange aOutRange;
92 std::unique_ptr<ScSheetSourceDesc> pSheetDesc; // for sheet data
93 std::unique_ptr<ScImportSourceDesc> pImpDesc; // for database data
94 std::unique_ptr<ScDPServiceDesc> pServDesc; // for external service
95 std::shared_ptr<ScDPTableData> mpTableData;
96 // cached data
97 css::uno::Reference<css::sheet::XDimensionsSupplier> xSource;
98 std::unique_ptr<ScDPOutput> pOutput;
100 // name -> sequence of sequences of css::xml::FastAttribute or css::xml::Attribute
101 // see PivotTable::putToInteropGrabBag in sc/source/filter/oox/pivottablebuffer.cxx for details
102 std::map<OUString, css::uno::Any> maInteropGrabBag;
104 sal_Int32 nHeaderRows; // page fields plus filter button
105 bool mbHeaderLayout:1; // true : grid, false : standard
106 bool bAllowMove:1;
107 bool bSettingsChanged:1;
108 bool mbEnableGetPivotData:1;
110 SAL_DLLPRIVATE ScDPTableData* GetTableData();
111 SAL_DLLPRIVATE void CreateObjects();
112 SAL_DLLPRIVATE void CreateOutput();
113 SAL_DLLPRIVATE void ClearSource();
114 SAL_DLLPRIVATE void FillLabelDataForDimension(
115 const css::uno::Reference< css::container::XIndexAccess>& xDims,
116 sal_Int32 nDim, ScDPLabelData& rLabelData);
118 public:
119 ScDPObject(ScDocument* pD);
120 ScDPObject(const ScDPObject& r);
121 ~ScDPObject();
123 ScDPObject& operator= (const ScDPObject& r);
125 void EnableGetPivotData(bool b);
127 void SetAllowMove(bool bSet);
129 void InvalidateData();
130 void Clear();
131 void ClearTableData();
132 void ReloadGroupTableData();
134 void Output( const ScAddress& rPos );
135 ScRange GetNewOutputRange( bool& rOverflow );
137 ScRange GetOutputRangeByType( sal_Int32 nType );
138 ScRange GetOutputRangeByType( sal_Int32 nType ) const;
140 void SetSaveData(const ScDPSaveData& rData);
141 ScDPSaveData* GetSaveData() const { return pSaveData.get(); }
143 void SetOutRange(const ScRange& rRange);
144 const ScRange& GetOutRange() const;
146 void SetHeaderLayout(bool bUseGrid);
147 bool GetHeaderLayout() const { return mbHeaderLayout;}
149 void SetSheetDesc(const ScSheetSourceDesc& rDesc);
150 void SetImportDesc(const ScImportSourceDesc& rDesc);
151 void SetServiceData(const ScDPServiceDesc& rDesc);
153 void WriteSourceDataTo( ScDPObject& rDest ) const;
154 void WriteTempDataTo( ScDPObject& rDest ) const;
156 const ScSheetSourceDesc* GetSheetDesc() const { return pSheetDesc.get(); }
157 const ScImportSourceDesc* GetImportSourceDesc() const { return pImpDesc.get(); }
158 const ScDPServiceDesc* GetDPServiceDesc() const { return pServDesc.get(); }
160 css::uno::Reference<css::sheet::XDimensionsSupplier> const & GetSource();
162 bool IsSheetData() const;
163 bool IsImportData() const { return(pImpDesc != nullptr); }
164 bool IsServiceData() const { return(pServDesc != nullptr); }
166 void SetName(const OUString& rNew);
167 const OUString& GetName() const { return aTableName; }
168 void SetTag(const OUString& rNew);
169 const OUString& GetTag() const { return aTableTag; }
172 * Data description cell displays the description of a data dimension if
173 * and only if there is only one data dimension. It's usually located at
174 * the upper-left corner of the table output.
176 bool IsDataDescriptionCell(const ScAddress& rPos);
178 bool IsDimNameInUse(std::u16string_view rName) const;
179 OUString GetDimName( tools::Long nDim, bool& rIsDataLayout, sal_Int32* pFlags = nullptr );
180 bool IsDuplicated( tools::Long nDim );
181 tools::Long GetDimCount();
182 void GetHeaderPositionData(const ScAddress& rPos, css::sheet::DataPilotTableHeaderData& rData);
183 tools::Long GetHeaderDim( const ScAddress& rPos, css::sheet::DataPilotFieldOrientation& rOrient );
184 bool GetHeaderDrag( const ScAddress& rPos, bool bMouseLeft, bool bMouseTop,
185 tools::Long nDragDim,
186 tools::Rectangle& rPosRect, css::sheet::DataPilotFieldOrientation& rOrient, tools::Long& rDimPos );
187 bool IsFilterButton( const ScAddress& rPos );
189 OUString GetFormattedString( std::u16string_view rDimName, const double fValue );
191 double GetPivotData(
192 const OUString& rDataFieldName,
193 std::vector<css::sheet::DataPilotFieldFilter>& rFilters);
195 bool ParseFilters(
196 OUString& rDataFieldName,
197 std::vector<css::sheet::DataPilotFieldFilter>& rFilters,
198 std::vector<sal_Int16>& rFilterFuncs,
199 std::u16string_view rFilterList );
201 void GetMemberResultNames(ScDPUniqueStringSet& rNames, tools::Long nDimension);
203 void ToggleDetails(const css::sheet::DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj);
205 void FillOldParam(ScPivotParam& rParam) const;
206 void FillLabelData(sal_Int32 nDim, ScDPLabelData& Labels);
207 void FillLabelData(ScPivotParam& rParam);
209 void GetFieldIdsNames(css::sheet::DataPilotFieldOrientation nOrient, std::vector<tools::Long>& rIndices,
210 std::vector<OUString>& rNames);
212 bool GetHierarchiesNA( sal_Int32 nDim, css::uno::Reference< css::container::XNameAccess >& xHiers );
213 void GetHierarchies( sal_Int32 nDim, css::uno::Sequence< OUString >& rHiers );
215 sal_Int32 GetUsedHierarchy( sal_Int32 nDim );
217 bool GetMembersNA( sal_Int32 nDim, css::uno::Reference< css::sheet::XMembersAccess >& xMembers );
218 bool GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, css::uno::Reference< css::sheet::XMembersAccess >& xMembers );
220 bool GetMemberNames( sal_Int32 nDim, css::uno::Sequence< OUString >& rNames );
221 bool GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector<ScDPLabelData::Member>& rMembers );
223 void UpdateReference( UpdateRefMode eUpdateRefMode,
224 const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz );
225 bool RefsEqual( const ScDPObject& r ) const;
226 void WriteRefsTo( ScDPObject& r ) const;
228 void GetPositionData(const ScAddress& rPos, css::sheet::DataPilotTablePositionData& rPosData);
230 bool GetDataFieldPositionData(const ScAddress& rPos,
231 css::uno::Sequence<
232 css::sheet::DataPilotFieldFilter >& rFilters);
234 void GetDrillDownData(const ScAddress& rPos,
235 css::uno::Sequence< css::uno::Sequence< css::uno::Any > >& rTableData);
237 // apply drop-down attribute, initialize nHeaderRows, without accessing the source
238 // (button attribute must be present)
239 void RefreshAfterLoad();
241 void BuildAllDimensionMembers();
244 * Remove in the save data entries for members that don't exist anymore.
245 * This is called during pivot table refresh.
247 bool SyncAllDimensionMembers();
249 static bool HasRegisteredSources();
250 static std::vector<OUString> GetRegisteredSources();
251 static css::uno::Reference<css::sheet::XDimensionsSupplier>
252 CreateSource( const ScDPServiceDesc& rDesc );
254 static void ConvertOrientation(
255 ScDPSaveData& rSaveData,
256 const ScPivotFieldVector& rFields, css::sheet::DataPilotFieldOrientation nOrient,
257 const css::uno::Reference< css::sheet::XDimensionsSupplier>& xSource,
258 const ScDPLabelDataVector& rLabels,
259 const ScPivotFieldVector* pRefColFields = nullptr,
260 const ScPivotFieldVector* pRefRowFields = nullptr,
261 const ScPivotFieldVector* pRefPageFields = nullptr );
263 static bool IsOrientationAllowed( css::sheet::DataPilotFieldOrientation nOrient, sal_Int32 nDimFlags );
265 void PutInteropGrabBag(std::map<OUString, css::uno::Any>&& val)
267 maInteropGrabBag = std::move(val);
269 std::pair<bool, css::uno::Any> GetInteropGrabBagValue(const OUString& sName) const
271 if (const auto it = maInteropGrabBag.find(sName); it != maInteropGrabBag.end())
272 return { true, it->second };
274 return { false, css::uno::Any() };
277 #if DUMP_PIVOT_TABLE
278 void Dump() const;
279 void DumpCache() const;
280 #endif
283 class ScDPCollection
285 friend class ScDPCache;
286 public:
289 * Stores and manages all caches from internal sheets.
291 class SheetCaches
293 friend class ScDPCollection;
294 typedef std::map<size_t, std::unique_ptr<ScDPCache>> CachesType;
295 typedef std::vector<ScRange> RangeIndexType;
296 CachesType m_Caches;
297 RangeIndexType maRanges;
298 ScDocument& mrDoc;
299 public:
300 SheetCaches(ScDocument& rDoc);
301 bool hasCache(const ScRange& rRange) const;
302 const ScDPCache* getCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData);
303 SC_DLLPUBLIC size_t size() const;
305 void updateReference(
306 UpdateRefMode eMode, const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz);
308 SC_DLLPUBLIC ScDPCache* getExistingCache(const ScRange& rRange);
309 SC_DLLPUBLIC const ScDPCache* getExistingCache(const ScRange& rRange) const;
311 void updateCache(const ScRange& rRange, o3tl::sorted_vector<ScDPObject*>& rRefs);
312 bool remove(const ScDPCache* p);
314 SC_DLLPUBLIC const std::vector<ScRange>& getAllRanges() const;
318 * Data caches for range name based source data.
320 class NameCaches
322 friend class ScDPCollection;
323 typedef ::std::map<OUString, std::unique_ptr<ScDPCache>> CachesType;
324 CachesType m_Caches;
325 ScDocument& mrDoc;
326 public:
327 NameCaches(ScDocument& rDoc);
328 bool hasCache(const OUString& rName) const;
329 const ScDPCache* getCache(
330 const OUString& rName, const ScRange& rRange, const ScDPDimensionSaveData* pDimData);
331 size_t size() const;
332 private:
333 ScDPCache* getExistingCache(const OUString& rName);
335 void updateCache(
336 const OUString& rName, const ScRange& rRange, o3tl::sorted_vector<ScDPObject*>& rRefs);
337 bool remove(const ScDPCache* p);
341 * Defines connection type to external data source. Used as a key to look
342 * up database cache.
344 struct DBType
346 sal_Int32 mnSdbType;
347 OUString maDBName;
348 OUString maCommand;
349 DBType(sal_Int32 nSdbType, OUString aDBName, OUString aCommand);
351 struct less
353 bool operator() (const DBType& left, const DBType& right) const;
358 * Data caches for external database sources.
360 class DBCaches
362 friend class ScDPCollection;
363 typedef ::std::map<DBType, std::unique_ptr<ScDPCache>, DBType::less> CachesType;
364 CachesType m_Caches;
365 ScDocument& mrDoc;
366 public:
367 DBCaches(ScDocument& rDoc);
368 bool hasCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) const;
369 const ScDPCache* getCache(
370 sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand,
371 const ScDPDimensionSaveData* pDimData);
373 private:
374 ScDPCache* getExistingCache(
375 sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand);
377 static css::uno::Reference<css::sdbc::XRowSet> createRowSet(
378 sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand);
380 void updateCache(
381 sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand,
382 o3tl::sorted_vector<ScDPObject*>& rRefs);
383 bool remove(const ScDPCache* p);
386 ScDPCollection(ScDocument& rDocument);
387 ScDPCollection(const ScDPCollection& r);
388 ~ScDPCollection();
390 TranslateId ReloadCache(const ScDPObject* pDPObj, o3tl::sorted_vector<ScDPObject*>& rRefs);
391 bool ReloadGroupsInCache(const ScDPObject* pDPObj, o3tl::sorted_vector<ScDPObject*>& rRefs);
392 SC_DLLPUBLIC bool GetReferenceGroups(const ScDPObject& rDPObj, const ScDPDimensionSaveData** pGroups) const;
394 SC_DLLPUBLIC size_t GetCount() const;
395 SC_DLLPUBLIC ScDPObject& operator[](size_t nIndex);
396 SC_DLLPUBLIC const ScDPObject& operator[](size_t nIndex) const;
398 ScDPObject* GetByName(std::u16string_view rName) const;
400 void DeleteOnTab( SCTAB nTab );
401 void UpdateReference( UpdateRefMode eUpdateRefMode,
402 const ScRange& r, SCCOL nDx, SCROW nDy, SCTAB nDz );
403 void CopyToTab( SCTAB nOld, SCTAB nNew );
404 bool RefsEqual( const ScDPCollection& r ) const;
405 void WriteRefsTo( ScDPCollection& r ) const;
408 * Create a new name that's not yet used by any existing data pilot
409 * objects. All data pilot names are 'DataPilot' + <num>
411 * @return new name for data pilot object.
413 OUString CreateNewName() const;
415 void FreeTable(const ScDPObject* pDPObj);
416 SC_DLLPUBLIC ScDPObject* InsertNewTable(std::unique_ptr<ScDPObject> pDPObj);
417 SC_DLLPUBLIC bool HasTable(const ScDPObject* pDPObj) const;
419 SC_DLLPUBLIC SheetCaches& GetSheetCaches();
420 SC_DLLPUBLIC const SheetCaches& GetSheetCaches() const;
421 NameCaches& GetNameCaches();
422 SC_DLLPUBLIC const NameCaches& GetNameCaches() const;
423 DBCaches& GetDBCaches();
424 SC_DLLPUBLIC const DBCaches& GetDBCaches() const;
426 ScRangeList GetAllTableRanges( SCTAB nTab ) const;
427 bool IntersectsTableByColumns( SCCOL nCol1, SCCOL nCol2, SCROW nRow, SCTAB nTab ) const;
428 bool IntersectsTableByRows( SCCOL nCol, SCROW nRow1, SCROW nRow2, SCTAB nTab ) const;
429 bool HasTable( const ScRange& rRange ) const;
431 #if DEBUG_PIVOT_TABLE
432 void DumpTables() const;
433 #endif
435 private:
436 /** Only to be called from ScDPCache::RemoveReference(). */
437 void RemoveCache(const ScDPCache* pCache);
439 void GetAllTables(const ScRange& rSrcRange, o3tl::sorted_vector<ScDPObject*>& rRefs) const;
440 void GetAllTables(std::u16string_view rSrcName, o3tl::sorted_vector<ScDPObject*>& rRefs) const;
441 void GetAllTables(
442 sal_Int32 nSdbType, std::u16string_view rDBName, std::u16string_view rCommand,
443 o3tl::sorted_vector<ScDPObject*>& rRefs) const;
445 private:
446 typedef std::vector< std::unique_ptr<ScDPObject> > TablesType;
448 ScDocument& mrDoc;
449 TablesType maTables;
450 SheetCaches maSheetCaches;
451 NameCaches maNameCaches;
452 DBCaches maDBCaches;
455 bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right);
457 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */