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( OUString aServ
, OUString aSrc
, OUString aNam
,
78 OUString aUser
, OUString aPass
);
80 bool operator== ( const ScDPServiceDesc
& rOther
) const;
86 ScDocument
* mpDocument
;
89 std::unique_ptr
<ScDPSaveData
> mpSaveData
;
92 ScRange maOutputRange
;
93 std::unique_ptr
<ScSheetSourceDesc
> mpSheetDescription
; // for sheet data
94 std::unique_ptr
<ScImportSourceDesc
> mpImportDescription
; // for database data
95 std::unique_ptr
<ScDPServiceDesc
> mpServiceDescription
; // for external service
96 std::shared_ptr
<ScDPTableData
> mpTableData
; // cached data
98 css::uno::Reference
<css::sheet::XDimensionsSupplier
> mxSource
;
99 std::unique_ptr
<ScDPOutput
> mpOutput
;
101 // name -> sequence of sequences of css::xml::FastAttribute or css::xml::Attribute
102 // see PivotTable::putToInteropGrabBag in sc/source/filter/oox/pivottablebuffer.cxx for details
103 std::map
<OUString
, css::uno::Any
> maInteropGrabBag
;
105 sal_Int32 mnHeaderRows
; // page fields plus filter button
106 bool mbHeaderLayout
: 1; // true : grid, false : standard
107 bool mbAllowMove
: 1;
108 bool mbSettingsChanged
: 1;
109 bool mbEnableGetPivotData
: 1;
110 bool mbHideHeader
: 1 = false;
112 void CreateObjects();
115 void FillLabelDataForDimension(
116 const css::uno::Reference
< css::container::XIndexAccess
>& xDims
,
117 sal_Int32 nDim
, ScDPLabelData
& rLabelData
);
120 SC_DLLPUBLIC
ScDPObject(ScDocument
* pD
);
121 ScDPObject(const ScDPObject
& r
);
122 SC_DLLPUBLIC
~ScDPObject();
124 ScDPObject
& operator= (const ScDPObject
& r
);
126 void EnableGetPivotData(bool b
);
128 void SetAllowMove(bool bSet
);
130 void InvalidateData();
132 void ClearTableData();
133 ScDPTableData
* GetTableData();
135 SC_DLLPUBLIC
void ReloadGroupTableData();
137 SC_DLLPUBLIC
void Output( const ScAddress
& rPos
);
138 ScRange
GetNewOutputRange( bool& rOverflow
);
140 SC_DLLPUBLIC ScRange
GetOutputRangeByType( sal_Int32 nType
);
141 SC_DLLPUBLIC ScRange
GetOutputRangeByType( sal_Int32 nType
) const;
143 SC_DLLPUBLIC
void SetSaveData(const ScDPSaveData
& rData
);
144 ScDPSaveData
* GetSaveData() const { return mpSaveData
.get(); }
146 SC_DLLPUBLIC
void SetOutRange(const ScRange
& rRange
);
147 SC_DLLPUBLIC
const ScRange
& GetOutRange() const;
149 SC_DLLPUBLIC
void SetHeaderLayout(bool bUseGrid
);
150 bool GetHeaderLayout() const { return mbHeaderLayout
;}
152 SC_DLLPUBLIC
void SetHideHeader(bool bHideHeader
);
153 bool GetHideHeader() const { return mbHideHeader
; }
155 SC_DLLPUBLIC
void SetSheetDesc(const ScSheetSourceDesc
& rDesc
);
156 void SetImportDesc(const ScImportSourceDesc
& rDesc
);
157 void SetServiceData(const ScDPServiceDesc
& rDesc
);
159 void WriteSourceDataTo( ScDPObject
& rDest
) const;
160 void WriteTempDataTo( ScDPObject
& rDest
) const;
162 const ScSheetSourceDesc
* GetSheetDesc() const { return mpSheetDescription
.get(); }
163 const ScImportSourceDesc
* GetImportSourceDesc() const { return mpImportDescription
.get(); }
164 const ScDPServiceDesc
* GetDPServiceDesc() const { return mpServiceDescription
.get(); }
166 SC_DLLPUBLIC
css::uno::Reference
<css::sheet::XDimensionsSupplier
> const & GetSource();
168 bool IsSheetData() const;
169 bool IsImportData() const { return mpImportDescription
!= nullptr; }
170 bool IsServiceData() const { return mpServiceDescription
!= nullptr; }
173 SC_DLLPUBLIC
void SetName(const OUString
& rNew
);
174 const OUString
& GetName() const { return maTableName
; }
175 void SetTag(const OUString
& rNew
);
176 const OUString
& GetTag() const { return maTableTag
; }
179 * Data description cell displays the description of a data dimension if
180 * and only if there is only one data dimension. It's usually located at
181 * the upper-left corner of the table output.
183 bool IsDataDescriptionCell(const ScAddress
& rPos
);
185 bool IsDimNameInUse(std::u16string_view rName
) const;
186 SC_DLLPUBLIC OUString
GetDimName( tools::Long nDim
, bool& rIsDataLayout
, sal_Int32
* pFlags
= nullptr );
187 SC_DLLPUBLIC
bool IsDuplicated( tools::Long nDim
);
188 SC_DLLPUBLIC
tools::Long
GetDimCount();
189 void GetHeaderPositionData(const ScAddress
& rPos
, css::sheet::DataPilotTableHeaderData
& rData
);
190 SC_DLLPUBLIC
tools::Long
GetHeaderDim( const ScAddress
& rPos
, css::sheet::DataPilotFieldOrientation
& rOrient
);
191 bool GetHeaderDrag( const ScAddress
& rPos
, bool bMouseLeft
, bool bMouseTop
,
192 tools::Long nDragDim
,
193 tools::Rectangle
& rPosRect
, css::sheet::DataPilotFieldOrientation
& rOrient
, tools::Long
& rDimPos
);
194 bool IsFilterButton( const ScAddress
& rPos
);
196 static OUString
GetFormattedString(ScDPTableData
* pTableData
, tools::Long nDimension
, const double fValue
);
197 SC_DLLPUBLIC OUString
GetFormattedString( std::u16string_view rDimName
, const double fValue
);
200 const OUString
& rDataFieldName
,
201 std::vector
<css::sheet::DataPilotFieldFilter
>& rFilters
);
204 OUString
& rDataFieldName
,
205 std::vector
<css::sheet::DataPilotFieldFilter
>& rFilters
,
206 std::vector
<sal_Int16
>& rFilterFuncs
,
207 std::u16string_view rFilterList
);
209 void GetMemberResultNames(ScDPUniqueStringSet
& rNames
, tools::Long nDimension
);
211 void ToggleDetails(const css::sheet::DataPilotTableHeaderData
& rElemDesc
, ScDPObject
* pDestObj
);
213 void FillOldParam(ScPivotParam
& rParam
) const;
214 void FillLabelData(sal_Int32 nDim
, ScDPLabelData
& Labels
);
215 void FillLabelData(ScPivotParam
& rParam
);
217 void GetFieldIdsNames(css::sheet::DataPilotFieldOrientation nOrient
, std::vector
<tools::Long
>& rIndices
,
218 std::vector
<OUString
>& rNames
);
220 bool GetHierarchiesNA( sal_Int32 nDim
, css::uno::Reference
< css::container::XNameAccess
>& xHiers
);
221 void GetHierarchies( sal_Int32 nDim
, css::uno::Sequence
< OUString
>& rHiers
);
223 SC_DLLPUBLIC sal_Int32
GetUsedHierarchy( sal_Int32 nDim
);
225 bool GetMembersNA( sal_Int32 nDim
, css::uno::Reference
< css::sheet::XMembersAccess
>& xMembers
);
226 bool GetMembersNA( sal_Int32 nDim
, sal_Int32 nHier
, css::uno::Reference
< css::sheet::XMembersAccess
>& xMembers
);
228 bool GetMemberNames( sal_Int32 nDim
, css::uno::Sequence
< OUString
>& rNames
);
229 SC_DLLPUBLIC
bool GetMembers( sal_Int32 nDim
, sal_Int32 nHier
, ::std::vector
<ScDPLabelData::Member
>& rMembers
);
231 void UpdateReference( UpdateRefMode eUpdateRefMode
,
232 const ScRange
& r
, SCCOL nDx
, SCROW nDy
, SCTAB nDz
);
233 bool RefsEqual( const ScDPObject
& r
) const;
234 void WriteRefsTo( ScDPObject
& r
) const;
236 void GetPositionData(const ScAddress
& rPos
, css::sheet::DataPilotTablePositionData
& rPosData
);
238 bool GetDataFieldPositionData(const ScAddress
& rPos
,
240 css::sheet::DataPilotFieldFilter
>& rFilters
);
242 void GetDrillDownData(const ScAddress
& rPos
,
243 css::uno::Sequence
< css::uno::Sequence
< css::uno::Any
> >& rTableData
);
245 // apply drop-down attribute, initialize mnHeaderRows, without accessing the source
246 // (button attribute must be present)
247 void RefreshAfterLoad();
249 SC_DLLPUBLIC
void BuildAllDimensionMembers();
252 * Remove in the save data entries for members that don't exist anymore.
253 * This is called during pivot table refresh.
255 SC_DLLPUBLIC
bool SyncAllDimensionMembers();
257 static bool HasRegisteredSources();
258 static std::vector
<OUString
> GetRegisteredSources();
259 static css::uno::Reference
<css::sheet::XDimensionsSupplier
>
260 CreateSource( const ScDPServiceDesc
& rDesc
);
262 static void ConvertOrientation(
263 ScDPSaveData
& rSaveData
,
264 const ScPivotFieldVector
& rFields
, css::sheet::DataPilotFieldOrientation nOrient
,
265 const css::uno::Reference
< css::sheet::XDimensionsSupplier
>& xSource
,
266 const ScDPLabelDataVector
& rLabels
,
267 const ScPivotFieldVector
* pRefColFields
= nullptr,
268 const ScPivotFieldVector
* pRefRowFields
= nullptr,
269 const ScPivotFieldVector
* pRefPageFields
= nullptr );
271 SC_DLLPUBLIC
static bool IsOrientationAllowed( css::sheet::DataPilotFieldOrientation nOrient
, sal_Int32 nDimFlags
);
273 void PutInteropGrabBag(std::map
<OUString
, css::uno::Any
>&& val
)
275 maInteropGrabBag
= std::move(val
);
277 std::pair
<bool, css::uno::Any
> GetInteropGrabBagValue(const OUString
& sName
) const
279 if (const auto it
= maInteropGrabBag
.find(sName
); it
!= maInteropGrabBag
.end())
280 return { true, it
->second
};
282 return { false, css::uno::Any() };
287 void DumpCache() const;
293 friend class ScDPCache
;
297 * Stores and manages all caches from internal sheets.
301 friend class ScDPCollection
;
302 typedef std::map
<size_t, std::unique_ptr
<ScDPCache
>> CachesType
;
303 typedef std::vector
<ScRange
> RangeIndexType
;
305 RangeIndexType maRanges
;
308 SheetCaches(ScDocument
& rDoc
);
309 bool hasCache(const ScRange
& rRange
) const;
310 const ScDPCache
* getCache(const ScRange
& rRange
, const ScDPDimensionSaveData
* pDimData
);
311 SC_DLLPUBLIC
size_t size() const;
313 void updateReference(
314 UpdateRefMode eMode
, const ScRange
& r
, SCCOL nDx
, SCROW nDy
, SCTAB nDz
);
316 SC_DLLPUBLIC ScDPCache
* getExistingCache(const ScRange
& rRange
);
317 SC_DLLPUBLIC
const ScDPCache
* getExistingCache(const ScRange
& rRange
) const;
319 void updateCache(const ScRange
& rRange
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
320 bool remove(const ScDPCache
* p
);
322 SC_DLLPUBLIC
const std::vector
<ScRange
>& getAllRanges() const;
326 * Data caches for range name based source data.
330 friend class ScDPCollection
;
331 typedef ::std::map
<OUString
, std::unique_ptr
<ScDPCache
>> CachesType
;
335 NameCaches(ScDocument
& rDoc
);
336 bool hasCache(const OUString
& rName
) const;
337 const ScDPCache
* getCache(
338 const OUString
& rName
, const ScRange
& rRange
, const ScDPDimensionSaveData
* pDimData
);
341 ScDPCache
* getExistingCache(const OUString
& rName
);
344 const OUString
& rName
, const ScRange
& rRange
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
345 bool remove(const ScDPCache
* p
);
349 * Defines connection type to external data source. Used as a key to look
357 DBType(sal_Int32 nSdbType
, OUString aDBName
, OUString aCommand
);
361 bool operator() (const DBType
& left
, const DBType
& right
) const;
366 * Data caches for external database sources.
370 friend class ScDPCollection
;
371 typedef ::std::map
<DBType
, std::unique_ptr
<ScDPCache
>, DBType::less
> CachesType
;
375 DBCaches(ScDocument
& rDoc
);
376 bool hasCache(sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
) const;
377 const ScDPCache
* getCache(
378 sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
,
379 const ScDPDimensionSaveData
* pDimData
);
382 ScDPCache
* getExistingCache(
383 sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
);
385 static css::uno::Reference
<css::sdbc::XRowSet
> createRowSet(
386 sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
);
389 sal_Int32 nSdbType
, const OUString
& rDBName
, const OUString
& rCommand
,
390 o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
391 bool remove(const ScDPCache
* p
);
394 ScDPCollection(ScDocument
& rDocument
);
395 ScDPCollection(const ScDPCollection
& r
);
398 TranslateId
ReloadCache(const ScDPObject
* pDPObj
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
399 bool ReloadGroupsInCache(const ScDPObject
* pDPObj
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
);
400 SC_DLLPUBLIC
bool GetReferenceGroups(const ScDPObject
& rDPObj
, const ScDPDimensionSaveData
** pGroups
) const;
402 SC_DLLPUBLIC
size_t GetCount() const;
403 SC_DLLPUBLIC ScDPObject
& operator[](size_t nIndex
);
404 SC_DLLPUBLIC
const ScDPObject
& operator[](size_t nIndex
) const;
406 ScDPObject
* GetByName(std::u16string_view rName
) const;
408 void DeleteOnTab( SCTAB nTab
);
409 void UpdateReference( UpdateRefMode eUpdateRefMode
,
410 const ScRange
& r
, SCCOL nDx
, SCROW nDy
, SCTAB nDz
);
411 void CopyToTab( SCTAB nOld
, SCTAB nNew
);
412 bool RefsEqual( const ScDPCollection
& r
) const;
413 void WriteRefsTo( ScDPCollection
& r
) const;
416 * Create a new name that's not yet used by any existing data pilot
417 * objects. All data pilot names are 'DataPilot' + <num>
419 * @return new name for data pilot object.
421 OUString
CreateNewName() const;
423 void FreeTable(const ScDPObject
* pDPObj
);
424 SC_DLLPUBLIC ScDPObject
* InsertNewTable(std::unique_ptr
<ScDPObject
> pDPObj
);
425 SC_DLLPUBLIC
bool HasTable(const ScDPObject
* pDPObj
) const;
427 SC_DLLPUBLIC SheetCaches
& GetSheetCaches();
428 SC_DLLPUBLIC
const SheetCaches
& GetSheetCaches() const;
429 NameCaches
& GetNameCaches();
430 SC_DLLPUBLIC
const NameCaches
& GetNameCaches() const;
431 DBCaches
& GetDBCaches();
432 SC_DLLPUBLIC
const DBCaches
& GetDBCaches() const;
434 ScRangeList
GetAllTableRanges( SCTAB nTab
) const;
435 bool IntersectsTableByColumns( SCCOL nCol1
, SCCOL nCol2
, SCROW nRow
, SCTAB nTab
) const;
436 bool IntersectsTableByRows( SCCOL nCol
, SCROW nRow1
, SCROW nRow2
, SCTAB nTab
) const;
437 bool HasTable( const ScRange
& rRange
) const;
439 #if DEBUG_PIVOT_TABLE
440 void DumpTables() const;
444 /** Only to be called from ScDPCache::RemoveReference(). */
445 void RemoveCache(const ScDPCache
* pCache
);
447 void GetAllTables(const ScRange
& rSrcRange
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
) const;
448 void GetAllTables(std::u16string_view rSrcName
, o3tl::sorted_vector
<ScDPObject
*>& rRefs
) const;
450 sal_Int32 nSdbType
, std::u16string_view rDBName
, std::u16string_view rCommand
,
451 o3tl::sorted_vector
<ScDPObject
*>& rRefs
) const;
454 typedef std::vector
< std::unique_ptr
<ScDPObject
> > TablesType
;
458 SheetCaches maSheetCaches
;
459 NameCaches maNameCaches
;
463 bool operator<(const ScDPCollection::DBType
& left
, const ScDPCollection::DBType
& right
);
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */