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  for (ScDPSaveMember* pMem : maMemberList)
614  {
615  const OUString& rMemName = pMem->GetName();
616  auto itr = rData.find(rMemName);
617  if (itr != rData.end())
618  pMem->SetIsVisible(itr->second);
619  }
620 }
621 
623 {
624  return std::any_of(maMemberList.begin(), maMemberList.end(),
625  [](const ScDPSaveMember* pMem) { return !pMem->GetIsVisible(); });
626 }
627 
629 {
630  MemberList aNew;
631  for (ScDPSaveMember* pMem : maMemberList)
632  {
633  if (rMembers.count(pMem->GetName()))
634  {
635  // This member still exists.
636  aNew.push_back(pMem);
637  }
638  else
639  {
640  maMemberHash.erase(pMem->GetName());
641  }
642  }
643 
644  maMemberList.swap(aNew);
645 }
646 
647 #if DUMP_PIVOT_TABLE
648 
649 void ScDPSaveDimension::Dump(int nIndent) const
650 {
651  static const char* pOrientNames[] = { "hidden", "column", "row", "page", "data" };
652  std::string aIndent(nIndent*4, ' ');
653 
654  cout << aIndent << "* dimension name: '" << aName << "'" << endl;
655 
656  cout << aIndent << " + orientation: ";
657  if (nOrientation <= DataPilotFieldOrientation_DATA)
658  cout << pOrientNames[static_cast<int>(nOrientation)];
659  else
660  cout << "(invalid)";
661  cout << endl;
662 
663  cout << aIndent << " + layout name: ";
664  if (mpLayoutName)
665  cout << "'" << *mpLayoutName << "'";
666  else
667  cout << "(none)";
668  cout << endl;
669 
670  cout << aIndent << " + subtotal name: ";
671  if (mpSubtotalName)
672  cout << "'" << *mpSubtotalName << "'";
673  else
674  cout << "(none)";
675  cout << endl;
676 
677  cout << aIndent << " + is data layout: " << (bIsDataLayout ? "yes" : "no") << endl;
678  cout << aIndent << " + is duplicate: " << (bDupFlag ? "yes" : "no") << endl;
679 
680  for (ScDPSaveMember* pMem : maMemberList)
681  {
682  pMem->Dump(nIndent+1);
683  }
684 
685  cout << endl; // blank line
686 }
687 
688 #endif
689 
691  nColumnGrandMode( SC_DPSAVEMODE_DONTKNOW ),
692  nRowGrandMode( SC_DPSAVEMODE_DONTKNOW ),
693  nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
694  nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
695  bFilterButton( true ),
696  bDrillDown( true ),
697  mbDimensionMembersBuilt(false)
698 {
699 }
700 
702  nColumnGrandMode( r.nColumnGrandMode ),
703  nRowGrandMode( r.nRowGrandMode ),
704  nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
705  nRepeatEmptyMode( r.nRepeatEmptyMode ),
706  bFilterButton( r.bFilterButton ),
707  bDrillDown( r.bDrillDown ),
708  mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
709  mpGrandTotalName(r.mpGrandTotalName)
710 {
711  if ( r.pDimensionData )
713 
714  for (auto const& it : r.m_DimList)
715  {
716  m_DimList.push_back(std::make_unique<ScDPSaveDimension>(*it));
717  }
718 }
719 
721 {
722  if ( &r != this )
723  {
724  this->~ScDPSaveData();
725  new( this ) ScDPSaveData ( r );
726  }
727  return *this;
728 }
729 
731 {
737  bDrillDown != r.bDrillDown ||
739  return false;
740 
741  if ( pDimensionData || r.pDimensionData )
742  if ( !pDimensionData || !r.pDimensionData || !( *pDimensionData == *r.pDimensionData ) )
743  return false;
744 
746  return false;
747 
748  if (mpGrandTotalName)
749  {
750  if (!r.mpGrandTotalName)
751  return false;
753  return false;
754  }
755  else if (r.mpGrandTotalName)
756  return false;
757 
758  return true;
759 }
760 
762 {
763 }
764 
765 void ScDPSaveData::SetGrandTotalName(const OUString& rName)
766 {
767  mpGrandTotalName = rName;
768 }
769 
770 const std::optional<OUString> & ScDPSaveData::GetGrandTotalName() const
771 {
772  return mpGrandTotalName;
773 }
774 
775 namespace {
776 
777 class DimOrderInserter
778 {
780 public:
781  explicit DimOrderInserter(ScDPSaveData::DimOrderType& rNames) : mrNames(rNames) {}
782 
783  void operator() (const ScDPSaveDimension* pDim)
784  {
785  size_t nRank = mrNames.size();
786  mrNames.emplace(pDim->GetName(), nRank);
787  }
788 };
789 
790 }
791 
793 {
794  if (!mpDimOrder)
795  {
796  mpDimOrder.reset(new DimOrderType);
797  std::vector<const ScDPSaveDimension*> aRowDims, aColDims;
798  GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aRowDims);
799  GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aColDims);
800 
801  std::for_each(aRowDims.begin(), aRowDims.end(), DimOrderInserter(*mpDimOrder));
802  std::for_each(aColDims.begin(), aColDims.end(), DimOrderInserter(*mpDimOrder));
803  }
804  return *mpDimOrder;
805 }
806 
808  sheet::DataPilotFieldOrientation eOrientation, std::vector<const ScDPSaveDimension*>& rDims) const
809 {
810  std::vector<const ScDPSaveDimension*> aDims;
811  for (auto const& it : m_DimList)
812  {
813  const ScDPSaveDimension& rDim = *it;
814  if (rDim.GetOrientation() != eOrientation)
815  continue;
816 
817  aDims.push_back(&rDim);
818  }
819 
820  rDims.swap(aDims);
821 }
822 
824 {
825  if (!pDim)
826  return;
827 
828  CheckDuplicateName(*pDim);
829  m_DimList.push_back(std::unique_ptr<ScDPSaveDimension>(pDim));
830 
832 }
833 
835 {
836  for (auto const& iter : m_DimList)
837  {
838  if (iter->GetName() == rName && !iter->IsDataLayout() )
839  return &(*iter);
840  }
841 
842  return AppendNewDimension(rName, false);
843 }
844 
846 {
847  for (auto const& iter : m_DimList)
848  {
849  if (iter->GetName() == rName && !iter->IsDataLayout() )
850  return &(*iter);
851  }
852  return nullptr; // don't create new
853 }
854 
856 {
857  for (auto const& iter : m_DimList)
858  {
859  if (iter->GetName() == rName && !iter->IsDataLayout() )
860  return DuplicateDimension(rName);
861  }
862 
863  return AppendNewDimension(rName, false);
864 }
865 
867 {
869  if (pDim)
870  return pDim;
871 
872  return AppendNewDimension(OUString(), true);
873 }
874 
876 {
877  for (auto const& iter : m_DimList)
878  {
879  if ( iter->IsDataLayout() )
880  return &(*iter);
881  }
882  return nullptr;
883 }
884 
886 {
887  // always insert new
888 
890  if (!pOld)
891  return nullptr;
892 
893  ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld );
894  AddDimension(pNew);
895  return pNew;
896 }
897 
898 void ScDPSaveData::RemoveDimensionByName(const OUString& rName)
899 {
900  auto iter = std::find_if(m_DimList.begin(), m_DimList.end(),
901  [&rName](const std::unique_ptr<ScDPSaveDimension>& rxDim) {
902  return rxDim->GetName() == rName && !rxDim->IsDataLayout(); });
903  if (iter != m_DimList.end())
904  {
905  m_DimList.erase(iter);
908  }
909 }
910 
912 {
913  ScDPSaveDimension* pNew = new ScDPSaveDimension( rDim );
914  AddDimension(pNew);
915  return *pNew;
916 }
917 
918 ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(DataPilotFieldOrientation nOrientation)
919 {
920  // return the innermost dimension for the given orientation,
921  // excluding data layout dimension
922 
923  auto iter = std::find_if(m_DimList.rbegin(), m_DimList.rend(),
924  [&nOrientation](const std::unique_ptr<ScDPSaveDimension>& rxDim) {
925  return rxDim->GetOrientation() == nOrientation && !rxDim->IsDataLayout(); });
926  if (iter != m_DimList.rend())
927  return iter->get();
928 
929  return nullptr;
930 }
931 
932 ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
933 {
934  for (auto const& iter : m_DimList)
935  {
936  if (iter->GetOrientation() == eOrientation && !iter->IsDataLayout())
937  return &(*iter);
938  }
939  return nullptr;
940 }
941 
943 {
944  long nDataCount = 0;
945 
946  for (auto const& iter : m_DimList)
947  {
948  if (iter->GetOrientation() == sheet::DataPilotFieldOrientation_DATA)
949  ++nDataCount;
950  }
951 
952  return nDataCount;
953 }
954 
956 {
957  // position (nNew) is counted within dimensions of the same orientation
958 
959  DataPilotFieldOrientation nOrient = pDim->GetOrientation();
960 
961  auto it = std::find_if(m_DimList.begin(), m_DimList.end(),
962  [&pDim](const std::unique_ptr<ScDPSaveDimension>& rxDim) { return pDim == rxDim.get(); });
963  if (it != m_DimList.end())
964  {
965  // Tell vector<unique_ptr> to give up ownership of this element.
966  // Don't delete this instance as it is re-inserted into the
967  // container later.
968  it->release();
969  m_DimList.erase(it);
970  }
971 
972  auto iterInsert = std::find_if(m_DimList.begin(), m_DimList.end(),
973  [&nOrient, &nNew](const std::unique_ptr<ScDPSaveDimension>& rxDim) {
974  if (rxDim->GetOrientation() == nOrient )
975  --nNew;
976  return nNew <= 0;
977  });
978 
979  m_DimList.insert(iterInsert, std::unique_ptr<ScDPSaveDimension>(pDim));
981 }
982 
984 {
985  nColumnGrandMode = sal_uInt16(bSet);
986 }
987 
989 {
990  nRowGrandMode = sal_uInt16(bSet);
991 }
992 
994 {
995  nIgnoreEmptyMode = sal_uInt16(bSet);
996 }
997 
999 {
1000  nRepeatEmptyMode = sal_uInt16(bSet);
1001 }
1002 
1004 {
1005  bFilterButton = bSet;
1006 }
1007 
1009 {
1010  bDrillDown = bSet;
1011 }
1012 
1013 static void lcl_ResetOrient( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
1014 {
1015  uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1016  uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
1017  long nIntCount = xIntDims->getCount();
1018  for (long nIntDim=0; nIntDim<nIntCount; nIntDim++)
1019  {
1020  uno::Reference<beans::XPropertySet> xDimProp(xIntDims->getByIndex(nIntDim), uno::UNO_QUERY);
1021  if (xDimProp.is())
1022  {
1023  xDimProp->setPropertyValue( SC_UNO_DP_ORIENTATION, uno::Any(sheet::DataPilotFieldOrientation_HIDDEN) );
1024  }
1025  }
1026 }
1027 
1028 void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
1029 {
1030  if (!xSource.is())
1031  return;
1032 
1033  // source options must be first!
1034 
1035  uno::Reference<beans::XPropertySet> xSourceProp( xSource, uno::UNO_QUERY );
1036  SAL_WARN_IF( !xSourceProp.is(), "sc.core", "no properties at source" );
1037  if ( xSourceProp.is() )
1038  {
1039  // source options are not available for external sources
1040  //TODO: use XPropertySetInfo to test for availability?
1041 
1042  try
1043  {
1045  lcl_SetBoolProperty( xSourceProp,
1046  SC_UNO_DP_IGNOREEMPTY, static_cast<bool>(nIgnoreEmptyMode) );
1048  lcl_SetBoolProperty( xSourceProp,
1049  SC_UNO_DP_REPEATEMPTY, static_cast<bool>(nRepeatEmptyMode) );
1050  }
1051  catch(uno::Exception&)
1052  {
1053  // no error
1054  }
1055 
1056  const std::optional<OUString> & pGrandTotalName = GetGrandTotalName();
1057  if (pGrandTotalName)
1059  }
1060 
1061  // exceptions in the other calls are errors
1062  try
1063  {
1064  // reset all orientations
1065  //TODO: "forgetSettings" or similar at source ?????
1066  //TODO: reset all duplicated dimensions, or reuse them below !!!
1067  SAL_INFO("sc.core", "ScDPSaveData::WriteToSource");
1068 
1069  lcl_ResetOrient( xSource );
1070 
1071  uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1072  uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
1073  long nIntCount = xIntDims->getCount();
1074 
1075  for (const auto& rxDim : m_DimList)
1076  {
1077  OUString aName = rxDim->GetName();
1078  OUString aCoreName = ScDPUtil::getSourceDimensionName(aName);
1079 
1080  SAL_INFO("sc.core", aName);
1081 
1082  bool bData = rxDim->IsDataLayout();
1083 
1084  //TODO: getByName for ScDPSource, including DataLayoutDimension !!!!!!!!
1085 
1086  bool bFound = false;
1087  for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
1088  {
1089  uno::Reference<uno::XInterface> xIntDim(xIntDims->getByIndex(nIntDim),
1090  uno::UNO_QUERY);
1091  if ( bData )
1092  {
1093  uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
1094  if ( xDimProp.is() )
1095  {
1096  bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1098  //TODO: error checking -- is "IsDataLayoutDimension" property required??
1099  }
1100  }
1101  else
1102  {
1103  uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
1104  if (xDimName.is() && xDimName->getName() == aCoreName)
1105  bFound = true;
1106  }
1107 
1108  if (bFound)
1109  {
1110  if (rxDim->GetDupFlag())
1111  {
1112  uno::Reference<util::XCloneable> xCloneable(xIntDim, uno::UNO_QUERY);
1113  SAL_WARN_IF(!xCloneable.is(), "sc.core", "cannot clone dimension");
1114  if (xCloneable.is())
1115  {
1116  uno::Reference<util::XCloneable> xNew = xCloneable->createClone();
1117  uno::Reference<container::XNamed> xNewName(xNew, uno::UNO_QUERY);
1118  if (xNewName.is())
1119  {
1120  xNewName->setName(aName);
1121  rxDim->WriteToSource(xNew);
1122  }
1123  }
1124  }
1125  else
1126  rxDim->WriteToSource( xIntDim );
1127  }
1128  }
1129  SAL_WARN_IF(!bFound, "sc.core", "WriteToSource: Dimension not found: " + aName + ".");
1130  }
1131 
1132  if ( xSourceProp.is() )
1133  {
1135  lcl_SetBoolProperty( xSourceProp,
1136  SC_UNO_DP_COLGRAND, static_cast<bool>(nColumnGrandMode) );
1138  lcl_SetBoolProperty( xSourceProp,
1139  SC_UNO_DP_ROWGRAND, static_cast<bool>(nRowGrandMode) );
1140  }
1141  }
1142  catch(uno::Exception const &)
1143  {
1144  TOOLS_WARN_EXCEPTION("sc.core", "WriteToSource");
1145  }
1146 }
1147 
1149 {
1150  for (auto const& iter : m_DimList)
1151  {
1152  if (iter->GetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN && !iter->IsDataLayout())
1153  return false;
1154  }
1155  return true; // no entries that are not hidden
1156 }
1157 
1158 void ScDPSaveData::RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames )
1159 {
1160  if (!pDimensionData)
1161  // No group dimensions exist. Nothing to do.
1162  return;
1163 
1164  // Remove numeric group dimension (exists once at most). No need to delete
1165  // anything in save data (grouping was done inplace in an existing base
1166  // dimension).
1167  pDimensionData->RemoveNumGroupDimension(rSrcDimName);
1168 
1169  // Remove named group dimension(s). Dimensions have to be removed from
1170  // dimension save data and from save data too.
1171  const ScDPSaveGroupDimension* pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
1172  while ( pExistingGroup )
1173  {
1174  OUString aGroupDimName = pExistingGroup->GetGroupDimName();
1175  pDimensionData->RemoveGroupDimension(aGroupDimName); // pExistingGroup is deleted
1176 
1177  // also remove SaveData settings for the dimension that no longer exists
1178  RemoveDimensionByName(aGroupDimName);
1179 
1180  if (pDeletedNames)
1181  pDeletedNames->push_back(aGroupDimName);
1182 
1183  // see if there are more group dimensions
1184  pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
1185 
1186  if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
1187  {
1188  // still get the same group dimension?
1189  OSL_FAIL("couldn't remove group dimension");
1190  pExistingGroup = nullptr; // avoid endless loop
1191  }
1192  }
1193 }
1194 
1196 {
1197  if (!pDimensionData)
1199  return pDimensionData.get();
1200 }
1201 
1203 {
1204  if ( pNew )
1205  pDimensionData.reset( new ScDPDimensionSaveData( *pNew ) );
1206  else
1207  pDimensionData.reset();
1208 }
1209 
1211 {
1213  return;
1214 
1215  // First, build a dimension name-to-index map.
1216  typedef std::unordered_map<OUString, long> NameIndexMap;
1217  NameIndexMap aMap;
1218  long nColCount = pData->GetColumnCount();
1219  for (long i = 0; i < nColCount; ++i)
1220  aMap.emplace(pData->getDimensionName(i), i);
1221 
1222  NameIndexMap::const_iterator itrEnd = aMap.end();
1223 
1224  for (auto const& iter : m_DimList)
1225  {
1226  const OUString& rDimName = iter->GetName();
1227  if (rDimName.isEmpty())
1228  // empty dimension name. It must be data layout.
1229  continue;
1230 
1231  NameIndexMap::const_iterator itr = aMap.find(rDimName);
1232  if (itr == itrEnd)
1233  // dimension name not in the data. This should never happen!
1234  continue;
1235 
1236  long nDimIndex = itr->second;
1237  const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
1238  size_t nMemberCount = rMembers.size();
1239  for (size_t j = 0; j < nMemberCount; ++j)
1240  {
1241  const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] );
1242  OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData, false);
1243  if (iter->GetExistingMemberByName(aMemName))
1244  // this member instance already exists. nothing to do.
1245  continue;
1246 
1247  unique_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName));
1248  pNewMember->SetIsVisible(true);
1249  iter->AddMember(std::move(pNewMember));
1250  }
1251  }
1252 
1253  mbDimensionMembersBuilt = true;
1254 }
1255 
1257 {
1258  typedef std::unordered_map<OUString, long> NameIndexMap;
1259 
1260  // First, build a dimension name-to-index map.
1261  NameIndexMap aMap;
1262  long nColCount = pData->GetColumnCount();
1263  for (long i = 0; i < nColCount; ++i)
1264  aMap.emplace(pData->getDimensionName(i), i);
1265 
1266  NameIndexMap::const_iterator itMapEnd = aMap.end();
1267 
1268  for (auto const& it : m_DimList)
1269  {
1270  const OUString& rDimName = it->GetName();
1271  if (rDimName.isEmpty())
1272  // empty dimension name. It must be data layout.
1273  continue;
1274 
1275  NameIndexMap::const_iterator itMap = aMap.find(rDimName);
1276  if (itMap == itMapEnd)
1277  // dimension name not in the data. This should never happen!
1278  continue;
1279 
1281  long nDimIndex = itMap->second;
1282  const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex);
1283  size_t nMemberCount = rMembers.size();
1284  for (size_t j = 0; j < nMemberCount; ++j)
1285  {
1286  const ScDPItemData* pMemberData = pData->GetMemberById(nDimIndex, rMembers[j]);
1287  OUString aMemName = pData->GetFormattedString(nDimIndex, *pMemberData, false);
1288  aMemNames.insert(aMemName);
1289  }
1290 
1291  it->RemoveObsoleteMembers(aMemNames);
1292  }
1293 }
1294 
1295 bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
1296 {
1298  if (!pDim)
1299  return false;
1300 
1301  return pDim->HasInvisibleMember();
1302 }
1303 
1304 #if DUMP_PIVOT_TABLE
1305 
1306 void ScDPSaveData::Dump() const
1307 {
1308  for (auto const& itDim : m_DimList)
1309  {
1310  const ScDPSaveDimension& rDim = *itDim;
1311  rDim.Dump();
1312  }
1313 }
1314 
1315 #endif
1316 
1318 {
1319  const OUString aName = ScDPUtil::getSourceDimensionName(rDim.GetName());
1320  DupNameCountType::iterator it = maDupNameCounts.find(aName);
1321  if (it != maDupNameCounts.end())
1322  {
1323  rDim.SetName(ScDPUtil::createDuplicateDimensionName(aName, ++it->second));
1324  rDim.SetDupFlag(true);
1325  }
1326  else
1327  // New name.
1328  maDupNameCounts.emplace(aName, 0);
1329 }
1330 
1331 void ScDPSaveData::RemoveDuplicateNameCount(const OUString& rName)
1332 {
1333  OUString aCoreName = rName;
1334  if (ScDPUtil::isDuplicateDimension(rName))
1335  aCoreName = ScDPUtil::getSourceDimensionName(rName);
1336 
1337  DupNameCountType::iterator it = maDupNameCounts.find(aCoreName);
1338  if (it == maDupNameCounts.end())
1339  return;
1340 
1341  if (!it->second)
1342  {
1343  maDupNameCounts.erase(it);
1344  return;
1345  }
1346 
1347  --it->second;
1348 }
1349 
1350 ScDPSaveDimension* ScDPSaveData::AppendNewDimension(const OUString& rName, bool bDataLayout)
1351 {
1352  if (ScDPUtil::isDuplicateDimension(rName))
1353  // This call is for original dimensions only.
1354  return nullptr;
1355 
1356  ScDPSaveDimension* pNew = new ScDPSaveDimension(rName, bDataLayout);
1357  m_DimList.push_back(std::unique_ptr<ScDPSaveDimension>(pNew));
1358  if (!maDupNameCounts.count(rName))
1359  maDupNameCounts.emplace(rName, 0);
1360 
1362  return pNew;
1363 }
1364 
1366 {
1367  mpDimOrder.reset();
1368 }
1369 
1370 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SC_DLLPUBLIC void SetRepeatIfEmpty(bool bSet)
Definition: dpsave.cxx:998
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:942
#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:1210
SC_DLLPUBLIC bool HasInvisibleMember(const OUString &rDimName) const
Check whether a dimension has one or more invisible members.
Definition: dpsave.cxx:1295
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:770
std::unique_ptr< DimOrderType > mpDimOrder
Definition: dpsave.hxx:256
void RemoveObsoleteMembers(const MemberSetType &rMembers)
Definition: dpsave.cxx:628
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:1317
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:1195
#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:955
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:823
bool HasInvisibleMember() const
Definition: dpsave.cxx:622
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:720
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:807
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:898
bool operator==(const ScDPSaveDimension &r) const
Definition: dpsave.cxx:234
int nCount
bool operator==(const ScDPSaveData &r) const
Definition: dpsave.cxx:730
const DimOrderType & GetDimensionSortOrder() const
Get sort order map to sort row and column dimensions in order of appearance.
Definition: dpsave.cxx:792
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:1148
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:918
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:1256
ScDPSaveDimension * GetFirstDimension(css::sheet::DataPilotFieldOrientation eOrientation)
Definition: dpsave.cxx:932
#define TOOLS_WARN_EXCEPTION(area, stream)
void RemoveDuplicateNameCount(const OUString &rName)
Definition: dpsave.cxx:1331
SC_DLLPUBLIC ScDPSaveDimension * GetNewDimensionByName(const OUString &rName)
Definition: dpsave.cxx:855
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:1202
int i
uno_Any a
ScDPSaveDimension * AppendNewDimension(const OUString &rName, bool bDataLayout)
Append a new original dimension.
Definition: dpsave.cxx:1350
SC_DLLPUBLIC ScDPSaveDimension * GetExistingDataLayoutDimension() const
Definition: dpsave.cxx:875
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:845
SC_DLLPUBLIC ~ScDPSaveData()
Definition: dpsave.cxx:761
static bool isDuplicateDimension(const OUString &rName)
Definition: dputil.cxx:59
SC_DLLPUBLIC void SetIgnoreEmptyRows(bool bSet)
Definition: dpsave.cxx:993
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:1003
#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:765
SC_DLLPUBLIC void SetDrillDown(bool bSet)
Definition: dpsave.cxx:1008
#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:1365
#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:885
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:983
DimsType m_DimList
Definition: dpsave.hxx:241
SC_DLLPUBLIC void SetRowGrand(bool bSet)
Definition: dpsave.cxx:988
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:1028
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:1158
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:834
static void lcl_ResetOrient(const uno::Reference< sheet::XDimensionsSupplier > &xSource)
Definition: dpsave.cxx:1013
void SetLayoutInfo(const css::sheet::DataPilotFieldLayoutInfo *pNew)
Definition: dpsave.cxx:418
SC_DLLPUBLIC ScDPSaveDimension * GetDataLayoutDimension()
Definition: dpsave.cxx:866
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:690
SC_DLLPUBLIC bool HasShowDetails() const
Definition: dpsave.cxx:100