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;
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 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
,
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() };
279 void DumpCache() const;
285 friend class ScDPCache
;
289 * Stores and manages all caches from internal sheets.
293 friend class ScDPCollection
;
294 typedef std::map
<size_t, std::unique_ptr
<ScDPCache
>> CachesType
;
295 typedef std::vector
<ScRange
> RangeIndexType
;
297 RangeIndexType maRanges
;
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.
322 friend class ScDPCollection
;
323 typedef ::std::map
<OUString
, std::unique_ptr
<ScDPCache
>> CachesType
;
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
);
333 ScDPCache
* getExistingCache(const OUString
& rName
);
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
349 DBType(sal_Int32 nSdbType
, OUString aDBName
, OUString aCommand
);
353 bool operator() (const DBType
& left
, const DBType
& right
) const;
358 * Data caches for external database sources.
362 friend class ScDPCollection
;
363 typedef ::std::map
<DBType
, std::unique_ptr
<ScDPCache
>, DBType::less
> CachesType
;
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
);
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
);
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
);
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;
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;
442 sal_Int32 nSdbType
, std::u16string_view rDBName
, std::u16string_view rCommand
,
443 o3tl::sorted_vector
<ScDPObject
*>& rRefs
) const;
446 typedef std::vector
< std::unique_ptr
<ScDPObject
> > TablesType
;
450 SheetCaches maSheetCaches
;
451 NameCaches maNameCaches
;
455 bool operator<(const ScDPCollection::DBType
& left
, const ScDPCollection::DBType
& right
);
457 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */