LibreOffice Module sc (master) 1
dpsave.cxx
Go to the documentation of this file.
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#include <memory>
21#include <dpsave.hxx>
22#include <dpdimsave.hxx>
23#include <miscuno.hxx>
24#include <unonames.hxx>
25#include <dputil.hxx>
26#include <generalfunction.hxx>
27#include <dptabdat.hxx>
28
29#include <sal/types.h>
30#include <sal/log.hxx>
31#include <osl/diagnose.h>
34
35#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
36#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
37#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
38#include <com/sun/star/sheet/DataPilotFieldReference.hpp>
39#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
40#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
41#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
42#include <com/sun/star/sheet/XLevelsSupplier.hpp>
43#include <com/sun/star/sheet/XMembersSupplier.hpp>
44#include <com/sun/star/container/XNamed.hpp>
45#include <com/sun/star/util/XCloneable.hpp>
47
48#include <unordered_map>
49#include <algorithm>
50#include <utility>
51
52using namespace com::sun::star;
53using namespace com::sun::star::sheet;
54using ::std::unique_ptr;
55
56#define SC_DPSAVEMODE_DONTKNOW 2
57
58static void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
59 const OUString& rName, bool bValue )
60{
61 //TODO: move to ScUnoHelpFunctions?
62
63 xProp->setPropertyValue( rName, uno::Any( bValue ) );
64}
65
67 aName(std::move( _aName )),
68 nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
69 nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
70{
71}
72
74 aName( r.aName ),
75 mpLayoutName( r.mpLayoutName ),
76 nVisibleMode( r.nVisibleMode ),
77 nShowDetailsMode( r.nShowDetailsMode )
78{
79}
80
82{
83}
84
86{
87 return aName == r.aName &&
90}
91
93{
95}
96
98{
99 nVisibleMode = sal_uInt16(bSet);
100}
101
103{
105}
106
108{
109 nShowDetailsMode = sal_uInt16(bSet);
110}
111
112void ScDPSaveMember::SetName( const OUString& rNew )
113{
114 // Used only if the source member was renamed (groups).
115 // For UI renaming of members, a layout name must be used.
116
117 aName = rNew;
118}
119
120void ScDPSaveMember::SetLayoutName( const OUString& rName )
121{
122 mpLayoutName = rName;
123}
124
125const std::optional<OUString> & ScDPSaveMember::GetLayoutName() const
126{
127 return mpLayoutName;
128}
129
131{
132 mpLayoutName.reset();
133}
134
135void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
136{
137 uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
138 OSL_ENSURE( xMembProp.is(), "no properties at member" );
139 if ( !xMembProp.is() )
140 return;
141
142 // exceptions are caught at ScDPSaveData::WriteToSource
143
145 lcl_SetBoolProperty( xMembProp,
146 SC_UNO_DP_ISVISIBLE, static_cast<bool>(nVisibleMode) );
147
149 lcl_SetBoolProperty( xMembProp,
150 SC_UNO_DP_SHOWDETAILS, static_cast<bool>(nShowDetailsMode) );
151
152 if (mpLayoutName)
154
155 if ( nPosition >= 0 )
157}
158
159#if DUMP_PIVOT_TABLE
160
161void ScDPSaveMember::Dump(int nIndent) const
162{
163 std::string aIndent(nIndent*4, ' ');
164 cout << aIndent << "* member name: '" << aName << "'" << endl;
165
166 cout << aIndent << " + layout name: ";
167 if (mpLayoutName)
168 cout << "'" << *mpLayoutName << "'";
169 else
170 cout << "(none)";
171 cout << endl;
172
173 cout << aIndent << " + visibility: ";
175 cout << "(unknown)";
176 else
177 cout << (nVisibleMode ? "visible" : "hidden");
178 cout << endl;
179}
180
181#endif
182
183ScDPSaveDimension::ScDPSaveDimension(OUString _aName, bool bDataLayout) :
184 aName(std::move( _aName )),
185 bIsDataLayout( bDataLayout ),
186 bDupFlag( false ),
187 nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ),
188 nFunction( ScGeneralFunction::AUTO ),
189 nUsedHierarchy( -1 ),
190 nShowEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
191 bRepeatItemLabels( false ),
192 bSubTotalDefault( true )
193{
194}
195
197 aName( r.aName ),
198 mpLayoutName( r.mpLayoutName ),
199 mpSubtotalName( r.mpSubtotalName ),
200 bIsDataLayout( r.bIsDataLayout ),
201 bDupFlag( r.bDupFlag ),
202 nOrientation( r.nOrientation ),
203 nFunction( r.nFunction ),
204 nUsedHierarchy( r.nUsedHierarchy ),
205 nShowEmptyMode( r.nShowEmptyMode ),
206 bRepeatItemLabels( r.bRepeatItemLabels ),
207 bSubTotalDefault( r.bSubTotalDefault ),
208 maSubTotalFuncs( r.maSubTotalFuncs )
209{
210 for (const ScDPSaveMember* pMem : r.maMemberList)
211 {
212 const OUString& rName = pMem->GetName();
213 std::unique_ptr<ScDPSaveMember> pNew(new ScDPSaveMember( *pMem ));
214 maMemberList.push_back( pNew.get() );
215 maMemberHash[rName] = std::move(pNew);
216 }
217 if (r.pReferenceValue)
218 pReferenceValue.reset( new sheet::DataPilotFieldReference( *(r.pReferenceValue) ) );
219 if (r.pSortInfo)
220 pSortInfo.reset( new sheet::DataPilotFieldSortInfo( *(r.pSortInfo) ) );
221 if (r.pAutoShowInfo)
222 pAutoShowInfo.reset( new sheet::DataPilotFieldAutoShowInfo( *(r.pAutoShowInfo) ) );
223 if (r.pLayoutInfo)
224 pLayoutInfo.reset(new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) ));
225}
226
228{
229 maMemberHash.clear();
230 pReferenceValue.reset();
231 pSortInfo.reset();
232 pAutoShowInfo.reset();
233 pLayoutInfo.reset();
234}
235
237{
238 if ( aName != r.aName ||
240 bDupFlag != r.bDupFlag ||
242 nFunction != r.nFunction ||
248 return false;
249
250 if (maMemberHash.size() != r.maMemberHash.size() )
251 return false;
252
253 if (!std::equal(maMemberList.begin(), maMemberList.end(), r.maMemberList.begin(), r.maMemberList.end(),
254 [](const ScDPSaveMember* a, const ScDPSaveMember* b) { return *a == *b; }))
255 return false;
256
258 {
259 if ( *pReferenceValue != *r.pReferenceValue )
260 {
261 return false;
262 }
263 }
264 else if ( pReferenceValue || r.pReferenceValue )
265 {
266 return false;
267 }
268 if( this->pSortInfo && r.pSortInfo )
269 {
270 if ( *this->pSortInfo != *r.pSortInfo )
271 {
272 return false;
273 }
274 }
275 else if ( this->pSortInfo || r.pSortInfo )
276 {
277 return false;
278 }
279 if( this->pAutoShowInfo && r.pAutoShowInfo )
280 {
281 if ( *this->pAutoShowInfo != *r.pAutoShowInfo )
282 {
283 return false;
284 }
285 }
286 else if ( this->pAutoShowInfo || r.pAutoShowInfo )
287 {
288 return false;
289 }
290
291 return true;
292}
293
294void ScDPSaveDimension::AddMember(std::unique_ptr<ScDPSaveMember> pMember)
295{
296 const OUString & rName = pMember->GetName();
297 auto aExisting = maMemberHash.find( rName );
298 auto tmp = pMember.get();
299 if ( aExisting == maMemberHash.end() )
300 {
301 maMemberHash[rName] = std::move(pMember);
302 }
303 else
304 {
305 maMemberList.erase(std::remove(maMemberList.begin(), maMemberList.end(), aExisting->second.get()), maMemberList.end());
306 aExisting->second = std::move(pMember);
307 }
308 maMemberList.push_back( tmp );
309}
310
311void ScDPSaveDimension::SetName( const OUString& rNew )
312{
313 // Used only if the source dim was renamed (groups).
314 // For UI renaming of dimensions, the layout name must be used.
315
316 aName = rNew;
317}
318
319void ScDPSaveDimension::SetOrientation(css::sheet::DataPilotFieldOrientation nNew)
320{
321 nOrientation = nNew;
322}
323
324void ScDPSaveDimension::SetSubTotals(std::vector<ScGeneralFunction> && rFuncs)
325{
326 maSubTotalFuncs = std::move(rFuncs);
327 bSubTotalDefault = false;
328}
329
331{
333}
334
336{
337 nShowEmptyMode = sal_uInt16(bSet);
338}
339
341{
342 bRepeatItemLabels = bSet;
343}
344
346{
347 nFunction = nNew;
348}
349
351{
352 nUsedHierarchy = nNew;
353}
354
355void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
356{
357 mpSubtotalName = rName;
358}
359
360const std::optional<OUString> & ScDPSaveDimension::GetSubtotalName() const
361{
362 return mpSubtotalName;
363}
364
366{
367 mpSubtotalName.reset();
368}
369
370bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const
371{
372 return std::any_of(maMemberList.begin(), maMemberList.end(), [&rName](const ScDPSaveMember* pMem) {
373 if (rName.equalsIgnoreAsciiCase(pMem->GetName()))
374 return true;
375
376 const std::optional<OUString> & pLayoutName = pMem->GetLayoutName();
377 return pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName);
378 });
379}
380
381void ScDPSaveDimension::SetLayoutName(const OUString& rName)
382{
383 mpLayoutName = rName;
384}
385
386const std::optional<OUString> & ScDPSaveDimension::GetLayoutName() const
387{
388 return mpLayoutName;
389}
390
392{
393 mpLayoutName.reset();
394}
395
396void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
397{
398 if (pNew)
399 pReferenceValue.reset( new sheet::DataPilotFieldReference(*pNew) );
400 else
401 pReferenceValue.reset();
402}
403
404void ScDPSaveDimension::SetSortInfo(const sheet::DataPilotFieldSortInfo* pNew)
405{
406 if (pNew)
407 pSortInfo.reset( new sheet::DataPilotFieldSortInfo(*pNew) );
408 else
409 pSortInfo.reset();
410}
411
412void ScDPSaveDimension::SetAutoShowInfo(const sheet::DataPilotFieldAutoShowInfo* pNew)
413{
414 if (pNew)
415 pAutoShowInfo.reset( new sheet::DataPilotFieldAutoShowInfo(*pNew) );
416 else
417 pAutoShowInfo.reset();
418}
419
420void ScDPSaveDimension::SetLayoutInfo(const sheet::DataPilotFieldLayoutInfo* pNew)
421{
422 if (pNew)
423 pLayoutInfo.reset( new sheet::DataPilotFieldLayoutInfo(*pNew) );
424 else
425 pLayoutInfo.reset();
426}
427
428void ScDPSaveDimension::SetCurrentPage( const OUString* pPage )
429{
430 // We use member's visibility attribute to filter by page dimension.
431
432 // pPage == nullptr -> all members visible.
433 for (ScDPSaveMember* pMem : maMemberList)
434 {
435 bool bVisible = !pPage || pMem->GetName() == *pPage;
436 pMem->SetIsVisible(bVisible);
437 }
438}
439
441{
442 MemberList::const_iterator it = std::find_if(maMemberList.begin(), maMemberList.end(),
443 [](const ScDPSaveMember* pMem) { return pMem->GetIsVisible(); });
444 if (it != maMemberList.end())
445 return (*it)->GetName();
446
447 return OUString();
448}
449
451{
452 auto res = maMemberHash.find (rName);
453 if (res != maMemberHash.end())
454 return res->second.get();
455 return nullptr;
456}
457
459{
460 auto res = maMemberHash.find (rName);
461 if (res != maMemberHash.end())
462 return res->second.get();
463
464 ScDPSaveMember* pNew = new ScDPSaveMember( rName );
465 maMemberHash[rName] = std::unique_ptr<ScDPSaveMember>(pNew);
466 maMemberList.push_back( pNew );
467 return pNew;
468}
469
470void ScDPSaveDimension::SetMemberPosition( const OUString& rName, sal_Int32 nNewPos )
471{
472 ScDPSaveMember* pMember = GetMemberByName( rName ); // make sure it exists and is in the hash
473
474 maMemberList.erase(std::remove( maMemberList.begin(), maMemberList.end(), pMember), maMemberList.end() );
475
476 maMemberList.insert( maMemberList.begin() + nNewPos, pMember );
477}
478
479void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xDim )
480{
481 uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
482 OSL_ENSURE( xDimProp.is(), "no properties at dimension" );
483 if ( xDimProp.is() )
484 {
485 // exceptions are caught at ScDPSaveData::WriteToSource
486
487 sheet::DataPilotFieldOrientation eOrient = nOrientation;
488 xDimProp->setPropertyValue( SC_UNO_DP_ORIENTATION, uno::Any(eOrient) );
489
490 sal_Int16 eFunc = static_cast<sal_Int16>(nFunction);
491 xDimProp->setPropertyValue( SC_UNO_DP_FUNCTION2, uno::Any(eFunc) );
492
493 if ( nUsedHierarchy >= 0 )
494 {
495 xDimProp->setPropertyValue( SC_UNO_DP_USEDHIERARCHY, uno::Any(static_cast<sal_Int32>(nUsedHierarchy)) );
496 }
497
498 if ( pReferenceValue )
499 {
500 ;
501 xDimProp->setPropertyValue( SC_UNO_DP_REFVALUE, uno::Any(*pReferenceValue) );
502 }
503
504 if (mpLayoutName)
506
507 const std::optional<OUString> & pSubTotalName = GetSubtotalName();
508 if (pSubTotalName)
509 // Custom subtotal name, with '?' being replaced by the visible field name later.
511 }
512
513 // Level loop outside of maMemberList loop
514 // because SubTotals have to be set independently of known members
515
517
518 tools::Long nHierCount = 0;
519 uno::Reference<container::XIndexAccess> xHiers;
520 uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
521 if ( xHierSupp.is() )
522 {
523 uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
524 xHiers = new ScNameToIndexAccess( xHiersName );
525 nHierCount = xHiers->getCount();
526 }
527
528 bool bHasHiddenMember = false;
529
530 for (tools::Long nHier=0; nHier<nHierCount; nHier++)
531 {
532 tools::Long nLevCount = 0;
533 uno::Reference<container::XIndexAccess> xLevels;
534 uno::Reference<sheet::XLevelsSupplier> xLevSupp(xHiers->getByIndex(nHier), uno::UNO_QUERY);
535 if ( xLevSupp.is() )
536 {
537 uno::Reference<container::XNameAccess> xLevelsName = xLevSupp->getLevels();
538 xLevels = new ScNameToIndexAccess( xLevelsName );
539 nLevCount = xLevels->getCount();
540 }
541
542 for (tools::Long nLev=0; nLev<nLevCount; nLev++)
543 {
544 uno::Reference<uno::XInterface> xLevel(xLevels->getByIndex(nLev), uno::UNO_QUERY);
545 uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
546 OSL_ENSURE( xLevProp.is(), "no properties at level" );
547 if ( xLevProp.is() )
548 {
549 if ( !bSubTotalDefault )
550 {
551 uno::Sequence<sal_Int16> aSeq(maSubTotalFuncs.size());
552 for(size_t i = 0; i < maSubTotalFuncs.size(); ++i)
553 aSeq.getArray()[i] = static_cast<sal_Int16>(maSubTotalFuncs[i]);
554 xLevProp->setPropertyValue( SC_UNO_DP_SUBTOTAL2, uno::Any(aSeq) );
555 }
557 lcl_SetBoolProperty( xLevProp,
558 SC_UNO_DP_SHOWEMPTY, static_cast<bool>(nShowEmptyMode) );
559
560 lcl_SetBoolProperty( xLevProp,
562
563 if ( pSortInfo )
565
566 if ( pAutoShowInfo )
568
569 if ( pLayoutInfo )
571
572 // exceptions are caught at ScDPSaveData::WriteToSource
573 }
574
575 if ( nCount > 0 )
576 {
577 uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevel, uno::UNO_QUERY );
578 if ( xMembSupp.is() )
579 {
580 uno::Reference<sheet::XMembersAccess> xMembers = xMembSupp->getMembers();
581 if ( xMembers.is() )
582 {
583 sal_Int32 nPosition = -1; // set position only in manual mode
584 if ( !pSortInfo || pSortInfo->Mode == sheet::DataPilotFieldSortMode::MANUAL )
585 nPosition = 0;
586
587 for (ScDPSaveMember* pMember : maMemberList)
588 {
589 if (!pMember->GetIsVisible())
590 bHasHiddenMember = true;
591 OUString aMemberName = pMember->GetName();
592 if ( xMembers->hasByName( aMemberName ) )
593 {
594 uno::Reference<uno::XInterface> xMemberInt(
595 xMembers->getByName(aMemberName), uno::UNO_QUERY);
596 pMember->WriteToSource( xMemberInt, nPosition );
597
598 if ( nPosition >= 0 )
599 ++nPosition; // increase if initialized
600 }
601 // missing member is no error
602 }
603 }
604 }
605 }
606 }
607 }
608
609 if (xDimProp.is())
611}
612
613void ScDPSaveDimension::UpdateMemberVisibility(const std::unordered_map<OUString, bool>& rData)
614{
615 for (ScDPSaveMember* pMem : maMemberList)
616 {
617 const OUString& rMemName = pMem->GetName();
618 auto itr = rData.find(rMemName);
619 if (itr != rData.end())
620 pMem->SetIsVisible(itr->second);
621 }
622}
623
625{
626 return std::any_of(maMemberList.begin(), maMemberList.end(),
627 [](const ScDPSaveMember* pMem) { return !pMem->GetIsVisible(); });
628}
629
631{
632 MemberList aNew;
633 for (ScDPSaveMember* pMem : maMemberList)
634 {
635 if (rMembers.count(pMem->GetName()))
636 {
637 // This member still exists.
638 aNew.push_back(pMem);
639 }
640 else
641 {
642 maMemberHash.erase(pMem->GetName());
643 }
644 }
645
646 maMemberList.swap(aNew);
647}
648
649#if DUMP_PIVOT_TABLE
650
651void ScDPSaveDimension::Dump(int nIndent) const
652{
653 static const char* pOrientNames[] = { "hidden", "column", "row", "page", "data" };
654 std::string aIndent(nIndent*4, ' ');
655
656 cout << aIndent << "* dimension name: '" << aName << "'" << endl;
657
658 cout << aIndent << " + orientation: ";
659 if (nOrientation <= DataPilotFieldOrientation_DATA)
660 cout << pOrientNames[static_cast<int>(nOrientation)];
661 else
662 cout << "(invalid)";
663 cout << endl;
664
665 cout << aIndent << " + layout name: ";
666 if (mpLayoutName)
667 cout << "'" << *mpLayoutName << "'";
668 else
669 cout << "(none)";
670 cout << endl;
671
672 cout << aIndent << " + subtotal name: ";
673 if (mpSubtotalName)
674 cout << "'" << *mpSubtotalName << "'";
675 else
676 cout << "(none)";
677 cout << endl;
678
679 cout << aIndent << " + is data layout: " << (bIsDataLayout ? "yes" : "no") << endl;
680 cout << aIndent << " + is duplicate: " << (bDupFlag ? "yes" : "no") << endl;
681
682 for (ScDPSaveMember* pMem : maMemberList)
683 {
684 pMem->Dump(nIndent+1);
685 }
686
687 cout << endl; // blank line
688}
689
690#endif
691
693 nColumnGrandMode( SC_DPSAVEMODE_DONTKNOW ),
694 nRowGrandMode( SC_DPSAVEMODE_DONTKNOW ),
695 nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
696 nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
697 bFilterButton( true ),
698 bDrillDown( true ),
699 bExpandCollapse( false ),
700 mbDimensionMembersBuilt(false)
701{
702}
703
705 nColumnGrandMode( r.nColumnGrandMode ),
706 nRowGrandMode( r.nRowGrandMode ),
707 nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
708 nRepeatEmptyMode( r.nRepeatEmptyMode ),
709 bFilterButton( r.bFilterButton ),
710 bDrillDown( r.bDrillDown ),
711 bExpandCollapse( r.bExpandCollapse ),
712 mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
713 mpGrandTotalName(r.mpGrandTotalName)
714{
715 if ( r.pDimensionData )
717
718 for (auto const& it : r.m_DimList)
719 {
720 m_DimList.push_back(std::make_unique<ScDPSaveDimension>(*it));
721 }
722}
723
725{
726 if ( &r != this )
727 {
728 this->~ScDPSaveData();
729 new( this ) ScDPSaveData ( r );
730 }
731 return *this;
732}
733
735{
741 bDrillDown != r.bDrillDown ||
743 return false;
744
747 return false;
748
749 if (!(::comphelper::ContainerUniquePtrEquals(m_DimList, r.m_DimList)))
750 return false;
751
753 {
754 if (!r.mpGrandTotalName)
755 return false;
757 return false;
758 }
759 else if (r.mpGrandTotalName)
760 return false;
761
762 return true;
763}
764
766{
767}
768
769void ScDPSaveData::SetGrandTotalName(const OUString& rName)
770{
771 mpGrandTotalName = rName;
772}
773
774const std::optional<OUString> & ScDPSaveData::GetGrandTotalName() const
775{
776 return mpGrandTotalName;
777}
778
779namespace {
780
781class DimOrderInserter
782{
784public:
785 explicit DimOrderInserter(ScDPSaveData::DimOrderType& rNames) : mrNames(rNames) {}
786
787 void operator() (const ScDPSaveDimension* pDim)
788 {
789 size_t nRank = mrNames.size();
790 mrNames.emplace(ScGlobal::getCharClass().uppercase(pDim->GetName()), nRank);
791 }
792};
793
794}
795
797{
798 if (!mpDimOrder)
799 {
800 mpDimOrder.reset(new DimOrderType);
801 std::vector<const ScDPSaveDimension*> aRowDims, aColDims;
802 GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aRowDims);
803 GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aColDims);
804
805 std::for_each(aRowDims.begin(), aRowDims.end(), DimOrderInserter(*mpDimOrder));
806 std::for_each(aColDims.begin(), aColDims.end(), DimOrderInserter(*mpDimOrder));
807 }
808 return *mpDimOrder;
809}
810
812 sheet::DataPilotFieldOrientation eOrientation, std::vector<const ScDPSaveDimension*>& rDims) const
813{
814 std::vector<const ScDPSaveDimension*> aDims;
815 for (auto const& it : m_DimList)
816 {
817 const ScDPSaveDimension& rDim = *it;
818 if (rDim.GetOrientation() != eOrientation)
819 continue;
820
821 aDims.push_back(&rDim);
822 }
823
824 rDims.swap(aDims);
825}
826
828{
829 if (!pDim)
830 return;
831
832 CheckDuplicateName(*pDim);
833 m_DimList.push_back(std::unique_ptr<ScDPSaveDimension>(pDim));
834
836}
837
839{
840 for (auto const& iter : m_DimList)
841 {
842 if (iter->GetName() == rName && !iter->IsDataLayout() )
843 return &(*iter);
844 }
845
846 return AppendNewDimension(rName, false);
847}
848
850{
851 for (auto const& iter : m_DimList)
852 {
853 if (iter->GetName() == rName && !iter->IsDataLayout() )
854 return &(*iter);
855 }
856 return nullptr; // don't create new
857}
858
860{
861 for (auto const& iter : m_DimList)
862 {
863 if (iter->GetName() == rName && !iter->IsDataLayout() )
864 return DuplicateDimension(rName);
865 }
866
867 return AppendNewDimension(rName, false);
868}
869
871{
873 if (pDim)
874 return pDim;
875
876 return AppendNewDimension(OUString(), true);
877}
878
880{
881 for (auto const& iter : m_DimList)
882 {
883 if ( iter->IsDataLayout() )
884 return &(*iter);
885 }
886 return nullptr;
887}
888
890{
891 // always insert new
892
894 if (!pOld)
895 return nullptr;
896
897 ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld );
898 AddDimension(pNew);
899 return pNew;
900}
901
902void ScDPSaveData::RemoveDimensionByName(const OUString& rName)
903{
904 auto iter = std::find_if(m_DimList.begin(), m_DimList.end(),
905 [&rName](const std::unique_ptr<ScDPSaveDimension>& rxDim) {
906 return rxDim->GetName() == rName && !rxDim->IsDataLayout(); });
907 if (iter != m_DimList.end())
908 {
909 m_DimList.erase(iter);
912 }
913}
914
916{
917 ScDPSaveDimension* pNew = new ScDPSaveDimension( rDim );
918 AddDimension(pNew);
919 return *pNew;
920}
921
922ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(DataPilotFieldOrientation nOrientation)
923{
924 // return the innermost dimension for the given orientation,
925 // excluding data layout dimension
926
927 auto iter = std::find_if(m_DimList.rbegin(), m_DimList.rend(),
928 [&nOrientation](const std::unique_ptr<ScDPSaveDimension>& rxDim) {
929 return rxDim->GetOrientation() == nOrientation && !rxDim->IsDataLayout(); });
930 if (iter != m_DimList.rend())
931 return iter->get();
932
933 return nullptr;
934}
935
936ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
937{
938 for (auto const& iter : m_DimList)
939 {
940 if (iter->GetOrientation() == eOrientation && !iter->IsDataLayout())
941 return &(*iter);
942 }
943 return nullptr;
944}
945
947{
948 tools::Long nDataCount = 0;
949
950 for (auto const& iter : m_DimList)
951 {
952 if (iter->GetOrientation() == sheet::DataPilotFieldOrientation_DATA)
953 ++nDataCount;
954 }
955
956 return nDataCount;
957}
958
960{
961 // position (nNew) is counted within dimensions of the same orientation
962
963 DataPilotFieldOrientation nOrient = pDim->GetOrientation();
964
965 auto it = std::find_if(m_DimList.begin(), m_DimList.end(),
966 [&pDim](const std::unique_ptr<ScDPSaveDimension>& rxDim) { return pDim == rxDim.get(); });
967 if (it != m_DimList.end())
968 {
969 // Tell vector<unique_ptr> to give up ownership of this element. Don't
970 // delete this instance as it is re-inserted into the container later.
971 // coverity[leaked_storage] - re-inserted into the container later
972 it->release();
973 m_DimList.erase(it);
974 }
975
976 auto iterInsert = std::find_if(m_DimList.begin(), m_DimList.end(),
977 [&nOrient, &nNew](const std::unique_ptr<ScDPSaveDimension>& rxDim) {
978 if (rxDim->GetOrientation() == nOrient )
979 --nNew;
980 return nNew <= 0;
981 });
982
983 m_DimList.insert(iterInsert, std::unique_ptr<ScDPSaveDimension>(pDim));
985}
986
988{
989 nColumnGrandMode = sal_uInt16(bSet);
990}
991
993{
994 nRowGrandMode = sal_uInt16(bSet);
995}
996
998{
999 nIgnoreEmptyMode = sal_uInt16(bSet);
1000}
1001
1003{
1004 nRepeatEmptyMode = sal_uInt16(bSet);
1005}
1006
1008{
1009 bFilterButton = bSet;
1010}
1011
1013{
1014 bDrillDown = bSet;
1015}
1016
1018{
1019 bExpandCollapse = bSet;
1020}
1021
1022static void lcl_ResetOrient( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
1023{
1024 uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1025 uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
1026 tools::Long nIntCount = xIntDims->getCount();
1027 for (tools::Long nIntDim=0; nIntDim<nIntCount; nIntDim++)
1028 {
1029 uno::Reference<beans::XPropertySet> xDimProp(xIntDims->getByIndex(nIntDim), uno::UNO_QUERY);
1030 if (xDimProp.is())
1031 {
1032 xDimProp->setPropertyValue( SC_UNO_DP_ORIENTATION, uno::Any(sheet::DataPilotFieldOrientation_HIDDEN) );
1033 }
1034 }
1035}
1036
1037void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
1038{
1039 if (!xSource.is())
1040 return;
1041
1042 // source options must be first!
1043
1044 uno::Reference<beans::XPropertySet> xSourceProp( xSource, uno::UNO_QUERY );
1045 SAL_WARN_IF( !xSourceProp.is(), "sc.core", "no properties at source" );
1046 if ( xSourceProp.is() )
1047 {
1048 // source options are not available for external sources
1049 //TODO: use XPropertySetInfo to test for availability?
1050
1051 try
1052 {
1054 lcl_SetBoolProperty( xSourceProp,
1055 SC_UNO_DP_IGNOREEMPTY, static_cast<bool>(nIgnoreEmptyMode) );
1057 lcl_SetBoolProperty( xSourceProp,
1058 SC_UNO_DP_REPEATEMPTY, static_cast<bool>(nRepeatEmptyMode) );
1059 }
1060 catch(uno::Exception&)
1061 {
1062 // no error
1063 }
1064
1065 const std::optional<OUString> & pGrandTotalName = GetGrandTotalName();
1066 if (pGrandTotalName)
1068 }
1069
1070 // exceptions in the other calls are errors
1071 try
1072 {
1073 // reset all orientations
1074 //TODO: "forgetSettings" or similar at source ?????
1075 //TODO: reset all duplicated dimensions, or reuse them below !!!
1076 SAL_INFO("sc.core", "ScDPSaveData::WriteToSource");
1077
1078 lcl_ResetOrient( xSource );
1079
1080 uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1081 uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
1082 tools::Long nIntCount = xIntDims->getCount();
1083
1084 for (const auto& rxDim : m_DimList)
1085 {
1086 OUString aName = rxDim->GetName();
1087 OUString aCoreName = ScDPUtil::getSourceDimensionName(aName);
1088
1089 SAL_INFO("sc.core", aName);
1090
1091 bool bData = rxDim->IsDataLayout();
1092
1093 //TODO: getByName for ScDPSource, including DataLayoutDimension !!!!!!!!
1094
1095 bool bFound = false;
1096 for (tools::Long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
1097 {
1098 uno::Reference<uno::XInterface> xIntDim(xIntDims->getByIndex(nIntDim),
1099 uno::UNO_QUERY);
1100 if ( bData )
1101 {
1102 uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
1103 if ( xDimProp.is() )
1104 {
1105 bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1107 //TODO: error checking -- is "IsDataLayoutDimension" property required??
1108 }
1109 }
1110 else
1111 {
1112 uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
1113 if (xDimName.is() && xDimName->getName() == aCoreName)
1114 bFound = true;
1115 }
1116
1117 if (bFound)
1118 {
1119 if (rxDim->GetDupFlag())
1120 {
1121 uno::Reference<util::XCloneable> xCloneable(xIntDim, uno::UNO_QUERY);
1122 SAL_WARN_IF(!xCloneable.is(), "sc.core", "cannot clone dimension");
1123 if (xCloneable.is())
1124 {
1125 uno::Reference<util::XCloneable> xNew = xCloneable->createClone();
1126 uno::Reference<container::XNamed> xNewName(xNew, uno::UNO_QUERY);
1127 if (xNewName.is())
1128 {
1129 xNewName->setName(aName);
1130 rxDim->WriteToSource(xNew);
1131 }
1132 }
1133 }
1134 else
1135 rxDim->WriteToSource( xIntDim );
1136 }
1137 }
1138 SAL_WARN_IF(!bFound, "sc.core", "WriteToSource: Dimension not found: " + aName + ".");
1139 }
1140
1141 if ( xSourceProp.is() )
1142 {
1144 lcl_SetBoolProperty( xSourceProp,
1145 SC_UNO_DP_COLGRAND, static_cast<bool>(nColumnGrandMode) );
1147 lcl_SetBoolProperty( xSourceProp,
1148 SC_UNO_DP_ROWGRAND, static_cast<bool>(nRowGrandMode) );
1149 }
1150 }
1151 catch(uno::Exception const &)
1152 {
1153 TOOLS_WARN_EXCEPTION("sc.core", "WriteToSource");
1154 }
1155}
1156
1158{
1159 for (auto const& iter : m_DimList)
1160 {
1161 if (iter->GetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN && !iter->IsDataLayout())
1162 return false;
1163 }
1164 return true; // no entries that are not hidden
1165}
1166
1167void ScDPSaveData::RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames )
1168{
1169 if (!pDimensionData)
1170 // No group dimensions exist. Nothing to do.
1171 return;
1172
1173 // Remove numeric group dimension (exists once at most). No need to delete
1174 // anything in save data (grouping was done inplace in an existing base
1175 // dimension).
1176 pDimensionData->RemoveNumGroupDimension(rSrcDimName);
1177
1178 // Remove named group dimension(s). Dimensions have to be removed from
1179 // dimension save data and from save data too.
1180 const ScDPSaveGroupDimension* pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
1181 while ( pExistingGroup )
1182 {
1183 OUString aGroupDimName = pExistingGroup->GetGroupDimName();
1184 pDimensionData->RemoveGroupDimension(aGroupDimName); // pExistingGroup is deleted
1185
1186 // also remove SaveData settings for the dimension that no longer exists
1187 RemoveDimensionByName(aGroupDimName);
1188
1189 if (pDeletedNames)
1190 pDeletedNames->push_back(aGroupDimName);
1191
1192 // see if there are more group dimensions
1193 pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
1194
1195 if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
1196 {
1197 // still get the same group dimension?
1198 OSL_FAIL("couldn't remove group dimension");
1199 pExistingGroup = nullptr; // avoid endless loop
1200 }
1201 }
1202}
1203
1205{
1206 if (!pDimensionData)
1208 return pDimensionData.get();
1209}
1210
1212{
1213 if ( pNew )
1214 pDimensionData.reset( new ScDPDimensionSaveData( *pNew ) );
1215 else
1216 pDimensionData.reset();
1217}
1218
1220{
1222 return;
1223
1224 // First, build a dimension name-to-index map.
1225 typedef std::unordered_map<OUString, tools::Long> NameIndexMap;
1226 NameIndexMap aMap;
1227 tools::Long nColCount = pData->GetColumnCount();
1228 for (tools::Long i = 0; i < nColCount; ++i)
1229 aMap.emplace(pData->getDimensionName(i), i);
1230
1231 NameIndexMap::const_iterator itrEnd = aMap.end();
1232
1233 for (auto const& iter : m_DimList)
1234 {
1235 const OUString& rDimName = iter->GetName();
1236 if (rDimName.isEmpty())
1237 // empty dimension name. It must be data layout.
1238 continue;
1239
1240 NameIndexMap::const_iterator itr = aMap.find(rDimName);
1241 if (itr == itrEnd)
1242 // dimension name not in the data. This should never happen!
1243 continue;
1244
1245 tools::Long nDimIndex = itr->second;
1246 const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
1247 size_t nMemberCount = rMembers.size();
1248 for (size_t j = 0; j < nMemberCount; ++j)
1249 {
1250 const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] );
1251 OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData, false);
1252 if (iter->GetExistingMemberByName(aMemName))
1253 // this member instance already exists. nothing to do.
1254 continue;
1255
1256 unique_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName));
1257 pNewMember->SetIsVisible(true);
1258 iter->AddMember(std::move(pNewMember));
1259 }
1260 }
1261
1263}
1264
1266{
1267 typedef std::unordered_map<OUString, tools::Long> NameIndexMap;
1268
1269 // First, build a dimension name-to-index map.
1270 NameIndexMap aMap;
1271 tools::Long nColCount = pData->GetColumnCount();
1272 for (tools::Long i = 0; i < nColCount; ++i)
1273 aMap.emplace(pData->getDimensionName(i), i);
1274
1275 NameIndexMap::const_iterator itMapEnd = aMap.end();
1276
1277 for (auto const& it : m_DimList)
1278 {
1279 const OUString& rDimName = it->GetName();
1280 if (rDimName.isEmpty())
1281 // empty dimension name. It must be data layout.
1282 continue;
1283
1284 NameIndexMap::const_iterator itMap = aMap.find(rDimName);
1285 if (itMap == itMapEnd)
1286 // dimension name not in the data. This should never happen!
1287 continue;
1288
1290 tools::Long nDimIndex = itMap->second;
1291 const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
1292 size_t nMemberCount = rMembers.size();
1293 for (size_t j = 0; j < nMemberCount; ++j)
1294 {
1295 const ScDPItemData* pMemberData = pData->GetMemberById(nDimIndex, rMembers[j]);
1296 // ScDPCache::GetItemDataById() (via
1297 // ScDPTableData::GetMemberById(),
1298 // ScDPGroupTableData::GetMemberById() through
1299 // GetCacheTable().getCache()) may return nullptr.
1300 if (pMemberData)
1301 {
1302 OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData, false);
1303 aMemNames.insert(aMemName);
1304 }
1305 else
1306 {
1307 SAL_WARN("sc.core", "No pMemberData for nDimIndex " << nDimIndex << ", rMembers[j] " << rMembers[j]
1308 << ", j " << j);
1309 }
1310 }
1311
1312 it->RemoveObsoleteMembers(aMemNames);
1313 }
1314}
1315
1316bool ScDPSaveData::HasInvisibleMember(std::u16string_view rDimName) const
1317{
1319 if (!pDim)
1320 return false;
1321
1322 return pDim->HasInvisibleMember();
1323}
1324
1325#if DUMP_PIVOT_TABLE
1326
1327void ScDPSaveData::Dump() const
1328{
1329 for (auto const& itDim : m_DimList)
1330 {
1331 const ScDPSaveDimension& rDim = *itDim;
1332 rDim.Dump();
1333 }
1334}
1335
1336#endif
1337
1339{
1340 const OUString aName = ScDPUtil::getSourceDimensionName(rDim.GetName());
1341 DupNameCountType::iterator it = maDupNameCounts.find(aName);
1342 if (it != maDupNameCounts.end())
1343 {
1345 rDim.SetDupFlag(true);
1346 }
1347 else
1348 // New name.
1349 maDupNameCounts.emplace(aName, 0);
1350}
1351
1353{
1354 OUString aCoreName = rName;
1356 aCoreName = ScDPUtil::getSourceDimensionName(rName);
1357
1358 DupNameCountType::iterator it = maDupNameCounts.find(aCoreName);
1359 if (it == maDupNameCounts.end())
1360 return;
1361
1362 if (!it->second)
1363 {
1364 maDupNameCounts.erase(it);
1365 return;
1366 }
1367
1368 --it->second;
1369}
1370
1371ScDPSaveDimension* ScDPSaveData::AppendNewDimension(const OUString& rName, bool bDataLayout)
1372{
1374 // This call is for original dimensions only.
1375 return nullptr;
1376
1377 ScDPSaveDimension* pNew = new ScDPSaveDimension(rName, bDataLayout);
1378 m_DimList.push_back(std::unique_ptr<ScDPSaveDimension>(pNew));
1379 if (!maDupNameCounts.count(rName))
1380 maDupNameCounts.emplace(rName, 0);
1381
1383 return pNew;
1384}
1385
1387{
1388 mpDimOrder.reset();
1389}
1390
1391/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
This class has to do with handling exclusively grouped dimensions? TODO: Find out what this class doe...
Definition: dpdimsave.hxx:164
When assigning a string value, you can also assign an interned string whose life-cycle is managed by ...
Definition: dpitemdata.hxx:29
std::unordered_map< OUString, size_t > DimOrderType
Definition: dpsave.hxx:237
bool bExpandCollapse
Definition: dpsave.hxx:250
void RemoveAllGroupDimensions(const OUString &rSrcDimName, std::vector< OUString > *pDeletedNames=nullptr)
Definition: dpsave.cxx:1167
void WriteToSource(const css::uno::Reference< css::sheet::XDimensionsSupplier > &xSource)
Definition: dpsave.cxx:1037
SC_DLLPUBLIC void SetIgnoreEmptyRows(bool bSet)
Definition: dpsave.cxx:997
ScDPSaveDimension * GetInnermostDimension(css::sheet::DataPilotFieldOrientation nOrientation)
Definition: dpsave.cxx:922
void RemoveDuplicateNameCount(const OUString &rName)
Definition: dpsave.cxx:1352
bool operator==(const ScDPSaveData &r) const
Definition: dpsave.cxx:734
SC_DLLPUBLIC ScDPSaveDimension * GetExistingDimensionByName(std::u16string_view rName) const
Definition: dpsave.cxx:849
void DimensionsChanged()
Definition: dpsave.cxx:1386
bool IsEmpty() const
Definition: dpsave.cxx:1157
const DimOrderType & GetDimensionSortOrder() const
Get sort order map to sort row and column dimensions in order of appearance.
Definition: dpsave.cxx:796
SC_DLLPUBLIC void GetAllDimensionsByOrientation(css::sheet::DataPilotFieldOrientation eOrientation, std::vector< const ScDPSaveDimension * > &rDims) const
Get all dimensions in a given orientation.
Definition: dpsave.cxx:811
SC_DLLPUBLIC void SetExpandCollapse(bool bSet)
Definition: dpsave.cxx:1017
ScDPSaveData & operator=(const ScDPSaveData &r)
Definition: dpsave.cxx:724
SC_DLLPUBLIC ScDPSaveDimension * GetNewDimensionByName(const OUString &rName)
Definition: dpsave.cxx:859
void Dump() const
ScDPSaveDimension * GetFirstDimension(css::sheet::DataPilotFieldOrientation eOrientation)
Definition: dpsave.cxx:936
bool bDrillDown
Definition: dpsave.hxx:249
void SetPosition(ScDPSaveDimension *pDim, tools::Long nNew)
Definition: dpsave.cxx:959
SC_DLLPUBLIC bool HasInvisibleMember(std::u16string_view rDimName) const
Check whether a dimension has one or more invisible members.
Definition: dpsave.cxx:1316
sal_uInt16 nRowGrandMode
Definition: dpsave.hxx:245
ScDPSaveDimension * DuplicateDimension(std::u16string_view rName)
Definition: dpsave.cxx:889
std::unique_ptr< DimOrderType > mpDimOrder
Definition: dpsave.hxx:257
sal_uInt16 nIgnoreEmptyMode
Definition: dpsave.hxx:246
SC_DLLPUBLIC const std::optional< OUString > & GetGrandTotalName() const
Definition: dpsave.cxx:774
bool bFilterButton
Definition: dpsave.hxx:248
void CheckDuplicateName(ScDPSaveDimension &rDim)
Definition: dpsave.cxx:1338
SC_DLLPUBLIC void SetRepeatIfEmpty(bool bSet)
Definition: dpsave.cxx:1002
DupNameCountType maDupNameCounts
Definition: dpsave.hxx:242
SC_DLLPUBLIC void SetFilterButton(bool bSet)
Definition: dpsave.cxx:1007
void RemoveDimensionByName(const OUString &rName)
Definition: dpsave.cxx:902
SC_DLLPUBLIC void SetGrandTotalName(const OUString &rName)
Definition: dpsave.cxx:769
SC_DLLPUBLIC ScDPSaveDimension * GetDataLayoutDimension()
Definition: dpsave.cxx:870
std::optional< OUString > mpGrandTotalName
Definition: dpsave.hxx:256
ScDPSaveDimension * AppendNewDimension(const OUString &rName, bool bDataLayout)
Append a new original dimension.
Definition: dpsave.cxx:1371
void AddDimension(ScDPSaveDimension *pDim)
Definition: dpsave.cxx:827
SC_DLLPUBLIC void SetRowGrand(bool bSet)
Definition: dpsave.cxx:992
SC_DLLPUBLIC void SetColumnGrand(bool bSet)
Definition: dpsave.cxx:987
SC_DLLPUBLIC ScDPSaveDimension * GetExistingDataLayoutDimension() const
Definition: dpsave.cxx:879
void SyncAllDimensionMembers(ScDPTableData *pData)
Definition: dpsave.cxx:1265
DimsType m_DimList
Definition: dpsave.hxx:241
SC_DLLPUBLIC ScDPDimensionSaveData * GetDimensionData()
Definition: dpsave.cxx:1204
SC_DLLPUBLIC void SetDimensionData(const ScDPDimensionSaveData *pNew)
Definition: dpsave.cxx:1211
SC_DLLPUBLIC tools::Long GetDataDimensionCount() const
Definition: dpsave.cxx:946
void BuildAllDimensionMembers(ScDPTableData *pData)
Definition: dpsave.cxx:1219
SC_DLLPUBLIC ScDPSaveDimension * GetDimensionByName(const OUString &rName)
Get a dimension object by its name.
Definition: dpsave.cxx:838
sal_uInt16 nColumnGrandMode
Definition: dpsave.hxx:244
SC_DLLPUBLIC void SetDrillDown(bool bSet)
Definition: dpsave.cxx:1012
bool mbDimensionMembersBuilt
if true, all dimensions already have all of their member instances created.
Definition: dpsave.hxx:254
std::unique_ptr< ScDPDimensionSaveData > pDimensionData
keep track of number of duplicates in each name.
Definition: dpsave.hxx:243
sal_uInt16 nRepeatEmptyMode
Definition: dpsave.hxx:247
SC_DLLPUBLIC ~ScDPSaveData()
Definition: dpsave.cxx:765
SC_DLLPUBLIC ScDPSaveData()
Definition: dpsave.cxx:692
void RemoveObsoleteMembers(const MemberSetType &rMembers)
Definition: dpsave.cxx:630
tools::Long nUsedHierarchy
Definition: dpsave.hxx:103
std::optional< OUString > mpSubtotalName
Definition: dpsave.hxx:98
void SetAutoShowInfo(const css::sheet::DataPilotFieldAutoShowInfo *pNew)
Definition: dpsave.cxx:412
bool bSubTotalDefault
at level
Definition: dpsave.hxx:106
sal_uInt16 nShowEmptyMode
Definition: dpsave.hxx:104
std::unique_ptr< css::sheet::DataPilotFieldLayoutInfo > pLayoutInfo
Definition: dpsave.hxx:111
void SetRepeatItemLabels(bool bSet)
Definition: dpsave.cxx:340
bool operator==(const ScDPSaveDimension &r) const
Definition: dpsave.cxx:236
void RemoveSubtotalName()
Definition: dpsave.cxx:365
void SetLayoutInfo(const css::sheet::DataPilotFieldLayoutInfo *pNew)
Definition: dpsave.cxx:420
void UpdateMemberVisibility(const std::unordered_map< OUString, bool > &rData)
Definition: dpsave.cxx:613
OUString aName
Definition: dpsave.hxx:96
std::vector< ScGeneralFunction > maSubTotalFuncs
at level
Definition: dpsave.hxx:107
std::unordered_set< OUString > MemberSetType
Definition: dpsave.hxx:114
bool HasShowEmpty() const
Definition: dpsave.cxx:330
bool bIsDataLayout
Definition: dpsave.hxx:99
void SetLayoutName(const OUString &rName)
Definition: dpsave.cxx:381
void SetReferenceValue(const css::sheet::DataPilotFieldReference *pNew)
Definition: dpsave.cxx:396
bool bRepeatItemLabels
at level
Definition: dpsave.hxx:105
OUString GetCurrentPage() const
Definition: dpsave.cxx:440
bool HasInvisibleMember() const
Definition: dpsave.cxx:624
std::unique_ptr< css::sheet::DataPilotFieldAutoShowInfo > pAutoShowInfo
Definition: dpsave.hxx:110
void SetOrientation(css::sheet::DataPilotFieldOrientation nNew)
Definition: dpsave.cxx:319
ScGeneralFunction nFunction
Definition: dpsave.hxx:102
void AddMember(std::unique_ptr< ScDPSaveMember > pMember)
Definition: dpsave.cxx:294
void SetDupFlag(bool bSet)
Definition: dpsave.hxx:133
ScDPSaveMember * GetExistingMemberByName(const OUString &rName)
Definition: dpsave.cxx:450
css::sheet::DataPilotFieldOrientation GetOrientation() const
Definition: dpsave.hxx:202
MemberList maMemberList
Definition: dpsave.hxx:119
std::unique_ptr< css::sheet::DataPilotFieldSortInfo > pSortInfo
Definition: dpsave.hxx:109
std::unordered_map< OUString, std::unique_ptr< ScDPSaveMember > > maMemberHash
Definition: dpsave.hxx:118
void SetSubtotalName(const OUString &rName)
Definition: dpsave.cxx:355
void SetUsedHierarchy(tools::Long nNew)
Definition: dpsave.cxx:350
std::unique_ptr< css::sheet::DataPilotFieldReference > pReferenceValue
Definition: dpsave.hxx:108
css::sheet::DataPilotFieldOrientation nOrientation
Definition: dpsave.hxx:101
std::optional< OUString > mpLayoutName
Definition: dpsave.hxx:97
void RemoveLayoutName()
Definition: dpsave.cxx:391
void SetSortInfo(const css::sheet::DataPilotFieldSortInfo *pNew)
Definition: dpsave.cxx:404
const std::optional< OUString > & GetSubtotalName() const
Definition: dpsave.cxx:360
bool IsMemberNameInUse(const OUString &rName) const
Definition: dpsave.cxx:370
ScDPSaveMember * GetMemberByName(const OUString &rName)
Get a member object by its name.
Definition: dpsave.cxx:458
const std::optional< OUString > & GetLayoutName() const
Definition: dpsave.cxx:386
ScDPSaveDimension(OUString aName, bool bDataLayout)
Definition: dpsave.cxx:183
void SetCurrentPage(const OUString *pPage)
Definition: dpsave.cxx:428
void WriteToSource(const css::uno::Reference< css::uno::XInterface > &xDim)
Definition: dpsave.cxx:479
void Dump(int nIndent=0) const
std::vector< ScDPSaveMember * > MemberList
Definition: dpsave.hxx:115
const OUString & GetName() const
Definition: dpsave.hxx:139
void SetSubTotals(std::vector< ScGeneralFunction > &&rFuncs)
Definition: dpsave.cxx:324
void SetName(const OUString &rNew)
Definition: dpsave.cxx:311
void SetShowEmpty(bool bSet)
Definition: dpsave.cxx:335
void SetMemberPosition(const OUString &rName, sal_Int32 nNewPos)
Definition: dpsave.cxx:470
void SetFunction(ScGeneralFunction nNew)
Definition: dpsave.cxx:345
Represents a new group dimension whose dimension ID is higher than the highest source dimension ID.
Definition: dpdimsave.hxx:91
const OUString & GetGroupDimName() const
Definition: dpdimsave.hxx:107
void SetName(const OUString &rNew)
Definition: dpsave.cxx:112
OUString aName
Definition: dpsave.hxx:54
SC_DLLPUBLIC void SetIsVisible(bool bSet)
Definition: dpsave.cxx:97
const OUString & GetName() const
Definition: dpsave.hxx:66
sal_uInt16 nVisibleMode
Definition: dpsave.hxx:56
std::optional< OUString > mpLayoutName
Definition: dpsave.hxx:55
void WriteToSource(const css::uno::Reference< css::uno::XInterface > &xMember, sal_Int32 nPosition)
Definition: dpsave.cxx:135
SC_DLLPUBLIC bool HasShowDetails() const
Definition: dpsave.cxx:102
SC_DLLPUBLIC bool HasIsVisible() const
Definition: dpsave.cxx:92
void Dump(int nIndent=0) const
SC_DLLPUBLIC void SetLayoutName(const OUString &rName)
Definition: dpsave.cxx:120
void RemoveLayoutName()
Definition: dpsave.cxx:130
ScDPSaveMember(OUString aName)
Definition: dpsave.cxx:66
bool operator==(const ScDPSaveMember &r) const
Definition: dpsave.cxx:85
sal_uInt16 nShowDetailsMode
Definition: dpsave.hxx:57
SC_DLLPUBLIC const std::optional< OUString > & GetLayoutName() const
Definition: dpsave.cxx:125
SC_DLLPUBLIC void SetShowDetails(bool bSet)
Definition: dpsave.cxx:107
Base class that abstracts different data source types of a datapilot table.
Definition: dptabdat.hxx:57
static SC_DLLPUBLIC OUString getSourceDimensionName(std::u16string_view rName)
Definition: dputil.cxx:66
static bool isDuplicateDimension(std::u16string_view rName)
Definition: dputil.cxx:61
static SC_DLLPUBLIC OUString createDuplicateDimensionName(const OUString &rOriginal, size_t nDupCount)
Definition: dputil.cxx:92
static SC_DLLPUBLIC const CharClass & getCharClass()
Definition: global.cxx:1064
static bool GetBoolProperty(const css::uno::Reference< css::beans::XPropertySet > &xProp, const OUString &rName, bool bDefault=false)
Definition: miscuno.cxx:36
static void SetOptionalPropertyValue(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const char *pPropName, const css::uno::Any &rVal)
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
static void lcl_ResetOrient(const uno::Reference< sheet::XDimensionsSupplier > &xSource)
Definition: dpsave.cxx:1022
static void lcl_SetBoolProperty(const uno::Reference< beans::XPropertySet > &xProp, const OUString &rName, bool bValue)
Definition: dpsave.cxx:58
#define SC_DPSAVEMODE_DONTKNOW
Definition: dpsave.cxx:56
ScGeneralFunction
the css::sheet::GeneralFunction enum is extended by constants in GeneralFunction2,...
OUString aName
uno_Any a
Sequence< sal_Int8 > aSeq
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
AUTO
int i
long Long
HashMap_OWString_Interface aMap
TOOLS_DLLPUBLIC SvStream & endl(SvStream &rStr)
bool bVisible
constexpr OUStringLiteral SC_UNO_DP_SORTING
Definition: unonames.hxx:634
constexpr OUStringLiteral SC_UNO_DP_HAS_HIDDEN_MEMBER
Definition: unonames.hxx:630
constexpr OUStringLiteral SC_UNO_DP_COLGRAND
Definition: unonames.hxx:603
constexpr OUStringLiteral SC_UNO_DP_POSITION
Definition: unonames.hxx:609
constexpr OUStringLiteral SC_UNO_DP_REPEATEMPTY
Definition: unonames.hxx:621
constexpr OUStringLiteral SC_UNO_DP_ISDATALAYOUT
Definition: unonames.hxx:607
constexpr OUStringLiteral SC_UNO_DP_IGNOREEMPTY
Definition: unonames.hxx:620
constexpr OUStringLiteral SC_UNO_DP_SUBTOTAL2
Definition: unonames.hxx:615
constexpr OUStringLiteral SC_UNO_DP_GRANDTOTAL_NAME
Definition: unonames.hxx:629
constexpr OUStringLiteral SC_UNO_DP_LAYOUTNAME
Definition: unonames.hxx:627
constexpr OUStringLiteral SC_UNO_DP_REPEATITEMLABELS
Definition: unonames.hxx:617
constexpr OUStringLiteral SC_UNO_DP_FUNCTION2
Definition: unonames.hxx:611
constexpr OUStringLiteral SC_UNO_DP_ROWGRAND
Definition: unonames.hxx:604
constexpr OUStringLiteral SC_UNO_DP_USEDHIERARCHY
Definition: unonames.hxx:612
constexpr OUStringLiteral SC_UNO_DP_ORIENTATION
Definition: unonames.hxx:608
constexpr OUStringLiteral SC_UNO_DP_FIELD_SUBTOTALNAME
Definition: unonames.hxx:628
constexpr OUStringLiteral SC_UNO_DP_ISVISIBLE
Definition: unonames.hxx:618
constexpr OUStringLiteral SC_UNO_DP_SHOWDETAILS
Definition: unonames.hxx:619
constexpr OUStringLiteral SC_UNO_DP_SHOWEMPTY
Definition: unonames.hxx:616
constexpr OUStringLiteral SC_UNO_DP_LAYOUT
Definition: unonames.hxx:636
constexpr OUStringLiteral SC_UNO_DP_REFVALUE
Definition: unonames.hxx:633
constexpr OUStringLiteral SC_UNO_DP_AUTOSHOW
Definition: unonames.hxx:635