LibreOffice Module sc (master)  1
dptabsrc.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 <dptabsrc.hxx>
21 
22 #include <algorithm>
23 #include <set>
24 #include <unordered_set>
25 #include <vector>
26 
27 #include <comphelper/sequence.hxx>
28 #include <o3tl/any.hxx>
29 #include <o3tl/safeint.hxx>
30 #include <osl/diagnose.h>
31 #include <rtl/math.hxx>
32 #include <sal/log.hxx>
33 #include <svl/itemprop.hxx>
34 #include <vcl/svapp.hxx>
35 
36 #include <dpcache.hxx>
37 #include <dptabres.hxx>
38 #include <dptabdat.hxx>
39 #include <global.hxx>
40 #include <miscuno.hxx>
41 #include <unonames.hxx>
42 #include <dpitemdata.hxx>
43 #include <dputil.hxx>
44 #include <dpresfilter.hxx>
45 #include <calcmacros.hxx>
46 #include <generalfunction.hxx>
47 
48 #include <com/sun/star/beans/PropertyAttribute.hpp>
49 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
50 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
51 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
52 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
53 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
54 #include <com/sun/star/sheet/GeneralFunction2.hpp>
55 #include <com/sun/star/sheet/TableFilterField.hpp>
56 
58 #include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
59 
60 using namespace com::sun::star;
61 using ::std::vector;
62 using ::com::sun::star::uno::Sequence;
63 using ::com::sun::star::uno::Any;
64 using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
65 
66 #define SC_MINCOUNT_LIMIT 1000000
67 
68 SC_SIMPLE_SERVICE_INFO( ScDPSource, "ScDPSource", "com.sun.star.sheet.DataPilotSource" )
69 SC_SIMPLE_SERVICE_INFO( ScDPDimensions, "ScDPDimensions", "com.sun.star.sheet.DataPilotSourceDimensions" )
70 SC_SIMPLE_SERVICE_INFO( ScDPDimension, "ScDPDimension", "com.sun.star.sheet.DataPilotSourceDimension" )
72  "com.sun.star.sheet.DataPilotSourceHierarchies", "com.sun.star.sheet.DataPilotSourceHierarcies" )
74  "com.sun.star.sheet.DataPilotSourceHierarchy", "com.sun.star.sheet.DataPilotSourceHierarcy" )
75 SC_SIMPLE_SERVICE_INFO( ScDPLevels, "ScDPLevels", "com.sun.star.sheet.DataPilotSourceLevels" )
76 SC_SIMPLE_SERVICE_INFO( ScDPLevel, "ScDPLevel", "com.sun.star.sheet.DataPilotSourceLevel" )
77 SC_SIMPLE_SERVICE_INFO( ScDPMembers, "ScDPMembers", "com.sun.star.sheet.DataPilotSourceMembers" )
78 SC_SIMPLE_SERVICE_INFO( ScDPMember, "ScDPMember", "com.sun.star.sheet.DataPilotSourceMember" )
79 
80 // property maps for PropertySetInfo
81 // DataDescription / NumberFormat are internal
82 
83 //TODO: move to a header?
84 static bool lcl_GetBoolFromAny( const uno::Any& aAny )
85 {
86  auto b = o3tl::tryAccess<bool>(aAny);
87  return b && *b;
88 }
89 
91  pData( pD ),
92  bColumnGrand( true ), // default is true
93  bRowGrand( true ),
94  bIgnoreEmptyRows( false ),
95  bRepeatIfEmpty( false ),
96  nDupCount( 0 ),
97  bResultOverflow( false ),
98  bPageFiltered( false )
99 {
101 }
102 
104 {
105  // free lists
106 
107  pColResults.reset();
108  pRowResults.reset();
109 
110  pColResRoot.reset();
111  pRowResRoot.reset();
112  pResData.reset();
113 }
114 
115 const std::optional<OUString> & ScDPSource::GetGrandTotalName() const
116 {
117  return mpGrandTotalName;
118 }
119 
120 sheet::DataPilotFieldOrientation ScDPSource::GetOrientation(long nColumn)
121 {
122  if (std::find(maColDims.begin(), maColDims.end(), nColumn) != maColDims.end())
123  return sheet::DataPilotFieldOrientation_COLUMN;
124 
125  if (std::find(maRowDims.begin(), maRowDims.end(), nColumn) != maRowDims.end())
126  return sheet::DataPilotFieldOrientation_ROW;
127 
128  if (std::find(maDataDims.begin(), maDataDims.end(), nColumn) != maDataDims.end())
129  return sheet::DataPilotFieldOrientation_DATA;
130 
131  if (std::find(maPageDims.begin(), maPageDims.end(), nColumn) != maPageDims.end())
132  return sheet::DataPilotFieldOrientation_PAGE;
133 
134  return sheet::DataPilotFieldOrientation_HIDDEN;
135 }
136 
138 {
139  return maDataDims.size();
140 }
141 
143 {
144  if (nIndex < 0 || o3tl::make_unsigned(nIndex) >= maDataDims.size())
145  return nullptr;
146 
147  long nDimIndex = maDataDims[nIndex];
148  return GetDimensionsObject()->getByIndex(nDimIndex);
149 }
150 
151 OUString ScDPSource::GetDataDimName(long nIndex)
152 {
153  OUString aRet;
154  ScDPDimension* pDim = GetDataDimension(nIndex);
155  if (pDim)
156  aRet = pDim->getName();
157  return aRet;
158 }
159 
160 long ScDPSource::GetPosition(long nColumn)
161 {
162  std::vector<long>::const_iterator it, itBeg = maColDims.begin(), itEnd = maColDims.end();
163  it = std::find(itBeg, itEnd, nColumn);
164  if (it != itEnd)
165  return std::distance(itBeg, it);
166 
167  itBeg = maRowDims.begin();
168  itEnd = maRowDims.end();
169  it = std::find(itBeg, itEnd, nColumn);
170  if (it != itEnd)
171  return std::distance(itBeg, it);
172 
173  itBeg = maDataDims.begin();
174  itEnd = maDataDims.end();
175  it = std::find(itBeg, itEnd, nColumn);
176  if (it != itEnd)
177  return std::distance(itBeg, it);
178 
179  itBeg = maPageDims.begin();
180  itEnd = maPageDims.end();
181  it = std::find(itBeg, itEnd, nColumn);
182  if (it != itEnd)
183  return std::distance(itBeg, it);
184 
185  return 0;
186 }
187 
188 namespace {
189 
190 bool testSubTotal( bool& rAllowed, long nColumn, const std::vector<long>& rDims, ScDPSource* pSource )
191 {
192  rAllowed = true;
193  std::vector<long>::const_iterator it = rDims.begin(), itEnd = rDims.end();
194  for (; it != itEnd; ++it)
195  {
196  if (*it != nColumn)
197  continue;
198 
199  if ( pSource->IsDataLayoutDimension(nColumn) )
200  {
201  // no subtotals for data layout dim, no matter where
202  rAllowed = false;
203  return true;
204  }
205 
206  // no subtotals if no other dim but data layout follows
207  ++it;
208  if (it != itEnd && pSource->IsDataLayoutDimension(*it))
209  ++it;
210  if (it == itEnd)
211  rAllowed = false;
212 
213  return true; // found
214  }
215 
216  return false;
217 }
218 
219 void removeDim( long nRemove, std::vector<long>& rDims )
220 {
221  std::vector<long>::iterator it = std::find(rDims.begin(), rDims.end(), nRemove);
222  if (it != rDims.end())
223  rDims.erase(it);
224 }
225 
226 }
227 
228 bool ScDPSource::SubTotalAllowed(long nColumn)
229 {
230  //TODO: cache this at ScDPResultData
231  bool bAllowed = true;
232  if ( testSubTotal(bAllowed, nColumn, maColDims, this) )
233  return bAllowed;
234  if ( testSubTotal(bAllowed, nColumn, maRowDims, this) )
235  return bAllowed;
236  return bAllowed;
237 }
238 
239 void ScDPSource::SetOrientation(long nColumn, sheet::DataPilotFieldOrientation nNew)
240 {
241  //TODO: change to no-op if new orientation is equal to old?
242 
243  // remove from old list
244  removeDim(nColumn, maColDims);
245  removeDim(nColumn, maRowDims);
246  removeDim(nColumn, maDataDims);
247  removeDim(nColumn, maPageDims);
248 
249  // add to new list
250  switch (nNew)
251  {
252  case sheet::DataPilotFieldOrientation_COLUMN:
253  maColDims.push_back(nColumn);
254  break;
255  case sheet::DataPilotFieldOrientation_ROW:
256  maRowDims.push_back(nColumn);
257  break;
258  case sheet::DataPilotFieldOrientation_DATA:
259  maDataDims.push_back(nColumn);
260  break;
261  case sheet::DataPilotFieldOrientation_PAGE:
262  maPageDims.push_back(nColumn);
263  break;
264  // DataPilot Migration - Cache&&Performance
265  case sheet::DataPilotFieldOrientation_HIDDEN:
266  break;
267  default:
268  OSL_FAIL( "ScDPSource::SetOrientation: unexpected orientation" );
269  break;
270  }
271 }
272 
274 {
275  return nDim == pData->GetColumnCount();
276 }
277 
278 sheet::DataPilotFieldOrientation ScDPSource::GetDataLayoutOrientation()
279 {
281 }
282 
284 {
285  return pData->IsDateDimension(nDim);
286 }
287 
289 {
290  if (!pDimensions.is())
291  {
292  pDimensions = new ScDPDimensions(this);
293  }
294  return pDimensions.get();
295 }
296 
297 uno::Reference<container::XNameAccess> SAL_CALL ScDPSource::getDimensions()
298 {
299  return GetDimensionsObject();
300 }
301 
302 void ScDPSource::SetDupCount( long nNew )
303 {
304  nDupCount = nNew;
305 }
306 
307 ScDPDimension* ScDPSource::AddDuplicated(const OUString& rNewName)
308 {
309  OSL_ENSURE( pDimensions.is(), "AddDuplicated without dimensions?" );
310 
311  // re-use
312 
313  long nOldDimCount = pDimensions->getCount();
314  for (long i=0; i<nOldDimCount; i++)
315  {
316  ScDPDimension* pDim = pDimensions->getByIndex(i);
317  if (pDim && pDim->getName() == rNewName)
318  {
319  //TODO: test if pDim is a duplicate of source
320  return pDim;
321  }
322  }
323 
324  SetDupCount( nDupCount + 1 );
325  pDimensions->CountChanged(); // uses nDupCount
326 
327  return pDimensions->getByIndex( pDimensions->getCount() - 1 );
328 }
329 
331 {
332  // original source dimension or data layout dimension?
333  if ( nDim <= pData->GetColumnCount() )
334  return nDim;
335 
336  if ( nDim < pDimensions->getCount() )
337  {
338  ScDPDimension* pDimObj = pDimensions->getByIndex( nDim );
339  if ( pDimObj )
340  {
341  long nSource = pDimObj->GetSourceDim();
342  if ( nSource >= 0 )
343  return nSource;
344  }
345  }
346 
347  OSL_FAIL("GetSourceDim: wrong dim");
348  return nDim;
349 }
350 
351 uno::Sequence< uno::Sequence<sheet::DataResult> > SAL_CALL ScDPSource::getResults()
352 {
353  CreateRes_Impl(); // create pColResRoot and pRowResRoot
354 
355  if ( bResultOverflow ) // set in CreateRes_Impl
356  {
357  // no results available
358  throw uno::RuntimeException();
359  }
360 
361  long nColCount = pColResRoot->GetSize(pResData->GetColStartMeasure());
362  long nRowCount = pRowResRoot->GetSize(pResData->GetRowStartMeasure());
363 
364  // allocate full sequence
365  //TODO: leave out empty rows???
366 
367  uno::Sequence< uno::Sequence<sheet::DataResult> > aSeq( nRowCount );
368  uno::Sequence<sheet::DataResult>* pRowAry = aSeq.getArray();
369  for (long nRow = 0; nRow < nRowCount; nRow++)
370  {
371  uno::Sequence<sheet::DataResult> aColSeq( nColCount );
372  // use default values of DataResult
373  pRowAry[nRow] = aColSeq;
374  }
375 
376  ScDPResultFilterContext aFilterCxt;
377  pRowResRoot->FillDataResults(
378  pColResRoot.get(), aFilterCxt, aSeq, pResData->GetRowStartMeasure());
379 
380  maResFilterSet.swap(aFilterCxt.maFilterSet); // Keep this data for GETPIVOTDATA.
381 
382  return aSeq;
383 }
384 
385 uno::Sequence<double> ScDPSource::getFilteredResults(
386  const uno::Sequence<sheet::DataPilotFieldFilter>& aFilters )
387 {
388  if (maResFilterSet.empty())
389  getResults(); // Build result tree first.
390 
391  // Get result values from the tree.
392  const ScDPResultTree::ValuesType* pVals = maResFilterSet.getResults(aFilters);
393  if (pVals && !pVals->empty())
394  {
395  size_t n = pVals->size();
396  uno::Sequence<double> aRet(n);
397  for (size_t i = 0; i < n; ++i)
398  aRet[i] = (*pVals)[i];
399 
400  return aRet;
401  }
402 
403  if (aFilters.getLength() == 1)
404  {
405  // Try to get result from the leaf nodes.
406  double fVal = maResFilterSet.getLeafResult(aFilters[0]);
407  if (!std::isnan(fVal))
408  {
409  uno::Sequence<double> aRet(1);
410  aRet[0] = fVal;
411  return aRet;
412  }
413  }
414 
415  return uno::Sequence<double>();
416 }
417 
418 void SAL_CALL ScDPSource::refresh()
419 {
420  disposeData();
421 }
422 
423 void SAL_CALL ScDPSource::addRefreshListener( const uno::Reference<util::XRefreshListener >& )
424 {
425  OSL_FAIL("not implemented"); //TODO: exception?
426 }
427 
428 void SAL_CALL ScDPSource::removeRefreshListener( const uno::Reference<util::XRefreshListener >& )
429 {
430  OSL_FAIL("not implemented"); //TODO: exception?
431 }
432 
433 Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<sheet::DataPilotFieldFilter>& aFilters)
434 {
435  long nColumnCount = GetData()->GetColumnCount();
436 
437  vector<ScDPFilteredCache::Criterion> aFilterCriteria;
438  for (const sheet::DataPilotFieldFilter& rFilter : aFilters)
439  {
440  const OUString& aFieldName = rFilter.FieldName;
441  for (long nCol = 0; nCol < nColumnCount; ++nCol)
442  {
443  if (aFieldName == pData->getDimensionName(nCol))
444  {
445  ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nCol );
446  ScDPMembers* pMembers = pDim->GetHierarchiesObject()->getByIndex(0)->
447  GetLevelsObject()->getByIndex(0)->GetMembersObject();
448  sal_Int32 nIndex = pMembers->GetIndexFromName( rFilter.MatchValueName );
449  if ( nIndex >= 0 )
450  {
451  ScDPItemData aItem(pMembers->getByIndex(nIndex)->FillItemData());
452  aFilterCriteria.emplace_back( );
453  aFilterCriteria.back().mnFieldIndex = nCol;
454  aFilterCriteria.back().mpFilter =
455  std::make_shared<ScDPFilteredCache::SingleFilter>(aItem);
456  }
457  }
458  }
459  }
460 
461  // Take into account the visibilities of field members.
462  ScDPResultVisibilityData aResVisData(this);
463  pRowResRoot->FillVisibilityData(aResVisData);
464  pColResRoot->FillVisibilityData(aResVisData);
465  aResVisData.fillFieldFilters(aFilterCriteria);
466 
467  Sequence< Sequence<Any> > aTabData;
468  std::unordered_set<sal_Int32> aCatDims;
469  GetCategoryDimensionIndices(aCatDims);
470  pData->GetDrillDownData(aFilterCriteria, aCatDims, aTabData);
471  return aTabData;
472 }
473 
475 {
476  CreateRes_Impl(); // create pResData
477 
478  OUString aRet;
479  if ( pResData->GetMeasureCount() == 1 )
480  {
481  bool bTotalResult = false;
482  aRet = pResData->GetMeasureString(0, true, SUBTOTAL_FUNC_NONE, bTotalResult);
483  }
484 
485  // empty for more than one measure
486 
487  return aRet;
488 }
489 
491 {
492  bIgnoreEmptyRows = bSet;
494 }
495 
497 {
498  bRepeatIfEmpty = bSet;
500 }
501 
503 {
505 
506  if ( pResData )
507  {
508  // reset all data...
509 
510  pColResRoot.reset();
511  pRowResRoot.reset();
512  pResData.reset();
513  pColResults.reset();
514  pRowResults.reset();
515  aColLevelList.clear();
516  aRowLevelList.clear();
517  }
518 
519  pDimensions.clear(); // settings have to be applied (from SaveData) again!
520  SetDupCount( 0 );
521 
522  maColDims.clear();
523  maRowDims.clear();
524  maDataDims.clear();
525  maPageDims.clear();
526 
527  pData->DisposeData(); // cached entries etc.
528  bPageFiltered = false;
529  bResultOverflow = false;
530 }
531 
532 static long lcl_CountMinMembers(const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLevel, long nLevels )
533 {
534  // Calculate the product of the member count for those consecutive levels that
535  // have the "show all" flag, one following level, and the data layout dimension.
536 
537  long nTotal = 1;
538  long nDataCount = 1;
539  bool bWasShowAll = true;
540  long nPos = nLevels;
541  while ( nPos > 0 )
542  {
543  --nPos;
544 
545  if ( nPos+1 < nLevels && ppDim[nPos] == ppDim[nPos+1] )
546  {
547  OSL_FAIL("lcl_CountMinMembers: multiple levels from one dimension not implemented");
548  return 0;
549  }
550 
551  bool bDo = false;
552  if ( ppDim[nPos]->getIsDataLayoutDimension() )
553  {
554  // data layout dim doesn't interfere with "show all" flags
555  nDataCount = ppLevel[nPos]->GetMembersObject()->getCount();
556  if ( nDataCount == 0 )
557  nDataCount = 1;
558  }
559  else if ( bWasShowAll ) // "show all" set for all following levels?
560  {
561  bDo = true;
562  if ( !ppLevel[nPos]->getShowEmpty() )
563  {
564  // this level is counted, following ones are not
565  bWasShowAll = false;
566  }
567  }
568  if ( bDo )
569  {
570  long nThisCount = ppLevel[nPos]->GetMembersObject()->getMinMembers();
571  if ( nThisCount == 0 )
572  {
573  nTotal = 1; // empty level -> start counting from here
574  //TODO: start with visible elements in this level?
575  }
576  else
577  {
578  if ( nTotal >= LONG_MAX / nThisCount )
579  return LONG_MAX; // overflow
580  nTotal *= nThisCount;
581  }
582  }
583  }
584 
585  // always include data layout dim, even after restarting
586  if ( nTotal >= LONG_MAX / nDataCount )
587  return LONG_MAX; // overflow
588  nTotal *= nDataCount;
589 
590  return nTotal;
591 }
592 
593 void ScDPSource::FillCalcInfo(bool bIsRow, ScDPTableData::CalcInfo& rInfo, bool &rHasAutoShow)
594 {
595  const std::vector<long>& rDims = bIsRow ? maRowDims : maColDims;
596  for (const auto& rDimIndex : rDims)
597  {
598  ScDPDimension* pDim = GetDimensionsObject()->getByIndex(rDimIndex);
599  long nHierarchy = ScDPDimension::getUsedHierarchy();
600  if ( nHierarchy >= ScDPHierarchies::getCount() )
601  nHierarchy = 0;
602  ScDPLevels* pLevels = pDim->GetHierarchiesObject()->getByIndex(nHierarchy)->GetLevelsObject();
603  long nCount = pLevels->getCount();
604 
605  //TODO: Test
606  if (pDim->getIsDataLayoutDimension() && maDataDims.size() < 2)
607  nCount = 0;
608  //TODO: Test
609 
610  for (long j = 0; j < nCount; ++j)
611  {
612  ScDPLevel* pLevel = pLevels->getByIndex(j);
613  pLevel->EvaluateSortOrder();
614 
615  // no layout flags for column fields, only for row fields
616  pLevel->SetEnableLayout( bIsRow );
617 
618  if ( pLevel->GetAutoShow().IsEnabled )
619  rHasAutoShow = true;
620 
621  if (bIsRow)
622  {
623  rInfo.aRowLevelDims.push_back(rDimIndex);
624  rInfo.aRowDims.push_back(pDim);
625  rInfo.aRowLevels.push_back(pLevel);
626  }
627  else
628  {
629  rInfo.aColLevelDims.push_back(rDimIndex);
630  rInfo.aColDims.push_back(pDim);
631  rInfo.aColLevels.push_back(pLevel);
632  }
633 
634  pLevel->GetMembersObject(); // initialize for groups
635  }
636  }
637 }
638 
639 namespace {
640 
641 class CategoryDimInserter
642 {
643  ScDPSource& mrSource;
644  std::unordered_set<sal_Int32>& mrCatDims;
645 public:
646  CategoryDimInserter(ScDPSource& rSource, std::unordered_set<sal_Int32>& rCatDims) :
647  mrSource(rSource),
648  mrCatDims(rCatDims) {}
649 
650  void operator() (long nDim)
651  {
652  if (!mrSource.IsDataLayoutDimension(nDim))
653  mrCatDims.insert(nDim);
654  }
655 };
656 
657 }
658 
659 void ScDPSource::GetCategoryDimensionIndices(std::unordered_set<sal_Int32>& rCatDims)
660 {
661  std::unordered_set<sal_Int32> aCatDims;
662 
663  CategoryDimInserter aInserter(*this, aCatDims);
664  std::for_each(maColDims.begin(), maColDims.end(), aInserter);
665  std::for_each(maRowDims.begin(), maRowDims.end(), aInserter);
666  std::for_each(maPageDims.begin(), maPageDims.end(), aInserter);
667 
668  rCatDims.swap(aCatDims);
669 }
670 
672 {
673  // #i117661# Repeated calls to ScDPFilteredCache::filterByPageDimension
674  // are invalid because rows are only hidden, never shown again. If
675  // FilterCacheByPageDimensions is called again, the cache table must
676  // be re-initialized. Currently, CreateRes_Impl always uses a fresh cache
677  // because ScDBDocFunc::DataPilotUpdate calls InvalidateData.
678 
679  if (bPageFiltered)
680  {
681  SAL_WARN( "sc.core","tried to apply page field filters several times");
682 
683  pData->DisposeData();
684  pData->CreateCacheTable(); // re-initialize the cache table
685  bPageFiltered = false;
686  }
687 
688  // filter table by page dimensions.
689  vector<ScDPFilteredCache::Criterion> aCriteria;
690  for (const auto& rDimIndex : maPageDims)
691  {
692  ScDPDimension* pDim = GetDimensionsObject()->getByIndex(rDimIndex);
693  long nField = pDim->GetDimension();
694 
695  ScDPMembers* pMems = pDim->GetHierarchiesObject()->getByIndex(0)->
696  GetLevelsObject()->getByIndex(0)->GetMembersObject();
697 
698  long nMemCount = pMems->getCount();
700  aFilter.mnFieldIndex = static_cast<sal_Int32>(nField);
701  aFilter.mpFilter = std::make_shared<ScDPFilteredCache::GroupFilter>();
702  ScDPFilteredCache::GroupFilter* pGrpFilter =
703  static_cast<ScDPFilteredCache::GroupFilter*>(aFilter.mpFilter.get());
704  for (long j = 0; j < nMemCount; ++j)
705  {
706  ScDPMember* pMem = pMems->getByIndex(j);
707  if (pMem->isVisible())
708  {
710  pGrpFilter->addMatchItem(aData);
711  }
712  }
713  if (pGrpFilter->getMatchItemCount() < o3tl::make_unsigned(nMemCount))
714  // there is at least one invisible item. Add this filter criterion to the mix.
715  aCriteria.push_back(aFilter);
716 
717  if (!pDim->HasSelectedPage())
718  continue;
719 
720  const ScDPItemData& rData = pDim->GetSelectedData();
721  aCriteria.emplace_back();
722  ScDPFilteredCache::Criterion& r = aCriteria.back();
723  r.mnFieldIndex = static_cast<sal_Int32>(nField);
724  r.mpFilter = std::make_shared<ScDPFilteredCache::SingleFilter>(rData);
725  }
726  if (!aCriteria.empty())
727  {
728  std::unordered_set<sal_Int32> aCatDims;
729  GetCategoryDimensionIndices(aCatDims);
730  pData->FilterCacheTable(aCriteria, aCatDims);
731  bPageFiltered = true;
732  }
733 }
734 
736 {
737  if (pResData)
738  return;
739 
740  sheet::DataPilotFieldOrientation nDataOrient = GetDataLayoutOrientation();
741  if (maDataDims.size() > 1 && ( nDataOrient != sheet::DataPilotFieldOrientation_COLUMN &&
742  nDataOrient != sheet::DataPilotFieldOrientation_ROW ) )
743  {
744  // if more than one data dimension, data layout orientation must be set
745  SetOrientation( pData->GetColumnCount(), sheet::DataPilotFieldOrientation_ROW );
746  nDataOrient = sheet::DataPilotFieldOrientation_ROW;
747  }
748 
749  // TODO: Aggregate pDataNames, pDataRefValues, nDataRefOrient, and
750  // eDataFunctions into a structure and use vector instead of static
751  // or pointer arrays.
752  vector<OUString> aDataNames;
753  vector<sheet::DataPilotFieldReference> aDataRefValues;
754  vector<ScSubTotalFunc> aDataFunctions;
755  vector<sheet::DataPilotFieldOrientation> aDataRefOrient;
756 
758 
759  // LateInit (initialize only those rows/children that are used) can be used unless
760  // any data dimension needs reference values from column/row dimensions
761  bool bLateInit = true;
762 
763  // Go through all data dimensions (i.e. fields) and build their meta data
764  // so that they can be passed on to ScDPResultData instance later.
765  // TODO: aggregate all of data dimension info into a structure.
766  for (const long nDimIndex : maDataDims)
767  {
768  // Get function for each data field.
769  ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nDimIndex);
770  ScGeneralFunction eUser = pDim->getFunction();
771  if (eUser == ScGeneralFunction::AUTO)
772  {
773  //TODO: test for numeric data
774  eUser = ScGeneralFunction::SUM;
775  }
776 
777  // Map UNO's enum to internal enum ScSubTotalFunc.
778  aDataFunctions.push_back(ScDPUtil::toSubTotalFunc(eUser));
779 
780  // Get reference field/item information.
781  aDataRefValues.push_back(pDim->GetReferenceValue());
782  sheet::DataPilotFieldOrientation nDataRefOrient = sheet::DataPilotFieldOrientation_HIDDEN; // default if not used
783  sal_Int32 eRefType = aDataRefValues.back().ReferenceType;
784  if ( eRefType == sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE ||
785  eRefType == sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE ||
786  eRefType == sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE ||
787  eRefType == sheet::DataPilotFieldReferenceType::RUNNING_TOTAL )
788  {
789  long nColumn = comphelper::findValue(
790  GetDimensionsObject()->getElementNames(), aDataRefValues.back().ReferenceField);
791  if ( nColumn >= 0 )
792  {
793  nDataRefOrient = GetOrientation(nColumn);
794  // need fully initialized results to find reference values
795  // (both in column or row dimensions), so updated values or
796  // differences to 0 can be displayed even for empty results.
797  bLateInit = false;
798  }
799  }
800 
801  aDataRefOrient.push_back(nDataRefOrient);
802 
803  aDataNames.push_back(pDim->getName());
804 
805  //TODO: modify user visible strings as in ScDPResultData::GetMeasureString instead!
806 
807  aDataNames.back() = ScDPUtil::getSourceDimensionName(aDataNames.back());
808 
809  //TODO: if the name is overridden by user, a flag must be set
810  //TODO: so the user defined name replaces the function string and field name.
811 
812  //TODO: the complete name (function and field) must be stored at the dimension
813 
814  long nSource = pDim->GetSourceDim();
815  if (nSource >= 0)
816  aInfo.aDataSrcCols.push_back(nSource);
817  else
818  aInfo.aDataSrcCols.push_back(nDimIndex);
819  }
820 
821  pResData.reset( new ScDPResultData(*this) );
822  pResData->SetMeasureData(aDataFunctions, aDataRefValues, aDataRefOrient, aDataNames);
823  pResData->SetDataLayoutOrientation(nDataOrient);
824  pResData->SetLateInit( bLateInit );
825 
826  bool bHasAutoShow = false;
827 
828  ScDPInitState aInitState;
829 
830  // Page field selections restrict the members shown in related fields
831  // (both in column and row fields). aInitState is filled with the page
832  // field selections, they are kept across the data iterator loop.
833 
834  for (const auto& rDimIndex : maPageDims)
835  {
836  ScDPDimension* pDim = GetDimensionsObject()->getByIndex(rDimIndex);
837  if ( pDim->HasSelectedPage() )
838  aInitState.AddMember(rDimIndex, GetCache()->GetIdByItemData(rDimIndex, pDim->GetSelectedData()));
839  }
840 
841  // Show grand total columns only when the option is set *and* there is at
842  // least one column field. Same for the grand total rows.
843  sheet::DataPilotFieldOrientation nDataLayoutOrient = GetDataLayoutOrientation();
844  long nColDimCount2 = maColDims.size() - (nDataLayoutOrient == sheet::DataPilotFieldOrientation_COLUMN ? 1 : 0);
845  long nRowDimCount2 = maRowDims.size() - (nDataLayoutOrient == sheet::DataPilotFieldOrientation_ROW ? 1 : 0);
846  bool bShowColGrand = bColumnGrand && nColDimCount2 > 0;
847  bool bShowRowGrand = bRowGrand && nRowDimCount2 > 0;
848  pColResRoot.reset( new ScDPResultMember(pResData.get(), bShowColGrand) );
849  pRowResRoot.reset( new ScDPResultMember(pResData.get(), bShowRowGrand) );
850 
851  FillCalcInfo(false, aInfo, bHasAutoShow);
852  long nColLevelCount = aInfo.aColLevels.size();
853 
854  pColResRoot->InitFrom( aInfo.aColDims, aInfo.aColLevels, 0, aInitState );
855  pColResRoot->SetHasElements();
856 
857  FillCalcInfo(true, aInfo, bHasAutoShow);
858  long nRowLevelCount = aInfo.aRowLevels.size();
859 
860  if ( nRowLevelCount > 0 )
861  {
862  // disable layout flags for the innermost row field (level)
863  aInfo.aRowLevels[nRowLevelCount-1]->SetEnableLayout( false );
864  }
865 
866  pRowResRoot->InitFrom( aInfo.aRowDims, aInfo.aRowLevels, 0, aInitState );
867  pRowResRoot->SetHasElements();
868 
869  // initialize members object also for all page dimensions (needed for numeric groups)
870  for (const auto& rDimIndex : maPageDims)
871  {
872  ScDPDimension* pDim = GetDimensionsObject()->getByIndex(rDimIndex);
873  long nHierarchy = ScDPDimension::getUsedHierarchy();
874  if ( nHierarchy >= ScDPHierarchies::getCount() )
875  nHierarchy = 0;
876 
877  ScDPLevels* pLevels = pDim->GetHierarchiesObject()->getByIndex(nHierarchy)->GetLevelsObject();
878  long nCount = pLevels->getCount();
879  for (long j=0; j<nCount; j++)
880  pLevels->getByIndex(j)->GetMembersObject(); // initialize for groups
881  }
882 
883  // pre-check: calculate minimum number of result columns / rows from
884  // levels that have the "show all" flag set
885 
886  long nMinColMembers = lcl_CountMinMembers( aInfo.aColDims, aInfo.aColLevels, nColLevelCount );
887  long nMinRowMembers = lcl_CountMinMembers( aInfo.aRowDims, aInfo.aRowLevels, nRowLevelCount );
888 
889  if ( nMinColMembers > MAXCOLCOUNT/*SC_MINCOUNT_LIMIT*/ || nMinRowMembers > SC_MINCOUNT_LIMIT )
890  {
891  // resulting table is too big -> abort before calculating
892  // (this relies on late init, so no members are allocated in InitFrom above)
893 
894  bResultOverflow = true;
895  return;
896  }
897 
899 
900  aInfo.aPageDims = maPageDims;
901  aInfo.pInitState = &aInitState;
902  aInfo.pColRoot = pColResRoot.get();
903  aInfo.pRowRoot = pRowResRoot.get();
904  pData->CalcResults(aInfo, false);
905 
906  pColResRoot->CheckShowEmpty();
907  pRowResRoot->CheckShowEmpty();
908 
909  // With all data processed, calculate the final results:
910 
911  // UpdateDataResults calculates all original results from the collected values,
912  // and stores them as reference values if needed.
913  pRowResRoot->UpdateDataResults( pColResRoot.get(), pResData->GetRowStartMeasure() );
914 
915  if ( bHasAutoShow ) // do the double calculation only if AutoShow is used
916  {
917  // Find the desired members and set bAutoHidden flag for the others
918  pRowResRoot->DoAutoShow( pColResRoot.get() );
919 
920  // Reset all results to empty, so they can be built again with data for the
921  // desired members only.
922  pColResRoot->ResetResults();
923  pRowResRoot->ResetResults();
924  pData->CalcResults(aInfo, true);
925 
926  // Call UpdateDataResults again, with the new (limited) values.
927  pRowResRoot->UpdateDataResults( pColResRoot.get(), pResData->GetRowStartMeasure() );
928  }
929 
930  // SortMembers does the sorting by a result dimension, using the original results,
931  // but not running totals etc.
932  pRowResRoot->SortMembers( pColResRoot.get() );
933 
934  // UpdateRunningTotals calculates running totals along column/row dimensions,
935  // differences from other members (named or relative), and column/row percentages
936  // or index values.
937  // Running totals and relative differences need to be done using the sorted values.
938  // Column/row percentages and index values must be done after sorting, because the
939  // results may no longer be in the right order (row total for percentage of row is
940  // always 1).
941  ScDPRunningTotalState aRunning( pColResRoot.get(), pRowResRoot.get() );
942  ScDPRowTotals aTotals;
943  pRowResRoot->UpdateRunningTotals( pColResRoot.get(), pResData->GetRowStartMeasure(), aRunning, aTotals );
944 
945 #if DUMP_PIVOT_TABLE
946  DumpResults();
947 #endif
948 }
949 
950 void ScDPSource::FillLevelList( sheet::DataPilotFieldOrientation nOrientation, std::vector<ScDPLevel*> &rList )
951 {
952  rList.clear();
953 
954  std::vector<long>* pDimIndex = nullptr;
955  switch (nOrientation)
956  {
957  case sheet::DataPilotFieldOrientation_COLUMN:
958  pDimIndex = &maColDims;
959  break;
960  case sheet::DataPilotFieldOrientation_ROW:
961  pDimIndex = &maRowDims;
962  break;
963  case sheet::DataPilotFieldOrientation_DATA:
964  pDimIndex = &maDataDims;
965  break;
966  case sheet::DataPilotFieldOrientation_PAGE:
967  pDimIndex = &maPageDims;
968  break;
969  default:
970  OSL_FAIL( "ScDPSource::FillLevelList: unexpected orientation" );
971  break;
972  }
973  if (!pDimIndex)
974  {
975  OSL_FAIL("invalid orientation");
976  return;
977  }
978 
980  for (const auto& rIndex : *pDimIndex)
981  {
982  ScDPDimension* pDim = pDims->getByIndex(rIndex);
983  OSL_ENSURE( pDim->getOrientation() == nOrientation, "orientations are wrong" );
984 
985  ScDPHierarchies* pHiers = pDim->GetHierarchiesObject();
986  long nHierarchy = ScDPDimension::getUsedHierarchy();
987  if ( nHierarchy >= ScDPHierarchies::getCount() )
988  nHierarchy = 0;
989  ScDPHierarchy* pHier = pHiers->getByIndex(nHierarchy);
990  ScDPLevels* pLevels = pHier->GetLevelsObject();
991  long nLevCount = pLevels->getCount();
992  for (long nLev=0; nLev<nLevCount; nLev++)
993  {
994  ScDPLevel* pLevel = pLevels->getByIndex(nLev);
995  rList.push_back(pLevel);
996  }
997  }
998 }
999 
1001 {
1002  if ( pColResults || pRowResults )
1003  return;
1004 
1005  CreateRes_Impl();
1006 
1007  if ( bResultOverflow ) // set in CreateRes_Impl
1008  {
1009  // no results available -> abort (leave empty)
1010  // exception is thrown in ScDPSource::getResults
1011  return;
1012  }
1013 
1014  FillLevelList( sheet::DataPilotFieldOrientation_COLUMN, aColLevelList );
1015  long nColLevelCount = aColLevelList.size();
1016  if (nColLevelCount)
1017  {
1018  long nColDimSize = pColResRoot->GetSize(pResData->GetColStartMeasure());
1019  pColResults.reset(new uno::Sequence<sheet::MemberResult>[nColLevelCount]);
1020  for (long i=0; i<nColLevelCount; i++)
1021  pColResults[i].realloc(nColDimSize);
1022 
1023  long nPos = 0;
1024  pColResRoot->FillMemberResults( pColResults.get(), nPos, pResData->GetColStartMeasure(),
1025  true, nullptr, nullptr );
1026  }
1027 
1028  FillLevelList( sheet::DataPilotFieldOrientation_ROW, aRowLevelList );
1029  long nRowLevelCount = aRowLevelList.size();
1030  if (nRowLevelCount)
1031  {
1032  long nRowDimSize = pRowResRoot->GetSize(pResData->GetRowStartMeasure());
1033  pRowResults.reset( new uno::Sequence<sheet::MemberResult>[nRowLevelCount] );
1034  for (long i=0; i<nRowLevelCount; i++)
1035  pRowResults[i].realloc(nRowDimSize);
1036 
1037  long nPos = 0;
1038  pRowResRoot->FillMemberResults( pRowResults.get(), nPos, pResData->GetRowStartMeasure(),
1039  true, nullptr, nullptr );
1040  }
1041 }
1042 
1043 const uno::Sequence<sheet::MemberResult>* ScDPSource::GetMemberResults( const ScDPLevel* pLevel )
1044 {
1046 
1047  long i = 0;
1048  long nColCount = aColLevelList.size();
1049  for (i=0; i<nColCount; i++)
1050  {
1051  ScDPLevel* pColLevel = aColLevelList[i];
1052  if ( pColLevel == pLevel )
1053  return &pColResults[i];
1054  }
1055  long nRowCount = aRowLevelList.size();
1056  for (i=0; i<nRowCount; i++)
1057  {
1058  ScDPLevel* pRowLevel = aRowLevelList[i];
1059  if ( pRowLevel == pLevel )
1060  return &pRowResults[i];
1061  }
1062  return nullptr;
1063 }
1064 
1065 // XPropertySet
1066 
1067 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo()
1068 {
1069  SolarMutexGuard aGuard;
1070  using beans::PropertyAttribute::READONLY;
1071 
1072  static const SfxItemPropertyMapEntry aDPSourceMap_Impl[] =
1073  {
1074  { OUString(SC_UNO_DP_COLGRAND), 0, cppu::UnoType<bool>::get(), 0, 0 },
1075  { OUString(SC_UNO_DP_DATADESC), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0 },
1076  { OUString(SC_UNO_DP_IGNOREEMPTY), 0, cppu::UnoType<bool>::get(), 0, 0 }, // for sheet data only
1077  { OUString(SC_UNO_DP_REPEATEMPTY), 0, cppu::UnoType<bool>::get(), 0, 0 }, // for sheet data only
1078  { OUString(SC_UNO_DP_ROWGRAND), 0, cppu::UnoType<bool>::get(), 0, 0 },
1082  { OUString(SC_UNO_DP_GRANDTOTAL_NAME), 0, cppu::UnoType<OUString>::get(), 0, 0 },
1083  { OUString(), 0, css::uno::Type(), 0, 0 }
1084  };
1085  static uno::Reference<beans::XPropertySetInfo> aRef =
1086  new SfxItemPropertySetInfo( aDPSourceMap_Impl );
1087  return aRef;
1088 }
1089 
1090 void SAL_CALL ScDPSource::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
1091 {
1092  if (aPropertyName == SC_UNO_DP_COLGRAND)
1093  bColumnGrand = lcl_GetBoolFromAny(aValue);
1094  else if (aPropertyName == SC_UNO_DP_ROWGRAND)
1095  bRowGrand = lcl_GetBoolFromAny(aValue);
1096  else if (aPropertyName == SC_UNO_DP_IGNOREEMPTY)
1098  else if (aPropertyName == SC_UNO_DP_REPEATEMPTY)
1099  setRepeatIfEmpty( lcl_GetBoolFromAny( aValue ) );
1100  else if (aPropertyName == SC_UNO_DP_GRANDTOTAL_NAME)
1101  {
1102  OUString aName;
1103  if (aValue >>= aName)
1104  mpGrandTotalName = aName;
1105  }
1106  else
1107  {
1108  OSL_FAIL("unknown property");
1109  //TODO: THROW( UnknownPropertyException() );
1110  }
1111 }
1112 
1113 uno::Any SAL_CALL ScDPSource::getPropertyValue( const OUString& aPropertyName )
1114 {
1115  uno::Any aRet;
1116  if ( aPropertyName == SC_UNO_DP_COLGRAND )
1117  aRet <<= bColumnGrand;
1118  else if ( aPropertyName == SC_UNO_DP_ROWGRAND )
1119  aRet <<= bRowGrand;
1120  else if ( aPropertyName == SC_UNO_DP_IGNOREEMPTY )
1121  aRet <<= bIgnoreEmptyRows;
1122  else if ( aPropertyName == SC_UNO_DP_REPEATEMPTY )
1123  aRet <<= bRepeatIfEmpty;
1124  else if ( aPropertyName == SC_UNO_DP_DATADESC ) // read-only
1125  aRet <<= getDataDescription();
1126  else if ( aPropertyName == SC_UNO_DP_ROWFIELDCOUNT ) // read-only
1127  aRet <<= static_cast<sal_Int32>(maRowDims.size());
1128  else if ( aPropertyName == SC_UNO_DP_COLUMNFIELDCOUNT ) // read-only
1129  aRet <<= static_cast<sal_Int32>(maColDims.size());
1130  else if ( aPropertyName == SC_UNO_DP_DATAFIELDCOUNT ) // read-only
1131  aRet <<= static_cast<sal_Int32>(maDataDims.size());
1132  else if (aPropertyName == SC_UNO_DP_GRANDTOTAL_NAME)
1133  {
1134  if (mpGrandTotalName)
1135  aRet <<= *mpGrandTotalName;
1136  }
1137  else
1138  {
1139  OSL_FAIL("unknown property");
1140  //TODO: THROW( UnknownPropertyException() );
1141  }
1142  return aRet;
1143 }
1144 
1145 #if DUMP_PIVOT_TABLE
1146 void ScDPSource::DumpResults() const
1147 {
1148  std::cout << "+++++ column root" << std::endl;
1149  pColResRoot->Dump(1);
1150  std::cout << "+++++ row root" << std::endl;
1151  pRowResRoot->Dump(1);
1152 }
1153 #endif
1154 
1156 
1158  pSource( pSrc )
1159 {
1160  //TODO: hold pSource
1161 
1162  // include data layout dimension and duplicated dimensions
1163  nDimCount = pSource->GetData()->GetColumnCount() + 1 + pSource->GetDupCount();
1164 }
1165 
1167 {
1168  //TODO: release pSource
1169 }
1170 
1172 {
1173  // include data layout dimension and duplicated dimensions
1174  long nNewCount = pSource->GetData()->GetColumnCount() + 1 + pSource->GetDupCount();
1175  if ( ppDims )
1176  {
1177  long i;
1178  long nCopy = std::min( nNewCount, nDimCount );
1180 
1181  for (i=0; i<nCopy; i++) // copy existing dims
1182  ppNew[i] = ppDims[i];
1183  for (i=nCopy; i<nNewCount; i++) // clear additional pointers
1184  ppNew[i] = nullptr;
1185 
1186  ppDims.reset( ppNew );
1187  }
1188  nDimCount = nNewCount;
1189 }
1190 
1191 // very simple XNameAccess implementation using getCount/getByIndex
1192 
1193 uno::Any SAL_CALL ScDPDimensions::getByName( const OUString& aName )
1194 {
1195  long nCount = getCount();
1196  for (long i=0; i<nCount; i++)
1197  if ( getByIndex(i)->getName() == aName )
1198  {
1199  uno::Reference<container::XNamed> xNamed = getByIndex(i);
1200  uno::Any aRet;
1201  aRet <<= xNamed;
1202  return aRet;
1203  }
1204 
1205  throw container::NoSuchElementException();
1206 // return uno::Any();
1207 }
1208 
1209 uno::Sequence<OUString> SAL_CALL ScDPDimensions::getElementNames()
1210 {
1211  long nCount = getCount();
1212  uno::Sequence<OUString> aSeq(nCount);
1213  OUString* pArr = aSeq.getArray();
1214  for (long i=0; i<nCount; i++)
1215  pArr[i] = getByIndex(i)->getName();
1216  return aSeq;
1217 }
1218 
1219 sal_Bool SAL_CALL ScDPDimensions::hasByName( const OUString& aName )
1220 {
1221  long nCount = getCount();
1222  for (long i=0; i<nCount; i++)
1223  if ( getByIndex(i)->getName() == aName )
1224  return true;
1225  return false;
1226 }
1227 
1229 {
1231 }
1232 
1234 {
1235  return ( getCount() > 0 );
1236 }
1237 
1238 // end of XNameAccess implementation
1239 
1241 {
1242  // in tabular data, every column of source data is a dimension
1243 
1244  return nDimCount;
1245 }
1246 
1248 {
1249  if ( nIndex >= 0 && nIndex < nDimCount )
1250  {
1251  if ( !ppDims )
1252  {
1253  const_cast<ScDPDimensions*>(this)->ppDims.reset(new rtl::Reference<ScDPDimension>[nDimCount] );
1254  for (long i=0; i<nDimCount; i++)
1255  ppDims[i] = nullptr;
1256  }
1257  if ( !ppDims[nIndex].is() )
1258  {
1259  ppDims[nIndex] = new ScDPDimension( pSource, nIndex );
1260  }
1261 
1262  return ppDims[nIndex].get();
1263  }
1264 
1265  return nullptr; //TODO: exception?
1266 }
1267 
1269  pSource( pSrc ),
1270  nDim( nD ),
1271  nFunction( ScGeneralFunction::SUM ), // sum is default
1272  nSourceDim( -1 ),
1273  bHasSelectedPage( false ),
1274  mbHasHiddenMember(false)
1275 {
1276  //TODO: hold pSource
1277 }
1278 
1280 {
1281  //TODO: release pSource
1282 }
1283 
1285 {
1286  if (!mxHierarchies.is())
1287  {
1288  mxHierarchies = new ScDPHierarchies( pSource, nDim );
1289  }
1290  return mxHierarchies.get();
1291 }
1292 
1293 const std::optional<OUString> & ScDPDimension::GetLayoutName() const
1294 {
1295  return mpLayoutName;
1296 }
1297 
1298 const std::optional<OUString> & ScDPDimension::GetSubtotalName() const
1299 {
1300  return mpSubtotalName;
1301 }
1302 
1303 uno::Reference<container::XNameAccess> SAL_CALL ScDPDimension::getHierarchies()
1304 {
1305  return GetHierarchiesObject();
1306 }
1307 
1308 OUString SAL_CALL ScDPDimension::getName()
1309 {
1310  if (!aName.isEmpty())
1311  return aName;
1312  else
1313  return pSource->GetData()->getDimensionName( nDim );
1314 }
1315 
1316 void SAL_CALL ScDPDimension::setName( const OUString& rNewName )
1317 {
1318  // used after cloning
1319  aName = rNewName;
1320 }
1321 
1322 sheet::DataPilotFieldOrientation ScDPDimension::getOrientation() const
1323 {
1324  return pSource->GetOrientation( nDim );
1325 }
1326 
1328 {
1329  return pSource->GetData()->getIsDataLayoutDimension( nDim );
1330 }
1331 
1333 {
1334  nFunction = nNew;
1335 }
1336 
1338 {
1339  OSL_ENSURE( nSourceDim < 0, "recursive duplicate - not implemented" );
1340 
1341  //TODO: set new name here, or temporary name ???
1342  OUString aNewName = aName;
1343 
1344  ScDPDimension* pNew = pSource->AddDuplicated( aNewName );
1345 
1346  pNew->aName = aNewName; //TODO: here or in source?
1347  pNew->nSourceDim = nDim; //TODO: recursive?
1348 
1349  return pNew;
1350 }
1351 
1352 uno::Reference<util::XCloneable> SAL_CALL ScDPDimension::createClone()
1353 {
1354  return CreateCloneObject();
1355 }
1356 
1358 {
1359  if ( !pSelectedData )
1360  {
1361  // find the named member to initialize pSelectedData from it, with name and value
1362 
1363  long nLevel = 0;
1364 
1365  long nHierarchy = getUsedHierarchy();
1366  if ( nHierarchy >= ScDPHierarchies::getCount() )
1367  nHierarchy = 0;
1368  ScDPLevels* pLevels = GetHierarchiesObject()->getByIndex(nHierarchy)->GetLevelsObject();
1369  long nLevCount = pLevels->getCount();
1370  if ( nLevel < nLevCount )
1371  {
1372  ScDPMembers* pMembers = pLevels->getByIndex(nLevel)->GetMembersObject();
1373 
1374  //TODO: merge with ScDPMembers::getByName
1375  long nCount = pMembers->getCount();
1376  for (long i=0; i<nCount && !pSelectedData; i++)
1377  {
1378  ScDPMember* pMember = pMembers->getByIndex(i);
1379  if (aSelectedPage == pMember->GetNameStr(false))
1380  {
1381  pSelectedData.reset( new ScDPItemData(pMember->FillItemData()) );
1382  }
1383  }
1384  }
1385 
1386  if ( !pSelectedData )
1387  pSelectedData.reset( new ScDPItemData(aSelectedPage) ); // default - name only
1388  }
1389 
1390  return *pSelectedData;
1391 }
1392 
1393 // XPropertySet
1394 
1395 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPDimension::getPropertySetInfo()
1396 {
1397  SolarMutexGuard aGuard;
1398 
1399  static const SfxItemPropertyMapEntry aDPDimensionMap_Impl[] =
1400  {
1402  { OUString(SC_UNO_DP_FLAGS), 0, cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
1404  { OUString(SC_UNO_DP_FUNCTION2), 0, cppu::UnoType<sal_Int16>::get(), 0, 0 },
1405  { OUString(SC_UNO_DP_ISDATALAYOUT), 0, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0 },
1406  { OUString(SC_UNO_DP_NUMBERFO), 0, cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
1408  { OUString(SC_UNO_DP_ORIGINAL), 0, cppu::UnoType<container::XNamed>::get(), beans::PropertyAttribute::READONLY, 0 },
1409  { OUString(SC_UNO_DP_ORIGINAL_POS), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
1410  { OUString(SC_UNO_DP_POSITION), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
1412  { OUString(SC_UNO_DP_USEDHIERARCHY), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
1413  { OUString(SC_UNO_DP_LAYOUTNAME), 0, cppu::UnoType<OUString>::get(), 0, 0 },
1415  { OUString(SC_UNO_DP_HAS_HIDDEN_MEMBER), 0, cppu::UnoType<bool>::get(), 0, 0 },
1416  { OUString(), 0, css::uno::Type(), 0, 0 }
1417  };
1418  static uno::Reference<beans::XPropertySetInfo> aRef =
1419  new SfxItemPropertySetInfo( aDPDimensionMap_Impl );
1420  return aRef;
1421 }
1422 
1423 void SAL_CALL ScDPDimension::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
1424 {
1425  if ( aPropertyName == SC_UNO_DP_USEDHIERARCHY )
1426  {
1427  // #i52547# don't use the incomplete date hierarchy implementation - ignore the call
1428  }
1429  else if ( aPropertyName == SC_UNO_DP_ORIENTATION )
1430  {
1431  sheet::DataPilotFieldOrientation eEnum;
1432  if (aValue >>= eEnum)
1433  pSource->SetOrientation( nDim, eEnum );
1434  }
1435  else if ( aPropertyName == SC_UNO_DP_FUNCTION )
1436  {
1437  sheet::GeneralFunction eEnum;
1438  if (aValue >>= eEnum)
1439  setFunction( static_cast<ScGeneralFunction>(eEnum) );
1440  }
1441  else if ( aPropertyName == SC_UNO_DP_FUNCTION2 )
1442  {
1443  sal_Int16 eEnum;
1444  if (aValue >>= eEnum)
1445  setFunction( static_cast<ScGeneralFunction>(eEnum) );
1446  }
1447  else if ( aPropertyName == SC_UNO_DP_REFVALUE )
1448  aValue >>= aReferenceValue;
1449  else if ( aPropertyName == SC_UNO_DP_FILTER )
1450  {
1451  bool bDone = false;
1452  uno::Sequence<sheet::TableFilterField> aSeq;
1453  if (aValue >>= aSeq)
1454  {
1455  sal_Int32 nLength = aSeq.getLength();
1456  if ( nLength == 0 )
1457  {
1458  aSelectedPage.clear();
1459  bHasSelectedPage = false;
1460  bDone = true;
1461  }
1462  else if ( nLength == 1 )
1463  {
1464  const sheet::TableFilterField& rField = aSeq[0];
1465  if ( rField.Field == 0 && rField.Operator == sheet::FilterOperator_EQUAL && !rField.IsNumeric )
1466  {
1467  aSelectedPage = rField.StringValue;
1468  bHasSelectedPage = true;
1469  bDone = true;
1470  }
1471  }
1472  }
1473  if ( !bDone )
1474  {
1475  OSL_FAIL("Filter property is not a single string");
1476  throw lang::IllegalArgumentException();
1477  }
1478  pSelectedData.reset(); // invalid after changing aSelectedPage
1479  }
1480  else if (aPropertyName == SC_UNO_DP_LAYOUTNAME)
1481  {
1482  OUString aTmpName;
1483  if (aValue >>= aTmpName)
1484  mpLayoutName = aTmpName;
1485  }
1486  else if (aPropertyName == SC_UNO_DP_FIELD_SUBTOTALNAME)
1487  {
1488  OUString aTmpName;
1489  if (aValue >>= aTmpName)
1490  mpSubtotalName = aTmpName;
1491  }
1492  else if (aPropertyName == SC_UNO_DP_HAS_HIDDEN_MEMBER)
1493  {
1494  bool b = false;
1495  aValue >>= b;
1496  mbHasHiddenMember = b;
1497  }
1498  else
1499  {
1500  OSL_FAIL("unknown property");
1501  //TODO: THROW( UnknownPropertyException() );
1502  }
1503 }
1504 
1505 uno::Any SAL_CALL ScDPDimension::getPropertyValue( const OUString& aPropertyName )
1506 {
1507  uno::Any aRet;
1508  if ( aPropertyName == SC_UNO_DP_POSITION )
1509  aRet <<= static_cast<sal_Int32>(pSource->GetPosition( nDim ));
1510  else if ( aPropertyName == SC_UNO_DP_USEDHIERARCHY )
1511  aRet <<= static_cast<sal_Int32>(getUsedHierarchy());
1512  else if ( aPropertyName == SC_UNO_DP_ORIENTATION )
1513  {
1514  sheet::DataPilotFieldOrientation eVal = getOrientation();
1515  aRet <<= eVal;
1516  }
1517  else if ( aPropertyName == SC_UNO_DP_FUNCTION )
1518  {
1519  ScGeneralFunction nVal = getFunction();
1520  if (nVal == ScGeneralFunction::MEDIAN)
1521  nVal = ScGeneralFunction::NONE;
1522  const int nValAsInt = static_cast<int>(nVal);
1523  assert(nValAsInt >= int(css::sheet::GeneralFunction_NONE) &&
1524  nValAsInt <= int(css::sheet::GeneralFunction_VARP));
1525  aRet <<= static_cast<sheet::GeneralFunction>(nValAsInt);
1526  }
1527  else if ( aPropertyName == SC_UNO_DP_FUNCTION2 )
1528  {
1529  ScGeneralFunction eVal = getFunction();
1530  aRet <<= static_cast<sal_Int16>(eVal);
1531  }
1532  else if ( aPropertyName == SC_UNO_DP_REFVALUE )
1533  aRet <<= aReferenceValue;
1534  else if ( aPropertyName == SC_UNO_DP_ISDATALAYOUT ) // read-only properties
1535  aRet <<= getIsDataLayoutDimension();
1536  else if ( aPropertyName == SC_UNO_DP_NUMBERFO )
1537  {
1538  sal_Int32 nFormat = 0;
1539  ScGeneralFunction eFunc = getFunction();
1540  // #i63745# don't use source format for "count"
1541  if ( eFunc != ScGeneralFunction::COUNT && eFunc != ScGeneralFunction::COUNTNUMS )
1542  nFormat = pSource->GetData()->GetNumberFormat( ( nSourceDim >= 0 ) ? nSourceDim : nDim );
1543 
1544  switch ( aReferenceValue.ReferenceType )
1545  {
1546  case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE:
1547  case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
1548  case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE:
1549  case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE:
1550  case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE:
1551  nFormat = pSource->GetData()->GetNumberFormatByIdx( NF_PERCENT_DEC2 );
1552  break;
1553  case sheet::DataPilotFieldReferenceType::INDEX:
1554  nFormat = pSource->GetData()->GetNumberFormatByIdx( NF_NUMBER_SYSTEM );
1555  break;
1556  default:
1557  break;
1558  }
1559 
1560  aRet <<= nFormat;
1561  }
1562  else if ( aPropertyName == SC_UNO_DP_ORIGINAL )
1563  {
1564  uno::Reference<container::XNamed> xOriginal;
1565  if (nSourceDim >= 0)
1566  xOriginal = pSource->GetDimensionsObject()->getByIndex(nSourceDim);
1567  aRet <<= xOriginal;
1568  }
1569  else if (aPropertyName == SC_UNO_DP_ORIGINAL_POS)
1570  {
1571  sal_Int32 nPos = static_cast<sal_Int32>(nSourceDim);
1572  aRet <<= nPos;
1573  }
1574  else if ( aPropertyName == SC_UNO_DP_FILTER )
1575  {
1576  if ( bHasSelectedPage )
1577  {
1578  // single filter field: first field equal to selected string
1579  sheet::TableFilterField aField( sheet::FilterConnection_AND, 0,
1580  sheet::FilterOperator_EQUAL, false, 0.0, aSelectedPage );
1581  aRet <<= uno::Sequence<sheet::TableFilterField>( &aField, 1 );
1582  }
1583  else
1584  aRet <<= uno::Sequence<sheet::TableFilterField>(0);
1585  }
1586  else if (aPropertyName == SC_UNO_DP_LAYOUTNAME)
1587  aRet <<= mpLayoutName ? *mpLayoutName : OUString();
1588  else if (aPropertyName == SC_UNO_DP_FIELD_SUBTOTALNAME)
1589  aRet <<= mpSubtotalName ? *mpSubtotalName : OUString();
1590  else if (aPropertyName == SC_UNO_DP_HAS_HIDDEN_MEMBER)
1591  aRet <<= mbHasHiddenMember;
1592  else if (aPropertyName == SC_UNO_DP_FLAGS)
1593  {
1594  aRet <<= sal_Int32(0); // tabular data: all orientations are possible
1595  }
1596  else
1597  {
1598  OSL_FAIL("unknown property");
1599  //TODO: THROW( UnknownPropertyException() );
1600  }
1601  return aRet;
1602 }
1603 
1605 
1607  pSource( pSrc ),
1608  nDim( nD )
1609 {
1610  //TODO: hold pSource
1611 }
1612 
1614 {
1615  //TODO: release pSource
1616 }
1617 
1618 // very simple XNameAccess implementation using getCount/getByIndex
1619 
1620 uno::Any SAL_CALL ScDPHierarchies::getByName( const OUString& aName )
1621 {
1622  long nCount = getCount();
1623  for (long i=0; i<nCount; i++)
1624  if ( getByIndex(i)->getName() == aName )
1625  {
1626  uno::Reference<container::XNamed> xNamed = getByIndex(i);
1627  uno::Any aRet;
1628  aRet <<= xNamed;
1629  return aRet;
1630  }
1631 
1632  throw container::NoSuchElementException();
1633 }
1634 
1635 uno::Sequence<OUString> SAL_CALL ScDPHierarchies::getElementNames()
1636 {
1637  long nCount = getCount();
1638  uno::Sequence<OUString> aSeq(nCount);
1639  OUString* pArr = aSeq.getArray();
1640  for (long i=0; i<nCount; i++)
1641  pArr[i] = getByIndex(i)->getName();
1642  return aSeq;
1643 }
1644 
1645 sal_Bool SAL_CALL ScDPHierarchies::hasByName( const OUString& aName )
1646 {
1647  long nCount = getCount();
1648  for (long i=0; i<nCount; i++)
1649  if ( getByIndex(i)->getName() == aName )
1650  return true;
1651  return false;
1652 }
1653 
1655 {
1657 }
1658 
1660 {
1661  return ( getCount() > 0 );
1662 }
1663 
1664 // end of XNameAccess implementation
1665 
1667 {
1668  return nHierCount;
1669 }
1670 
1672 {
1673  // pass hierarchy index to new object in case the implementation
1674  // will be extended to more than one hierarchy
1675 
1676  if ( nIndex >= 0 && nIndex < nHierCount )
1677  {
1678  if ( !ppHiers )
1679  {
1680  const_cast<ScDPHierarchies*>(this)->ppHiers.reset( new rtl::Reference<ScDPHierarchy>[nHierCount] );
1681  for (long i=0; i<nHierCount; i++)
1682  ppHiers[i] = nullptr;
1683  }
1684  if ( !ppHiers[nIndex].is() )
1685  {
1686  ppHiers[nIndex] = new ScDPHierarchy( pSource, nDim, nIndex );
1687  }
1688 
1689  return ppHiers[nIndex].get();
1690  }
1691 
1692  return nullptr; //TODO: exception?
1693 }
1694 
1695 ScDPHierarchy::ScDPHierarchy( ScDPSource* pSrc, long nD, long nH ) :
1696  pSource( pSrc ),
1697  nDim( nD ),
1698  nHier( nH )
1699 {
1700  //TODO: hold pSource
1701 }
1702 
1704 {
1705  //TODO: release pSource
1706 }
1707 
1709 {
1710  if (!mxLevels.is())
1711  {
1712  mxLevels = new ScDPLevels( pSource, nDim, nHier );
1713  }
1714  return mxLevels.get();
1715 }
1716 
1717 uno::Reference<container::XNameAccess> SAL_CALL ScDPHierarchy::getLevels()
1718 {
1719  return GetLevelsObject();
1720 }
1721 
1722 OUString SAL_CALL ScDPHierarchy::getName()
1723 {
1724  OUString aRet; //TODO: globstr-ID !!!!
1725  switch (nHier)
1726  {
1728  aRet = "flat";
1729  break; //TODO: name ???????
1731  aRet = "Quarter";
1732  break; //TODO: name ???????
1734  aRet = "Week";
1735  break; //TODO: name ???????
1736  default:
1737  OSL_FAIL( "ScDPHierarchy::getName: unexpected hierarchy" );
1738  break;
1739  }
1740  return aRet;
1741 }
1742 
1743 void SAL_CALL ScDPHierarchy::setName( const OUString& /* rNewName */ )
1744 {
1745  OSL_FAIL("not implemented"); //TODO: exception?
1746 }
1747 
1748 ScDPLevels::ScDPLevels( ScDPSource* pSrc, long nD, long nH ) :
1749  pSource( pSrc ),
1750  nDim( nD ),
1751  nHier( nH )
1752 {
1753  //TODO: hold pSource
1754 
1755  // text columns have only one level
1756 
1757  long nSrcDim = pSource->GetSourceDim( nDim );
1758  if ( pSource->IsDateDimension( nSrcDim ) )
1759  {
1760  switch ( nHier )
1761  {
1765  default:
1766  OSL_FAIL("wrong hierarchy");
1767  nLevCount = 0;
1768  }
1769  }
1770  else
1771  nLevCount = 1;
1772 }
1773 
1775 {
1776  //TODO: release pSource
1777 }
1778 
1779 // very simple XNameAccess implementation using getCount/getByIndex
1780 
1781 uno::Any SAL_CALL ScDPLevels::getByName( const OUString& aName )
1782 {
1783  long nCount = getCount();
1784  for (long i=0; i<nCount; i++)
1785  if ( getByIndex(i)->getName() == aName )
1786  {
1787  uno::Reference<container::XNamed> xNamed = getByIndex(i);
1788  uno::Any aRet;
1789  aRet <<= xNamed;
1790  return aRet;
1791  }
1792 
1793  throw container::NoSuchElementException();
1794 }
1795 
1796 uno::Sequence<OUString> SAL_CALL ScDPLevels::getElementNames()
1797 {
1798  long nCount = getCount();
1799  uno::Sequence<OUString> aSeq(nCount);
1800  OUString* pArr = aSeq.getArray();
1801  for (long i=0; i<nCount; i++)
1802  pArr[i] = getByIndex(i)->getName();
1803  return aSeq;
1804 }
1805 
1806 sal_Bool SAL_CALL ScDPLevels::hasByName( const OUString& aName )
1807 {
1808  long nCount = getCount();
1809  for (long i=0; i<nCount; i++)
1810  if ( getByIndex(i)->getName() == aName )
1811  return true;
1812  return false;
1813 }
1814 
1816 {
1818 }
1819 
1821 {
1822  return ( getCount() > 0 );
1823 }
1824 
1825 // end of XNameAccess implementation
1826 
1828 {
1829  return nLevCount;
1830 }
1831 
1833 {
1834  if ( nIndex >= 0 && nIndex < nLevCount )
1835  {
1836  if ( !ppLevs )
1837  {
1838  const_cast<ScDPLevels*>(this)->ppLevs.reset(new rtl::Reference<ScDPLevel>[nLevCount] );
1839  for (long i=0; i<nLevCount; i++)
1840  ppLevs[i] = nullptr;
1841  }
1842  if ( !ppLevs[nIndex].is() )
1843  {
1844  ppLevs[nIndex] = new ScDPLevel( pSource, nDim, nHier, nIndex );
1845  }
1846 
1847  return ppLevs[nIndex].get();
1848  }
1849 
1850  return nullptr; //TODO: exception?
1851 }
1852 
1853 namespace {
1854 
1855 class ScDPGlobalMembersOrder
1856 {
1857  ScDPLevel& rLevel;
1858  bool bAscending;
1859 
1860 public:
1861  ScDPGlobalMembersOrder( ScDPLevel& rLev, bool bAsc ) :
1862  rLevel(rLev),
1863  bAscending(bAsc)
1864  {}
1865 
1866  bool operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const;
1867 };
1868 
1869 }
1870 
1871 bool ScDPGlobalMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) const
1872 {
1873  sal_Int32 nCompare = 0;
1874  // seems that some ::std::sort() implementations pass the same index twice
1875  if( nIndex1 != nIndex2 )
1876  {
1877  ScDPMembers* pMembers = rLevel.GetMembersObject();
1878  ScDPMember* pMember1 = pMembers->getByIndex(nIndex1);
1879  ScDPMember* pMember2 = pMembers->getByIndex(nIndex2);
1880  nCompare = pMember1->Compare( *pMember2 );
1881  }
1882  return bAscending ? (nCompare < 0) : (nCompare > 0);
1883 }
1884 
1885 ScDPLevel::ScDPLevel( ScDPSource* pSrc, long nD, long nH, long nL ) :
1886  pSource( pSrc ),
1887  nDim( nD ),
1888  nHier( nH ),
1889  nLev( nL ),
1890  aSortInfo( EMPTY_OUSTRING, true, sheet::DataPilotFieldSortMode::NAME ), // default: sort by name
1891  nSortMeasure( 0 ),
1892  nAutoMeasure( 0 ),
1893  bShowEmpty( false ),
1894  bEnableLayout( false ),
1895  bRepeatItemLabels( false )
1896 {
1897  //TODO: hold pSource
1898  // aSubTotals is empty
1899 }
1900 
1902 {
1903  //TODO: release pSource
1904 }
1905 
1907 {
1908  switch (aSortInfo.Mode)
1909  {
1910  case sheet::DataPilotFieldSortMode::DATA:
1911  {
1912  // find index of measure (index among data dimensions)
1913 
1914  long nMeasureCount = pSource->GetDataDimensionCount();
1915  for (long nMeasure=0; nMeasure<nMeasureCount; nMeasure++)
1916  {
1917  if (pSource->GetDataDimName(nMeasure) == aSortInfo.Field)
1918  {
1919  nSortMeasure = nMeasure;
1920  break;
1921  }
1922  }
1923 
1924  //TODO: error if not found?
1925  }
1926  break;
1927  case sheet::DataPilotFieldSortMode::MANUAL:
1928  case sheet::DataPilotFieldSortMode::NAME:
1929  {
1930  ScDPMembers* pLocalMembers = GetMembersObject();
1931  long nCount = pLocalMembers->getCount();
1932 
1933  aGlobalOrder.resize( nCount );
1934  for (long nPos=0; nPos<nCount; nPos++)
1935  aGlobalOrder[nPos] = nPos;
1936 
1937  // allow manual or name (manual is always ascending)
1938  bool bAscending = ( aSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL || aSortInfo.IsAscending );
1939  ScDPGlobalMembersOrder aComp( *this, bAscending );
1940  ::std::sort( aGlobalOrder.begin(), aGlobalOrder.end(), aComp );
1941  }
1942  break;
1943  }
1944 
1945  if ( !aAutoShowInfo.IsEnabled )
1946  return;
1947 
1948  // find index of measure (index among data dimensions)
1949 
1950  long nMeasureCount = pSource->GetDataDimensionCount();
1951  for (long nMeasure=0; nMeasure<nMeasureCount; nMeasure++)
1952  {
1953  if (pSource->GetDataDimName(nMeasure) == aAutoShowInfo.DataField)
1954  {
1955  nAutoMeasure = nMeasure;
1956  break;
1957  }
1958  }
1959 
1960  //TODO: error if not found?
1961 }
1962 
1964 {
1965  bEnableLayout = bSet;
1966 }
1967 
1969 {
1970  if (!mxMembers.is())
1971  {
1972  mxMembers = new ScDPMembers( pSource, nDim, nHier, nLev );
1973  }
1974  return mxMembers.get();
1975 }
1976 
1977 uno::Reference<sheet::XMembersAccess> SAL_CALL ScDPLevel::getMembers()
1978 {
1979  return GetMembersObject();
1980 }
1981 
1982 uno::Sequence<sheet::MemberResult> SAL_CALL ScDPLevel::getResults()
1983 {
1984  const uno::Sequence<sheet::MemberResult>* pRes = pSource->GetMemberResults( this );
1985  if (pRes)
1986  return *pRes;
1987 
1988  return uno::Sequence<sheet::MemberResult>(0); //TODO: Error?
1989 }
1990 
1991 OUString SAL_CALL ScDPLevel::getName()
1992 {
1993  long nSrcDim = pSource->GetSourceDim( nDim );
1994  if ( pSource->IsDateDimension( nSrcDim ) )
1995  {
1996  OUString aRet; //TODO: globstr-ID !!!!
1997 
1999  {
2000  switch ( nLev )
2001  {
2002  case SC_DAPI_LEVEL_YEAR:
2003  aRet = "Year";
2004  break;
2005  case SC_DAPI_LEVEL_QUARTER:
2006  aRet = "Quarter";
2007  break;
2008  case SC_DAPI_LEVEL_MONTH:
2009  aRet = "Month";
2010  break;
2011  case SC_DAPI_LEVEL_DAY:
2012  aRet = "Day";
2013  break;
2014  default:
2015  OSL_FAIL( "ScDPLevel::getName: unexpected level" );
2016  break;
2017  }
2018  }
2019  else if ( nHier == SC_DAPI_HIERARCHY_WEEK )
2020  {
2021  switch ( nLev )
2022  {
2023  case SC_DAPI_LEVEL_YEAR:
2024  aRet = "Year";
2025  break;
2026  case SC_DAPI_LEVEL_WEEK:
2027  aRet = "Week";
2028  break;
2029  case SC_DAPI_LEVEL_WEEKDAY:
2030  aRet = "Weekday";
2031  break;
2032  default:
2033  OSL_FAIL( "ScDPLevel::getName: unexpected level" );
2034  break;
2035  }
2036  }
2037  if (!aRet.isEmpty())
2038  return aRet;
2039  }
2040 
2041  ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
2042  if (!pDim)
2043  return OUString();
2044 
2045  return pDim->getName();
2046 }
2047 
2048 void SAL_CALL ScDPLevel::setName( const OUString& /* rNewName */ )
2049 {
2050  OSL_FAIL("not implemented"); //TODO: exception?
2051 }
2052 
2053 uno::Sequence<sal_Int16> ScDPLevel::getSubTotals() const
2054 {
2055  //TODO: separate functions for settings and evaluation?
2056 
2057  long nSrcDim = pSource->GetSourceDim( nDim );
2058  if ( !pSource->SubTotalAllowed( nSrcDim ) )
2059  return uno::Sequence<sal_Int16>(0);
2060 
2061  return aSubTotals;
2062 }
2063 
2064 // XPropertySet
2065 
2066 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPLevel::getPropertySetInfo()
2067 {
2068  SolarMutexGuard aGuard;
2069 
2070  static const SfxItemPropertyMapEntry aDPLevelMap_Impl[] =
2071  {
2072  //TODO: change type of AutoShow/Layout/Sorting to API struct when available
2075  { OUString(SC_UNO_DP_SHOWEMPTY), 0, cppu::UnoType<bool>::get(), 0, 0 },
2076  { OUString(SC_UNO_DP_REPEATITEMLABELS), 0, cppu::UnoType<bool>::get(), 0, 0 },
2079  { OUString(SC_UNO_DP_SUBTOTAL2), 0, cppu::UnoType<uno::Sequence<sal_Int16>>::get(), 0, 0 },
2080  { OUString(), 0, css::uno::Type(), 0, 0 }
2081  };
2082  static uno::Reference<beans::XPropertySetInfo> aRef =
2083  new SfxItemPropertySetInfo( aDPLevelMap_Impl );
2084  return aRef;
2085 }
2086 
2087 void SAL_CALL ScDPLevel::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
2088 {
2089  if ( aPropertyName == SC_UNO_DP_SHOWEMPTY )
2090  bShowEmpty = lcl_GetBoolFromAny(aValue);
2091  else if ( aPropertyName == SC_UNO_DP_REPEATITEMLABELS )
2093  else if ( aPropertyName == SC_UNO_DP_SUBTOTAL )
2094  {
2095  uno::Sequence<sheet::GeneralFunction> aSeq;
2096  aValue >>= aSeq;
2097  aSubTotals.realloc(aSeq.getLength());
2098  std::transform(aSeq.begin(), aSeq.end(), aSubTotals.begin(),
2099  [](const sheet::GeneralFunction& rFunc) -> sal_Int16 {
2100  return static_cast<sal_Int16>(rFunc); });
2101  }
2102  else if ( aPropertyName == SC_UNO_DP_SUBTOTAL2 )
2103  aValue >>= aSubTotals;
2104  else if ( aPropertyName == SC_UNO_DP_SORTING )
2105  aValue >>= aSortInfo;
2106  else if ( aPropertyName == SC_UNO_DP_AUTOSHOW )
2107  aValue >>= aAutoShowInfo;
2108  else if ( aPropertyName == SC_UNO_DP_LAYOUT )
2109  aValue >>= aLayoutInfo;
2110  else
2111  {
2112  OSL_FAIL("unknown property");
2113  }
2114 }
2115 
2116 uno::Any SAL_CALL ScDPLevel::getPropertyValue( const OUString& aPropertyName )
2117 {
2118  uno::Any aRet;
2119  if ( aPropertyName == SC_UNO_DP_SHOWEMPTY )
2120  aRet <<= bShowEmpty;
2121  else if ( aPropertyName == SC_UNO_DP_REPEATITEMLABELS )
2122  aRet <<= bRepeatItemLabels;
2123  else if ( aPropertyName == SC_UNO_DP_SUBTOTAL )
2124  {
2125  const uno::Sequence<sal_Int16> aSeq = getSubTotals();
2126  uno::Sequence<sheet::GeneralFunction> aNewSeq;
2127  aNewSeq.realloc(aSeq.getLength());
2128  std::transform(aSeq.begin(), aSeq.end(), aNewSeq.begin(),
2129  [](const sal_Int16 nFunc) -> sheet::GeneralFunction {
2130  if (nFunc == sheet::GeneralFunction2::MEDIAN)
2131  return sheet::GeneralFunction_NONE;
2132  return static_cast<sheet::GeneralFunction>(nFunc);
2133  });
2134 
2135  aRet <<= aNewSeq;
2136  }
2137  else if ( aPropertyName == SC_UNO_DP_SUBTOTAL2 )
2138  {
2139  uno::Sequence<sal_Int16> aSeq = getSubTotals(); //TODO: avoid extra copy?
2140  aRet <<= aSeq;
2141  }
2142  else if ( aPropertyName == SC_UNO_DP_SORTING )
2143  aRet <<= aSortInfo;
2144  else if ( aPropertyName == SC_UNO_DP_AUTOSHOW )
2145  aRet <<= aAutoShowInfo;
2146  else if ( aPropertyName == SC_UNO_DP_LAYOUT )
2147  aRet <<= aLayoutInfo;
2148  else if (aPropertyName == SC_UNO_DP_LAYOUTNAME)
2149  {
2150  // read only property
2151  long nSrcDim = pSource->GetSourceDim(nDim);
2152  ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
2153  if (!pDim)
2154  return aRet;
2155 
2156  const std::optional<OUString> & pLayoutName = pDim->GetLayoutName();
2157  if (!pLayoutName)
2158  return aRet;
2159 
2160  aRet <<= *pLayoutName;
2161  }
2162  else
2163  {
2164  OSL_FAIL("unknown property");
2165  }
2166  return aRet;
2167 }
2168 
2170 
2171 ScDPMembers::ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL ) :
2172  pSource( pSrc ),
2173  nDim( nD ),
2174  nHier( nH ),
2175  nLev( nL )
2176 {
2177  //TODO: hold pSource
2178 
2179  long nSrcDim = pSource->GetSourceDim( nDim );
2180  if ( pSource->IsDataLayoutDimension(nSrcDim) )
2181  nMbrCount = pSource->GetDataDimensionCount();
2182  else if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) )
2183  {
2184  nMbrCount = 0;
2185  if ( nHier == SC_DAPI_HIERARCHY_QUARTER )
2186  {
2187  switch (nLev)
2188  {
2189  case SC_DAPI_LEVEL_YEAR:
2190  {
2191  const ScDPItemData* pLastNumData = nullptr;
2192  for ( SCROW n = 0; n < static_cast<SCROW>(pSource->GetData()->GetColumnEntries(nDim).size()); n-- )
2193  {
2194  const ScDPItemData* pData = GetSrcItemDataByIndex( n );
2195  if ( pData && pData->HasStringData() )
2196  break;
2197  else
2198  pLastNumData = pData;
2199  }
2200 
2201  if ( pLastNumData )
2202  {
2203  const ScDPItemData* pFirstData = GetSrcItemDataByIndex( 0 );
2204  double fFirstVal = pFirstData->GetValue();
2205  double fLastVal = pLastNumData->GetValue();
2206 
2207  long nFirstYear = pSource->GetData()->GetDatePart(
2208  static_cast<long>(::rtl::math::approxFloor( fFirstVal )),
2209  nHier, nLev );
2210  long nLastYear = pSource->GetData()->GetDatePart(
2211  static_cast<long>(::rtl::math::approxFloor( fLastVal )),
2212  nHier, nLev );
2213 
2214  nMbrCount = nLastYear + 1 - nFirstYear;
2215  }
2216  else
2217  nMbrCount = 0; // no values
2218  }
2219  break;
2220  case SC_DAPI_LEVEL_QUARTER: nMbrCount = 4; break;
2221  case SC_DAPI_LEVEL_MONTH: nMbrCount = 12; break;
2222  case SC_DAPI_LEVEL_DAY: nMbrCount = 31; break;
2223  default:
2224  OSL_FAIL( "ScDPMembers::ScDPMembers: unexpected level" );
2225  break;
2226  }
2227  }
2228  else if ( nHier == SC_DAPI_HIERARCHY_WEEK )
2229  {
2230  switch (nLev)
2231  {
2232  case SC_DAPI_LEVEL_YEAR: nMbrCount = 1; break; //TODO: get years from source
2233  case SC_DAPI_LEVEL_WEEK: nMbrCount = 53; break;
2234  case SC_DAPI_LEVEL_WEEKDAY: nMbrCount = 7; break;
2235  default:
2236  OSL_FAIL( "ScDPMembers::ScDPMembers: unexpected level" );
2237  break;
2238  }
2239  }
2240  }
2241  else
2242  nMbrCount = pSource->GetData()->GetMembersCount( nSrcDim );
2243 }
2244 
2246 {
2247 }
2248 
2249 // XNameAccess implementation using getCount/getByIndex
2250 
2251 sal_Int32 ScDPMembers::GetIndexFromName( const OUString& rName ) const
2252 {
2253  if ( aHashMap.empty() )
2254  {
2255  // store the index for each name
2256 
2257  sal_Int32 nCount = getCount();
2258  for (sal_Int32 i=0; i<nCount; i++)
2259  aHashMap[ getByIndex(i)->getName() ] = i;
2260  }
2261 
2262  ScDPMembersHashMap::const_iterator aIter = aHashMap.find( rName );
2263  if ( aIter != aHashMap.end() )
2264  return aIter->second; // found index
2265  else
2266  return -1; // not found
2267 }
2268 
2269 uno::Any SAL_CALL ScDPMembers::getByName( const OUString& aName )
2270 {
2271  sal_Int32 nIndex = GetIndexFromName( aName );
2272  if ( nIndex >= 0 )
2273  {
2274  uno::Reference<container::XNamed> xNamed = getByIndex(nIndex);
2275  uno::Any aRet;
2276  aRet <<= xNamed;
2277  return aRet;
2278  }
2279 
2280  throw container::NoSuchElementException();
2281 }
2282 
2283 uno::Sequence<OUString> SAL_CALL ScDPMembers::getElementNames()
2284 {
2285  return getElementNames( false );
2286 }
2287 
2288 sal_Bool SAL_CALL ScDPMembers::hasByName( const OUString& aName )
2289 {
2290  return ( GetIndexFromName( aName ) >= 0 );
2291 }
2292 
2294 {
2296 }
2297 
2299 {
2300  return ( getCount() > 0 );
2301 }
2302 
2303 // end of XNameAccess implementation
2304 
2305 // XMembersAccess implementation
2306 
2307 uno::Sequence<OUString> SAL_CALL ScDPMembers::getLocaleIndependentElementNames()
2308 {
2309  return getElementNames( true );
2310 }
2311 
2312 // end of XMembersAccess implementation
2313 
2314 uno::Sequence<OUString> ScDPMembers::getElementNames( bool bLocaleIndependent ) const
2315 {
2316  // Return list of names in sorted order,
2317  // so it's displayed in that order in the field options dialog.
2318  // Sorting is done at the level object (parent of this).
2319 
2320  ScDPLevel* pLevel = pSource->GetDimensionsObject()->getByIndex(nDim)->
2321  GetHierarchiesObject()->getByIndex(nHier)->GetLevelsObject()->getByIndex(nLev);
2322  pLevel->EvaluateSortOrder();
2323  const std::vector<sal_Int32>& rGlobalOrder = pLevel->GetGlobalOrder();
2324  bool bSort = !rGlobalOrder.empty();
2325 
2326  long nCount = getCount();
2327  uno::Sequence<OUString> aSeq(nCount);
2328  OUString* pArr = aSeq.getArray();
2329  for (long i=0; i<nCount; i++)
2330  pArr[i] = getByIndex(bSort ? rGlobalOrder[i] : i)->GetNameStr( bLocaleIndependent);
2331  return aSeq;
2332 }
2333 
2335 {
2336  // used in lcl_CountMinMembers
2337 
2338  long nVisCount = 0;
2339  if (!maMembers.empty())
2340  {
2341  nVisCount = std::count_if(maMembers.begin(), maMembers.end(), [](const rtl::Reference<ScDPMember>& pMbr) {
2342  // count only visible with details (default is true for both)
2343  return !pMbr || (pMbr->isVisible() && pMbr->getShowDetails()); });
2344  }
2345  else
2346  nVisCount = nMbrCount; // default for all
2347 
2348  return nVisCount;
2349 }
2350 
2352 {
2353  // result of GetColumnEntries must not change between ScDPMembers ctor
2354  // and all calls to getByIndex
2355 
2356  if ( nIndex >= 0 && nIndex < nMbrCount )
2357  {
2358  if (maMembers.empty())
2359  maMembers.resize(nMbrCount);
2360 
2361  if (!maMembers[nIndex])
2362  {
2364  long nSrcDim = pSource->GetSourceDim( nDim );
2365  if ( pSource->IsDataLayoutDimension(nSrcDim) )
2366  {
2367  // empty name (never shown, not used for lookup)
2368  pNew.set(new ScDPMember(pSource, nDim, nHier, nLev, 0));
2369  }
2370  else if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) )
2371  {
2372  sal_Int32 nGroupBy = 0;
2373  sal_Int32 nVal = 0;
2374  OUString aName;
2375 
2376  if ( nLev == SC_DAPI_LEVEL_YEAR ) // YEAR is in both hierarchies
2377  {
2378  //TODO: cache year range here!
2379 
2380  double fFirstVal = pSource->GetData()->GetMemberByIndex( nSrcDim, 0 )->GetValue();
2381  long nFirstYear = pSource->GetData()->GetDatePart(
2382  static_cast<long>(::rtl::math::approxFloor( fFirstVal )),
2383  nHier, nLev );
2384 
2385  nVal = nFirstYear + nIndex;
2386  }
2388  {
2389  nVal = nIndex; // DayOfWeek is 0-based
2391  css::i18n::CalendarDisplayIndex::DAY,
2392  sal::static_int_cast<sal_Int16>(nVal), 0 );
2393  }
2395  {
2396  nVal = nIndex; // Month is 0-based
2398  css::i18n::CalendarDisplayIndex::MONTH,
2399  sal::static_int_cast<sal_Int16>(nVal), 0 );
2400  }
2401  else
2402  nVal = nIndex + 1; // Quarter, Day, Week are 1-based
2403 
2404  switch (nLev)
2405  {
2406  case SC_DAPI_LEVEL_YEAR:
2407  nGroupBy = sheet::DataPilotFieldGroupBy::YEARS;
2408  break;
2409  case SC_DAPI_LEVEL_QUARTER:
2410  case SC_DAPI_LEVEL_WEEK:
2411  nGroupBy = sheet::DataPilotFieldGroupBy::QUARTERS;
2412  break;
2413  case SC_DAPI_LEVEL_MONTH:
2414  case SC_DAPI_LEVEL_WEEKDAY:
2415  nGroupBy = sheet::DataPilotFieldGroupBy::MONTHS;
2416  break;
2417  case SC_DAPI_LEVEL_DAY:
2418  nGroupBy = sheet::DataPilotFieldGroupBy::DAYS;
2419  break;
2420  default:
2421  ;
2422  }
2423  if (aName.isEmpty())
2424  aName = OUString::number(nVal);
2425 
2426  ScDPItemData aData(nGroupBy, nVal);
2427  SCROW nId = pSource->GetCache()->GetIdByItemData(nDim, aData);
2428  pNew.set(new ScDPMember(pSource, nDim, nHier, nLev, nId));
2429  }
2430  else
2431  {
2432  const std::vector<SCROW>& memberIndexs = pSource->GetData()->GetColumnEntries(nSrcDim);
2433  pNew.set(new ScDPMember(pSource, nDim, nHier, nLev, memberIndexs[nIndex]));
2434  }
2435  maMembers[nIndex] = pNew;
2436  }
2437 
2438  return maMembers[nIndex].get();
2439  }
2440 
2441  return nullptr; //TODO: exception?
2442 }
2443 
2445  ScDPSource* pSrc, long nD, long nH, long nL, SCROW nIndex) :
2446  pSource( pSrc ),
2447  nDim( nD ),
2448  nHier( nH ),
2449  nLev( nL ),
2450  mnDataId( nIndex ),
2451  nPosition( -1 ),
2452  bVisible( true ),
2453  bShowDet( true )
2454 {
2455  //TODO: hold pSource
2456 }
2457 
2459 {
2460  //TODO: release pSource
2461 }
2462 
2463 bool ScDPMember::IsNamedItem(SCROW nIndex) const
2464 {
2465  long nSrcDim = pSource->GetSourceDim( nDim );
2466  if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) )
2467  {
2468  const ScDPItemData* pData = pSource->GetCache()->GetItemDataById(nDim, nIndex);
2469  if (pData->IsValue())
2470  {
2471  long nComp = pSource->GetData()->GetDatePart(
2472  static_cast<long>(::rtl::math::approxFloor( pData->GetValue() )),
2473  nHier, nLev );
2474  // fValue is converted from integer, so simple comparison works
2475  const ScDPItemData* pData2 = GetItemData();
2476  return pData2 && nComp == pData2->GetValue();
2477  }
2478  }
2479 
2480  return nIndex == mnDataId;
2481 }
2482 
2483 sal_Int32 ScDPMember::Compare( const ScDPMember& rOther ) const
2484 {
2485  if ( nPosition >= 0 )
2486  {
2487  if ( rOther.nPosition >= 0 )
2488  {
2489  OSL_ENSURE( nPosition != rOther.nPosition, "same position for two members" );
2490  return ( nPosition < rOther.nPosition ) ? -1 : 1;
2491  }
2492  else
2493  {
2494  // only this has a position - members with specified positions come before those without
2495  return -1;
2496  }
2497  }
2498  else if ( rOther.nPosition >= 0 )
2499  {
2500  // only rOther has a position
2501  return 1;
2502  }
2503 
2504  // no positions set - compare names
2505  return pSource->GetData()->Compare( pSource->GetSourceDim(nDim),mnDataId,rOther.GetItemDataId());
2506 }
2507 
2509 {
2510  //TODO: handle date hierarchy...
2511 
2512  const ScDPItemData* pData = GetItemData();
2513  return (pData ? *pData : ScDPItemData());
2514 }
2515 
2516 const std::optional<OUString> & ScDPMember::GetLayoutName() const
2517 {
2518  return mpLayoutName;
2519 }
2520 
2521 OUString ScDPMember::GetNameStr( bool bLocaleIndependent ) const
2522 {
2523  const ScDPItemData* pData = GetItemData();
2524  if (pData)
2525  return pSource->GetData()->GetFormattedString(nDim, *pData, bLocaleIndependent);
2526  return OUString();
2527 }
2528 
2529 OUString SAL_CALL ScDPMember::getName()
2530 {
2531  return GetNameStr( false );
2532 }
2533 
2534 void SAL_CALL ScDPMember::setName( const OUString& /* rNewName */ )
2535 {
2536  OSL_FAIL("not implemented"); //TODO: exception?
2537 }
2538 
2539 // XPropertySet
2540 
2541 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPMember::getPropertySetInfo()
2542 {
2543  SolarMutexGuard aGuard;
2544 
2545  static const SfxItemPropertyMapEntry aDPMemberMap_Impl[] =
2546  {
2547  { OUString(SC_UNO_DP_ISVISIBLE), 0, cppu::UnoType<bool>::get(), 0, 0 },
2548  { OUString(SC_UNO_DP_POSITION), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
2549  { OUString(SC_UNO_DP_SHOWDETAILS), 0, cppu::UnoType<bool>::get(), 0, 0 },
2550  { OUString(SC_UNO_DP_LAYOUTNAME), 0, cppu::UnoType<OUString>::get(), 0, 0 },
2551  { OUString(), 0, css::uno::Type(), 0, 0 }
2552  };
2553  static uno::Reference<beans::XPropertySetInfo> aRef =
2554  new SfxItemPropertySetInfo( aDPMemberMap_Impl );
2555  return aRef;
2556 }
2557 
2558 void SAL_CALL ScDPMember::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
2559 {
2560  if ( aPropertyName == SC_UNO_DP_ISVISIBLE )
2561  bVisible = lcl_GetBoolFromAny(aValue);
2562  else if ( aPropertyName == SC_UNO_DP_SHOWDETAILS )
2563  bShowDet = lcl_GetBoolFromAny(aValue);
2564  else if ( aPropertyName == SC_UNO_DP_POSITION )
2565  aValue >>= nPosition;
2566  else if (aPropertyName == SC_UNO_DP_LAYOUTNAME)
2567  {
2568  OUString aName;
2569  if (aValue >>= aName)
2570  mpLayoutName = aName;
2571  }
2572  else
2573  {
2574  OSL_FAIL("unknown property");
2575  }
2576 }
2577 
2578 uno::Any SAL_CALL ScDPMember::getPropertyValue( const OUString& aPropertyName )
2579 {
2580  uno::Any aRet;
2581  if ( aPropertyName == SC_UNO_DP_ISVISIBLE )
2582  aRet <<= bVisible;
2583  else if ( aPropertyName == SC_UNO_DP_SHOWDETAILS )
2584  aRet <<= bShowDet;
2585  else if ( aPropertyName == SC_UNO_DP_POSITION )
2586  aRet <<= nPosition;
2587  else if (aPropertyName == SC_UNO_DP_LAYOUTNAME)
2588  aRet <<= mpLayoutName ? *mpLayoutName : OUString();
2589  else
2590  {
2591  OSL_FAIL("unknown property");
2592  }
2593  return aRet;
2594 }
2595 
2597 
2598 const ScDPCache* ScDPSource::GetCache()
2599 {
2600  OSL_ENSURE( GetData() , "empty ScDPTableData pointer");
2601  return ( GetData()!=nullptr ) ? &GetData()->GetCacheTable().getCache() : nullptr ;
2602 }
2603 
2605 {
2606  const ScDPItemData* pData = pSource->GetItemDataById(nDim, mnDataId);
2607  SAL_WARN_IF( !pData, "sc.core", "ScDPMember::GetItemData: what data? nDim " << nDim << ", mnDataId " << mnDataId);
2608  return pData;
2609 }
2610 
2611 const ScDPItemData* ScDPSource::GetItemDataById(long nDim, long nId)
2612 {
2613  return GetData()->GetMemberById(nDim, nId);
2614 }
2615 
2617 {
2618  const std::vector< SCROW >& memberIds = pSource->GetData()->GetColumnEntries( nDim );
2619  if ( nIndex >= static_cast<long>(memberIds.size()) || nIndex < 0 )
2620  return nullptr;
2621  SCROW nId = memberIds[ nIndex ];
2622  return pSource->GetItemDataById( nDim, nId );
2623 }
2624 
2625 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void DumpResults() const
OUString getDataDescription()
Definition: dptabsrc.cxx:474
const int nColCount
void SetDupCount(long nNew)
Definition: dptabsrc.cxx:302
virtual const ScDPItemData * GetMemberById(long nDim, long nId)
Definition: dptabdat.cxx:258
#define SC_UNO_DP_LAYOUT
Definition: unonames.hxx:620
com sun star sheet DataPilotSourceHierarchy
Definition: dptabsrc.cxx:73
ScDPDimension * GetDataDimension(long nIndex)
Definition: dptabsrc.cxx:142
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: dptabsrc.cxx:2541
bool SubTotalAllowed(long nColumn)
Definition: dptabsrc.cxx:228
virtual long GetMembersCount(long nDim)
Definition: dptabdat.cxx:241
#define SC_UNO_DP_FIELD_SUBTOTALNAME
Definition: unonames.hxx:612
function is determined automatically.
double getLeafResult(const css::sheet::DataPilotFieldFilter &rFilter) const
ScDPTableData * GetData()
Definition: dptabsrc.hxx:144
virtual ~ScDPMember() override
Definition: dptabsrc.cxx:2458
#define SC_UNO_DP_IGNOREEMPTY
Definition: unonames.hxx:604
sal_Int32 nIndex
ScDPMember * getByIndex(long nIndex) const
Definition: dptabsrc.cxx:2351
bool bVisible
void SetEnableLayout(bool bSet)
Definition: dptabsrc.cxx:1963
long nDim
Definition: dptabsrc.hxx:452
rtl::Reference< ScDPHierarchies > mxHierarchies
Definition: dptabsrc.hxx:268
#define EMPTY_OUSTRING
Definition: global.hxx:214
void FillLevelList(css::sheet::DataPilotFieldOrientation nOrientation, std::vector< ScDPLevel * > &rList)
Definition: dptabsrc.cxx:950
const std::optional< OUString > & GetGrandTotalName() const
Definition: dptabsrc.cxx:115
sal_Int32 nPosition
Definition: dptabsrc.hxx:609
long GetSourceDim(long nDim)
Definition: dptabsrc.cxx:330
ScDPHierarchy(ScDPSource *pSrc, long nD, long nH)
Definition: dptabsrc.cxx:1695
virtual ~ScDPLevel() override
Definition: dptabsrc.cxx:1901
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: dptabsrc.cxx:1796
::std::vector< long > aColLevelDims
Definition: dptabdat.hxx:71
const css::sheet::DataPilotFieldAutoShowInfo & GetAutoShow() const
Definition: dptabsrc.hxx:512
#define SC_UNO_DP_REFVALUE
Definition: unonames.hxx:617
ScDPLevels * GetLevelsObject()
Definition: dptabsrc.cxx:1708
const char aData[]
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: dptabsrc.cxx:1645
void EvaluateSortOrder()
Definition: dptabsrc.cxx:1906
virtual sal_Bool SAL_CALL hasElements() override
Definition: dptabsrc.cxx:1233
void swap(ScDPResultTree &rOther)
std::unique_ptr< ContentProperties > pData
ScGeneralFunction nFunction
Definition: dptabsrc.hxx:269
ScDPDimension(ScDPSource *pSrc, long nD)
Definition: dptabsrc.cxx:1268
ScDPResultTree maFilterSet
void setFunction(ScGeneralFunction nNew)
Definition: dptabsrc.cxx:1332
std::optional< OUString > mpLayoutName
Definition: dptabsrc.hxx:271
std::optional< OUString > mpGrandTotalName
Definition: dptabsrc.hxx:112
ScDPLevel * getByIndex(long nIndex) const
Definition: dptabsrc.cxx:1832
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
The term 'measure' here roughly equals "data dimension" ?
Definition: dptabres.hxx:273
com sun star sheet com sun star sheet static DataPilotSourceHierarcy bool lcl_GetBoolFromAny(const uno::Any &aAny)
Definition: dptabsrc.cxx:84
std::unique_ptr< ScDPResultMember > pRowResRoot
Definition: dptabsrc.hxx:104
ScDPTableData * pData
Definition: dptabsrc.hxx:84
OUString aName
Definition: dptabsrc.hxx:270
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: dptabsrc.cxx:2116
bool mbHasHiddenMember
Definition: dptabsrc.hxx:280
virtual void SAL_CALL refresh() override
Definition: dptabsrc.cxx:418
ScDPHierarchy * getByIndex(long nIndex) const
Definition: dptabsrc.cxx:1671
long getCount() const
Definition: dptabsrc.cxx:1240
#define SC_UNO_DP_COLGRAND
Definition: unonames.hxx:587
#define SC_UNO_DP_SORTING
Definition: unonames.hxx:618
ScDPLevels(ScDPSource *pSrc, long nD, long nH)
Definition: dptabsrc.cxx:1748
sal_Int64 n
virtual void CalcResults(CalcInfo &rInfo, bool bAutoShow)=0
const css::sheet::DataPilotFieldReference & GetReferenceValue() const
Definition: dptabsrc.hxx:340
const ScDPCache * GetCache()
Definition: dptabsrc.cxx:2598
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: dptabsrc.cxx:1113
virtual long GetColumnCount()=0
use (new) typed collection instead of ScStrCollection or separate Str and ValueCollection ...
Member names that are being processed for InitFrom/LateInitFrom (needed for initialization of grouped...
Definition: dptabres.hxx:56
sal_Int16 nId
const ContentProperties & rData
virtual void GetDrillDownData(const std::vector< ScDPFilteredCache::Criterion > &rCriteria, const std::unordered_set< sal_Int32 > &rCatDims, css::uno::Sequence< css::uno::Sequence< css::uno::Any > > &rData)=0
void GetCategoryDimensionIndices(std::unordered_set< sal_Int32 > &rCatDims)
Compile a list of dimension indices that are either, column, row or page dimensions (i...
Definition: dptabsrc.cxx:659
ScDPMembers * GetMembersObject()
Definition: dptabsrc.cxx:1968
std::unique_ptr< css::uno::Sequence< css::sheet::MemberResult >[]> pColResults
Definition: dptabsrc.hxx:105
void SetOrientation(long nColumn, css::sheet::DataPilotFieldOrientation nNew)
Definition: dptabsrc.cxx:239
#define SC_MINCOUNT_LIMIT
Definition: dptabsrc.cxx:66
numerical values are counted.
#define SC_UNO_DP_REPEATEMPTY
Definition: unonames.hxx:605
#define SC_UNO_DP_FUNCTION
Definition: unonames.hxx:594
#define SC_UNO_DP_POSITION
Definition: unonames.hxx:593
sum of all numerical values is calculated.
std::vector< long > maDataDims
Definition: dptabsrc.hxx:90
long nMbrCount
Definition: dptabsrc.hxx:557
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: dptabsrc.cxx:1635
bool bPageFiltered
Definition: dptabsrc.hxx:110
const SCCOL MAXCOLCOUNT
Definition: address.hxx:64
This class represents the cached data part of the datapilot cache table implementation.
Definition: dpcache.hxx:47
css::sheet::DataPilotFieldLayoutInfo aLayoutInfo
Definition: dptabsrc.hxx:459
#define SC_UNO_DP_FILTER
Definition: unonames.hxx:597
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: dptabsrc.cxx:2087
virtual sal_Bool SAL_CALL hasElements() override
Definition: dptabsrc.cxx:2298
int nDimCount
virtual void SAL_CALL setName(const OUString &aName) override
Definition: dptabsrc.cxx:1316
const css::uno::Sequence< css::sheet::MemberResult > * GetMemberResults(const ScDPLevel *pLevel)
Definition: dptabsrc.cxx:1043
static long lcl_CountMinMembers(const vector< ScDPDimension * > &ppDim, const vector< ScDPLevel * > &ppLevel, long nLevels)
Definition: dptabsrc.cxx:532
#define SC_UNO_DP_GRANDTOTAL_NAME
Definition: unonames.hxx:613
const ValuesType * getResults(const css::uno::Sequence< css::sheet::DataPilotFieldFilter > &rFilters) const
const ScDPItemData & GetSelectedData()
Definition: dptabsrc.cxx:1357
ScDPDimension * AddDuplicated(const OUString &rNewName)
move to ScDPResultData
Definition: dptabsrc.cxx:307
::std::vector< ScDPDimension * > aColDims
Definition: dptabdat.hxx:72
NF_PERCENT_DEC2
long getMinMembers() const
Definition: dptabsrc.cxx:2334
long nHier
Definition: dptabsrc.hxx:603
virtual OUString getDimensionName(long nColumn)=0
exports com.sun.star. sheet
#define SC_UNO_DP_ORIGINAL
Definition: unonames.hxx:589
const ScDPItemData * GetSrcItemDataByIndex(SCROW nIndex)
Definition: dptabsrc.cxx:2616
NAME
std::vector< long > maRowDims
Definition: dptabsrc.hxx:89
#define SC_UNO_DP_LAYOUTNAME
Definition: unonames.hxx:611
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: dptabsrc.cxx:1219
rtl::Reference< ScDPDimensions > pDimensions
Definition: dptabsrc.hxx:85
::std::vector< sal_Int32 > aGlobalOrder
Definition: dptabsrc.hxx:461
const ScDPItemData * GetItemDataById(long nDim, long nId)
Definition: dptabsrc.cxx:2611
#define SC_UNO_DP_SUBTOTAL
Definition: unonames.hxx:598
const std::optional< OUString > & GetSubtotalName() const
Definition: dptabsrc.cxx:1298
virtual OUString SAL_CALL getName() override
Definition: dptabsrc.cxx:1991
long getCount() const
Definition: dptabsrc.hxx:582
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: dptabsrc.cxx:2558
bool HasSelectedPage() const
Definition: dptabsrc.hxx:337
virtual ~ScDPHierarchy() override
Definition: dptabsrc.cxx:1703
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
MembersType maMembers
Definition: dptabsrc.hxx:558
std::optional< OUString > mpSubtotalName
Definition: dptabsrc.hxx:272
ScDPDimensions * GetDimensionsObject()
Definition: dptabsrc.cxx:288
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: dptabsrc.cxx:1090
ScDPSource(ScDPTableData *pD)
Definition: dptabsrc.cxx:90
bool bRowGrand
Definition: dptabsrc.hxx:95
multi-item (group) filter.
ScGeneralFunction getFunction() const
Definition: dptabsrc.hxx:333
int nCount
virtual void CreateCacheTable()=0
SCROW mnDataId
Definition: dptabsrc.hxx:606
ScDPDimension * getByIndex(long nIndex) const
Definition: dptabsrc.cxx:1247
long GetDimension() const
Definition: dptabsrc.hxx:288
ScDPDimension * CreateCloneObject()
Definition: dptabsrc.cxx:1337
virtual bool getIsDataLayoutDimension(long nColumn)=0
virtual OUString SAL_CALL getName() override
Definition: dptabsrc.cxx:1308
virtual ~ScDPDimension() override
Definition: dptabsrc.cxx:1279
virtual css::uno::Type SAL_CALL getElementType() override
Definition: dptabsrc.cxx:2293
virtual ~ScDPDimensions() override
Definition: dptabsrc.cxx:1166
std::shared_ptr< FilterBase > mpFilter
virtual void SetEmptyFlags(bool bIgnoreEmptyRows, bool bRepeatIfEmpty)=0
const ScDPItemData * GetMemberByIndex(long nDim, long nIndex)
Definition: dptabdat.cxx:248
#define SC_UNO_DP_ROWFIELDCOUNT
Definition: unonames.hxx:608
virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL getDimensions() override
Definition: dptabsrc.cxx:297
long nLevCount
Definition: dptabsrc.hxx:417
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: dptabsrc.cxx:2283
const ::std::vector< sal_Int32 > & GetGlobalOrder() const
Definition: dptabsrc.hxx:517
css::sheet::DataPilotFieldAutoShowInfo aAutoShowInfo
Definition: dptabsrc.hxx:458
#define SC_UNO_DP_REPEATITEMLABELS
Definition: unonames.hxx:601
void FillCalcInfo(bool bIsRow, ScDPTableData::CalcInfo &rInfo, bool &bHasAutoShow)
Definition: dptabsrc.cxx:593
::std::vector< ScDPLevel * > aColLevels
Definition: dptabdat.hxx:73
long GetDatePart(long nDateVal, long nHierarchy, long nLevel)
Definition: dptabdat.cxx:57
indexes when calculating running totals
Definition: dptabres.hxx:105
virtual void SAL_CALL setName(const OUString &aName) override
Definition: dptabsrc.cxx:2534
#define SC_DAPI_QUARTER_LEVELS
Definition: dptabdat.hxx:36
::std::vector< long > aRowLevelDims
Definition: dptabdat.hxx:74
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: dptabsrc.cxx:2288
::std::vector< ScDPDimension * > aRowDims
Definition: dptabdat.hxx:75
bool bShowDet
Definition: dptabsrc.hxx:611
virtual void SAL_CALL setName(const OUString &aName) override
Definition: dptabsrc.cxx:1743
css::sheet::DataPilotFieldOrientation GetDataLayoutOrientation()
Definition: dptabsrc.cxx:278
std::optional< OUString > mpLayoutName
Definition: dptabsrc.hxx:607
virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL getLevels() override
Definition: dptabsrc.cxx:1717
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: dptabsrc.cxx:1620
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
virtual ~ScDPLevels() override
Definition: dptabsrc.cxx:1774
SC_SIMPLE_SERVICE_INFO_COMPAT(ScDPHierarchies,"ScDPHierarchies","com.sun.star.sheet.DataPilotSourceHierarchies","com.sun.star.sheet.DataPilotSourceHierarcies") SC_SIMPLE_SERVICE_INFO_COMPAT(ScDPHierarchy
virtual void DisposeData()=0
std::unique_ptr< rtl::Reference< ScDPLevel >[]> ppLevs
Definition: dptabsrc.hxx:419
int i
This structure stores dimension information used when calculating results.
Definition: dptabdat.hxx:69
virtual ~ScDPHierarchies() override
Definition: dptabsrc.cxx:1613
#define SC_DAPI_HIERARCHY_WEEK
Definition: dptabdat.hxx:33
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: dptabsrc.cxx:2066
virtual css::uno::Type SAL_CALL getElementType() override
Definition: dptabsrc.cxx:1228
long nLev
Definition: dptabsrc.hxx:454
#define SC_DAPI_LEVEL_YEAR
Definition: dptabdat.hxx:39
std::unique_ptr< ScDPResultMember > pColResRoot
Definition: dptabsrc.hxx:103
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: dptabsrc.cxx:2269
std::unique_ptr< rtl::Reference< ScDPHierarchy >[]> ppHiers
Definition: dptabsrc.hxx:354
static SC_DLLPUBLIC OUString getSourceDimensionName(const OUString &rName)
Definition: dputil.cxx:64
sal_uInt32 GetNumberFormatByIdx(NfIndexTableOffset)
Definition: dpshttab.cxx:138
#define SC_DAPI_LEVEL_QUARTER
Definition: dptabdat.hxx:40
virtual OUString SAL_CALL getName() override
Definition: dptabsrc.cxx:2529
std::unique_ptr< css::uno::Sequence< css::sheet::MemberResult >[]> pRowResults
Definition: dptabsrc.hxx:106
#define SC_DAPI_LEVEL_DAY
Definition: dptabdat.hxx:42
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
#define SC_DAPI_WEEK_LEVELS
Definition: dptabdat.hxx:37
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: dptabsrc.cxx:1193
virtual long Compare(long nDim, long nDataId1, long nDataId2)
Definition: dptabdat.cxx:274
SCROW GetItemDataId() const
Definition: dptabsrc.hxx:622
unsigned char sal_Bool
bool bEnableLayout
Definition: dptabsrc.hxx:465
std::vector< long > maColDims
Definition: dptabsrc.hxx:88
#define SC_DAPI_LEVEL_MONTH
Definition: dptabdat.hxx:41
void FilterCacheByPageDimensions()
Set visibilities of individual rows in the cache table based on the page field data.
Definition: dptabsrc.cxx:671
ScDPResultMember * pColRoot
Definition: dptabdat.hxx:81
void FillMemberResults()
Definition: dptabsrc.cxx:1000
void setIgnoreEmptyRows(bool bSet)
???
Definition: dptabsrc.cxx:490
css::uno::Type const & get()
#define SC_DAPI_HIERARCHY_FLAT
Definition: dptabdat.hxx:31
#define SC_SIMPLE_SERVICE_INFO(ClassName, ClassNameAscii, ServiceAscii)
Definition: miscuno.hxx:64
virtual void SAL_CALL removeRefreshListener(const css::uno::Reference< css::util::XRefreshListener > &l) override
Definition: dptabsrc.cxx:428
#define SC_UNO_DP_AUTOSHOW
Definition: unonames.hxx:619
#define SC_UNO_DP_COLUMNFIELDCOUNT
Definition: unonames.hxx:609
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: dptabsrc.cxx:1423
ScDPItemData FillItemData() const
Definition: dptabsrc.cxx:2508
css::uno::Sequence< sal_Int16 > getSubTotals() const
Definition: dptabsrc.cxx:2053
ScDPLevel(ScDPSource *pSrc, long nD, long nH, long nL)
Definition: dptabsrc.cxx:1885
css::sheet::DataPilotFieldReference aReferenceValue
Definition: dptabsrc.hxx:275
virtual OUString SAL_CALL getName() override
Definition: dptabsrc.cxx:1722
#define SC_UNO_DP_HAS_HIDDEN_MEMBER
Definition: unonames.hxx:614
long getCount() const
Definition: dptabsrc.cxx:1827
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: dptabsrc.cxx:1781
virtual bool IsDateDimension(long nDim)=0
long nHier
Definition: dptabsrc.hxx:453
void fillFieldFilters(::std::vector< ScDPFilteredCache::Criterion > &rFilters) const
Definition: dptabres.cxx:3907
const long LONG_MAX
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: dptabsrc.cxx:1806
#define SC_IMPL_DUMMY_PROPERTY_LISTENER(ClassName)
Definition: miscuno.hxx:73
#define SC_DAPI_LEVEL_WEEKDAY
Definition: dptabdat.hxx:44
NF_NUMBER_SYSTEM
css::sheet::DataPilotFieldSortInfo aSortInfo
Definition: dptabsrc.hxx:457
OUString getDisplayName(sal_Int16 nCalendarDisplayIndex, sal_Int16 nIdx, sal_Int16 nNameType) const
#define SC_UNO_DP_ROWGRAND
Definition: unonames.hxx:588
OUString GetDataDimName(long nIndex)
Definition: dptabsrc.cxx:151
std::vector< double > ValuesType
Definition: dpresfilter.hxx:53
#define SC_UNO_DP_DATAFIELDCOUNT
Definition: unonames.hxx:610
#define SC_UNO_DP_FLAGS
Definition: unonames.hxx:615
SCROW GetIdByItemData(long nDim, const ScDPItemData &rItem) const
Definition: dpcache.cxx:1125
#define SC_UNO_DP_ORIENTATION
Definition: unonames.hxx:592
median of all numerical values is calculated.
::std::vector< long > aPageDims
Definition: dptabdat.hxx:77
#define SC_UNO_DP_ORIGINAL_POS
Definition: unonames.hxx:590
bool empty() const
long GetPosition(long nColumn)
Definition: dptabsrc.cxx:160
#define SC_UNO_DP_SHOWEMPTY
Definition: unonames.hxx:600
std::unique_ptr< rtl::Reference< ScDPDimension >[]> ppDims
Definition: dptabsrc.hxx:233
std::vector< ScDPLevel * > aColLevelList
Definition: dptabsrc.hxx:107
virtual css::uno::Sequence< css::uno::Sequence< css::sheet::DataResult > > SAL_CALL getResults() override
Definition: dptabsrc.cxx:351
Base class that abstracts different data source types of a datapilot table.
Definition: dptabdat.hxx:56
sal_Int32 SCROW
Definition: types.hxx:18
void setRepeatIfEmpty(bool bSet)
Definition: dptabsrc.cxx:496
virtual css::uno::Sequence< double > SAL_CALL getFilteredResults(const css::uno::Sequence< css::sheet::DataPilotFieldFilter > &aFilters) override
Definition: dptabsrc.cxx:385
rtl::Reference< ScDPMembers > mxMembers
Definition: dptabsrc.hxx:455
single filtering criterion.
std::vector< long > maPageDims
Definition: dptabsrc.hxx:91
bool bRepeatItemLabels
Definition: dptabsrc.hxx:466
bool IsNamedItem(SCROW nIndex) const
Definition: dptabsrc.cxx:2463
static CalendarWrapper * GetCalendar()
Definition: global.cxx:1027
sal_Int32 Compare(const ScDPMember &rOther) const
Definition: dptabsrc.cxx:2483
bool bRepeatIfEmpty
Definition: dptabsrc.hxx:97
std::vector< ScDPLevel * > aRowLevelList
Definition: dptabsrc.hxx:108
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: dptabsrc.cxx:1395
bool bShowEmpty
Definition: dptabsrc.hxx:464
ScDPInitState * pInitState
Definition: dptabdat.hxx:80
#define SC_UNO_DP_USEDHIERARCHY
Definition: unonames.hxx:596
#define SAL_WARN_IF(condition, area, stream)
sal_Int32 GetIndexFromName(const OUString &rName) const
Definition: dptabsrc.cxx:2251
virtual void SAL_CALL setName(const OUString &aName) override
Definition: dptabsrc.cxx:2048
#define SC_UNO_DP_DATADESC
Definition: unonames.hxx:606
virtual sal_Bool SAL_CALL hasElements() override
Definition: dptabsrc.cxx:1659
virtual css::uno::Sequence< OUString > SAL_CALL getLocaleIndependentElementNames() override
Definition: dptabsrc.cxx:2307
ScGeneralFunction
the css::sheet::GeneralFunction enum is extended by constants in GeneralFunction2, which causes some type-safety issues.
OUString aName
bool bResultOverflow
Definition: dptabsrc.hxx:109
bool IsDataLayoutDimension(long nDim)
Definition: dptabsrc.cxx:273
This class collects visible members of each dimension and uses that information to create filtering c...
Definition: dptabres.hxx:650
#define SC_UNO_DP_ISVISIBLE
Definition: unonames.hxx:602
OUString GetFormattedString(long nDim, const ScDPItemData &rItem, bool bLocaleIndependent) const
Definition: dptabdat.cxx:51
virtual css::uno::Type SAL_CALL getElementType() override
Definition: dptabsrc.cxx:1815
all values, including non-numerical values, are counted.
bool HasStringData() const
Definition: dpitemdata.cxx:366
nothing is calculated.
static long getCount()
Definition: dptabsrc.cxx:1666
virtual ~ScDPMembers() override
Definition: dptabsrc.cxx:2245
virtual sal_uInt32 GetNumberFormat(long nDim)
Definition: dptabdat.cxx:107
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: dptabsrc.cxx:2578
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: dptabsrc.cxx:1067
virtual void FilterCacheTable(const std::vector< ScDPFilteredCache::Criterion > &rCriteria, const std::unordered_set< sal_Int32 > &rDataDims)=0
ScDPResultTree maResFilterSet
Definition: dptabsrc.hxx:92
double GetValue() const
Definition: dpitemdata.cxx:347
Sequence< sal_Int8 > aSeq
virtual sal_Bool SAL_CALL hasElements() override
Definition: dptabsrc.cxx:1820
virtual css::uno::Reference< css::sheet::XMembersAccess > SAL_CALL getMembers() override
Definition: dptabsrc.cxx:1977
bool bColumnGrand
Definition: dptabsrc.hxx:94
OUString GetNameStr(bool bLocaleIndependent) const
Definition: dptabsrc.cxx:2521
virtual void SAL_CALL addRefreshListener(const css::uno::Reference< css::util::XRefreshListener > &l) override
Definition: dptabsrc.cxx:423
bool IsValue() const
Definition: dpitemdata.cxx:322
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: dptabsrc.cxx:1209
::std::vector< ScDPLevel * > aRowLevels
Definition: dptabdat.hxx:76
virtual ~ScDPSource() override
Definition: dptabsrc.cxx:103
css::uno::Sequence< sal_Int16 > aSubTotals
Definition: dptabsrc.hxx:456
virtual const std::vector< SCROW > & GetColumnEntries(long nColumn)
Definition: dptabdat.cxx:263
bool getIsDataLayoutDimension() const
Definition: dptabsrc.cxx:1327
::std::vector< long > aDataSrcCols
Definition: dptabdat.hxx:78
#define SC_DAPI_LEVEL_WEEK
Definition: dptabdat.hxx:43
#define SAL_WARN(area, stream)
ScDPResultMember * pRowRoot
Definition: dptabdat.hxx:82
bool IsDateDimension(long nDim)
Definition: dptabsrc.cxx:283
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: dptabsrc.cxx:1505
long nHier
Definition: dptabsrc.hxx:416
long nAutoMeasure
Definition: dptabsrc.hxx:463
bool bIgnoreEmptyRows
Definition: dptabsrc.hxx:96
#define SC_UNO_DP_SHOWDETAILS
Definition: unonames.hxx:603
detail::Optional< bool >::type tryAccess< bool >(css::uno::Any const &any)
sal_Int32 nLength
#define SC_DAPI_FLAT_LEVELS
Definition: dptabdat.hxx:35
#define SC_UNO_DP_ISDATALAYOUT
Definition: unonames.hxx:591
static long getUsedHierarchy()
Definition: dptabsrc.hxx:335
const ScDPItemData * GetItemDataById(long nDim, SCROW nId) const
Definition: dpcache.cxx:986
virtual css::uno::Type SAL_CALL getElementType() override
Definition: dptabsrc.cxx:1654
ScDPHierarchies * GetHierarchiesObject()
Definition: dptabsrc.cxx:1284
std::unique_ptr< ScDPItemData > pSelectedData
Definition: dptabsrc.hxx:279
rtl::Reference< ScDPLevels > mxLevels
Definition: dptabsrc.hxx:387
long GetDupCount() const
Definition: dptabsrc.hxx:169
const std::optional< OUString > & GetLayoutName() const
Definition: dptabsrc.cxx:2516
virtual css::uno::Sequence< css::uno::Sequence< css::uno::Any > > SAL_CALL getDrillDownData(const css::uno::Sequence< css::sheet::DataPilotFieldFilter > &aFilters) override
Definition: dptabsrc.cxx:433
void CountChanged()
Definition: dptabsrc.cxx:1171
ScDPHierarchy
Definition: dptabsrc.cxx:73
virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override
Definition: dptabsrc.cxx:1352
void disposeData()
Definition: dptabsrc.cxx:502
#define SC_DAPI_HIERARCHY_QUARTER
Definition: dptabdat.hxx:32
bool bHasSelectedPage
Definition: dptabsrc.hxx:276
ScDPMembersHashMap aHashMap
Definition: dptabsrc.hxx:559
#define SC_UNO_DP_SUBTOTAL2
Definition: unonames.hxx:599
virtual css::uno::Reference< css::container::XNameAccess > SAL_CALL getHierarchies() override
Definition: dptabsrc.cxx:1303
long GetSourceDim() const
Definition: dptabsrc.hxx:289
#define SC_UNO_DP_NUMBERFO
Definition: unonames.hxx:607
void AddMember(long nSourceIndex, SCROW nMember)
Definition: dptabres.cxx:255
long nDupCount
Definition: dptabsrc.hxx:99
void CreateRes_Impl()
Definition: dptabsrc.cxx:735
css::sheet::DataPilotFieldOrientation getOrientation() const
Definition: dptabsrc.cxx:1322
const ScDPItemData * GetItemData() const
Definition: dptabsrc.cxx:2604
bool bVisible
Definition: dptabsrc.hxx:610
sal_uInt16 nPos
static SC_DLLPUBLIC ScSubTotalFunc toSubTotalFunc(ScGeneralFunction eGenFunc)
Definition: dputil.cxx:405
long nSortMeasure
Definition: dptabsrc.hxx:462
ScDPMember(ScDPSource *pSrc, long nD, long nH, long nL, SCROW nIndex)
Definition: dptabsrc.cxx:2444
css::sheet::DataPilotFieldOrientation GetOrientation(long nColumn)
Definition: dptabsrc.cxx:120
OUString aSelectedPage
Definition: dptabsrc.hxx:277
const bool READONLY
static const long nHierCount
Definition: dptabsrc.hxx:352
std::unique_ptr< ScDPResultData > pResData
Definition: dptabsrc.hxx:102
long GetDataDimensionCount() const
Definition: dptabsrc.cxx:137
bool isVisible() const
Definition: dptabsrc.hxx:655
const std::optional< OUString > & GetLayoutName() const
Definition: dptabsrc.cxx:1293
virtual css::uno::Sequence< css::sheet::MemberResult > SAL_CALL getResults() override
Definition: dptabsrc.cxx:1982