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