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