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