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