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