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