1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
24 #include "address.hxx"
25 #include "dpcache.hxx"
26 #include "dptypes.hxx"
28 #include "calcmacros.hxx"
30 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
31 #include <o3tl/sorted_vector.hxx>
32 #include <unotools/resmgr.hxx>
38 namespace com::sun::star
{
51 class XDimensionsSupplier
;
52 struct DataPilotTablePositionData
;
53 struct DataPilotTableHeaderData
;
54 struct DataPilotFieldFilter
;
58 namespace tools
{ class Rectangle
; }
61 struct ScImportSourceDesc
;
62 class ScSheetSourceDesc
;
64 class ScDPDimensionSaveData
;
69 struct ScDPServiceDesc
71 OUString aServiceName
;
77 ScDPServiceDesc( const OUString
& rServ
, const OUString
& rSrc
, const OUString
& rNam
,
78 const OUString
& rUser
, const OUString
& rPass
);
80 bool operator== ( const ScDPServiceDesc
& rOther
) const;
83 class SC_DLLPUBLIC ScDPObject
88 std::unique_ptr
<ScDPSaveData
> pSaveData
;
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
;
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
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
);
119 ScDPObject(ScDocument
* pD
);
120 ScDPObject(const ScDPObject
& r
);
123 ScDPObject
& operator= (const ScDPObject
& r
);
125 void EnableGetPivotData(bool b
);
127 void SetAllowMove(bool bSet
);
129 void InvalidateData();
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
);
192 const OUString
& rDataFieldName
,
193 std::vector
<css::sheet::DataPilotFieldFilter
>& rFilters
);
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 bool GetHierarchiesNA( sal_Int32 nDim
, css::uno::Reference
< css::container::XNameAccess
>& xHiers
);
210 void GetHierarchies( sal_Int32 nDim
, css::uno::Sequence
< OUString
>& rHiers
);
212 sal_Int32
GetUsedHierarchy( sal_Int32 nDim
);
214 bool GetMembersNA( sal_Int32 nDim
, css::uno::Reference
< css::sheet::XMembersAccess
>& xMembers
);
215 bool GetMembersNA( sal_Int32 nDim
, sal_Int32 nHier
, css::uno::Reference
< css::sheet::XMembersAccess
>& xMembers
);
217 bool GetMemberNames( sal_Int32 nDim
, css::uno::Sequence
< OUString
>& rNames
);
218 bool GetMembers( sal_Int32 nDim
, sal_Int32 nHier
, ::std::vector
<ScDPLabelData::Member
>& rMembers
);
220 void UpdateReference( UpdateRefMode eUpdateRefMode
,
221 const ScRange
& r
, SCCOL nDx
, SCROW nDy
, SCTAB nDz
);
222 bool RefsEqual( const ScDPObject
& r
) const;
223 void WriteRefsTo( ScDPObject
& r
) const;
225 void GetPositionData(const ScAddress
& rPos
, css::sheet::DataPilotTablePositionData
& rPosData
);
227 bool GetDataFieldPositionData(const ScAddress
& rPos
,
229 css::sheet::DataPilotFieldFilter
>& rFilters
);
231 void GetDrillDownData(const ScAddress
& rPos
,
232 css::uno::Sequence
< css::uno::Sequence
< css::uno::Any
> >& rTableData
);
234 // apply drop-down attribute, initialize nHeaderRows, without accessing the source
235 // (button attribute must be present)
236 void RefreshAfterLoad();
238 void BuildAllDimensionMembers();
241 * Remove in the save data entries for members that don't exist anymore.
242 * This is called during pivot table refresh.
244 bool SyncAllDimensionMembers();
246 static bool HasRegisteredSources();
247 static std::vector
<OUString
> GetRegisteredSources();
248 static css::uno::Reference
<css::sheet::XDimensionsSupplier
>
249 CreateSource( const ScDPServiceDesc
& rDesc
);
251 static void ConvertOrientation(
252 ScDPSaveData
& rSaveData
,
253 const ScPivotFieldVector
& rFields
, css::sheet::DataPilotFieldOrientation nOrient
,
254 const css::uno::Reference
< css::sheet::XDimensionsSupplier
>& xSource
,
255 const ScDPLabelDataVector
& rLabels
,
256 const ScPivotFieldVector
* pRefColFields
= nullptr,
257 const ScPivotFieldVector
* pRefRowFields
= nullptr,
258 const ScPivotFieldVector
* pRefPageFields
= nullptr );
260 static bool IsOrientationAllowed( css::sheet::DataPilotFieldOrientation nOrient
, sal_Int32 nDimFlags
);
262 void PutInteropGrabBag(std::map
<OUString
, css::uno::Any
>&& val
)
264 maInteropGrabBag
= std::move(val
);
266 std::pair
<bool, css::uno::Any
> GetInteropGrabBagValue(const OUString
& sName
) const
268 if (const auto it
= maInteropGrabBag
.find(sName
); it
!= maInteropGrabBag
.end())
269 return { true, it
->second
};
271 return { false, css::uno::Any() };
276 void DumpCache() const;
282 friend class ScDPCache
;
286 * Stores and manages all caches from internal sheets.
290 friend class ScDPCollection
;
291 typedef std::map
<size_t, std::unique_ptr
<ScDPCache
>> CachesType
;
292 typedef std::vector
<ScRange
> RangeIndexType
;
294 RangeIndexType maRanges
;
297 SheetCaches(ScDocument
& rDoc
);
298 bool hasCache(const ScRange
& rRange
) const;
299 const ScDPCache
* getCache(const ScRange
& rRange
, const ScDPDimensionSaveData
* pDimData
);
300 SC_DLLPUBLIC
size_t size() const;
302 void updateReference(
303 UpdateRefMode eMode
, const ScRange
& r
, SCCOL nDx
, SCROW nDy
, SCTAB nDz
);
305 SC_DLLPUBLIC ScDPCache
* getExistingCache(const ScRange
& rRange
);
306 SC_DLLPUBLIC
const ScDPCache
* getExistingCache(const ScRange
& rRange
) const;
308 void updateCache(const ScRange
& rRange
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
309 bool remove(const ScDPCache
* p
);
311 SC_DLLPUBLIC
const std::vector
<ScRange
>& getAllRanges() const;
315 * Data caches for range name based source data.
319 friend class ScDPCollection
;
320 typedef ::std::map
<OUString
, std::unique_ptr
<ScDPCache
>> CachesType
;
324 NameCaches(ScDocument
& rDoc
);
325 bool hasCache(const OUString
& rName
) const;
326 const ScDPCache
* getCache(
327 const OUString
& rName
, const ScRange
& rRange
, const ScDPDimensionSaveData
* pDimData
);
330 ScDPCache
* getExistingCache(const OUString
& rName
);
333 const OUString
& rName
, const ScRange
& rRange
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
334 bool remove(const ScDPCache
* p
);
338 * Defines connection type to external data source. Used as a key to look
346 DBType(sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
);
350 bool operator() (const DBType
& left
, const DBType
& right
) const;
355 * Data caches for external database sources.
359 friend class ScDPCollection
;
360 typedef ::std::map
<DBType
, std::unique_ptr
<ScDPCache
>, DBType::less
> CachesType
;
364 DBCaches(ScDocument
& rDoc
);
365 bool hasCache(sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
) const;
366 const ScDPCache
* getCache(
367 sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
,
368 const ScDPDimensionSaveData
* pDimData
);
371 ScDPCache
* getExistingCache(
372 sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
);
374 static css::uno::Reference
<css::sdbc::XRowSet
> createRowSet(
375 sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
);
378 sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
,
379 o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
380 bool remove(const ScDPCache
* p
);
383 ScDPCollection(ScDocument
& rDocument
);
384 ScDPCollection(const ScDPCollection
& r
);
387 TranslateId
ReloadCache(const ScDPObject
* pDPObj
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
388 bool ReloadGroupsInCache(const ScDPObject
* pDPObj
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
389 SC_DLLPUBLIC
bool GetReferenceGroups(const ScDPObject
& rDPObj
, const ScDPDimensionSaveData
** pGroups
) const;
391 SC_DLLPUBLIC
size_t GetCount() const;
392 SC_DLLPUBLIC ScDPObject
& operator[](size_t nIndex
);
393 SC_DLLPUBLIC
const ScDPObject
& operator[](size_t nIndex
) const;
395 ScDPObject
* GetByName(std::u16string_view rName
) const;
397 void DeleteOnTab( SCTAB nTab
);
398 void UpdateReference( UpdateRefMode eUpdateRefMode
,
399 const ScRange
& r
, SCCOL nDx
, SCROW nDy
, SCTAB nDz
);
400 void CopyToTab( SCTAB nOld
, SCTAB nNew
);
401 bool RefsEqual( const ScDPCollection
& r
) const;
402 void WriteRefsTo( ScDPCollection
& r
) const;
405 * Create a new name that's not yet used by any existing data pilot
406 * objects. All data pilot names are 'DataPilot' + <num>
408 * @return new name for data pilot object.
410 OUString
CreateNewName() const;
412 void FreeTable(const ScDPObject
* pDPObj
);
413 SC_DLLPUBLIC ScDPObject
* InsertNewTable(std::unique_ptr
<ScDPObject
> pDPObj
);
414 SC_DLLPUBLIC
bool HasTable(const ScDPObject
* pDPObj
) const;
416 SC_DLLPUBLIC SheetCaches
& GetSheetCaches();
417 SC_DLLPUBLIC
const SheetCaches
& GetSheetCaches() const;
418 NameCaches
& GetNameCaches();
419 SC_DLLPUBLIC
const NameCaches
& GetNameCaches() const;
420 DBCaches
& GetDBCaches();
421 SC_DLLPUBLIC
const DBCaches
& GetDBCaches() const;
423 ScRangeList
GetAllTableRanges( SCTAB nTab
) const;
424 bool IntersectsTableByColumns( SCCOL nCol1
, SCCOL nCol2
, SCROW nRow
, SCTAB nTab
) const;
425 bool IntersectsTableByRows( SCCOL nCol
, SCROW nRow1
, SCROW nRow2
, SCTAB nTab
) const;
426 bool HasTable( const ScRange
& rRange
) const;
428 #if DEBUG_PIVOT_TABLE
429 void DumpTables() const;
433 /** Only to be called from ScDPCache::RemoveReference(). */
434 void RemoveCache(const ScDPCache
* pCache
);
436 void GetAllTables(const ScRange
& rSrcRange
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
) const;
437 void GetAllTables(std::u16string_view rSrcName
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
) const;
439 sal_Int32 nSdbType
, std::u16string_view rDBName
, std::u16string_view rCommand
,
440 o3tl::sorted_vector
<ScDPObject
*>& rRefs
) const;
443 typedef std::vector
< std::unique_ptr
<ScDPObject
> > TablesType
;
447 SheetCaches maSheetCaches
;
448 NameCaches maNameCaches
;
452 bool operator<(const ScDPCollection::DBType
& left
, const ScDPCollection::DBType
& right
);
454 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */