xref: /aoo42x/main/sc/source/core/data/dpobject.cxx (revision 86e1cf34)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10b3f79822SAndrew Rist  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19b3f79822SAndrew Rist  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "dpobject.hxx"
32cdf0e10cSrcweir #include "dptabsrc.hxx"
33cdf0e10cSrcweir #include "dpsave.hxx"
34cdf0e10cSrcweir #include "dpdimsave.hxx"
35cdf0e10cSrcweir #include "dpoutput.hxx"
36cdf0e10cSrcweir #include "dpshttab.hxx"
37cdf0e10cSrcweir #include "dpsdbtab.hxx"
38cdf0e10cSrcweir #include "dpgroup.hxx"
39cdf0e10cSrcweir #include "document.hxx"
40cdf0e10cSrcweir #include "rechead.hxx"
41cdf0e10cSrcweir #include "pivot.hxx"		// PIVOT_DATA_FIELD
42cdf0e10cSrcweir #include "dapiuno.hxx"		// ScDataPilotConversion
43cdf0e10cSrcweir #include "miscuno.hxx"
44cdf0e10cSrcweir #include "scerrors.hxx"
45cdf0e10cSrcweir #include "refupdat.hxx"
46cdf0e10cSrcweir #include "scresid.hxx"
47cdf0e10cSrcweir #include "sc.hrc"
48cdf0e10cSrcweir #include "attrib.hxx"
49cdf0e10cSrcweir #include "scitems.hxx"
50cdf0e10cSrcweir #include "unonames.hxx"
51cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
52cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
53cdf0e10cSrcweir #include "dpglobal.hxx"
54cdf0e10cSrcweir #include "globstr.hrc"
55cdf0e10cSrcweir // End Comments
56cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
57cdf0e10cSrcweir #include <com/sun/star/sheet/GeneralFunction.hpp>
58cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
59cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
60cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
61cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
62cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
63cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
64cdf0e10cSrcweir #include <com/sun/star/sheet/DimensionFlags.hpp>
65cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
66cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
67cdf0e10cSrcweir #include <com/sun/star/lang/XSingleComponentFactory.hpp>
68cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
69cdf0e10cSrcweir #include <com/sun/star/container/XContentEnumerationAccess.hpp>
70cdf0e10cSrcweir #include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
71cdf0e10cSrcweir 
72cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
73cdf0e10cSrcweir #include <tools/debug.hxx>
74cdf0e10cSrcweir #include <tools/diagnose_ex.h>
75cdf0e10cSrcweir #include <svl/zforlist.hxx>		// IsNumberFormat
76cdf0e10cSrcweir 
77cdf0e10cSrcweir #include <vector>
78cdf0e10cSrcweir #include <stdio.h>
79cdf0e10cSrcweir 
80cdf0e10cSrcweir using namespace com::sun::star;
81cdf0e10cSrcweir using ::std::vector;
82cdf0e10cSrcweir using ::boost::shared_ptr;
83cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
84cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
85cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY;
86cdf0e10cSrcweir using ::com::sun::star::uno::Any;
87cdf0e10cSrcweir using ::com::sun::star::uno::Exception;
88cdf0e10cSrcweir using ::com::sun::star::lang::XComponent;
89cdf0e10cSrcweir using ::com::sun::star::sheet::DataPilotTableHeaderData;
90cdf0e10cSrcweir using ::com::sun::star::sheet::DataPilotTablePositionData;
91cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySet;
92cdf0e10cSrcweir using ::rtl::OUString;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 
95cdf0e10cSrcweir // -----------------------------------------------------------------------
96cdf0e10cSrcweir 
97cdf0e10cSrcweir #define SCDPSOURCE_SERVICE	"com.sun.star.sheet.DataPilotSource"
98cdf0e10cSrcweir 
99cdf0e10cSrcweir // -----------------------------------------------------------------------
100cdf0e10cSrcweir 
101cdf0e10cSrcweir // incompatible versions of data pilot files
102cdf0e10cSrcweir #define SC_DP_VERSION_CURRENT	6
103cdf0e10cSrcweir 
104cdf0e10cSrcweir // type of source data
105cdf0e10cSrcweir #define SC_DP_SOURCE_SHEET		0
106cdf0e10cSrcweir #define SC_DP_SOURCE_DATABASE	1
107cdf0e10cSrcweir #define SC_DP_SOURCE_SERVICE	2
108cdf0e10cSrcweir 
109cdf0e10cSrcweir // -----------------------------------------------------------------------
110cdf0e10cSrcweir 
111cdf0e10cSrcweir //!	move to a header file
112cdf0e10cSrcweir #define DP_PROP_COLUMNGRAND			"ColumnGrand"
113cdf0e10cSrcweir #define DP_PROP_FUNCTION			"Function"
114cdf0e10cSrcweir #define DP_PROP_IGNOREEMPTY			"IgnoreEmptyRows"
115cdf0e10cSrcweir #define DP_PROP_ISDATALAYOUT		"IsDataLayoutDimension"
116cdf0e10cSrcweir //#define DP_PROP_ISVISIBLE			"IsVisible"
117cdf0e10cSrcweir #define DP_PROP_ORIENTATION			"Orientation"
118cdf0e10cSrcweir #define DP_PROP_ORIGINAL			"Original"
119cdf0e10cSrcweir #define DP_PROP_POSITION			"Position"
120cdf0e10cSrcweir #define DP_PROP_REPEATIFEMPTY		"RepeatIfEmpty"
121cdf0e10cSrcweir #define DP_PROP_ROWGRAND			"RowGrand"
122cdf0e10cSrcweir #define DP_PROP_SHOWDETAILS			"ShowDetails"
123cdf0e10cSrcweir #define DP_PROP_SHOWEMPTY			"ShowEmpty"
124cdf0e10cSrcweir #define DP_PROP_SUBTOTALS			"SubTotals"
125cdf0e10cSrcweir #define DP_PROP_USEDHIERARCHY		"UsedHierarchy"
126cdf0e10cSrcweir 
127cdf0e10cSrcweir // -----------------------------------------------------------------------
128cdf0e10cSrcweir 
lcl_GetDataGetOrientation(const uno::Reference<sheet::XDimensionsSupplier> & xSource)129cdf0e10cSrcweir sal_uInt16 lcl_GetDataGetOrientation( const uno::Reference<sheet::XDimensionsSupplier>& xSource )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir 	long nRet = sheet::DataPilotFieldOrientation_HIDDEN;
132cdf0e10cSrcweir 	if ( xSource.is() )
133cdf0e10cSrcweir 	{
134cdf0e10cSrcweir 		uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
135cdf0e10cSrcweir 		uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
136cdf0e10cSrcweir 		long nIntCount = xIntDims->getCount();
137cdf0e10cSrcweir 		sal_Bool bFound = sal_False;
138cdf0e10cSrcweir 		for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++)
139cdf0e10cSrcweir 		{
140cdf0e10cSrcweir 			uno::Reference<uno::XInterface> xIntDim =
141cdf0e10cSrcweir 				ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) );
142cdf0e10cSrcweir 			uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
143cdf0e10cSrcweir 			if ( xDimProp.is() )
144cdf0e10cSrcweir 			{
145cdf0e10cSrcweir 				bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
146cdf0e10cSrcweir 					rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
147cdf0e10cSrcweir 				//!	error checking -- is "IsDataLayoutDimension" property required??
148cdf0e10cSrcweir 				if (bFound)
149cdf0e10cSrcweir 					nRet = ScUnoHelpFunctions::GetEnumProperty(
150cdf0e10cSrcweir 							xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
151cdf0e10cSrcweir 							sheet::DataPilotFieldOrientation_HIDDEN );
152cdf0e10cSrcweir 			}
153cdf0e10cSrcweir 		}
154cdf0e10cSrcweir 	}
155cdf0e10cSrcweir     return static_cast< sal_uInt16 >( nRet );
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir // -----------------------------------------------------------------------
159cdf0e10cSrcweir 
ScDPObject(ScDocument * pD)160cdf0e10cSrcweir ScDPObject::ScDPObject( ScDocument* pD ) :
161cdf0e10cSrcweir 	pDoc( pD ),
162cdf0e10cSrcweir 	pSaveData( NULL ),
163cdf0e10cSrcweir 	pSheetDesc( NULL ),
164cdf0e10cSrcweir 	pImpDesc( NULL ),
165cdf0e10cSrcweir 	pServDesc( NULL ),
166cdf0e10cSrcweir     mpTableData(static_cast<ScDPTableData*>(NULL)),
167cdf0e10cSrcweir 	pOutput( NULL ),
168cdf0e10cSrcweir 	bSettingsChanged( sal_False ),
169cdf0e10cSrcweir 	bAlive( sal_False ),
170cdf0e10cSrcweir 	bAllowMove( sal_False ),
171cdf0e10cSrcweir 	nHeaderRows( 0 ),
172cdf0e10cSrcweir     mbHeaderLayout(false),
173cdf0e10cSrcweir 	bRefresh( sal_False ), // Wang Xu Ming - DataPilot migration
174cdf0e10cSrcweir     mnCacheId( -1 ), // Wang Xu Ming - DataPilot migration
175cdf0e10cSrcweir     mbCreatingTableData( false )
176cdf0e10cSrcweir {
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
ScDPObject(const ScDPObject & r)179cdf0e10cSrcweir ScDPObject::ScDPObject(const ScDPObject& r) :
180cdf0e10cSrcweir     ScDataObject(),
181cdf0e10cSrcweir 	pDoc( r.pDoc ),
182cdf0e10cSrcweir 	pSaveData( NULL ),
183cdf0e10cSrcweir 	aTableName( r.aTableName ),
184cdf0e10cSrcweir 	aTableTag( r.aTableTag ),
185cdf0e10cSrcweir 	aOutRange( r.aOutRange ),
186cdf0e10cSrcweir 	pSheetDesc( NULL ),
187cdf0e10cSrcweir 	pImpDesc( NULL ),
188cdf0e10cSrcweir 	pServDesc( NULL ),
189cdf0e10cSrcweir     mpTableData(static_cast<ScDPTableData*>(NULL)),
190cdf0e10cSrcweir 	pOutput( NULL ),
191cdf0e10cSrcweir 	bSettingsChanged( sal_False ),
192cdf0e10cSrcweir 	bAlive( sal_False ),
193cdf0e10cSrcweir 	bAllowMove( sal_False ),
194cdf0e10cSrcweir 	nHeaderRows( r.nHeaderRows ),
195cdf0e10cSrcweir     mbHeaderLayout( r.mbHeaderLayout ),
196cdf0e10cSrcweir 	bRefresh( r.bRefresh ), // Wang Xu Ming - DataPilot migration
197cdf0e10cSrcweir     mnCacheId ( r.mnCacheId ), // Wang Xu Ming - DataPilot migration
198cdf0e10cSrcweir     mbCreatingTableData( false )
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	if (r.pSaveData)
201cdf0e10cSrcweir 		pSaveData = new ScDPSaveData(*r.pSaveData);
202cdf0e10cSrcweir 	if (r.pSheetDesc)
203cdf0e10cSrcweir 		pSheetDesc = new ScSheetSourceDesc(*r.pSheetDesc);
204cdf0e10cSrcweir 	if (r.pImpDesc)
205cdf0e10cSrcweir 		pImpDesc = new ScImportSourceDesc(*r.pImpDesc);
206cdf0e10cSrcweir 	if (r.pServDesc)
207cdf0e10cSrcweir 		pServDesc = new ScDPServiceDesc(*r.pServDesc);
208cdf0e10cSrcweir 	// xSource (and pOutput) is not copied
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
~ScDPObject()211cdf0e10cSrcweir ScDPObject::~ScDPObject()
212cdf0e10cSrcweir {
213cdf0e10cSrcweir 	delete pOutput;
214cdf0e10cSrcweir 	delete pSaveData;
215cdf0e10cSrcweir 	delete pSheetDesc;
216cdf0e10cSrcweir 	delete pImpDesc;
217cdf0e10cSrcweir 	delete pServDesc;
218cdf0e10cSrcweir 	mnCacheId = -1; // Wang Xu Ming - DataPilot migration
219cdf0e10cSrcweir     InvalidateSource();
220cdf0e10cSrcweir }
221cdf0e10cSrcweir 
Clone() const222cdf0e10cSrcweir ScDataObject* ScDPObject::Clone() const
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	return new ScDPObject(*this);
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
SetAlive(sal_Bool bSet)227cdf0e10cSrcweir void ScDPObject::SetAlive(sal_Bool bSet)
228cdf0e10cSrcweir {
229cdf0e10cSrcweir 	bAlive = bSet;
230cdf0e10cSrcweir }
231cdf0e10cSrcweir 
SetAllowMove(sal_Bool bSet)232cdf0e10cSrcweir void ScDPObject::SetAllowMove(sal_Bool bSet)
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	bAllowMove = bSet;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir 
SetSaveData(const ScDPSaveData & rData)237cdf0e10cSrcweir void ScDPObject::SetSaveData(const ScDPSaveData& rData)
238cdf0e10cSrcweir {
239cdf0e10cSrcweir     if ( pSaveData != &rData )      // API implementation modifies the original SaveData object
240cdf0e10cSrcweir     {
241cdf0e10cSrcweir         delete pSaveData;
242cdf0e10cSrcweir         pSaveData = new ScDPSaveData( rData );
243cdf0e10cSrcweir         // Wang Xu Ming -- 2009-8-17
244cdf0e10cSrcweir         // DataPilot Migration - Cache&&Performance
245cdf0e10cSrcweir         if ( rData.GetCacheId() >= 0 )
246cdf0e10cSrcweir             mnCacheId = rData.GetCacheId();
247cdf0e10cSrcweir         else if ( mnCacheId >= 0 )
248cdf0e10cSrcweir             pSaveData->SetCacheId( mnCacheId );
249cdf0e10cSrcweir         // End Comments
250cdf0e10cSrcweir     }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 	InvalidateData();		// re-init source from SaveData
253cdf0e10cSrcweir }
254cdf0e10cSrcweir 
SetHeaderLayout(bool bUseGrid)255cdf0e10cSrcweir void ScDPObject::SetHeaderLayout (bool bUseGrid)
256cdf0e10cSrcweir {
257cdf0e10cSrcweir     mbHeaderLayout = bUseGrid;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
GetHeaderLayout() const260cdf0e10cSrcweir bool ScDPObject::GetHeaderLayout() const
261cdf0e10cSrcweir {
262cdf0e10cSrcweir     return mbHeaderLayout;
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
SetOutRange(const ScRange & rRange)265cdf0e10cSrcweir void ScDPObject::SetOutRange(const ScRange& rRange)
266cdf0e10cSrcweir {
267cdf0e10cSrcweir 	aOutRange = rRange;
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 	if ( pOutput )
270cdf0e10cSrcweir 		pOutput->SetPosition( rRange.aStart );
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
SetSheetDesc(const ScSheetSourceDesc & rDesc,bool bFromRefUpdate)273cdf0e10cSrcweir void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate)
274cdf0e10cSrcweir {
275cdf0e10cSrcweir 	if ( pSheetDesc && rDesc == *pSheetDesc )
276cdf0e10cSrcweir 		return;				// nothing to do
277cdf0e10cSrcweir 
278cdf0e10cSrcweir 	DELETEZ( pImpDesc );
279cdf0e10cSrcweir 	DELETEZ( pServDesc );
280cdf0e10cSrcweir 
281cdf0e10cSrcweir     delete pSheetDesc;
282cdf0e10cSrcweir 	pSheetDesc = new ScSheetSourceDesc(rDesc);
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 	//	make valid QueryParam
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 	pSheetDesc->aQueryParam.nCol1 = pSheetDesc->aSourceRange.aStart.Col();
287cdf0e10cSrcweir 	pSheetDesc->aQueryParam.nRow1 = pSheetDesc->aSourceRange.aStart.Row();
288cdf0e10cSrcweir 	pSheetDesc->aQueryParam.nCol2 = pSheetDesc->aSourceRange.aEnd.Col();
289cdf0e10cSrcweir 	pSheetDesc->aQueryParam.nRow2 = pSheetDesc->aSourceRange.aEnd.Row();;
290cdf0e10cSrcweir 	pSheetDesc->aQueryParam.bHasHeader = sal_True;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 	InvalidateSource();		// new source must be created
293cdf0e10cSrcweir     if (!bFromRefUpdate)
294cdf0e10cSrcweir         SetCacheId( -1 );   // #i116504# don't use the same cache ID for a different range (except reference update)
295cdf0e10cSrcweir }
296cdf0e10cSrcweir 
SetImportDesc(const ScImportSourceDesc & rDesc)297cdf0e10cSrcweir void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc)
298cdf0e10cSrcweir {
299cdf0e10cSrcweir 	if ( pImpDesc && rDesc == *pImpDesc )
300cdf0e10cSrcweir 		return;				// nothing to do
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 	DELETEZ( pSheetDesc );
303cdf0e10cSrcweir 	DELETEZ( pServDesc );
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 	delete pImpDesc;
306cdf0e10cSrcweir 	pImpDesc = new ScImportSourceDesc(rDesc);
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 	InvalidateSource();		// new source must be created
309cdf0e10cSrcweir     SetCacheId( -1 );
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
SetServiceData(const ScDPServiceDesc & rDesc)312cdf0e10cSrcweir void ScDPObject::SetServiceData(const ScDPServiceDesc& rDesc)
313cdf0e10cSrcweir {
314cdf0e10cSrcweir 	if ( pServDesc && rDesc == *pServDesc )
315cdf0e10cSrcweir 		return;				// nothing to do
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 	DELETEZ( pSheetDesc );
318cdf0e10cSrcweir 	DELETEZ( pImpDesc );
319cdf0e10cSrcweir 
320cdf0e10cSrcweir 	delete pServDesc;
321cdf0e10cSrcweir 	pServDesc = new ScDPServiceDesc(rDesc);
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 	InvalidateSource();		// new source must be created
324cdf0e10cSrcweir }
325cdf0e10cSrcweir 
WriteSourceDataTo(ScDPObject & rDest) const326cdf0e10cSrcweir void ScDPObject::WriteSourceDataTo( ScDPObject& rDest ) const
327cdf0e10cSrcweir {
328cdf0e10cSrcweir 	if ( pSheetDesc )
329cdf0e10cSrcweir 		rDest.SetSheetDesc( *pSheetDesc );
330cdf0e10cSrcweir 	else if ( pImpDesc )
331cdf0e10cSrcweir 		rDest.SetImportDesc( *pImpDesc );
332cdf0e10cSrcweir 	else if ( pServDesc )
333cdf0e10cSrcweir 		rDest.SetServiceData( *pServDesc );
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 	//	name/tag are not source data, but needed along with source data
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 	rDest.aTableName = aTableName;
338cdf0e10cSrcweir 	rDest.aTableTag  = aTableTag;
339cdf0e10cSrcweir }
340cdf0e10cSrcweir 
WriteTempDataTo(ScDPObject & rDest) const341cdf0e10cSrcweir void ScDPObject::WriteTempDataTo( ScDPObject& rDest ) const
342cdf0e10cSrcweir {
343cdf0e10cSrcweir 	rDest.nHeaderRows = nHeaderRows;
344cdf0e10cSrcweir }
345cdf0e10cSrcweir 
IsSheetData() const346cdf0e10cSrcweir sal_Bool ScDPObject::IsSheetData() const
347cdf0e10cSrcweir {
348cdf0e10cSrcweir 	return ( pSheetDesc != NULL );
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
SetName(const String & rNew)351cdf0e10cSrcweir void ScDPObject::SetName(const String& rNew)
352cdf0e10cSrcweir {
353cdf0e10cSrcweir 	aTableName = rNew;
354cdf0e10cSrcweir }
355cdf0e10cSrcweir 
SetTag(const String & rNew)356cdf0e10cSrcweir void ScDPObject::SetTag(const String& rNew)
357cdf0e10cSrcweir {
358cdf0e10cSrcweir 	aTableTag = rNew;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir 
IsDataDescriptionCell(const ScAddress & rPos)361cdf0e10cSrcweir bool ScDPObject::IsDataDescriptionCell(const ScAddress& rPos)
362cdf0e10cSrcweir {
363cdf0e10cSrcweir     if (!pSaveData)
364cdf0e10cSrcweir         return false;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir     long nDataDimCount = pSaveData->GetDataDimensionCount();
367cdf0e10cSrcweir     if (nDataDimCount != 1)
368cdf0e10cSrcweir         // There has to be exactly one data dimension for the description to
369cdf0e10cSrcweir         // appear at top-left corner.
370cdf0e10cSrcweir         return false;
371cdf0e10cSrcweir 
372cdf0e10cSrcweir     CreateOutput();
373cdf0e10cSrcweir     ScRange aTabRange = pOutput->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE);
374cdf0e10cSrcweir     return (rPos == aTabRange.aStart);
375cdf0e10cSrcweir }
376cdf0e10cSrcweir 
GetSource()377cdf0e10cSrcweir uno::Reference<sheet::XDimensionsSupplier> ScDPObject::GetSource()
378cdf0e10cSrcweir {
379cdf0e10cSrcweir 	CreateObjects();
380cdf0e10cSrcweir 	return xSource;
381cdf0e10cSrcweir }
382cdf0e10cSrcweir 
CreateOutput()383cdf0e10cSrcweir void ScDPObject::CreateOutput()
384cdf0e10cSrcweir {
385cdf0e10cSrcweir 	CreateObjects();
386cdf0e10cSrcweir 	if (!pOutput)
387cdf0e10cSrcweir 	{
388cdf0e10cSrcweir         sal_Bool bFilterButton = IsSheetData() && pSaveData && pSaveData->GetFilterButton();
389cdf0e10cSrcweir         pOutput = new ScDPOutput( pDoc, xSource, aOutRange.aStart, bFilterButton );
390cdf0e10cSrcweir         pOutput->SetHeaderLayout ( mbHeaderLayout );
391cdf0e10cSrcweir 
392cdf0e10cSrcweir 		long nOldRows = nHeaderRows;
393cdf0e10cSrcweir 		nHeaderRows = pOutput->GetHeaderRows();
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 		if ( bAllowMove && nHeaderRows != nOldRows )
396cdf0e10cSrcweir 		{
397cdf0e10cSrcweir 			long nDiff = nOldRows - nHeaderRows;
398cdf0e10cSrcweir 			if ( nOldRows == 0 )
399cdf0e10cSrcweir 				--nDiff;
400cdf0e10cSrcweir 			if ( nHeaderRows == 0 )
401cdf0e10cSrcweir 				++nDiff;
402cdf0e10cSrcweir 
403cdf0e10cSrcweir 			long nNewRow = aOutRange.aStart.Row() + nDiff;
404cdf0e10cSrcweir 			if ( nNewRow < 0 )
405cdf0e10cSrcweir 				nNewRow = 0;
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 			ScAddress aStart( aOutRange.aStart );
408cdf0e10cSrcweir             aStart.SetRow(nNewRow);
409cdf0e10cSrcweir 			pOutput->SetPosition( aStart );
410cdf0e10cSrcweir 
411cdf0e10cSrcweir 			//!	modify aOutRange?
412cdf0e10cSrcweir 
413cdf0e10cSrcweir 			bAllowMove = sal_False;		// use only once
414cdf0e10cSrcweir 		}
415cdf0e10cSrcweir 	}
416cdf0e10cSrcweir }
417cdf0e10cSrcweir 
GetTableData()418cdf0e10cSrcweir ScDPTableData* ScDPObject::GetTableData()
419cdf0e10cSrcweir {
420cdf0e10cSrcweir     if (!mpTableData && !mbCreatingTableData)
421cdf0e10cSrcweir     {
422cdf0e10cSrcweir         // #i117239# While filling the cache, mpTableData is still null.
423cdf0e10cSrcweir         // Prevent nested calls from GetPivotData and similar functions.
424cdf0e10cSrcweir         mbCreatingTableData = true;
425cdf0e10cSrcweir 
426cdf0e10cSrcweir         shared_ptr<ScDPTableData> pData;
427cdf0e10cSrcweir         if ( pImpDesc )
428cdf0e10cSrcweir         {
429cdf0e10cSrcweir             // database data
430cdf0e10cSrcweir             pData.reset(new ScDatabaseDPData(pDoc, *pImpDesc, GetCacheId()));
431cdf0e10cSrcweir         }
432cdf0e10cSrcweir         else
433cdf0e10cSrcweir         {
434cdf0e10cSrcweir             // cell data
435cdf0e10cSrcweir             if (!pSheetDesc)
436cdf0e10cSrcweir             {
437cdf0e10cSrcweir                 DBG_ERROR("no source descriptor");
438cdf0e10cSrcweir                 pSheetDesc = new ScSheetSourceDesc;     // dummy defaults
439cdf0e10cSrcweir             }
440cdf0e10cSrcweir             // Wang Xu Ming -- 2009-8-17
441cdf0e10cSrcweir             // DataPilot Migration - Cache&&Performance
442cdf0e10cSrcweir             pData.reset(new ScSheetDPData(pDoc, *pSheetDesc, GetCacheId()));
443cdf0e10cSrcweir             // End Comments
444cdf0e10cSrcweir         }
445cdf0e10cSrcweir 
446cdf0e10cSrcweir         // grouping (for cell or database data)
447cdf0e10cSrcweir         if ( pSaveData && pSaveData->GetExistingDimensionData() )
448cdf0e10cSrcweir         {
449cdf0e10cSrcweir             shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(pData, pDoc));
450cdf0e10cSrcweir             pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData);
451cdf0e10cSrcweir             pData = pGroupData;
452cdf0e10cSrcweir         }
453cdf0e10cSrcweir 
454cdf0e10cSrcweir         // Wang Xu Ming -- 2009-8-17
455cdf0e10cSrcweir         // DataPilot Migration - Cache&&Performance
456cdf0e10cSrcweir         if ( pData )
457cdf0e10cSrcweir            SetCacheId( pData->GetCacheId());        // resets mpTableData
458cdf0e10cSrcweir         // End Comments
459cdf0e10cSrcweir 
460cdf0e10cSrcweir         mpTableData = pData;                        // after SetCacheId
461cdf0e10cSrcweir 
462cdf0e10cSrcweir         mbCreatingTableData = false;
463cdf0e10cSrcweir     }
464cdf0e10cSrcweir 
465cdf0e10cSrcweir     return mpTableData.get();
466cdf0e10cSrcweir }
467cdf0e10cSrcweir 
CreateObjects()468cdf0e10cSrcweir void ScDPObject::CreateObjects()
469cdf0e10cSrcweir {
470cdf0e10cSrcweir     // if groups are involved, create a new source with the ScDPGroupTableData
471cdf0e10cSrcweir     if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() )
472cdf0e10cSrcweir         InvalidateSource();
473cdf0e10cSrcweir 
474cdf0e10cSrcweir     if (!xSource.is())
475cdf0e10cSrcweir     {
476cdf0e10cSrcweir         //!	cache DPSource and/or Output?
477cdf0e10cSrcweir 
478cdf0e10cSrcweir         DBG_ASSERT( bAlive, "CreateObjects on non-inserted DPObject" );
479cdf0e10cSrcweir 
480cdf0e10cSrcweir         DELETEZ( pOutput );		// not valid when xSource is changed
481cdf0e10cSrcweir 
482cdf0e10cSrcweir         if ( pServDesc )
483cdf0e10cSrcweir         {
484cdf0e10cSrcweir             xSource = CreateSource( *pServDesc );
485cdf0e10cSrcweir         }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir         if ( !xSource.is() )    // database or sheet data, or error in CreateSource
488cdf0e10cSrcweir 		{
489cdf0e10cSrcweir 			DBG_ASSERT( !pServDesc, "DPSource could not be created" );
490cdf0e10cSrcweir             ScDPTableData* pData = GetTableData();
491cdf0e10cSrcweir 
492cdf0e10cSrcweir             if ( pData )    // nested GetTableData calls may return NULL
493cdf0e10cSrcweir             {
494cdf0e10cSrcweir                 ScDPSource* pSource = new ScDPSource( pData );
495cdf0e10cSrcweir                 xSource = pSource;
496cdf0e10cSrcweir 
497cdf0e10cSrcweir                 if ( pSaveData && bRefresh )
498cdf0e10cSrcweir                 {
499cdf0e10cSrcweir                     pSaveData->Refresh( xSource );
500cdf0e10cSrcweir                     bRefresh = sal_False;
501cdf0e10cSrcweir                 }
502cdf0e10cSrcweir             }
503cdf0e10cSrcweir 		}
504cdf0e10cSrcweir         if ( xSource.is() && pSaveData )
505cdf0e10cSrcweir             pSaveData->WriteToSource( xSource );
506cdf0e10cSrcweir     }
507cdf0e10cSrcweir     else if (bSettingsChanged)
508cdf0e10cSrcweir     {
509cdf0e10cSrcweir         DELETEZ( pOutput );		// not valid when xSource is changed
510cdf0e10cSrcweir 
511cdf0e10cSrcweir         uno::Reference<util::XRefreshable> xRef( xSource, uno::UNO_QUERY );
512cdf0e10cSrcweir         if (xRef.is())
513cdf0e10cSrcweir         {
514cdf0e10cSrcweir             try
515cdf0e10cSrcweir             {
516cdf0e10cSrcweir                 xRef->refresh();
517cdf0e10cSrcweir             }
518cdf0e10cSrcweir             catch(uno::Exception&)
519cdf0e10cSrcweir             {
520cdf0e10cSrcweir                 DBG_ERROR("exception in refresh");
521cdf0e10cSrcweir             }
522cdf0e10cSrcweir         }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir         if (pSaveData)
525cdf0e10cSrcweir             pSaveData->WriteToSource( xSource );
526cdf0e10cSrcweir     }
527cdf0e10cSrcweir 	bSettingsChanged = sal_False;
528cdf0e10cSrcweir }
529cdf0e10cSrcweir 
InvalidateData()530cdf0e10cSrcweir void ScDPObject::InvalidateData()
531cdf0e10cSrcweir {
532cdf0e10cSrcweir 	bSettingsChanged = sal_True;
533cdf0e10cSrcweir }
534cdf0e10cSrcweir 
InvalidateSource()535cdf0e10cSrcweir void ScDPObject::InvalidateSource()
536cdf0e10cSrcweir {
537cdf0e10cSrcweir     Reference< XComponent > xObjectComp( xSource, UNO_QUERY );
538cdf0e10cSrcweir     if ( xObjectComp.is() )
539cdf0e10cSrcweir     {
540cdf0e10cSrcweir         try
541cdf0e10cSrcweir         {
542cdf0e10cSrcweir             xObjectComp->dispose();
543cdf0e10cSrcweir         }
544cdf0e10cSrcweir         catch( const Exception& )
545cdf0e10cSrcweir         {
546cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
547cdf0e10cSrcweir         }
548cdf0e10cSrcweir     }
549cdf0e10cSrcweir     xSource = NULL;
550cdf0e10cSrcweir     mpTableData.reset();
551cdf0e10cSrcweir }
552cdf0e10cSrcweir 
GetNewOutputRange(sal_Bool & rOverflow)553cdf0e10cSrcweir ScRange ScDPObject::GetNewOutputRange( sal_Bool& rOverflow )
554cdf0e10cSrcweir {
555cdf0e10cSrcweir 	CreateOutput();				// create xSource and pOutput if not already done
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 	rOverflow = pOutput->HasError();		// range overflow or exception from source
558cdf0e10cSrcweir 	if ( rOverflow )
559cdf0e10cSrcweir 		return ScRange( aOutRange.aStart );
560cdf0e10cSrcweir 	else
561cdf0e10cSrcweir 	{
562cdf0e10cSrcweir 		//	don't store the result in aOutRange, because nothing has been output yet
563cdf0e10cSrcweir 		return pOutput->GetOutputRange();
564cdf0e10cSrcweir 	}
565cdf0e10cSrcweir }
566cdf0e10cSrcweir 
Output(const ScAddress & rPos)567cdf0e10cSrcweir void ScDPObject::Output( const ScAddress& rPos )
568cdf0e10cSrcweir {
569cdf0e10cSrcweir 	//	clear old output area
570cdf0e10cSrcweir 	pDoc->DeleteAreaTab( aOutRange.aStart.Col(), aOutRange.aStart.Row(),
571cdf0e10cSrcweir 						 aOutRange.aEnd.Col(),   aOutRange.aEnd.Row(),
572cdf0e10cSrcweir 						 aOutRange.aStart.Tab(), IDF_ALL );
573cdf0e10cSrcweir 	pDoc->RemoveFlagsTab( aOutRange.aStart.Col(), aOutRange.aStart.Row(),
574cdf0e10cSrcweir 						  aOutRange.aEnd.Col(),   aOutRange.aEnd.Row(),
575cdf0e10cSrcweir 						  aOutRange.aStart.Tab(), SC_MF_AUTO );
576cdf0e10cSrcweir 
577cdf0e10cSrcweir 	CreateOutput();				// create xSource and pOutput if not already done
578cdf0e10cSrcweir 
579cdf0e10cSrcweir     pOutput->SetPosition( rPos );
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 	pOutput->Output();
582cdf0e10cSrcweir 
583cdf0e10cSrcweir 	//	aOutRange is always the range that was last output to the document
584cdf0e10cSrcweir 	aOutRange = pOutput->GetOutputRange();
585cdf0e10cSrcweir     const ScAddress& s = aOutRange.aStart;
586cdf0e10cSrcweir     const ScAddress& e = aOutRange.aEnd;
587cdf0e10cSrcweir     pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
588cdf0e10cSrcweir }
589cdf0e10cSrcweir 
GetOutputRangeByType(sal_Int32 nType)590cdf0e10cSrcweir const ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType )
591cdf0e10cSrcweir {
592cdf0e10cSrcweir     CreateOutput();
593cdf0e10cSrcweir 
594cdf0e10cSrcweir     if (pOutput->HasError())
595cdf0e10cSrcweir         return ScRange(aOutRange.aStart);
596cdf0e10cSrcweir 
597cdf0e10cSrcweir     return pOutput->GetOutputRange(nType);
598cdf0e10cSrcweir }
599cdf0e10cSrcweir 
lcl_HasButton(ScDocument * pDoc,SCCOL nCol,SCROW nRow,SCTAB nTab)600cdf0e10cSrcweir sal_Bool lcl_HasButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
601cdf0e10cSrcweir {
602cdf0e10cSrcweir 	return ((const ScMergeFlagAttr*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->HasButton();
603cdf0e10cSrcweir }
604cdf0e10cSrcweir 
RefreshAfterLoad()605cdf0e10cSrcweir void ScDPObject::RefreshAfterLoad()
606cdf0e10cSrcweir {
607cdf0e10cSrcweir 	// apply drop-down attribute, initialize nHeaderRows, without accessing the source
608cdf0e10cSrcweir 	// (button attribute must be present)
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 	// simple test: block of button cells at the top, followed by an empty cell
611cdf0e10cSrcweir 
612cdf0e10cSrcweir 	SCCOL nFirstCol = aOutRange.aStart.Col();
613cdf0e10cSrcweir 	SCROW nFirstRow = aOutRange.aStart.Row();
614cdf0e10cSrcweir 	SCTAB nTab = aOutRange.aStart.Tab();
615cdf0e10cSrcweir 
616cdf0e10cSrcweir 	SCROW nInitial = 0;
617cdf0e10cSrcweir 	SCROW nOutRows = aOutRange.aEnd.Row() + 1 - aOutRange.aStart.Row();
618cdf0e10cSrcweir 	while ( nInitial + 1 < nOutRows && lcl_HasButton( pDoc, nFirstCol, nFirstRow + nInitial, nTab ) )
619cdf0e10cSrcweir 		++nInitial;
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 	if ( nInitial + 1 < nOutRows &&
622cdf0e10cSrcweir 		pDoc->IsBlockEmpty( nTab, nFirstCol, nFirstRow + nInitial, nFirstCol, nFirstRow + nInitial ) &&
623cdf0e10cSrcweir 		aOutRange.aEnd.Col() > nFirstCol )
624cdf0e10cSrcweir 	{
625cdf0e10cSrcweir 		sal_Bool bFilterButton = IsSheetData();			// when available, filter button setting must be checked here
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 		SCROW nSkip = bFilterButton ? 1 : 0;
628cdf0e10cSrcweir 		for (SCROW nPos=nSkip; nPos<nInitial; nPos++)
629cdf0e10cSrcweir 			pDoc->ApplyAttr( nFirstCol + 1, nFirstRow + nPos, nTab, ScMergeFlagAttr(SC_MF_AUTO) );
630cdf0e10cSrcweir 
631cdf0e10cSrcweir 		nHeaderRows = nInitial;
632cdf0e10cSrcweir 	}
633cdf0e10cSrcweir 	else
634cdf0e10cSrcweir 		nHeaderRows = 0;		// nothing found, no drop-down lists
635cdf0e10cSrcweir }
636cdf0e10cSrcweir 
BuildAllDimensionMembers()637cdf0e10cSrcweir void ScDPObject::BuildAllDimensionMembers()
638cdf0e10cSrcweir {
639cdf0e10cSrcweir     if (!pSaveData)
640cdf0e10cSrcweir         return;
641cdf0e10cSrcweir 
642cdf0e10cSrcweir     // #i111857# don't always create empty mpTableData for external service.
643cdf0e10cSrcweir     // #163781# Initialize all members from xSource instead.
644cdf0e10cSrcweir     if (pServDesc)
645cdf0e10cSrcweir     {
646cdf0e10cSrcweir         pSaveData->BuildAllDimensionMembersFromSource( this );
647cdf0e10cSrcweir         return;
648cdf0e10cSrcweir     }
649cdf0e10cSrcweir 
650cdf0e10cSrcweir     pSaveData->BuildAllDimensionMembers(GetTableData());
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
GetMemberNames(sal_Int32 nDim,Sequence<OUString> & rNames)653cdf0e10cSrcweir bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence<OUString>& rNames )
654cdf0e10cSrcweir {
655cdf0e10cSrcweir     vector<ScDPLabelData::Member> aMembers;
656cdf0e10cSrcweir     if (!GetMembers(nDim, GetUsedHierarchy(nDim), aMembers))
657cdf0e10cSrcweir         return false;
658cdf0e10cSrcweir 
659cdf0e10cSrcweir     size_t n = aMembers.size();
660cdf0e10cSrcweir     rNames.realloc(n);
661cdf0e10cSrcweir     for (size_t i = 0; i < n; ++i)
662cdf0e10cSrcweir         rNames[i] = aMembers[i].maName;
663cdf0e10cSrcweir 
664cdf0e10cSrcweir     return true;
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
GetMembers(sal_Int32 nDim,sal_Int32 nHier,vector<ScDPLabelData::Member> & rMembers)667cdf0e10cSrcweir bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelData::Member>& rMembers )
668cdf0e10cSrcweir {
669cdf0e10cSrcweir     Reference< container::XNameAccess > xMembersNA;
670cdf0e10cSrcweir     if (!GetMembersNA( nDim, nHier, xMembersNA ))
671cdf0e10cSrcweir         return false;
672cdf0e10cSrcweir 
673cdf0e10cSrcweir     Reference<container::XIndexAccess> xMembersIA( new ScNameToIndexAccess(xMembersNA) );
674cdf0e10cSrcweir     sal_Int32 nCount = xMembersIA->getCount();
675cdf0e10cSrcweir     vector<ScDPLabelData::Member> aMembers;
676cdf0e10cSrcweir     aMembers.reserve(nCount);
677cdf0e10cSrcweir 
678cdf0e10cSrcweir     for (sal_Int32 i = 0; i < nCount; ++i)
679cdf0e10cSrcweir     {
680cdf0e10cSrcweir         Reference<container::XNamed> xMember(xMembersIA->getByIndex(i), UNO_QUERY);
681cdf0e10cSrcweir         ScDPLabelData::Member aMem;
682cdf0e10cSrcweir 
683cdf0e10cSrcweir         if (xMember.is())
684cdf0e10cSrcweir             aMem.maName = xMember->getName();
685cdf0e10cSrcweir 
686cdf0e10cSrcweir         Reference<beans::XPropertySet> xMemProp(xMember, UNO_QUERY);
687cdf0e10cSrcweir         if (xMemProp.is())
688cdf0e10cSrcweir         {
689cdf0e10cSrcweir             aMem.mbVisible     = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_ISVISIBL));
690cdf0e10cSrcweir             aMem.mbShowDetails = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_SHOWDETA));
691cdf0e10cSrcweir 
692cdf0e10cSrcweir             aMem.maLayoutName = ScUnoHelpFunctions::GetStringProperty(
693cdf0e10cSrcweir                 xMemProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
694cdf0e10cSrcweir         }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir         aMembers.push_back(aMem);
697cdf0e10cSrcweir     }
698cdf0e10cSrcweir     rMembers.swap(aMembers);
699cdf0e10cSrcweir     return true;
700cdf0e10cSrcweir }
701cdf0e10cSrcweir 
UpdateReference(UpdateRefMode eUpdateRefMode,const ScRange & rRange,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)702cdf0e10cSrcweir void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
703cdf0e10cSrcweir 									 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
704cdf0e10cSrcweir {
705cdf0e10cSrcweir 	// Output area
706cdf0e10cSrcweir 
707cdf0e10cSrcweir 	SCCOL nCol1 = aOutRange.aStart.Col();
708cdf0e10cSrcweir 	SCROW nRow1 = aOutRange.aStart.Row();
709cdf0e10cSrcweir 	SCTAB nTab1 = aOutRange.aStart.Tab();
710cdf0e10cSrcweir 	SCCOL nCol2 = aOutRange.aEnd.Col();
711cdf0e10cSrcweir 	SCROW nRow2 = aOutRange.aEnd.Row();
712cdf0e10cSrcweir 	SCTAB nTab2 = aOutRange.aEnd.Tab();
713cdf0e10cSrcweir 
714cdf0e10cSrcweir 	ScRefUpdateRes eRes =
715cdf0e10cSrcweir 		ScRefUpdate::Update( pDoc, eUpdateRefMode,
716cdf0e10cSrcweir 			rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
717cdf0e10cSrcweir 			rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
718cdf0e10cSrcweir 			nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
719cdf0e10cSrcweir 	if ( eRes != UR_NOTHING )
720cdf0e10cSrcweir 		SetOutRange( ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ) );
721cdf0e10cSrcweir 
722cdf0e10cSrcweir 	// sheet source data
723cdf0e10cSrcweir 
724cdf0e10cSrcweir 	if ( pSheetDesc )
725cdf0e10cSrcweir 	{
726cdf0e10cSrcweir 		nCol1 = pSheetDesc->aSourceRange.aStart.Col();
727cdf0e10cSrcweir 		nRow1 = pSheetDesc->aSourceRange.aStart.Row();
728cdf0e10cSrcweir 		nTab1 = pSheetDesc->aSourceRange.aStart.Tab();
729cdf0e10cSrcweir 		nCol2 = pSheetDesc->aSourceRange.aEnd.Col();
730cdf0e10cSrcweir 		nRow2 = pSheetDesc->aSourceRange.aEnd.Row();
731cdf0e10cSrcweir 		nTab2 = pSheetDesc->aSourceRange.aEnd.Tab();
732cdf0e10cSrcweir 
733cdf0e10cSrcweir 		eRes = ScRefUpdate::Update( pDoc, eUpdateRefMode,
734cdf0e10cSrcweir 				rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(),
735cdf0e10cSrcweir 				rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), nDx, nDy, nDz,
736cdf0e10cSrcweir 				nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
737cdf0e10cSrcweir 		if ( eRes != UR_NOTHING )
738cdf0e10cSrcweir 		{
739cdf0e10cSrcweir 			ScSheetSourceDesc aNewDesc;
740cdf0e10cSrcweir 			aNewDesc.aSourceRange = ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
741cdf0e10cSrcweir 
742cdf0e10cSrcweir 			SCsCOL nDiffX = nCol1 - (SCsCOL) pSheetDesc->aSourceRange.aStart.Col();
743cdf0e10cSrcweir 			SCsROW nDiffY = nRow1 - (SCsROW) pSheetDesc->aSourceRange.aStart.Row();
744cdf0e10cSrcweir 
745cdf0e10cSrcweir 			aNewDesc.aQueryParam = pSheetDesc->aQueryParam;
746cdf0e10cSrcweir             aNewDesc.aQueryParam.nCol1 = sal::static_int_cast<SCCOL>( aNewDesc.aQueryParam.nCol1 + nDiffX );
747cdf0e10cSrcweir             aNewDesc.aQueryParam.nCol2 = sal::static_int_cast<SCCOL>( aNewDesc.aQueryParam.nCol2 + nDiffX );
748cdf0e10cSrcweir 			aNewDesc.aQueryParam.nRow1 += nDiffY;	//! used?
749cdf0e10cSrcweir 			aNewDesc.aQueryParam.nRow2 += nDiffY;	//! used?
750cdf0e10cSrcweir 			SCSIZE nEC = aNewDesc.aQueryParam.GetEntryCount();
751cdf0e10cSrcweir 			for (SCSIZE i=0; i<nEC; i++)
752cdf0e10cSrcweir 				if (aNewDesc.aQueryParam.GetEntry(i).bDoQuery)
753cdf0e10cSrcweir 					aNewDesc.aQueryParam.GetEntry(i).nField += nDiffX;
754cdf0e10cSrcweir 
755cdf0e10cSrcweir             SetSheetDesc( aNewDesc, true );     // allocates new pSheetDesc
756cdf0e10cSrcweir 		}
757cdf0e10cSrcweir 	}
758cdf0e10cSrcweir }
759cdf0e10cSrcweir 
RefsEqual(const ScDPObject & r) const760cdf0e10cSrcweir sal_Bool ScDPObject::RefsEqual( const ScDPObject& r ) const
761cdf0e10cSrcweir {
762cdf0e10cSrcweir 	if ( aOutRange != r.aOutRange )
763cdf0e10cSrcweir 		return sal_False;
764cdf0e10cSrcweir 
765cdf0e10cSrcweir 	if ( pSheetDesc && r.pSheetDesc )
766cdf0e10cSrcweir 	{
767cdf0e10cSrcweir 		if ( pSheetDesc->aSourceRange != r.pSheetDesc->aSourceRange )
768cdf0e10cSrcweir 			return sal_False;
769cdf0e10cSrcweir 	}
770cdf0e10cSrcweir 	else if ( pSheetDesc || r.pSheetDesc )
771cdf0e10cSrcweir 	{
772cdf0e10cSrcweir 		DBG_ERROR("RefsEqual: SheetDesc set at only one object");
773cdf0e10cSrcweir 		return sal_False;
774cdf0e10cSrcweir 	}
775cdf0e10cSrcweir 
776cdf0e10cSrcweir 	return sal_True;
777cdf0e10cSrcweir }
778cdf0e10cSrcweir 
WriteRefsTo(ScDPObject & r) const779cdf0e10cSrcweir void ScDPObject::WriteRefsTo( ScDPObject& r ) const
780cdf0e10cSrcweir {
781cdf0e10cSrcweir 	r.SetOutRange( aOutRange );
782cdf0e10cSrcweir 	if ( pSheetDesc )
783cdf0e10cSrcweir         r.SetSheetDesc( *pSheetDesc, true );
784cdf0e10cSrcweir }
785cdf0e10cSrcweir 
GetPositionData(const ScAddress & rPos,DataPilotTablePositionData & rPosData)786cdf0e10cSrcweir void ScDPObject::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
787cdf0e10cSrcweir {
788cdf0e10cSrcweir     CreateOutput();
789cdf0e10cSrcweir     pOutput->GetPositionData(rPos, rPosData);
790cdf0e10cSrcweir }
791cdf0e10cSrcweir 
GetDataFieldPositionData(const ScAddress & rPos,Sequence<sheet::DataPilotFieldFilter> & rFilters)792cdf0e10cSrcweir bool ScDPObject::GetDataFieldPositionData(
793cdf0e10cSrcweir     const ScAddress& rPos, Sequence<sheet::DataPilotFieldFilter>& rFilters)
794cdf0e10cSrcweir {
795cdf0e10cSrcweir     CreateOutput();
796cdf0e10cSrcweir 
797cdf0e10cSrcweir     vector<sheet::DataPilotFieldFilter> aFilters;
798cdf0e10cSrcweir     if (!pOutput->GetDataResultPositionData(aFilters, rPos))
799cdf0e10cSrcweir         return false;
800cdf0e10cSrcweir 
801cdf0e10cSrcweir     sal_Int32 n = static_cast<sal_Int32>(aFilters.size());
802cdf0e10cSrcweir     rFilters.realloc(n);
803cdf0e10cSrcweir     for (sal_Int32 i = 0; i < n; ++i)
804cdf0e10cSrcweir         rFilters[i] = aFilters[i];
805cdf0e10cSrcweir 
806cdf0e10cSrcweir     return true;
807cdf0e10cSrcweir }
808cdf0e10cSrcweir 
GetDrillDownData(const ScAddress & rPos,Sequence<Sequence<Any>> & rTableData)809cdf0e10cSrcweir void ScDPObject::GetDrillDownData(const ScAddress& rPos, Sequence< Sequence<Any> >& rTableData)
810cdf0e10cSrcweir {
811cdf0e10cSrcweir     CreateOutput();
812cdf0e10cSrcweir 
813cdf0e10cSrcweir     Reference<sheet::XDrillDownDataSupplier> xDrillDownData(xSource, UNO_QUERY);
814cdf0e10cSrcweir     if (!xDrillDownData.is())
815cdf0e10cSrcweir         return;
816cdf0e10cSrcweir 
817cdf0e10cSrcweir     Sequence<sheet::DataPilotFieldFilter> filters;
818cdf0e10cSrcweir     if (!GetDataFieldPositionData(rPos, filters))
819cdf0e10cSrcweir         return;
820cdf0e10cSrcweir 
821cdf0e10cSrcweir     rTableData = xDrillDownData->getDrillDownData(filters);
822cdf0e10cSrcweir }
823cdf0e10cSrcweir 
IsDimNameInUse(const OUString & rName) const824cdf0e10cSrcweir bool ScDPObject::IsDimNameInUse(const OUString& rName) const
825cdf0e10cSrcweir {
826cdf0e10cSrcweir     if (!xSource.is())
827cdf0e10cSrcweir         return false;
828cdf0e10cSrcweir 
829cdf0e10cSrcweir     Reference<container::XNameAccess> xDims = xSource->getDimensions();
830cdf0e10cSrcweir     Sequence<OUString> aDimNames = xDims->getElementNames();
831cdf0e10cSrcweir     sal_Int32 n = aDimNames.getLength();
832cdf0e10cSrcweir     for (sal_Int32 i = 0; i < n; ++i)
833cdf0e10cSrcweir     {
834cdf0e10cSrcweir         const OUString& rDimName = aDimNames[i];
835cdf0e10cSrcweir         if (rDimName.equalsIgnoreAsciiCase(rName))
836cdf0e10cSrcweir             return true;
837cdf0e10cSrcweir 
838cdf0e10cSrcweir         Reference<beans::XPropertySet> xPropSet(xDims->getByName(rDimName), UNO_QUERY);
839cdf0e10cSrcweir         if (!xPropSet.is())
840cdf0e10cSrcweir             continue;
841cdf0e10cSrcweir 
842cdf0e10cSrcweir         OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
843cdf0e10cSrcweir             xPropSet, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
844cdf0e10cSrcweir         if (aLayoutName.equalsIgnoreAsciiCase(rName))
845cdf0e10cSrcweir             return true;
846cdf0e10cSrcweir     }
847cdf0e10cSrcweir     return false;
848cdf0e10cSrcweir }
849cdf0e10cSrcweir 
GetDimName(long nDim,sal_Bool & rIsDataLayout,sal_Int32 * pFlags)850cdf0e10cSrcweir String ScDPObject::GetDimName( long nDim, sal_Bool& rIsDataLayout, sal_Int32* pFlags )
851cdf0e10cSrcweir {
852cdf0e10cSrcweir 	rIsDataLayout = sal_False;
853cdf0e10cSrcweir 	String aRet;
854cdf0e10cSrcweir 
855cdf0e10cSrcweir 	if ( xSource.is() )
856cdf0e10cSrcweir 	{
857cdf0e10cSrcweir 		uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
858cdf0e10cSrcweir 		uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
859cdf0e10cSrcweir 		long nDimCount = xDims->getCount();
860cdf0e10cSrcweir 		if ( nDim < nDimCount )
861cdf0e10cSrcweir 		{
862cdf0e10cSrcweir 			uno::Reference<uno::XInterface> xIntDim =
863cdf0e10cSrcweir 				ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
864cdf0e10cSrcweir 			uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
865cdf0e10cSrcweir 			uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
866cdf0e10cSrcweir 			if ( xDimName.is() && xDimProp.is() )
867cdf0e10cSrcweir 			{
868cdf0e10cSrcweir 				sal_Bool bData = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
869cdf0e10cSrcweir 								rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
870cdf0e10cSrcweir 				//!	error checking -- is "IsDataLayoutDimension" property required??
871cdf0e10cSrcweir 
872cdf0e10cSrcweir 				rtl::OUString aName;
873cdf0e10cSrcweir 				try
874cdf0e10cSrcweir 				{
875cdf0e10cSrcweir 					aName = xDimName->getName();
876cdf0e10cSrcweir 				}
877cdf0e10cSrcweir 				catch(uno::Exception&)
878cdf0e10cSrcweir 				{
879cdf0e10cSrcweir 				}
880cdf0e10cSrcweir 				if ( bData )
881cdf0e10cSrcweir 					rIsDataLayout = sal_True;
882cdf0e10cSrcweir 				else
883cdf0e10cSrcweir 					aRet = String( aName );
884cdf0e10cSrcweir 
885cdf0e10cSrcweir                 if (pFlags)
886cdf0e10cSrcweir                     *pFlags = ScUnoHelpFunctions::GetLongProperty( xDimProp,
887cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(SC_UNO_FLAGS), 0 );
888cdf0e10cSrcweir 			}
889cdf0e10cSrcweir 		}
890cdf0e10cSrcweir 	}
891cdf0e10cSrcweir 
892cdf0e10cSrcweir 	return aRet;
893cdf0e10cSrcweir }
894cdf0e10cSrcweir 
IsDuplicated(long nDim)895cdf0e10cSrcweir sal_Bool ScDPObject::IsDuplicated( long nDim )
896cdf0e10cSrcweir {
897cdf0e10cSrcweir     sal_Bool bDuplicated = sal_False;
898cdf0e10cSrcweir     if ( xSource.is() )
899cdf0e10cSrcweir     {
900cdf0e10cSrcweir         uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
901cdf0e10cSrcweir         uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
902cdf0e10cSrcweir         long nDimCount = xDims->getCount();
903cdf0e10cSrcweir         if ( nDim < nDimCount )
904cdf0e10cSrcweir         {
905cdf0e10cSrcweir             uno::Reference<uno::XInterface> xIntDim =
906cdf0e10cSrcweir                 ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
907cdf0e10cSrcweir             uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
908cdf0e10cSrcweir             if ( xDimProp.is() )
909cdf0e10cSrcweir             {
910cdf0e10cSrcweir                 try
911cdf0e10cSrcweir                 {
912cdf0e10cSrcweir                     uno::Any aOrigAny = xDimProp->getPropertyValue(
913cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(DP_PROP_ORIGINAL) );
914cdf0e10cSrcweir                     uno::Reference<uno::XInterface> xIntOrig;
915cdf0e10cSrcweir                     if ( (aOrigAny >>= xIntOrig) && xIntOrig.is() )
916cdf0e10cSrcweir                         bDuplicated = sal_True;
917cdf0e10cSrcweir                 }
918cdf0e10cSrcweir                 catch(uno::Exception&)
919cdf0e10cSrcweir                 {
920cdf0e10cSrcweir                 }
921cdf0e10cSrcweir             }
922cdf0e10cSrcweir         }
923cdf0e10cSrcweir     }
924cdf0e10cSrcweir     return bDuplicated;
925cdf0e10cSrcweir }
926cdf0e10cSrcweir 
GetDimCount()927cdf0e10cSrcweir long ScDPObject::GetDimCount()
928cdf0e10cSrcweir {
929cdf0e10cSrcweir     long nRet = 0;
930cdf0e10cSrcweir     if ( xSource.is() )
931cdf0e10cSrcweir     {
932cdf0e10cSrcweir         try
933cdf0e10cSrcweir         {
934cdf0e10cSrcweir             uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
935cdf0e10cSrcweir             if ( xDimsName.is() )
936cdf0e10cSrcweir                 nRet = xDimsName->getElementNames().getLength();
937cdf0e10cSrcweir         }
938cdf0e10cSrcweir         catch(uno::Exception&)
939cdf0e10cSrcweir         {
940cdf0e10cSrcweir         }
941cdf0e10cSrcweir     }
942cdf0e10cSrcweir     return nRet;
943cdf0e10cSrcweir }
944cdf0e10cSrcweir 
FillPageList(TypedScStrCollection & rStrings,long nField)945cdf0e10cSrcweir void ScDPObject::FillPageList( TypedScStrCollection& rStrings, long nField )
946cdf0e10cSrcweir {
947cdf0e10cSrcweir 	//!	merge members access with ToggleDetails?
948cdf0e10cSrcweir 
949cdf0e10cSrcweir 	//!	convert field index to dimension index?
950cdf0e10cSrcweir 
951cdf0e10cSrcweir 	DBG_ASSERT( xSource.is(), "no source" );
952cdf0e10cSrcweir 	if ( !xSource.is() ) return;
953cdf0e10cSrcweir 
954cdf0e10cSrcweir 	uno::Reference<container::XNamed> xDim;
955cdf0e10cSrcweir 	uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
956cdf0e10cSrcweir 	uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
957cdf0e10cSrcweir 	long nIntCount = xIntDims->getCount();
958cdf0e10cSrcweir 	if ( nField < nIntCount )
959cdf0e10cSrcweir 	{
960cdf0e10cSrcweir 		uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface(
961cdf0e10cSrcweir 									xIntDims->getByIndex(nField) );
962cdf0e10cSrcweir 		xDim = uno::Reference<container::XNamed>( xIntDim, uno::UNO_QUERY );
963cdf0e10cSrcweir 	}
964cdf0e10cSrcweir 	DBG_ASSERT( xDim.is(), "dimension not found" );
965cdf0e10cSrcweir 	if ( !xDim.is() ) return;
966cdf0e10cSrcweir 
967cdf0e10cSrcweir 	uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
968cdf0e10cSrcweir 	long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
969cdf0e10cSrcweir 							rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
970cdf0e10cSrcweir 	long nLevel = 0;
971cdf0e10cSrcweir 
972cdf0e10cSrcweir 	long nHierCount = 0;
973cdf0e10cSrcweir 	uno::Reference<container::XIndexAccess> xHiers;
974cdf0e10cSrcweir 	uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
975cdf0e10cSrcweir 	if ( xHierSupp.is() )
976cdf0e10cSrcweir 	{
977cdf0e10cSrcweir 		uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
978cdf0e10cSrcweir 		xHiers = new ScNameToIndexAccess( xHiersName );
979cdf0e10cSrcweir 		nHierCount = xHiers->getCount();
980cdf0e10cSrcweir 	}
981cdf0e10cSrcweir 	uno::Reference<uno::XInterface> xHier;
982cdf0e10cSrcweir 	if ( nHierarchy < nHierCount )
983cdf0e10cSrcweir 		xHier = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHierarchy) );
984cdf0e10cSrcweir 	DBG_ASSERT( xHier.is(), "hierarchy not found" );
985cdf0e10cSrcweir 	if ( !xHier.is() ) return;
986cdf0e10cSrcweir 
987cdf0e10cSrcweir 	long nLevCount = 0;
988cdf0e10cSrcweir 	uno::Reference<container::XIndexAccess> xLevels;
989cdf0e10cSrcweir 	uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHier, uno::UNO_QUERY );
990cdf0e10cSrcweir 	if ( xLevSupp.is() )
991cdf0e10cSrcweir 	{
992cdf0e10cSrcweir 		uno::Reference<container::XNameAccess> xLevsName = xLevSupp->getLevels();
993cdf0e10cSrcweir 		xLevels = new ScNameToIndexAccess( xLevsName );
994cdf0e10cSrcweir 		nLevCount = xLevels->getCount();
995cdf0e10cSrcweir 	}
996cdf0e10cSrcweir 	uno::Reference<uno::XInterface> xLevel;
997cdf0e10cSrcweir 	if ( nLevel < nLevCount )
998cdf0e10cSrcweir 		xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(nLevel) );
999cdf0e10cSrcweir 	DBG_ASSERT( xLevel.is(), "level not found" );
1000cdf0e10cSrcweir 	if ( !xLevel.is() ) return;
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir 	uno::Reference<container::XNameAccess> xMembers;
1003cdf0e10cSrcweir 	uno::Reference<sheet::XMembersSupplier> xMbrSupp( xLevel, uno::UNO_QUERY );
1004cdf0e10cSrcweir 	if ( xMbrSupp.is() )
1005cdf0e10cSrcweir 		xMembers = xMbrSupp->getMembers();
1006cdf0e10cSrcweir 	DBG_ASSERT( xMembers.is(), "members not found" );
1007cdf0e10cSrcweir 	if ( !xMembers.is() ) return;
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir 	uno::Sequence<rtl::OUString> aNames = xMembers->getElementNames();
1010cdf0e10cSrcweir 	long nNameCount = aNames.getLength();
1011cdf0e10cSrcweir 	const rtl::OUString* pNameArr = aNames.getConstArray();
1012cdf0e10cSrcweir 	for (long nPos = 0; nPos < nNameCount; ++nPos)
1013cdf0e10cSrcweir 	{
1014cdf0e10cSrcweir         // Make sure to insert only visible members.
1015cdf0e10cSrcweir         Reference<XPropertySet> xPropSet(xMembers->getByName(pNameArr[nPos]), UNO_QUERY);
1016cdf0e10cSrcweir         sal_Bool bVisible = false;
1017cdf0e10cSrcweir         if (xPropSet.is())
1018cdf0e10cSrcweir         {
1019cdf0e10cSrcweir             Any any = xPropSet->getPropertyValue(OUString::createFromAscii(SC_UNO_ISVISIBL));
1020cdf0e10cSrcweir             any >>= bVisible;
1021cdf0e10cSrcweir         }
1022cdf0e10cSrcweir 
1023cdf0e10cSrcweir         if (bVisible)
1024cdf0e10cSrcweir         {
1025cdf0e10cSrcweir             // use the order from getElementNames
1026cdf0e10cSrcweir             TypedStrData* pData = new TypedStrData( pNameArr[nPos] );
1027cdf0e10cSrcweir             if ( !rStrings.AtInsert( rStrings.GetCount(), pData ) )
1028cdf0e10cSrcweir                 delete pData;
1029cdf0e10cSrcweir         }
1030cdf0e10cSrcweir     }
1031cdf0e10cSrcweir 
1032cdf0e10cSrcweir 	//	add "-all-" entry to the top (unsorted)
1033cdf0e10cSrcweir 	TypedStrData* pAllData = new TypedStrData( String( ScResId( SCSTR_ALL ) ) );	//! separate string? (also output)
1034cdf0e10cSrcweir 	if ( !rStrings.AtInsert( 0, pAllData ) )
1035cdf0e10cSrcweir 		delete pAllData;
1036cdf0e10cSrcweir }
1037cdf0e10cSrcweir 
GetHeaderPositionData(const ScAddress & rPos,DataPilotTableHeaderData & rData)1038cdf0e10cSrcweir void ScDPObject::GetHeaderPositionData(const ScAddress& rPos, DataPilotTableHeaderData& rData)
1039cdf0e10cSrcweir {
1040cdf0e10cSrcweir     using namespace ::com::sun::star::sheet::DataPilotTablePositionType;
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir 	CreateOutput();				// create xSource and pOutput if not already done
1043cdf0e10cSrcweir 
1044cdf0e10cSrcweir     // Reset member values to invalid state.
1045cdf0e10cSrcweir     rData.Dimension = rData.Hierarchy = rData.Level = -1;
1046cdf0e10cSrcweir     rData.Flags = 0;
1047cdf0e10cSrcweir 
1048cdf0e10cSrcweir     DataPilotTablePositionData aPosData;
1049cdf0e10cSrcweir     pOutput->GetPositionData(rPos, aPosData);
1050cdf0e10cSrcweir     const sal_Int32 nPosType = aPosData.PositionType;
1051cdf0e10cSrcweir     if (nPosType == COLUMN_HEADER || nPosType == ROW_HEADER)
1052cdf0e10cSrcweir         aPosData.PositionData >>= rData;
1053cdf0e10cSrcweir }
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir // Returns sal_True on success and stores the result in rTarget
GetPivotData(ScDPGetPivotDataField & rTarget,const std::vector<ScDPGetPivotDataField> & rFilters)1056cdf0e10cSrcweir sal_Bool ScDPObject::GetPivotData( ScDPGetPivotDataField& rTarget,
1057cdf0e10cSrcweir                                const std::vector< ScDPGetPivotDataField >& rFilters )
1058cdf0e10cSrcweir {
1059cdf0e10cSrcweir     // #i117239# Exit with an error if called from creating the cache for this object
1060cdf0e10cSrcweir     // (don't create an empty pOutput object)
1061cdf0e10cSrcweir     if (mbCreatingTableData)
1062cdf0e10cSrcweir         return sal_False;
1063cdf0e10cSrcweir 
1064cdf0e10cSrcweir     CreateOutput();             // create xSource and pOutput if not already done
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir     return pOutput->GetPivotData( rTarget, rFilters );
1067cdf0e10cSrcweir }
1068cdf0e10cSrcweir 
IsFilterButton(const ScAddress & rPos)1069cdf0e10cSrcweir sal_Bool ScDPObject::IsFilterButton( const ScAddress& rPos )
1070cdf0e10cSrcweir {
1071cdf0e10cSrcweir 	CreateOutput();				// create xSource and pOutput if not already done
1072cdf0e10cSrcweir 
1073cdf0e10cSrcweir 	return pOutput->IsFilterButton( rPos );
1074cdf0e10cSrcweir }
1075cdf0e10cSrcweir 
GetHeaderDim(const ScAddress & rPos,sal_uInt16 & rOrient)1076cdf0e10cSrcweir long ScDPObject::GetHeaderDim( const ScAddress& rPos, sal_uInt16& rOrient )
1077cdf0e10cSrcweir {
1078cdf0e10cSrcweir 	CreateOutput();				// create xSource and pOutput if not already done
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir 	return pOutput->GetHeaderDim( rPos, rOrient );
1081cdf0e10cSrcweir }
1082cdf0e10cSrcweir 
GetHeaderDrag(const ScAddress & rPos,sal_Bool bMouseLeft,sal_Bool bMouseTop,long nDragDim,Rectangle & rPosRect,sal_uInt16 & rOrient,long & rDimPos)1083cdf0e10cSrcweir sal_Bool ScDPObject::GetHeaderDrag( const ScAddress& rPos, sal_Bool bMouseLeft, sal_Bool bMouseTop, long nDragDim,
1084cdf0e10cSrcweir 								Rectangle& rPosRect, sal_uInt16& rOrient, long& rDimPos )
1085cdf0e10cSrcweir {
1086cdf0e10cSrcweir 	CreateOutput();				// create xSource and pOutput if not already done
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir 	return pOutput->GetHeaderDrag( rPos, bMouseLeft, bMouseTop, nDragDim, rPosRect, rOrient, rDimPos );
1089cdf0e10cSrcweir }
1090cdf0e10cSrcweir 
GetMemberResultNames(ScStrCollection & rNames,long nDimension)1091cdf0e10cSrcweir void ScDPObject::GetMemberResultNames( ScStrCollection& rNames, long nDimension )
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir     CreateOutput();             // create xSource and pOutput if not already done
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir     pOutput->GetMemberResultNames( rNames, nDimension );    // used only with table data -> level not needed
1096cdf0e10cSrcweir }
1097cdf0e10cSrcweir 
lcl_Dequote(const String & rSource,xub_StrLen nStartPos,xub_StrLen & rEndPos,String & rResult)1098cdf0e10cSrcweir bool lcl_Dequote( const String& rSource, xub_StrLen nStartPos, xub_StrLen& rEndPos, String& rResult )
1099cdf0e10cSrcweir {
1100cdf0e10cSrcweir     // nStartPos has to point to opening quote
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir     bool bRet = false;
1103cdf0e10cSrcweir     const sal_Unicode cQuote = '\'';
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir     if ( rSource.GetChar(nStartPos) == cQuote )
1106cdf0e10cSrcweir     {
1107cdf0e10cSrcweir         rtl::OUStringBuffer aBuffer;
1108cdf0e10cSrcweir         xub_StrLen nPos = nStartPos + 1;
1109cdf0e10cSrcweir         const xub_StrLen nLen = rSource.Len();
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir         while ( nPos < nLen )
1112cdf0e10cSrcweir         {
1113cdf0e10cSrcweir             const sal_Unicode cNext = rSource.GetChar(nPos);
1114cdf0e10cSrcweir             if ( cNext == cQuote )
1115cdf0e10cSrcweir             {
1116cdf0e10cSrcweir                 if ( nPos+1 < nLen && rSource.GetChar(nPos+1) == cQuote )
1117cdf0e10cSrcweir                 {
1118cdf0e10cSrcweir                     // double quote is used for an embedded quote
1119cdf0e10cSrcweir                     aBuffer.append( cNext );    // append one quote
1120cdf0e10cSrcweir                     ++nPos;                     // skip the next one
1121cdf0e10cSrcweir                 }
1122cdf0e10cSrcweir                 else
1123cdf0e10cSrcweir                 {
1124cdf0e10cSrcweir                     // end of quoted string
1125cdf0e10cSrcweir                     rResult = aBuffer.makeStringAndClear();
1126cdf0e10cSrcweir                     rEndPos = nPos + 1;         // behind closing quote
1127cdf0e10cSrcweir                     return true;
1128cdf0e10cSrcweir                 }
1129cdf0e10cSrcweir             }
1130cdf0e10cSrcweir             else
1131cdf0e10cSrcweir                 aBuffer.append( cNext );
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir             ++nPos;
1134cdf0e10cSrcweir         }
1135cdf0e10cSrcweir         // no closing quote before the end of the string -> error (bRet still false)
1136cdf0e10cSrcweir     }
1137cdf0e10cSrcweir 
1138cdf0e10cSrcweir     return bRet;
1139cdf0e10cSrcweir }
1140cdf0e10cSrcweir 
1141cdf0e10cSrcweir struct ScGetPivotDataFunctionEntry
1142cdf0e10cSrcweir {
1143cdf0e10cSrcweir     const sal_Char*         pName;
1144cdf0e10cSrcweir     sheet::GeneralFunction  eFunc;
1145cdf0e10cSrcweir };
1146cdf0e10cSrcweir 
lcl_ParseFunction(const String & rList,xub_StrLen nStartPos,xub_StrLen & rEndPos,sheet::GeneralFunction & rFunc)1147cdf0e10cSrcweir bool lcl_ParseFunction( const String& rList, xub_StrLen nStartPos, xub_StrLen& rEndPos, sheet::GeneralFunction& rFunc )
1148cdf0e10cSrcweir {
1149cdf0e10cSrcweir     static const ScGetPivotDataFunctionEntry aFunctions[] =
1150cdf0e10cSrcweir     {
1151cdf0e10cSrcweir         // our names
1152cdf0e10cSrcweir         { "Sum",        sheet::GeneralFunction_SUM       },
1153cdf0e10cSrcweir         { "Count",      sheet::GeneralFunction_COUNT     },
1154cdf0e10cSrcweir         { "Average",    sheet::GeneralFunction_AVERAGE   },
1155cdf0e10cSrcweir         { "Max",        sheet::GeneralFunction_MAX       },
1156cdf0e10cSrcweir         { "Min",        sheet::GeneralFunction_MIN       },
1157cdf0e10cSrcweir         { "Product",    sheet::GeneralFunction_PRODUCT   },
1158cdf0e10cSrcweir         { "CountNums",  sheet::GeneralFunction_COUNTNUMS },
1159cdf0e10cSrcweir         { "StDev",      sheet::GeneralFunction_STDEV     },
1160cdf0e10cSrcweir         { "StDevp",     sheet::GeneralFunction_STDEVP    },
1161cdf0e10cSrcweir         { "Var",        sheet::GeneralFunction_VAR       },
1162cdf0e10cSrcweir         { "VarP",       sheet::GeneralFunction_VARP      },
1163cdf0e10cSrcweir         // compatibility names
1164cdf0e10cSrcweir         { "Count Nums", sheet::GeneralFunction_COUNTNUMS },
1165cdf0e10cSrcweir         { "StdDev",     sheet::GeneralFunction_STDEV     },
1166cdf0e10cSrcweir         { "StdDevp",    sheet::GeneralFunction_STDEVP    }
1167cdf0e10cSrcweir 	};
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir     const xub_StrLen nListLen = rList.Len();
1170cdf0e10cSrcweir     while ( nStartPos < nListLen && rList.GetChar(nStartPos) == ' ' )
1171cdf0e10cSrcweir         ++nStartPos;
1172cdf0e10cSrcweir 
1173cdf0e10cSrcweir     bool bParsed = false;
1174cdf0e10cSrcweir     bool bFound = false;
1175cdf0e10cSrcweir     String aFuncStr;
1176cdf0e10cSrcweir     xub_StrLen nFuncEnd = 0;
1177cdf0e10cSrcweir     if ( nStartPos < nListLen && rList.GetChar(nStartPos) == '\'' )
1178cdf0e10cSrcweir         bParsed = lcl_Dequote( rList, nStartPos, nFuncEnd, aFuncStr );
1179cdf0e10cSrcweir     else
1180cdf0e10cSrcweir     {
1181cdf0e10cSrcweir         nFuncEnd = rList.Search( static_cast<sal_Unicode>(']'), nStartPos );
1182cdf0e10cSrcweir         if ( nFuncEnd != STRING_NOTFOUND )
1183cdf0e10cSrcweir         {
1184cdf0e10cSrcweir             aFuncStr = rList.Copy( nStartPos, nFuncEnd - nStartPos );
1185cdf0e10cSrcweir             bParsed = true;
1186cdf0e10cSrcweir         }
1187cdf0e10cSrcweir     }
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir     if ( bParsed )
1190cdf0e10cSrcweir     {
1191cdf0e10cSrcweir         aFuncStr.EraseLeadingAndTrailingChars( ' ' );
1192cdf0e10cSrcweir 
1193cdf0e10cSrcweir         const sal_Int32 nFuncCount = sizeof(aFunctions) / sizeof(aFunctions[0]);
1194cdf0e10cSrcweir         for ( sal_Int32 nFunc=0; nFunc<nFuncCount && !bFound; nFunc++ )
1195cdf0e10cSrcweir         {
1196cdf0e10cSrcweir             if ( aFuncStr.EqualsIgnoreCaseAscii( aFunctions[nFunc].pName ) )
1197cdf0e10cSrcweir             {
1198cdf0e10cSrcweir                 rFunc = aFunctions[nFunc].eFunc;
1199cdf0e10cSrcweir                 bFound = true;
1200cdf0e10cSrcweir 
1201cdf0e10cSrcweir                 while ( nFuncEnd < nListLen && rList.GetChar(nFuncEnd) == ' ' )
1202cdf0e10cSrcweir                     ++nFuncEnd;
1203cdf0e10cSrcweir                 rEndPos = nFuncEnd;
1204cdf0e10cSrcweir             }
1205cdf0e10cSrcweir         }
1206cdf0e10cSrcweir     }
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir     return bFound;
1209cdf0e10cSrcweir }
1210cdf0e10cSrcweir 
lcl_IsAtStart(const String & rList,const String & rSearch,sal_Int32 & rMatched,bool bAllowBracket,sheet::GeneralFunction * pFunc)1211cdf0e10cSrcweir bool lcl_IsAtStart( const String& rList, const String& rSearch, sal_Int32& rMatched,
1212cdf0e10cSrcweir                     bool bAllowBracket, sheet::GeneralFunction* pFunc )
1213cdf0e10cSrcweir {
1214cdf0e10cSrcweir     sal_Int32 nMatchList = 0;
1215cdf0e10cSrcweir     sal_Int32 nMatchSearch = 0;
1216cdf0e10cSrcweir     sal_Unicode cFirst = rList.GetChar(0);
1217cdf0e10cSrcweir     if ( cFirst == '\'' || cFirst == '[' )
1218cdf0e10cSrcweir     {
1219cdf0e10cSrcweir         // quoted string or string in brackets must match completely
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir         String aDequoted;
1222cdf0e10cSrcweir         xub_StrLen nQuoteEnd = 0;
1223cdf0e10cSrcweir         bool bParsed = false;
1224cdf0e10cSrcweir 
1225cdf0e10cSrcweir         if ( cFirst == '\'' )
1226cdf0e10cSrcweir             bParsed = lcl_Dequote( rList, 0, nQuoteEnd, aDequoted );
1227cdf0e10cSrcweir         else if ( cFirst == '[' )
1228cdf0e10cSrcweir         {
1229cdf0e10cSrcweir             // skip spaces after the opening bracket
1230cdf0e10cSrcweir 
1231cdf0e10cSrcweir             xub_StrLen nStartPos = 1;
1232cdf0e10cSrcweir             const xub_StrLen nListLen = rList.Len();
1233cdf0e10cSrcweir             while ( nStartPos < nListLen && rList.GetChar(nStartPos) == ' ' )
1234cdf0e10cSrcweir                 ++nStartPos;
1235cdf0e10cSrcweir 
1236cdf0e10cSrcweir             if ( rList.GetChar(nStartPos) == '\'' )         // quoted within the brackets?
1237cdf0e10cSrcweir             {
1238cdf0e10cSrcweir                 if ( lcl_Dequote( rList, nStartPos, nQuoteEnd, aDequoted ) )
1239cdf0e10cSrcweir                 {
1240cdf0e10cSrcweir                     // after the quoted string, there must be the closing bracket, optionally preceded by spaces,
1241cdf0e10cSrcweir                     // and/or a function name
1242cdf0e10cSrcweir                     while ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ' ' )
1243cdf0e10cSrcweir                         ++nQuoteEnd;
1244cdf0e10cSrcweir 
1245cdf0e10cSrcweir                     // semicolon separates function name
1246cdf0e10cSrcweir                     if ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ';' && pFunc )
1247cdf0e10cSrcweir                     {
1248cdf0e10cSrcweir                         xub_StrLen nFuncEnd = 0;
1249cdf0e10cSrcweir                         if ( lcl_ParseFunction( rList, nQuoteEnd + 1, nFuncEnd, *pFunc ) )
1250cdf0e10cSrcweir                             nQuoteEnd = nFuncEnd;
1251cdf0e10cSrcweir                     }
1252cdf0e10cSrcweir                     if ( nQuoteEnd < nListLen && rList.GetChar(nQuoteEnd) == ']' )
1253cdf0e10cSrcweir                     {
1254cdf0e10cSrcweir                         ++nQuoteEnd;        // include the closing bracket for the matched length
1255cdf0e10cSrcweir                         bParsed = true;
1256cdf0e10cSrcweir                     }
1257cdf0e10cSrcweir                 }
1258cdf0e10cSrcweir             }
1259cdf0e10cSrcweir             else
1260cdf0e10cSrcweir             {
1261cdf0e10cSrcweir                 // implicit quoting to the closing bracket
1262cdf0e10cSrcweir 
1263cdf0e10cSrcweir                 xub_StrLen nClosePos = rList.Search( static_cast<sal_Unicode>(']'), nStartPos );
1264cdf0e10cSrcweir                 if ( nClosePos != STRING_NOTFOUND )
1265cdf0e10cSrcweir                 {
1266cdf0e10cSrcweir                     xub_StrLen nNameEnd = nClosePos;
1267cdf0e10cSrcweir                     xub_StrLen nSemiPos = rList.Search( static_cast<sal_Unicode>(';'), nStartPos );
1268cdf0e10cSrcweir                     if ( nSemiPos != STRING_NOTFOUND && nSemiPos < nClosePos && pFunc )
1269cdf0e10cSrcweir                     {
1270cdf0e10cSrcweir                         xub_StrLen nFuncEnd = 0;
1271cdf0e10cSrcweir                         if ( lcl_ParseFunction( rList, nSemiPos + 1, nFuncEnd, *pFunc ) )
1272cdf0e10cSrcweir                             nNameEnd = nSemiPos;
1273cdf0e10cSrcweir                     }
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir                     aDequoted = rList.Copy( nStartPos, nNameEnd - nStartPos );
1276cdf0e10cSrcweir                     aDequoted.EraseTrailingChars( ' ' );        // spaces before the closing bracket or semicolon
1277cdf0e10cSrcweir                     nQuoteEnd = nClosePos + 1;
1278cdf0e10cSrcweir                     bParsed = true;
1279cdf0e10cSrcweir                 }
1280cdf0e10cSrcweir             }
1281cdf0e10cSrcweir         }
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir         if ( bParsed && ScGlobal::GetpTransliteration()->isEqual( aDequoted, rSearch ) )
1284cdf0e10cSrcweir         {
1285cdf0e10cSrcweir             nMatchList = nQuoteEnd;             // match count in the list string, including quotes
1286cdf0e10cSrcweir             nMatchSearch = rSearch.Len();
1287cdf0e10cSrcweir         }
1288cdf0e10cSrcweir     }
1289cdf0e10cSrcweir     else
1290cdf0e10cSrcweir     {
1291cdf0e10cSrcweir         // otherwise look for search string at the start of rList
1292cdf0e10cSrcweir         ScGlobal::GetpTransliteration()->equals( rList, 0, rList.Len(), nMatchList,
1293cdf0e10cSrcweir                                             rSearch, 0, rSearch.Len(), nMatchSearch );
1294cdf0e10cSrcweir     }
1295cdf0e10cSrcweir 
1296cdf0e10cSrcweir     if ( nMatchSearch == rSearch.Len() )
1297cdf0e10cSrcweir     {
1298cdf0e10cSrcweir         // search string is at start of rList - look for following space or end of string
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir         bool bValid = false;
1301cdf0e10cSrcweir         if ( sal::static_int_cast<xub_StrLen>(nMatchList) >= rList.Len() )
1302cdf0e10cSrcweir             bValid = true;
1303cdf0e10cSrcweir         else
1304cdf0e10cSrcweir         {
1305cdf0e10cSrcweir             sal_Unicode cNext = rList.GetChar(sal::static_int_cast<xub_StrLen>(nMatchList));
1306cdf0e10cSrcweir             if ( cNext == ' ' || ( bAllowBracket && cNext == '[' ) )
1307cdf0e10cSrcweir                 bValid = true;
1308cdf0e10cSrcweir         }
1309cdf0e10cSrcweir 
1310cdf0e10cSrcweir         if ( bValid )
1311cdf0e10cSrcweir         {
1312cdf0e10cSrcweir             rMatched = nMatchList;
1313cdf0e10cSrcweir             return true;
1314cdf0e10cSrcweir         }
1315cdf0e10cSrcweir     }
1316cdf0e10cSrcweir 
1317cdf0e10cSrcweir     return false;
1318cdf0e10cSrcweir }
1319cdf0e10cSrcweir 
ParseFilters(ScDPGetPivotDataField & rTarget,std::vector<ScDPGetPivotDataField> & rFilters,const String & rFilterList)1320cdf0e10cSrcweir sal_Bool ScDPObject::ParseFilters( ScDPGetPivotDataField& rTarget,
1321cdf0e10cSrcweir                                std::vector< ScDPGetPivotDataField >& rFilters,
1322cdf0e10cSrcweir                                const String& rFilterList )
1323cdf0e10cSrcweir {
1324cdf0e10cSrcweir     // parse the string rFilterList into parameters for GetPivotData
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir     CreateObjects();            // create xSource if not already done
1327cdf0e10cSrcweir 
1328cdf0e10cSrcweir     std::vector<String> aDataNames;     // data fields (source name)
1329cdf0e10cSrcweir     std::vector<String> aGivenNames;    // data fields (compound name)
1330cdf0e10cSrcweir     std::vector<String> aFieldNames;    // column/row/data fields
1331cdf0e10cSrcweir     std::vector< uno::Sequence<rtl::OUString> > aFieldValues;
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir     //
1334cdf0e10cSrcweir     // get all the field and item names
1335cdf0e10cSrcweir     //
1336cdf0e10cSrcweir 
1337cdf0e10cSrcweir     uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1338cdf0e10cSrcweir     uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
1339cdf0e10cSrcweir     sal_Int32 nDimCount = xIntDims->getCount();
1340cdf0e10cSrcweir     for ( sal_Int32 nDim = 0; nDim<nDimCount; nDim++ )
1341cdf0e10cSrcweir     {
1342cdf0e10cSrcweir         uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nDim) );
1343cdf0e10cSrcweir         uno::Reference<container::XNamed> xDim( xIntDim, uno::UNO_QUERY );
1344cdf0e10cSrcweir         uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1345cdf0e10cSrcweir         uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDim, uno::UNO_QUERY );
1346cdf0e10cSrcweir         sal_Bool bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1347cdf0e10cSrcweir                             rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
1348cdf0e10cSrcweir         sal_Int32 nOrient = ScUnoHelpFunctions::GetEnumProperty(
1349cdf0e10cSrcweir                             xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
1350cdf0e10cSrcweir                             sheet::DataPilotFieldOrientation_HIDDEN );
1351cdf0e10cSrcweir         if ( !bDataLayout )
1352cdf0e10cSrcweir         {
1353cdf0e10cSrcweir             if ( nOrient == sheet::DataPilotFieldOrientation_DATA )
1354cdf0e10cSrcweir             {
1355cdf0e10cSrcweir                 String aSourceName;
1356cdf0e10cSrcweir                 String aGivenName;
1357cdf0e10cSrcweir                 ScDPOutput::GetDataDimensionNames( aSourceName, aGivenName, xIntDim );
1358cdf0e10cSrcweir                 aDataNames.push_back( aSourceName );
1359cdf0e10cSrcweir                 aGivenNames.push_back( aGivenName );
1360cdf0e10cSrcweir             }
1361cdf0e10cSrcweir             else if ( nOrient != sheet::DataPilotFieldOrientation_HIDDEN )
1362cdf0e10cSrcweir             {
1363cdf0e10cSrcweir                 // get level names, as in ScDPOutput
1364cdf0e10cSrcweir 
1365cdf0e10cSrcweir                 uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
1366cdf0e10cSrcweir                 sal_Int32 nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
1367cdf0e10cSrcweir                                                     rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
1368cdf0e10cSrcweir                 if ( nHierarchy >= xHiers->getCount() )
1369cdf0e10cSrcweir                     nHierarchy = 0;
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir                 uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface(
1372cdf0e10cSrcweir                                                     xHiers->getByIndex(nHierarchy) );
1373cdf0e10cSrcweir                 uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
1374cdf0e10cSrcweir                 if ( xHierSupp.is() )
1375cdf0e10cSrcweir                 {
1376cdf0e10cSrcweir                     uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() );
1377cdf0e10cSrcweir                     sal_Int32 nLevCount = xLevels->getCount();
1378cdf0e10cSrcweir                     for (sal_Int32 nLev=0; nLev<nLevCount; nLev++)
1379cdf0e10cSrcweir                     {
1380cdf0e10cSrcweir                         uno::Reference<uno::XInterface> xLevel = ScUnoHelpFunctions::AnyToInterface(
1381cdf0e10cSrcweir                                                             xLevels->getByIndex(nLev) );
1382cdf0e10cSrcweir                         uno::Reference<container::XNamed> xLevNam( xLevel, uno::UNO_QUERY );
1383cdf0e10cSrcweir                         uno::Reference<sheet::XMembersSupplier> xLevSupp( xLevel, uno::UNO_QUERY );
1384cdf0e10cSrcweir                         if ( xLevNam.is() && xLevSupp.is() )
1385cdf0e10cSrcweir                         {
1386cdf0e10cSrcweir                             uno::Reference<container::XNameAccess> xMembers = xLevSupp->getMembers();
1387cdf0e10cSrcweir 
1388cdf0e10cSrcweir                             String aFieldName( xLevNam->getName() );
1389cdf0e10cSrcweir                             uno::Sequence<rtl::OUString> aMemberNames( xMembers->getElementNames() );
1390cdf0e10cSrcweir 
1391cdf0e10cSrcweir                             aFieldNames.push_back( aFieldName );
1392cdf0e10cSrcweir                             aFieldValues.push_back( aMemberNames );
1393cdf0e10cSrcweir                         }
1394cdf0e10cSrcweir                     }
1395cdf0e10cSrcweir                 }
1396cdf0e10cSrcweir             }
1397cdf0e10cSrcweir         }
1398cdf0e10cSrcweir     }
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir     //
1401cdf0e10cSrcweir     // compare and build filters
1402cdf0e10cSrcweir     //
1403cdf0e10cSrcweir 
1404cdf0e10cSrcweir     SCSIZE nDataFields = aDataNames.size();
1405cdf0e10cSrcweir     SCSIZE nFieldCount = aFieldNames.size();
1406cdf0e10cSrcweir     DBG_ASSERT( aGivenNames.size() == nDataFields && aFieldValues.size() == nFieldCount, "wrong count" );
1407cdf0e10cSrcweir 
1408cdf0e10cSrcweir     bool bError = false;
1409cdf0e10cSrcweir     bool bHasData = false;
1410cdf0e10cSrcweir     String aRemaining( rFilterList );
1411cdf0e10cSrcweir     aRemaining.EraseLeadingAndTrailingChars( ' ' );
1412cdf0e10cSrcweir     while ( aRemaining.Len() && !bError )
1413cdf0e10cSrcweir     {
1414cdf0e10cSrcweir         bool bUsed = false;
1415cdf0e10cSrcweir 
1416cdf0e10cSrcweir         // look for data field name
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir         for ( SCSIZE nDataPos=0; nDataPos<nDataFields && !bUsed; nDataPos++ )
1419cdf0e10cSrcweir         {
1420cdf0e10cSrcweir             String aFound;
1421cdf0e10cSrcweir             sal_Int32 nMatched = 0;
1422cdf0e10cSrcweir             if ( lcl_IsAtStart( aRemaining, aDataNames[nDataPos], nMatched, false, NULL ) )
1423cdf0e10cSrcweir                 aFound = aDataNames[nDataPos];
1424cdf0e10cSrcweir             else if ( lcl_IsAtStart( aRemaining, aGivenNames[nDataPos], nMatched, false, NULL ) )
1425cdf0e10cSrcweir                 aFound = aGivenNames[nDataPos];
1426cdf0e10cSrcweir 
1427cdf0e10cSrcweir             if ( aFound.Len() )
1428cdf0e10cSrcweir             {
1429cdf0e10cSrcweir                 rTarget.maFieldName = aFound;
1430cdf0e10cSrcweir                 aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
1431cdf0e10cSrcweir                 bHasData = true;
1432cdf0e10cSrcweir                 bUsed = true;
1433cdf0e10cSrcweir             }
1434cdf0e10cSrcweir         }
1435cdf0e10cSrcweir 
1436cdf0e10cSrcweir         // look for field name
1437cdf0e10cSrcweir 
1438cdf0e10cSrcweir         String aSpecField;
1439cdf0e10cSrcweir         bool bHasFieldName = false;
1440cdf0e10cSrcweir         if ( !bUsed )
1441cdf0e10cSrcweir         {
1442cdf0e10cSrcweir             sal_Int32 nMatched = 0;
1443cdf0e10cSrcweir             for ( SCSIZE nField=0; nField<nFieldCount && !bHasFieldName; nField++ )
1444cdf0e10cSrcweir             {
1445cdf0e10cSrcweir                 if ( lcl_IsAtStart( aRemaining, aFieldNames[nField], nMatched, true, NULL ) )
1446cdf0e10cSrcweir                 {
1447cdf0e10cSrcweir                     aSpecField = aFieldNames[nField];
1448cdf0e10cSrcweir                     aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
1449cdf0e10cSrcweir                     aRemaining.EraseLeadingChars( ' ' );
1450cdf0e10cSrcweir 
1451cdf0e10cSrcweir                     // field name has to be followed by item name in brackets
1452cdf0e10cSrcweir                     if ( aRemaining.GetChar(0) == '[' )
1453cdf0e10cSrcweir                     {
1454cdf0e10cSrcweir                         bHasFieldName = true;
1455cdf0e10cSrcweir                         // bUsed remains false - still need the item
1456cdf0e10cSrcweir                     }
1457cdf0e10cSrcweir                     else
1458cdf0e10cSrcweir                     {
1459cdf0e10cSrcweir                         bUsed = true;
1460cdf0e10cSrcweir                         bError = true;
1461cdf0e10cSrcweir                     }
1462cdf0e10cSrcweir                 }
1463cdf0e10cSrcweir             }
1464cdf0e10cSrcweir         }
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir         // look for field item
1467cdf0e10cSrcweir 
1468cdf0e10cSrcweir         if ( !bUsed )
1469cdf0e10cSrcweir         {
1470cdf0e10cSrcweir             bool bItemFound = false;
1471cdf0e10cSrcweir             sal_Int32 nMatched = 0;
1472cdf0e10cSrcweir             String aFoundName;
1473cdf0e10cSrcweir             String aFoundValue;
1474cdf0e10cSrcweir             sheet::GeneralFunction eFunc = sheet::GeneralFunction_NONE;
1475cdf0e10cSrcweir             sheet::GeneralFunction eFoundFunc = sheet::GeneralFunction_NONE;
1476cdf0e10cSrcweir 
1477cdf0e10cSrcweir             for ( SCSIZE nField=0; nField<nFieldCount; nField++ )
1478cdf0e10cSrcweir             {
1479cdf0e10cSrcweir                 // If a field name is given, look in that field only, otherwise in all fields.
1480cdf0e10cSrcweir                 // aSpecField is initialized from aFieldNames array, so exact comparison can be used.
1481cdf0e10cSrcweir                 if ( !bHasFieldName || aFieldNames[nField] == aSpecField )
1482cdf0e10cSrcweir                 {
1483cdf0e10cSrcweir                     const uno::Sequence<rtl::OUString>& rItems = aFieldValues[nField];
1484cdf0e10cSrcweir                     sal_Int32 nItemCount = rItems.getLength();
1485cdf0e10cSrcweir                     const rtl::OUString* pItemArr = rItems.getConstArray();
1486cdf0e10cSrcweir                     for ( sal_Int32 nItem=0; nItem<nItemCount; nItem++ )
1487cdf0e10cSrcweir                     {
1488cdf0e10cSrcweir                         if ( lcl_IsAtStart( aRemaining, pItemArr[nItem], nMatched, false, &eFunc ) )
1489cdf0e10cSrcweir                         {
1490cdf0e10cSrcweir                             if ( bItemFound )
1491cdf0e10cSrcweir                                 bError = true;      // duplicate (also across fields)
1492cdf0e10cSrcweir                             else
1493cdf0e10cSrcweir                             {
1494cdf0e10cSrcweir                                 aFoundName = aFieldNames[nField];
1495cdf0e10cSrcweir                                 aFoundValue = pItemArr[nItem];
1496cdf0e10cSrcweir                                 eFoundFunc = eFunc;
1497cdf0e10cSrcweir                                 bItemFound = true;
1498cdf0e10cSrcweir                                 bUsed = true;
1499cdf0e10cSrcweir                             }
1500cdf0e10cSrcweir                         }
1501cdf0e10cSrcweir                     }
1502cdf0e10cSrcweir                 }
1503cdf0e10cSrcweir             }
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir             if ( bItemFound && !bError )
1506cdf0e10cSrcweir             {
1507cdf0e10cSrcweir                 ScDPGetPivotDataField aField;
1508cdf0e10cSrcweir                 aField.maFieldName = aFoundName;
1509cdf0e10cSrcweir                 aField.meFunction = eFoundFunc;
1510cdf0e10cSrcweir                 aField.mbValIsStr = true;
1511cdf0e10cSrcweir                 aField.maValStr = aFoundValue;
1512cdf0e10cSrcweir                 aField.mnValNum = 0.0;
1513cdf0e10cSrcweir                 rFilters.push_back( aField );
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir                 aRemaining.Erase( 0, sal::static_int_cast<xub_StrLen>(nMatched) );
1516cdf0e10cSrcweir             }
1517cdf0e10cSrcweir         }
1518cdf0e10cSrcweir 
1519cdf0e10cSrcweir         if ( !bUsed )
1520cdf0e10cSrcweir             bError = true;
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir         aRemaining.EraseLeadingChars( ' ' );        // remove any number of spaces between entries
1523cdf0e10cSrcweir     }
1524cdf0e10cSrcweir 
1525cdf0e10cSrcweir     if ( !bError && !bHasData && aDataNames.size() == 1 )
1526cdf0e10cSrcweir     {
1527cdf0e10cSrcweir         // if there's only one data field, its name need not be specified
1528cdf0e10cSrcweir         rTarget.maFieldName = aDataNames[0];
1529cdf0e10cSrcweir         bHasData = true;
1530cdf0e10cSrcweir     }
1531cdf0e10cSrcweir 
1532cdf0e10cSrcweir     return bHasData && !bError;
1533cdf0e10cSrcweir }
1534cdf0e10cSrcweir 
ToggleDetails(const DataPilotTableHeaderData & rElemDesc,ScDPObject * pDestObj)1535cdf0e10cSrcweir void ScDPObject::ToggleDetails(const DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj)
1536cdf0e10cSrcweir {
1537cdf0e10cSrcweir 	CreateObjects();			// create xSource if not already done
1538cdf0e10cSrcweir 
1539cdf0e10cSrcweir 	//	find dimension name
1540cdf0e10cSrcweir 
1541cdf0e10cSrcweir 	uno::Reference<container::XNamed> xDim;
1542cdf0e10cSrcweir 	uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1543cdf0e10cSrcweir 	uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
1544cdf0e10cSrcweir 	long nIntCount = xIntDims->getCount();
1545cdf0e10cSrcweir 	if ( rElemDesc.Dimension < nIntCount )
1546cdf0e10cSrcweir 	{
1547cdf0e10cSrcweir 		uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface(
1548cdf0e10cSrcweir 									xIntDims->getByIndex(rElemDesc.Dimension) );
1549cdf0e10cSrcweir 		xDim = uno::Reference<container::XNamed>( xIntDim, uno::UNO_QUERY );
1550cdf0e10cSrcweir 	}
1551cdf0e10cSrcweir 	DBG_ASSERT( xDim.is(), "dimension not found" );
1552cdf0e10cSrcweir 	if ( !xDim.is() ) return;
1553cdf0e10cSrcweir 	String aDimName = xDim->getName();
1554cdf0e10cSrcweir 
1555cdf0e10cSrcweir 	uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1556cdf0e10cSrcweir 	sal_Bool bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1557cdf0e10cSrcweir 						rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
1558cdf0e10cSrcweir 	if (bDataLayout)
1559cdf0e10cSrcweir 	{
1560cdf0e10cSrcweir 		//	the elements of the data layout dimension can't be found by their names
1561cdf0e10cSrcweir 		//	-> don't change anything
1562cdf0e10cSrcweir 		return;
1563cdf0e10cSrcweir 	}
1564cdf0e10cSrcweir 
1565cdf0e10cSrcweir 	//	query old state
1566cdf0e10cSrcweir 
1567cdf0e10cSrcweir 	long nHierCount = 0;
1568cdf0e10cSrcweir 	uno::Reference<container::XIndexAccess> xHiers;
1569cdf0e10cSrcweir 	uno::Reference<sheet::XHierarchiesSupplier> xHierSupp( xDim, uno::UNO_QUERY );
1570cdf0e10cSrcweir 	if ( xHierSupp.is() )
1571cdf0e10cSrcweir 	{
1572cdf0e10cSrcweir 		uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
1573cdf0e10cSrcweir 		xHiers = new ScNameToIndexAccess( xHiersName );
1574cdf0e10cSrcweir 		nHierCount = xHiers->getCount();
1575cdf0e10cSrcweir 	}
1576cdf0e10cSrcweir 	uno::Reference<uno::XInterface> xHier;
1577cdf0e10cSrcweir 	if ( rElemDesc.Hierarchy < nHierCount )
1578cdf0e10cSrcweir 		xHier = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(rElemDesc.Hierarchy) );
1579cdf0e10cSrcweir 	DBG_ASSERT( xHier.is(), "hierarchy not found" );
1580cdf0e10cSrcweir 	if ( !xHier.is() ) return;
1581cdf0e10cSrcweir 
1582cdf0e10cSrcweir 	long nLevCount = 0;
1583cdf0e10cSrcweir 	uno::Reference<container::XIndexAccess> xLevels;
1584cdf0e10cSrcweir 	uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHier, uno::UNO_QUERY );
1585cdf0e10cSrcweir 	if ( xLevSupp.is() )
1586cdf0e10cSrcweir 	{
1587cdf0e10cSrcweir 		uno::Reference<container::XNameAccess> xLevsName = xLevSupp->getLevels();
1588cdf0e10cSrcweir 		xLevels = new ScNameToIndexAccess( xLevsName );
1589cdf0e10cSrcweir 		nLevCount = xLevels->getCount();
1590cdf0e10cSrcweir 	}
1591cdf0e10cSrcweir 	uno::Reference<uno::XInterface> xLevel;
1592cdf0e10cSrcweir 	if ( rElemDesc.Level < nLevCount )
1593cdf0e10cSrcweir 		xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex(rElemDesc.Level) );
1594cdf0e10cSrcweir 	DBG_ASSERT( xLevel.is(), "level not found" );
1595cdf0e10cSrcweir 	if ( !xLevel.is() ) return;
1596cdf0e10cSrcweir 
1597cdf0e10cSrcweir 	uno::Reference<container::XNameAccess> xMembers;
1598cdf0e10cSrcweir 	uno::Reference<sheet::XMembersSupplier> xMbrSupp( xLevel, uno::UNO_QUERY );
1599cdf0e10cSrcweir 	if ( xMbrSupp.is() )
1600cdf0e10cSrcweir 		xMembers = xMbrSupp->getMembers();
1601cdf0e10cSrcweir 
1602cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
1603cdf0e10cSrcweir 	sal_Bool bShowDetails = sal_True;
1604cdf0e10cSrcweir 
1605cdf0e10cSrcweir 	if ( xMembers.is() )
1606cdf0e10cSrcweir 	{
1607cdf0e10cSrcweir 		if ( xMembers->hasByName(rElemDesc.MemberName) )
1608cdf0e10cSrcweir 		{
1609cdf0e10cSrcweir 			uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
1610cdf0e10cSrcweir 											xMembers->getByName(rElemDesc.MemberName) );
1611cdf0e10cSrcweir 			uno::Reference<beans::XPropertySet> xMbrProp( xMemberInt, uno::UNO_QUERY );
1612cdf0e10cSrcweir 			if ( xMbrProp.is() )
1613cdf0e10cSrcweir 			{
1614cdf0e10cSrcweir 				bShowDetails = ScUnoHelpFunctions::GetBoolProperty( xMbrProp,
1615cdf0e10cSrcweir 									rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS) );
1616cdf0e10cSrcweir 				//! don't set bFound if property is unknown?
1617cdf0e10cSrcweir 				bFound = sal_True;
1618cdf0e10cSrcweir 			}
1619cdf0e10cSrcweir 		}
1620cdf0e10cSrcweir 	}
1621cdf0e10cSrcweir 
1622cdf0e10cSrcweir 	DBG_ASSERT( bFound, "member not found" );
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir 	//!	use Hierarchy and Level in SaveData !!!!
1625cdf0e10cSrcweir 
1626cdf0e10cSrcweir 	//	modify pDestObj if set, this object otherwise
1627cdf0e10cSrcweir 	ScDPSaveData* pModifyData = pDestObj ? ( pDestObj->pSaveData ) : pSaveData;
1628cdf0e10cSrcweir 	DBG_ASSERT( pModifyData, "no data?" );
1629cdf0e10cSrcweir 	if ( pModifyData )
1630cdf0e10cSrcweir 	{
1631cdf0e10cSrcweir         const String aName = rElemDesc.MemberName;
1632cdf0e10cSrcweir 		pModifyData->GetDimensionByName(aDimName)->
1633cdf0e10cSrcweir 			GetMemberByName(aName)->SetShowDetails( !bShowDetails );	// toggle
1634cdf0e10cSrcweir 
1635cdf0e10cSrcweir 		if ( pDestObj )
1636cdf0e10cSrcweir 			pDestObj->InvalidateData();		// re-init source from SaveData
1637cdf0e10cSrcweir 		else
1638cdf0e10cSrcweir 			InvalidateData();				// re-init source from SaveData
1639cdf0e10cSrcweir 	}
1640cdf0e10cSrcweir }
1641cdf0e10cSrcweir 
lcl_FindName(const rtl::OUString & rString,const uno::Reference<container::XNameAccess> & xCollection)1642cdf0e10cSrcweir long lcl_FindName( const rtl::OUString& rString, const uno::Reference<container::XNameAccess>& xCollection )
1643cdf0e10cSrcweir {
1644cdf0e10cSrcweir 	if ( xCollection.is() )
1645cdf0e10cSrcweir 	{
1646cdf0e10cSrcweir 		uno::Sequence<rtl::OUString> aSeq = xCollection->getElementNames();
1647cdf0e10cSrcweir 		long nCount = aSeq.getLength();
1648cdf0e10cSrcweir 		const rtl::OUString* pArr = aSeq.getConstArray();
1649cdf0e10cSrcweir 		for (long nPos=0; nPos<nCount; nPos++)
1650cdf0e10cSrcweir 			if ( pArr[nPos] == rString )
1651cdf0e10cSrcweir 				return nPos;
1652cdf0e10cSrcweir 	}
1653cdf0e10cSrcweir 	return -1;		// not found
1654cdf0e10cSrcweir }
1655cdf0e10cSrcweir 
lcl_FirstSubTotal(const uno::Reference<beans::XPropertySet> & xDimProp)1656cdf0e10cSrcweir sal_uInt16 lcl_FirstSubTotal( const uno::Reference<beans::XPropertySet>& xDimProp )		// PIVOT_FUNC mask
1657cdf0e10cSrcweir {
1658cdf0e10cSrcweir 	uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
1659cdf0e10cSrcweir 	if ( xDimProp.is() && xDimSupp.is() )
1660cdf0e10cSrcweir 	{
1661cdf0e10cSrcweir 		uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
1662cdf0e10cSrcweir 		long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
1663cdf0e10cSrcweir 								rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
1664cdf0e10cSrcweir 		if ( nHierarchy >= xHiers->getCount() )
1665cdf0e10cSrcweir 			nHierarchy = 0;
1666cdf0e10cSrcweir 
1667cdf0e10cSrcweir 		uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface(
1668cdf0e10cSrcweir 									xHiers->getByIndex(nHierarchy) );
1669cdf0e10cSrcweir 		uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
1670cdf0e10cSrcweir 		if ( xHierSupp.is() )
1671cdf0e10cSrcweir 		{
1672cdf0e10cSrcweir 			uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() );
1673cdf0e10cSrcweir 			uno::Reference<uno::XInterface> xLevel =
1674cdf0e10cSrcweir 				ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex( 0 ) );
1675cdf0e10cSrcweir 			uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
1676cdf0e10cSrcweir 			if ( xLevProp.is() )
1677cdf0e10cSrcweir 			{
1678cdf0e10cSrcweir 				uno::Any aSubAny;
1679cdf0e10cSrcweir 				try
1680cdf0e10cSrcweir 				{
1681cdf0e10cSrcweir 					aSubAny = xLevProp->getPropertyValue(
1682cdf0e10cSrcweir 							rtl::OUString::createFromAscii(DP_PROP_SUBTOTALS) );
1683cdf0e10cSrcweir 				}
1684cdf0e10cSrcweir 				catch(uno::Exception&)
1685cdf0e10cSrcweir 				{
1686cdf0e10cSrcweir 				}
1687cdf0e10cSrcweir 				uno::Sequence<sheet::GeneralFunction> aSeq;
1688cdf0e10cSrcweir 				if ( aSubAny >>= aSeq )
1689cdf0e10cSrcweir 				{
1690cdf0e10cSrcweir 					sal_uInt16 nMask = 0;
1691cdf0e10cSrcweir 					const sheet::GeneralFunction* pArray = aSeq.getConstArray();
1692cdf0e10cSrcweir 					long nCount = aSeq.getLength();
1693cdf0e10cSrcweir 					for (long i=0; i<nCount; i++)
1694cdf0e10cSrcweir 						nMask |= ScDataPilotConversion::FunctionBit(pArray[i]);
1695cdf0e10cSrcweir 					return nMask;
1696cdf0e10cSrcweir 				}
1697cdf0e10cSrcweir 			}
1698cdf0e10cSrcweir 		}
1699cdf0e10cSrcweir 	}
1700cdf0e10cSrcweir 
1701cdf0e10cSrcweir 	DBG_ERROR("FirstSubTotal: NULL");
1702cdf0e10cSrcweir 	return 0;
1703cdf0e10cSrcweir }
1704cdf0e10cSrcweir 
lcl_CountBits(sal_uInt16 nBits)1705cdf0e10cSrcweir sal_uInt16 lcl_CountBits( sal_uInt16 nBits )
1706cdf0e10cSrcweir {
1707cdf0e10cSrcweir 	if (!nBits) return 0;
1708cdf0e10cSrcweir 
1709cdf0e10cSrcweir 	sal_uInt16 nCount = 0;
1710cdf0e10cSrcweir 	sal_uInt16 nMask = 1;
1711cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<16; i++)
1712cdf0e10cSrcweir 	{
1713cdf0e10cSrcweir 		if ( nBits & nMask )
1714cdf0e10cSrcweir 			++nCount;
1715cdf0e10cSrcweir 		nMask <<= 1;
1716cdf0e10cSrcweir 	}
1717cdf0e10cSrcweir 	return nCount;
1718cdf0e10cSrcweir }
1719cdf0e10cSrcweir 
lcl_FillOldFields(ScPivotFieldVector & rFields,const uno::Reference<sheet::XDimensionsSupplier> & xSource,sal_uInt16 nOrient,SCCOL nColAdd,bool bAddData)1720cdf0e10cSrcweir void lcl_FillOldFields( ScPivotFieldVector& rFields,
1721cdf0e10cSrcweir 							const uno::Reference<sheet::XDimensionsSupplier>& xSource,
1722cdf0e10cSrcweir 							sal_uInt16 nOrient, SCCOL nColAdd, bool bAddData )
1723cdf0e10cSrcweir {
1724cdf0e10cSrcweir 	bool bDataFound = false;
1725cdf0e10cSrcweir 	rFields.clear();
1726cdf0e10cSrcweir 
1727*86e1cf34SPedro Giffuni 	//!	merge multiple occurrences (data field with different functions)
1728cdf0e10cSrcweir 	//!	force data field in one dimension
1729cdf0e10cSrcweir 
1730cdf0e10cSrcweir     std::vector< long > aPos;
1731cdf0e10cSrcweir 
1732cdf0e10cSrcweir 	uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1733cdf0e10cSrcweir 	uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
1734cdf0e10cSrcweir 	long nDimCount = xDims->getCount();
1735cdf0e10cSrcweir     for (long nDim=0; nDim < nDimCount; nDim++)
1736cdf0e10cSrcweir 	{
1737cdf0e10cSrcweir 		uno::Reference<uno::XInterface> xIntDim =
1738cdf0e10cSrcweir 			ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
1739cdf0e10cSrcweir 		uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
1740cdf0e10cSrcweir 		long nDimOrient = ScUnoHelpFunctions::GetEnumProperty(
1741cdf0e10cSrcweir 							xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
1742cdf0e10cSrcweir 							sheet::DataPilotFieldOrientation_HIDDEN );
1743cdf0e10cSrcweir 		if ( xDimProp.is() && nDimOrient == nOrient )
1744cdf0e10cSrcweir 		{
1745cdf0e10cSrcweir 			sal_uInt16 nMask = 0;
1746cdf0e10cSrcweir 			if ( nOrient == sheet::DataPilotFieldOrientation_DATA )
1747cdf0e10cSrcweir 			{
1748cdf0e10cSrcweir 				sheet::GeneralFunction eFunc = (sheet::GeneralFunction)ScUnoHelpFunctions::GetEnumProperty(
1749cdf0e10cSrcweir 											xDimProp, rtl::OUString::createFromAscii(DP_PROP_FUNCTION),
1750cdf0e10cSrcweir 											sheet::GeneralFunction_NONE );
1751cdf0e10cSrcweir 				if ( eFunc == sheet::GeneralFunction_AUTO )
1752cdf0e10cSrcweir 				{
1753cdf0e10cSrcweir 					//!	test for numeric data
1754cdf0e10cSrcweir 					eFunc = sheet::GeneralFunction_SUM;
1755cdf0e10cSrcweir 				}
1756cdf0e10cSrcweir 				nMask = ScDataPilotConversion::FunctionBit(eFunc);
1757cdf0e10cSrcweir 			}
1758cdf0e10cSrcweir 			else
1759cdf0e10cSrcweir 				nMask = lcl_FirstSubTotal( xDimProp );		// from first hierarchy
1760cdf0e10cSrcweir 
1761cdf0e10cSrcweir 			sal_Bool bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1762cdf0e10cSrcweir 									rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
1763cdf0e10cSrcweir 			uno::Any aOrigAny;
1764cdf0e10cSrcweir 			try
1765cdf0e10cSrcweir 			{
1766cdf0e10cSrcweir 				aOrigAny = xDimProp->getPropertyValue(
1767cdf0e10cSrcweir 								rtl::OUString::createFromAscii(DP_PROP_ORIGINAL) );
1768cdf0e10cSrcweir 			}
1769cdf0e10cSrcweir 			catch(uno::Exception&)
1770cdf0e10cSrcweir 			{
1771cdf0e10cSrcweir 			}
1772cdf0e10cSrcweir 
1773cdf0e10cSrcweir 			long nDupSource = -1;
1774cdf0e10cSrcweir 			uno::Reference<uno::XInterface> xIntOrig = ScUnoHelpFunctions::AnyToInterface( aOrigAny );
1775cdf0e10cSrcweir 			if ( xIntOrig.is() )
1776cdf0e10cSrcweir 			{
1777cdf0e10cSrcweir 				uno::Reference<container::XNamed> xNameOrig( xIntOrig, uno::UNO_QUERY );
1778cdf0e10cSrcweir 				if ( xNameOrig.is() )
1779cdf0e10cSrcweir 					nDupSource = lcl_FindName( xNameOrig->getName(), xDimsName );
1780cdf0e10cSrcweir 			}
1781cdf0e10cSrcweir 
1782cdf0e10cSrcweir 			bool bDupUsed = false;
1783cdf0e10cSrcweir 			if ( nDupSource >= 0 )
1784cdf0e10cSrcweir 			{
1785cdf0e10cSrcweir 				//	add function bit to previous entry
1786cdf0e10cSrcweir 
1787cdf0e10cSrcweir 				SCsCOL nCompCol;
1788cdf0e10cSrcweir 				if ( bDataLayout )
1789cdf0e10cSrcweir 					nCompCol = PIVOT_DATA_FIELD;
1790cdf0e10cSrcweir 				else
1791cdf0e10cSrcweir 					nCompCol = static_cast<SCsCOL>(nDupSource)+nColAdd;		//! seek source column from name
1792cdf0e10cSrcweir 
1793cdf0e10cSrcweir 				for (ScPivotFieldVector::iterator aIt = rFields.begin(), aEnd = rFields.end(); (aIt != aEnd) && !bDupUsed; ++aIt)
1794cdf0e10cSrcweir 					if ( aIt->nCol == nCompCol )
1795cdf0e10cSrcweir 					{
1796cdf0e10cSrcweir 						//	add to previous column only if new bits aren't already set there
1797cdf0e10cSrcweir 						if ( ( aIt->nFuncMask & nMask ) == 0 )
1798cdf0e10cSrcweir 						{
1799cdf0e10cSrcweir 							aIt->nFuncMask |= nMask;
1800cdf0e10cSrcweir 							aIt->nFuncCount = lcl_CountBits( aIt->nFuncMask );
1801cdf0e10cSrcweir 							bDupUsed = true;
1802cdf0e10cSrcweir 						}
1803cdf0e10cSrcweir 					}
1804cdf0e10cSrcweir 			}
1805cdf0e10cSrcweir 
1806cdf0e10cSrcweir 			if ( !bDupUsed )		// also for duplicated dim if original has different orientation
1807cdf0e10cSrcweir 			{
1808cdf0e10cSrcweir                 rFields.resize( rFields.size() + 1 );
1809cdf0e10cSrcweir                 ScPivotField& rField = rFields.back();
1810cdf0e10cSrcweir 
1811cdf0e10cSrcweir 				if ( bDataLayout )
1812cdf0e10cSrcweir 				{
1813cdf0e10cSrcweir 					rField.nCol = PIVOT_DATA_FIELD;
1814cdf0e10cSrcweir 					bDataFound = true;
1815cdf0e10cSrcweir 				}
1816cdf0e10cSrcweir 				else if ( nDupSource >= 0 )		// if source was not found (different orientation)
1817cdf0e10cSrcweir 					rField.nCol = static_cast<SCsCOL>(nDupSource)+nColAdd;		//! seek from name
1818cdf0e10cSrcweir 				else
1819cdf0e10cSrcweir 					rField.nCol = static_cast<SCsCOL>(nDim)+nColAdd;	//! seek source column from name
1820cdf0e10cSrcweir 
1821cdf0e10cSrcweir 				rField.nFuncMask = nMask;
1822cdf0e10cSrcweir 				rField.nFuncCount = lcl_CountBits( nMask );
1823cdf0e10cSrcweir 
1824cdf0e10cSrcweir                 aPos.push_back( ScUnoHelpFunctions::GetLongProperty( xDimProp,
1825cdf0e10cSrcweir 									rtl::OUString::createFromAscii(DP_PROP_POSITION) ) );
1826cdf0e10cSrcweir 
1827cdf0e10cSrcweir                 try
1828cdf0e10cSrcweir                 {
1829cdf0e10cSrcweir                     if( nOrient == sheet::DataPilotFieldOrientation_DATA )
1830cdf0e10cSrcweir                         xDimProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_REFVALUE ) ) )
1831cdf0e10cSrcweir                             >>= rFields.back().maFieldRef;
1832cdf0e10cSrcweir                 }
1833cdf0e10cSrcweir                 catch( uno::Exception& )
1834cdf0e10cSrcweir                 {
1835cdf0e10cSrcweir                 }
1836cdf0e10cSrcweir 			}
1837cdf0e10cSrcweir 		}
1838cdf0e10cSrcweir 	}
1839cdf0e10cSrcweir 
1840cdf0e10cSrcweir 	//	sort by getPosition() value
1841cdf0e10cSrcweir     size_t nSize = aPos.size();
1842cdf0e10cSrcweir 	for (size_t i=0; i+1<nSize; i++)
1843cdf0e10cSrcweir 	{
1844cdf0e10cSrcweir 		for (size_t j=0; j+i+1<nSize; j++)
1845cdf0e10cSrcweir             if ( aPos[j+1] < aPos[j] )
1846cdf0e10cSrcweir 			{
1847cdf0e10cSrcweir                 std::swap( aPos[j], aPos[j+1] );
1848cdf0e10cSrcweir                 std::swap( rFields[j], rFields[j+1] );
1849cdf0e10cSrcweir 			}
1850cdf0e10cSrcweir 	}
1851cdf0e10cSrcweir 
1852cdf0e10cSrcweir 	if ( bAddData && !bDataFound )
1853cdf0e10cSrcweir 	{
1854cdf0e10cSrcweir         rFields.resize( rFields.size() + 1 );
1855cdf0e10cSrcweir         ScPivotField& rField = rFields.back();
1856cdf0e10cSrcweir 		rField.nCol = PIVOT_DATA_FIELD;
1857cdf0e10cSrcweir 		rField.nFuncMask = 0;
1858cdf0e10cSrcweir 		rField.nFuncCount = 0;
1859cdf0e10cSrcweir 	}
1860cdf0e10cSrcweir }
1861cdf0e10cSrcweir 
FillOldParam(ScPivotParam & rParam) const1862cdf0e10cSrcweir sal_Bool ScDPObject::FillOldParam(ScPivotParam& rParam) const
1863cdf0e10cSrcweir {
1864cdf0e10cSrcweir 	((ScDPObject*)this)->CreateObjects();		// xSource is needed for field numbers
1865cdf0e10cSrcweir 
1866cdf0e10cSrcweir 	rParam.nCol = aOutRange.aStart.Col();
1867cdf0e10cSrcweir 	rParam.nRow = aOutRange.aStart.Row();
1868cdf0e10cSrcweir 	rParam.nTab = aOutRange.aStart.Tab();
1869cdf0e10cSrcweir 	// ppLabelArr / nLabels is not changed
1870cdf0e10cSrcweir 
1871cdf0e10cSrcweir 	SCCOL nColAdd = 0;
1872cdf0e10cSrcweir 	bool bAddData = ( lcl_GetDataGetOrientation( xSource ) == sheet::DataPilotFieldOrientation_HIDDEN );
1873cdf0e10cSrcweir     lcl_FillOldFields( rParam.maPageArr, xSource, sheet::DataPilotFieldOrientation_PAGE,   nColAdd, false );
1874cdf0e10cSrcweir 	lcl_FillOldFields( rParam.maColArr,  xSource, sheet::DataPilotFieldOrientation_COLUMN, nColAdd, bAddData );
1875cdf0e10cSrcweir 	lcl_FillOldFields( rParam.maRowArr,  xSource, sheet::DataPilotFieldOrientation_ROW,    nColAdd, false );
1876cdf0e10cSrcweir 	lcl_FillOldFields( rParam.maDataArr, xSource, sheet::DataPilotFieldOrientation_DATA,   nColAdd, false );
1877cdf0e10cSrcweir 
1878cdf0e10cSrcweir 	uno::Reference<beans::XPropertySet> xProp( xSource, uno::UNO_QUERY );
1879cdf0e10cSrcweir 	if (xProp.is())
1880cdf0e10cSrcweir 	{
1881cdf0e10cSrcweir 		try
1882cdf0e10cSrcweir 		{
1883cdf0e10cSrcweir 			rParam.bMakeTotalCol = ScUnoHelpFunctions::GetBoolProperty( xProp,
1884cdf0e10cSrcweir 						rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND), sal_True );
1885cdf0e10cSrcweir 			rParam.bMakeTotalRow = ScUnoHelpFunctions::GetBoolProperty( xProp,
1886cdf0e10cSrcweir 						rtl::OUString::createFromAscii(DP_PROP_ROWGRAND), sal_True );
1887cdf0e10cSrcweir 
1888cdf0e10cSrcweir 			// following properties may be missing for external sources
1889cdf0e10cSrcweir 			rParam.bIgnoreEmptyRows = ScUnoHelpFunctions::GetBoolProperty( xProp,
1890cdf0e10cSrcweir 						rtl::OUString::createFromAscii(DP_PROP_IGNOREEMPTY) );
1891cdf0e10cSrcweir 			rParam.bDetectCategories = ScUnoHelpFunctions::GetBoolProperty( xProp,
1892cdf0e10cSrcweir 						rtl::OUString::createFromAscii(DP_PROP_REPEATIFEMPTY) );
1893cdf0e10cSrcweir 		}
1894cdf0e10cSrcweir 		catch(uno::Exception&)
1895cdf0e10cSrcweir 		{
1896cdf0e10cSrcweir 			// no error
1897cdf0e10cSrcweir 		}
1898cdf0e10cSrcweir 	}
1899cdf0e10cSrcweir 	return sal_True;
1900cdf0e10cSrcweir }
1901cdf0e10cSrcweir 
lcl_FillLabelData(ScDPLabelData & rData,const uno::Reference<beans::XPropertySet> & xDimProp)1902cdf0e10cSrcweir void lcl_FillLabelData( ScDPLabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
1903cdf0e10cSrcweir {
1904cdf0e10cSrcweir 	uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
1905cdf0e10cSrcweir 	if ( xDimProp.is() && xDimSupp.is() )
1906cdf0e10cSrcweir 	{
1907cdf0e10cSrcweir 		uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() );
1908cdf0e10cSrcweir 		long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp,
1909cdf0e10cSrcweir 								rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
1910cdf0e10cSrcweir 		if ( nHierarchy >= xHiers->getCount() )
1911cdf0e10cSrcweir 			nHierarchy = 0;
1912cdf0e10cSrcweir         rData.mnUsedHier = nHierarchy;
1913cdf0e10cSrcweir 
1914cdf0e10cSrcweir 		uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface(
1915cdf0e10cSrcweir 									xHiers->getByIndex(nHierarchy) );
1916cdf0e10cSrcweir 
1917cdf0e10cSrcweir 		uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
1918cdf0e10cSrcweir 		if ( xHierSupp.is() )
1919cdf0e10cSrcweir 		{
1920cdf0e10cSrcweir 			uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() );
1921cdf0e10cSrcweir 			uno::Reference<uno::XInterface> xLevel =
1922cdf0e10cSrcweir 				ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex( 0 ) );
1923cdf0e10cSrcweir 			uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY );
1924cdf0e10cSrcweir 			if ( xLevProp.is() )
1925cdf0e10cSrcweir             {
1926cdf0e10cSrcweir                 rData.mbShowAll = ScUnoHelpFunctions::GetBoolProperty( xLevProp,
1927cdf0e10cSrcweir 									rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY) );
1928cdf0e10cSrcweir 
1929cdf0e10cSrcweir                 try
1930cdf0e10cSrcweir                 {
1931cdf0e10cSrcweir                     xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SORTING ) ) )
1932cdf0e10cSrcweir                         >>= rData.maSortInfo;
1933cdf0e10cSrcweir                     xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_LAYOUT ) ) )
1934cdf0e10cSrcweir                         >>= rData.maLayoutInfo;
1935cdf0e10cSrcweir                     xLevProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_AUTOSHOW ) ) )
1936cdf0e10cSrcweir                         >>= rData.maShowInfo;
1937cdf0e10cSrcweir                 }
1938cdf0e10cSrcweir                 catch(uno::Exception&)
1939cdf0e10cSrcweir                 {
1940cdf0e10cSrcweir                 }
1941cdf0e10cSrcweir             }
1942cdf0e10cSrcweir 		}
1943cdf0e10cSrcweir 	}
1944cdf0e10cSrcweir }
1945cdf0e10cSrcweir 
FillLabelData(ScPivotParam & rParam)1946cdf0e10cSrcweir sal_Bool ScDPObject::FillLabelData(ScPivotParam& rParam)
1947cdf0e10cSrcweir {
1948cdf0e10cSrcweir     rParam.maLabelArray.clear();
1949cdf0e10cSrcweir 
1950cdf0e10cSrcweir 	((ScDPObject*)this)->CreateObjects();
1951cdf0e10cSrcweir 
1952cdf0e10cSrcweir 	uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1953cdf0e10cSrcweir 	uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
1954cdf0e10cSrcweir 	long nDimCount = xDims->getCount();
1955cdf0e10cSrcweir 	if ( nDimCount > MAX_LABELS )
1956cdf0e10cSrcweir 		nDimCount = MAX_LABELS;
1957cdf0e10cSrcweir 	if (!nDimCount)
1958cdf0e10cSrcweir 		return sal_False;
1959cdf0e10cSrcweir 
1960cdf0e10cSrcweir 	for (long nDim=0; nDim < nDimCount; nDim++)
1961cdf0e10cSrcweir 	{
1962cdf0e10cSrcweir 		String aFieldName;
1963cdf0e10cSrcweir 		uno::Reference<uno::XInterface> xIntDim =
1964cdf0e10cSrcweir 			ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
1965cdf0e10cSrcweir 		uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
1966cdf0e10cSrcweir 		uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY );
1967cdf0e10cSrcweir 
1968cdf0e10cSrcweir 		if ( xDimName.is() && xDimProp.is() )
1969cdf0e10cSrcweir 		{
1970cdf0e10cSrcweir 			sal_Bool bDuplicated = sal_False;
1971cdf0e10cSrcweir 			sal_Bool bData = ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1972cdf0e10cSrcweir 							rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
1973cdf0e10cSrcweir 			//!	error checking -- is "IsDataLayoutDimension" property required??
1974cdf0e10cSrcweir 
1975cdf0e10cSrcweir 			try
1976cdf0e10cSrcweir 			{
1977cdf0e10cSrcweir 				aFieldName = String( xDimName->getName() );
1978cdf0e10cSrcweir 
1979cdf0e10cSrcweir 				uno::Any aOrigAny = xDimProp->getPropertyValue(
1980cdf0e10cSrcweir 							rtl::OUString::createFromAscii(DP_PROP_ORIGINAL) );
1981cdf0e10cSrcweir 				uno::Reference<uno::XInterface> xIntOrig;
1982cdf0e10cSrcweir 				if ( (aOrigAny >>= xIntOrig) && xIntOrig.is() )
1983cdf0e10cSrcweir 					bDuplicated = sal_True;
1984cdf0e10cSrcweir 			}
1985cdf0e10cSrcweir 			catch(uno::Exception&)
1986cdf0e10cSrcweir 			{
1987cdf0e10cSrcweir 			}
1988cdf0e10cSrcweir 
1989cdf0e10cSrcweir             OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
1990cdf0e10cSrcweir                 xDimProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
1991cdf0e10cSrcweir 
1992cdf0e10cSrcweir 			if ( aFieldName.Len() && !bData && !bDuplicated )
1993cdf0e10cSrcweir 			{
1994cdf0e10cSrcweir                 SCsCOL nCol = static_cast< SCsCOL >( nDim );           //! ???
1995cdf0e10cSrcweir                 bool bIsValue = true;                               //! check
1996cdf0e10cSrcweir 
1997cdf0e10cSrcweir                 ScDPLabelData aNewLabel(aFieldName, nCol, bIsValue);
1998cdf0e10cSrcweir                 aNewLabel.maLayoutName = aLayoutName;
1999cdf0e10cSrcweir                 GetHierarchies(nDim, aNewLabel.maHiers);
2000cdf0e10cSrcweir                 GetMembers(nDim, GetUsedHierarchy(nDim), aNewLabel.maMembers);
2001cdf0e10cSrcweir                 lcl_FillLabelData(aNewLabel, xDimProp);
2002cdf0e10cSrcweir                 aNewLabel.mnFlags = ScUnoHelpFunctions::GetLongProperty( xDimProp,
2003cdf0e10cSrcweir                                         rtl::OUString::createFromAscii(SC_UNO_FLAGS), 0 );
2004cdf0e10cSrcweir                 rParam.maLabelArray.push_back(aNewLabel);
2005cdf0e10cSrcweir 			}
2006cdf0e10cSrcweir 		}
2007cdf0e10cSrcweir 	}
2008cdf0e10cSrcweir 
2009cdf0e10cSrcweir 	return sal_True;
2010cdf0e10cSrcweir }
2011cdf0e10cSrcweir 
GetHierarchiesNA(sal_Int32 nDim,uno::Reference<container::XNameAccess> & xHiers)2012cdf0e10cSrcweir sal_Bool ScDPObject::GetHierarchiesNA( sal_Int32 nDim, uno::Reference< container::XNameAccess >& xHiers )
2013cdf0e10cSrcweir {
2014cdf0e10cSrcweir     sal_Bool bRet = sal_False;
2015cdf0e10cSrcweir     uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
2016cdf0e10cSrcweir     uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
2017cdf0e10cSrcweir     if( xIntDims.is() )
2018cdf0e10cSrcweir     {
2019cdf0e10cSrcweir         uno::Reference<sheet::XHierarchiesSupplier> xHierSup(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
2020cdf0e10cSrcweir         if (xHierSup.is())
2021cdf0e10cSrcweir         {
2022cdf0e10cSrcweir             xHiers.set( xHierSup->getHierarchies() );
2023cdf0e10cSrcweir             bRet = xHiers.is();
2024cdf0e10cSrcweir         }
2025cdf0e10cSrcweir     }
2026cdf0e10cSrcweir     return bRet;
2027cdf0e10cSrcweir }
2028cdf0e10cSrcweir 
GetHierarchies(sal_Int32 nDim,uno::Sequence<rtl::OUString> & rHiers)2029cdf0e10cSrcweir sal_Bool ScDPObject::GetHierarchies( sal_Int32 nDim, uno::Sequence< rtl::OUString >& rHiers )
2030cdf0e10cSrcweir {
2031cdf0e10cSrcweir     sal_Bool bRet = sal_False;
2032cdf0e10cSrcweir     uno::Reference< container::XNameAccess > xHiersNA;
2033cdf0e10cSrcweir     if( GetHierarchiesNA( nDim, xHiersNA ) )
2034cdf0e10cSrcweir     {
2035cdf0e10cSrcweir         rHiers = xHiersNA->getElementNames();
2036cdf0e10cSrcweir         bRet = sal_True;
2037cdf0e10cSrcweir     }
2038cdf0e10cSrcweir     return bRet;
2039cdf0e10cSrcweir }
2040cdf0e10cSrcweir 
GetUsedHierarchy(sal_Int32 nDim)2041cdf0e10cSrcweir sal_Int32 ScDPObject::GetUsedHierarchy( sal_Int32 nDim )
2042cdf0e10cSrcweir {
2043cdf0e10cSrcweir     sal_Int32 nHier = 0;
2044cdf0e10cSrcweir     uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
2045cdf0e10cSrcweir     uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
2046cdf0e10cSrcweir     uno::Reference<beans::XPropertySet> xDim(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
2047cdf0e10cSrcweir     if (xDim.is())
2048cdf0e10cSrcweir         nHier = ScUnoHelpFunctions::GetLongProperty( xDim, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_USEDHIER ) ) );
2049cdf0e10cSrcweir     return nHier;
2050cdf0e10cSrcweir }
2051cdf0e10cSrcweir 
GetMembersNA(sal_Int32 nDim,uno::Reference<container::XNameAccess> & xMembers)2052cdf0e10cSrcweir sal_Bool ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< container::XNameAccess >& xMembers )
2053cdf0e10cSrcweir {
2054cdf0e10cSrcweir     return GetMembersNA( nDim, GetUsedHierarchy( nDim ), xMembers );
2055cdf0e10cSrcweir }
2056cdf0e10cSrcweir 
GetMembersNA(sal_Int32 nDim,sal_Int32 nHier,uno::Reference<container::XNameAccess> & xMembers)2057cdf0e10cSrcweir sal_Bool ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< container::XNameAccess >& xMembers )
2058cdf0e10cSrcweir {
2059cdf0e10cSrcweir     sal_Bool bRet = sal_False;
2060cdf0e10cSrcweir     uno::Reference<container::XNameAccess> xDimsName( GetSource()->getDimensions() );
2061cdf0e10cSrcweir     uno::Reference<container::XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
2062cdf0e10cSrcweir     uno::Reference<beans::XPropertySet> xDim(xIntDims->getByIndex( nDim ), uno::UNO_QUERY);
2063cdf0e10cSrcweir     if (xDim.is())
2064cdf0e10cSrcweir     {
2065cdf0e10cSrcweir         uno::Reference<sheet::XHierarchiesSupplier> xHierSup(xDim, uno::UNO_QUERY);
2066cdf0e10cSrcweir         if (xHierSup.is())
2067cdf0e10cSrcweir         {
2068cdf0e10cSrcweir             uno::Reference<container::XIndexAccess> xHiers(new ScNameToIndexAccess(xHierSup->getHierarchies()));
2069cdf0e10cSrcweir             uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHiers->getByIndex(nHier), uno::UNO_QUERY );
2070cdf0e10cSrcweir             if ( xLevSupp.is() )
2071cdf0e10cSrcweir             {
2072cdf0e10cSrcweir                 uno::Reference<container::XIndexAccess> xLevels(new ScNameToIndexAccess( xLevSupp->getLevels()));
2073cdf0e10cSrcweir                 if (xLevels.is())
2074cdf0e10cSrcweir                 {
2075cdf0e10cSrcweir                     sal_Int32 nLevCount = xLevels->getCount();
2076cdf0e10cSrcweir                     if (nLevCount > 0)
2077cdf0e10cSrcweir                     {
2078cdf0e10cSrcweir                         uno::Reference<sheet::XMembersSupplier> xMembSupp( xLevels->getByIndex(0), uno::UNO_QUERY );
2079cdf0e10cSrcweir                         if ( xMembSupp.is() )
2080cdf0e10cSrcweir                         {
2081cdf0e10cSrcweir                             xMembers.set(xMembSupp->getMembers());
2082cdf0e10cSrcweir                             bRet = sal_True;
2083cdf0e10cSrcweir                         }
2084cdf0e10cSrcweir                     }
2085cdf0e10cSrcweir                 }
2086cdf0e10cSrcweir             }
2087cdf0e10cSrcweir         }
2088cdf0e10cSrcweir     }
2089cdf0e10cSrcweir     return bRet;
2090cdf0e10cSrcweir }
2091cdf0e10cSrcweir 
2092cdf0e10cSrcweir //------------------------------------------------------------------------
2093cdf0e10cSrcweir //	convert old pivot tables into new datapilot tables
2094cdf0e10cSrcweir 
lcl_GetDimName(const uno::Reference<sheet::XDimensionsSupplier> & xSource,long nDim)2095cdf0e10cSrcweir String lcl_GetDimName( const uno::Reference<sheet::XDimensionsSupplier>& xSource, long nDim )
2096cdf0e10cSrcweir {
2097cdf0e10cSrcweir 	rtl::OUString aName;
2098cdf0e10cSrcweir 	if ( xSource.is() )
2099cdf0e10cSrcweir 	{
2100cdf0e10cSrcweir 		uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
2101cdf0e10cSrcweir 		uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName );
2102cdf0e10cSrcweir 		long nDimCount = xDims->getCount();
2103cdf0e10cSrcweir 		if ( nDim < nDimCount )
2104cdf0e10cSrcweir 		{
2105cdf0e10cSrcweir 			uno::Reference<uno::XInterface> xIntDim =
2106cdf0e10cSrcweir 				ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
2107cdf0e10cSrcweir 			uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY );
2108cdf0e10cSrcweir 			if (xDimName.is())
2109cdf0e10cSrcweir 			{
2110cdf0e10cSrcweir 				try
2111cdf0e10cSrcweir 				{
2112cdf0e10cSrcweir 					aName = xDimName->getName();
2113cdf0e10cSrcweir 				}
2114cdf0e10cSrcweir 				catch(uno::Exception&)
2115cdf0e10cSrcweir 				{
2116cdf0e10cSrcweir 				}
2117cdf0e10cSrcweir 			}
2118cdf0e10cSrcweir 		}
2119cdf0e10cSrcweir 	}
2120cdf0e10cSrcweir 	return aName;
2121cdf0e10cSrcweir }
2122cdf0e10cSrcweir 
2123cdf0e10cSrcweir // static
ConvertOrientation(ScDPSaveData & rSaveData,const ScPivotFieldVector & rFields,sal_uInt16 nOrient,ScDocument * pDoc,SCROW nRow,SCTAB nTab,const uno::Reference<sheet::XDimensionsSupplier> & xSource,bool bOldDefaults,const ScPivotFieldVector * pRefColFields,const ScPivotFieldVector * pRefRowFields,const ScPivotFieldVector * pRefPageFields)2124cdf0e10cSrcweir void ScDPObject::ConvertOrientation( ScDPSaveData& rSaveData,
2125cdf0e10cSrcweir 							const ScPivotFieldVector& rFields, sal_uInt16 nOrient,
2126cdf0e10cSrcweir 							ScDocument* pDoc, SCROW nRow, SCTAB nTab,
2127cdf0e10cSrcweir 							const uno::Reference<sheet::XDimensionsSupplier>& xSource,
2128cdf0e10cSrcweir 							bool bOldDefaults,
2129cdf0e10cSrcweir 							const ScPivotFieldVector* pRefColFields,
2130cdf0e10cSrcweir                             const ScPivotFieldVector* pRefRowFields,
2131cdf0e10cSrcweir                             const ScPivotFieldVector* pRefPageFields )
2132cdf0e10cSrcweir {
2133cdf0e10cSrcweir 	//	pDoc or xSource must be set
2134cdf0e10cSrcweir 	DBG_ASSERT( pDoc || xSource.is(), "missing string source" );
2135cdf0e10cSrcweir 
2136cdf0e10cSrcweir 	String aDocStr;
2137cdf0e10cSrcweir 	ScDPSaveDimension* pDim;
2138cdf0e10cSrcweir 
2139cdf0e10cSrcweir 	for (ScPivotFieldVector::const_iterator aIt = rFields.begin(), aEnd = rFields.end(); aIt != aEnd; ++aIt)
2140cdf0e10cSrcweir 	{
2141cdf0e10cSrcweir 		SCCOL nCol = aIt->nCol;
2142cdf0e10cSrcweir 		sal_uInt16 nFuncs = aIt->nFuncMask;
2143cdf0e10cSrcweir         const sheet::DataPilotFieldReference& rFieldRef = aIt->maFieldRef;
2144cdf0e10cSrcweir 
2145cdf0e10cSrcweir 		if ( nCol == PIVOT_DATA_FIELD )
2146cdf0e10cSrcweir 			pDim = rSaveData.GetDataLayoutDimension();
2147cdf0e10cSrcweir 		else
2148cdf0e10cSrcweir 		{
2149cdf0e10cSrcweir 			if ( pDoc )
2150cdf0e10cSrcweir 				pDoc->GetString( nCol, nRow, nTab, aDocStr );
2151cdf0e10cSrcweir 			else
2152cdf0e10cSrcweir 				aDocStr = lcl_GetDimName( xSource, nCol );	// cols must start at 0
2153cdf0e10cSrcweir 
2154cdf0e10cSrcweir 			if ( aDocStr.Len() )
2155cdf0e10cSrcweir 				pDim = rSaveData.GetDimensionByName(aDocStr);
2156cdf0e10cSrcweir 			else
2157cdf0e10cSrcweir 				pDim = NULL;
2158cdf0e10cSrcweir 		}
2159cdf0e10cSrcweir 
2160cdf0e10cSrcweir 		if ( pDim )
2161cdf0e10cSrcweir 		{
2162cdf0e10cSrcweir 			if ( nOrient == sheet::DataPilotFieldOrientation_DATA )		// set summary function
2163cdf0e10cSrcweir 			{
2164cdf0e10cSrcweir 				//	generate an individual entry for each function
2165cdf0e10cSrcweir 				bool bFirst = true;
2166cdf0e10cSrcweir 
2167cdf0e10cSrcweir                 //  if a dimension is used for column/row/page and data,
2168cdf0e10cSrcweir 				//	use duplicated dimensions for all data occurrences
2169cdf0e10cSrcweir 				if (pRefColFields)
2170cdf0e10cSrcweir                     for (ScPivotFieldVector::const_iterator aRefIt = pRefColFields->begin(), aRefEnd = pRefColFields->end(); bFirst && (aRefIt != aRefEnd); ++aRefIt)
2171cdf0e10cSrcweir 						if (aRefIt->nCol == nCol)
2172cdf0e10cSrcweir 							bFirst = false;
2173cdf0e10cSrcweir 				if (pRefRowFields)
2174cdf0e10cSrcweir                     for (ScPivotFieldVector::const_iterator aRefIt = pRefRowFields->begin(), aRefEnd = pRefRowFields->end(); bFirst && (aRefIt != aRefEnd); ++aRefIt)
2175cdf0e10cSrcweir 						if (aRefIt->nCol == nCol)
2176cdf0e10cSrcweir 							bFirst = false;
2177cdf0e10cSrcweir                 if (pRefPageFields)
2178cdf0e10cSrcweir                     for (ScPivotFieldVector::const_iterator aRefIt = pRefPageFields->begin(), aRefEnd = pRefPageFields->end(); bFirst && (aRefIt != aRefEnd); ++aRefIt)
2179cdf0e10cSrcweir 						if (aRefIt->nCol == nCol)
2180cdf0e10cSrcweir 							bFirst = false;
2181cdf0e10cSrcweir 
2182cdf0e10cSrcweir 				//	if set via api, a data column may occur several times
2183cdf0e10cSrcweir 				//	(if the function hasn't been changed yet) -> also look for duplicate data column
2184cdf0e10cSrcweir                 for (ScPivotFieldVector::const_iterator aRefIt = rFields.begin(); bFirst && (aRefIt != aIt); ++aRefIt)
2185cdf0e10cSrcweir 					if (aRefIt->nCol == nCol)
2186cdf0e10cSrcweir 						bFirst = false;
2187cdf0e10cSrcweir 
2188cdf0e10cSrcweir 				sal_uInt16 nMask = 1;
2189cdf0e10cSrcweir 				for (sal_uInt16 nBit=0; nBit<16; nBit++)
2190cdf0e10cSrcweir 				{
2191cdf0e10cSrcweir 					if ( nFuncs & nMask )
2192cdf0e10cSrcweir 					{
2193cdf0e10cSrcweir 						sheet::GeneralFunction eFunc = ScDataPilotConversion::FirstFunc( nMask );
2194cdf0e10cSrcweir                         ScDPSaveDimension* pCurrDim = bFirst ? pDim : rSaveData.DuplicateDimension(pDim->GetName());
2195cdf0e10cSrcweir                         pCurrDim->SetOrientation( nOrient );
2196cdf0e10cSrcweir                         pCurrDim->SetFunction( sal::static_int_cast<sal_uInt16>(eFunc) );
2197cdf0e10cSrcweir 
2198cdf0e10cSrcweir                         if( rFieldRef.ReferenceType == sheet::DataPilotFieldReferenceType::NONE )
2199cdf0e10cSrcweir                             pCurrDim->SetReferenceValue( 0 );
2200cdf0e10cSrcweir                         else
2201cdf0e10cSrcweir                             pCurrDim->SetReferenceValue( &rFieldRef );
2202cdf0e10cSrcweir 
2203cdf0e10cSrcweir                         bFirst = false;
2204cdf0e10cSrcweir 					}
2205cdf0e10cSrcweir 					nMask *= 2;
2206cdf0e10cSrcweir 				}
2207cdf0e10cSrcweir 			}
2208cdf0e10cSrcweir 			else											// set SubTotals
2209cdf0e10cSrcweir 			{
2210cdf0e10cSrcweir 				pDim->SetOrientation( nOrient );
2211cdf0e10cSrcweir 
2212cdf0e10cSrcweir 				sal_uInt16 nFuncArray[16];
2213cdf0e10cSrcweir 				sal_uInt16 nFuncCount = 0;
2214cdf0e10cSrcweir 				sal_uInt16 nMask = 1;
2215cdf0e10cSrcweir 				for (sal_uInt16 nBit=0; nBit<16; nBit++)
2216cdf0e10cSrcweir 				{
2217cdf0e10cSrcweir 					if ( nFuncs & nMask )
2218cdf0e10cSrcweir                         nFuncArray[nFuncCount++] = sal::static_int_cast<sal_uInt16>(ScDataPilotConversion::FirstFunc( nMask ));
2219cdf0e10cSrcweir 					nMask *= 2;
2220cdf0e10cSrcweir 				}
2221cdf0e10cSrcweir 				pDim->SetSubTotals( nFuncCount, nFuncArray );
2222cdf0e10cSrcweir 
2223cdf0e10cSrcweir 				//	ShowEmpty was implicit in old tables,
2224cdf0e10cSrcweir 				//	must be set for data layout dimension (not accessible in dialog)
2225cdf0e10cSrcweir 				if ( bOldDefaults || nCol == PIVOT_DATA_FIELD )
2226cdf0e10cSrcweir 					pDim->SetShowEmpty( sal_True );
2227cdf0e10cSrcweir 			}
2228cdf0e10cSrcweir 		}
2229cdf0e10cSrcweir 	}
2230cdf0e10cSrcweir }
2231cdf0e10cSrcweir 
2232cdf0e10cSrcweir // static
IsOrientationAllowed(sal_uInt16 nOrient,sal_Int32 nDimFlags)2233cdf0e10cSrcweir bool ScDPObject::IsOrientationAllowed( sal_uInt16 nOrient, sal_Int32 nDimFlags )
2234cdf0e10cSrcweir {
2235cdf0e10cSrcweir     bool bAllowed = true;
2236cdf0e10cSrcweir     switch (nOrient)
2237cdf0e10cSrcweir     {
2238cdf0e10cSrcweir         case sheet::DataPilotFieldOrientation_PAGE:
2239cdf0e10cSrcweir             bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_PAGE_ORIENTATION ) == 0;
2240cdf0e10cSrcweir             break;
2241cdf0e10cSrcweir         case sheet::DataPilotFieldOrientation_COLUMN:
2242cdf0e10cSrcweir             bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_COLUMN_ORIENTATION ) == 0;
2243cdf0e10cSrcweir             break;
2244cdf0e10cSrcweir         case sheet::DataPilotFieldOrientation_ROW:
2245cdf0e10cSrcweir             bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_ROW_ORIENTATION ) == 0;
2246cdf0e10cSrcweir             break;
2247cdf0e10cSrcweir         case sheet::DataPilotFieldOrientation_DATA:
2248cdf0e10cSrcweir             bAllowed = ( nDimFlags & sheet::DimensionFlags::NO_DATA_ORIENTATION ) == 0;
2249cdf0e10cSrcweir             break;
2250cdf0e10cSrcweir         default:
2251cdf0e10cSrcweir             {
2252cdf0e10cSrcweir                 // allowed to remove from previous orientation
2253cdf0e10cSrcweir             }
2254cdf0e10cSrcweir     }
2255cdf0e10cSrcweir     return bAllowed;
2256cdf0e10cSrcweir }
2257cdf0e10cSrcweir 
2258cdf0e10cSrcweir // -----------------------------------------------------------------------
2259cdf0e10cSrcweir 
2260cdf0e10cSrcweir //	static
HasRegisteredSources()2261cdf0e10cSrcweir sal_Bool ScDPObject::HasRegisteredSources()
2262cdf0e10cSrcweir {
2263cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
2264cdf0e10cSrcweir 
2265cdf0e10cSrcweir 	uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
2266cdf0e10cSrcweir 	uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
2267cdf0e10cSrcweir 	if ( xEnAc.is() )
2268cdf0e10cSrcweir 	{
2269cdf0e10cSrcweir 		uno::Reference<container::XEnumeration> xEnum = xEnAc->createContentEnumeration(
2270cdf0e10cSrcweir 										rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE ) );
2271cdf0e10cSrcweir 		if ( xEnum.is() && xEnum->hasMoreElements() )
2272cdf0e10cSrcweir 			bFound = sal_True;
2273cdf0e10cSrcweir 	}
2274cdf0e10cSrcweir 
2275cdf0e10cSrcweir 	return bFound;
2276cdf0e10cSrcweir }
2277cdf0e10cSrcweir 
2278cdf0e10cSrcweir //	static
GetRegisteredSources()2279cdf0e10cSrcweir uno::Sequence<rtl::OUString> ScDPObject::GetRegisteredSources()
2280cdf0e10cSrcweir {
2281cdf0e10cSrcweir 	long nCount = 0;
2282cdf0e10cSrcweir 	uno::Sequence<rtl::OUString> aSeq(0);
2283cdf0e10cSrcweir 
2284cdf0e10cSrcweir 	//	use implementation names...
2285cdf0e10cSrcweir 
2286cdf0e10cSrcweir 	uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
2287cdf0e10cSrcweir 	uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
2288cdf0e10cSrcweir 	if ( xEnAc.is() )
2289cdf0e10cSrcweir 	{
2290cdf0e10cSrcweir 		uno::Reference<container::XEnumeration> xEnum = xEnAc->createContentEnumeration(
2291cdf0e10cSrcweir 										rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE ) );
2292cdf0e10cSrcweir 		if ( xEnum.is() )
2293cdf0e10cSrcweir 		{
2294cdf0e10cSrcweir 			while ( xEnum->hasMoreElements() )
2295cdf0e10cSrcweir 			{
2296cdf0e10cSrcweir 				uno::Any aAddInAny = xEnum->nextElement();
2297cdf0e10cSrcweir //				if ( aAddInAny.getReflection()->getTypeClass() == TypeClass_INTERFACE )
2298cdf0e10cSrcweir 				{
2299cdf0e10cSrcweir 					uno::Reference<uno::XInterface> xIntFac;
2300cdf0e10cSrcweir 					aAddInAny >>= xIntFac;
2301cdf0e10cSrcweir 					if ( xIntFac.is() )
2302cdf0e10cSrcweir 					{
2303cdf0e10cSrcweir 						uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
2304cdf0e10cSrcweir 						if ( xInfo.is() )
2305cdf0e10cSrcweir 						{
2306cdf0e10cSrcweir 							rtl::OUString sName = xInfo->getImplementationName();
2307cdf0e10cSrcweir 
2308cdf0e10cSrcweir 							aSeq.realloc( nCount+1 );
2309cdf0e10cSrcweir 							aSeq.getArray()[nCount] = sName;
2310cdf0e10cSrcweir 							++nCount;
2311cdf0e10cSrcweir 						}
2312cdf0e10cSrcweir 					}
2313cdf0e10cSrcweir 				}
2314cdf0e10cSrcweir 			}
2315cdf0e10cSrcweir 		}
2316cdf0e10cSrcweir 	}
2317cdf0e10cSrcweir 
2318cdf0e10cSrcweir 	return aSeq;
2319cdf0e10cSrcweir }
2320cdf0e10cSrcweir 
2321cdf0e10cSrcweir // use getContext from addincol.cxx
2322cdf0e10cSrcweir uno::Reference<uno::XComponentContext> getContext(uno::Reference<lang::XMultiServiceFactory> xMSF);
2323cdf0e10cSrcweir 
2324cdf0e10cSrcweir //	static
CreateSource(const ScDPServiceDesc & rDesc)2325cdf0e10cSrcweir uno::Reference<sheet::XDimensionsSupplier> ScDPObject::CreateSource( const ScDPServiceDesc& rDesc )
2326cdf0e10cSrcweir {
2327cdf0e10cSrcweir 	rtl::OUString aImplName = rDesc.aServiceName;
2328cdf0e10cSrcweir 	uno::Reference<sheet::XDimensionsSupplier> xRet = NULL;
2329cdf0e10cSrcweir 
2330cdf0e10cSrcweir 	uno::Reference<lang::XMultiServiceFactory> xManager = comphelper::getProcessServiceFactory();
2331cdf0e10cSrcweir 	uno::Reference<container::XContentEnumerationAccess> xEnAc( xManager, uno::UNO_QUERY );
2332cdf0e10cSrcweir 	if ( xEnAc.is() )
2333cdf0e10cSrcweir 	{
2334cdf0e10cSrcweir 		uno::Reference<container::XEnumeration> xEnum = xEnAc->createContentEnumeration(
2335cdf0e10cSrcweir 										rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE ) );
2336cdf0e10cSrcweir 		if ( xEnum.is() )
2337cdf0e10cSrcweir 		{
2338cdf0e10cSrcweir 			while ( xEnum->hasMoreElements() && !xRet.is() )
2339cdf0e10cSrcweir 			{
2340cdf0e10cSrcweir 				uno::Any aAddInAny = xEnum->nextElement();
2341cdf0e10cSrcweir //				if ( aAddInAny.getReflection()->getTypeClass() == TypeClass_INTERFACE )
2342cdf0e10cSrcweir 				{
2343cdf0e10cSrcweir 					uno::Reference<uno::XInterface> xIntFac;
2344cdf0e10cSrcweir 					aAddInAny >>= xIntFac;
2345cdf0e10cSrcweir 					if ( xIntFac.is() )
2346cdf0e10cSrcweir 					{
2347cdf0e10cSrcweir 						uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
2348cdf0e10cSrcweir 						if ( xInfo.is() && xInfo->getImplementationName() == aImplName )
2349cdf0e10cSrcweir 						{
2350cdf0e10cSrcweir 							try
2351cdf0e10cSrcweir 							{
2352cdf0e10cSrcweir                                 // #i113160# try XSingleComponentFactory in addition to (old) XSingleServiceFactory,
2353cdf0e10cSrcweir                                 // passing the context to the component (see ScUnoAddInCollection::Initialize)
2354cdf0e10cSrcweir 
2355cdf0e10cSrcweir                                 uno::Reference<uno::XInterface> xInterface;
2356cdf0e10cSrcweir                                 uno::Reference<uno::XComponentContext> xCtx = getContext(xManager);
2357cdf0e10cSrcweir                                 uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY );
2358cdf0e10cSrcweir                                 if (xCtx.is() && xCFac.is())
2359cdf0e10cSrcweir                                     xInterface = xCFac->createInstanceWithContext(xCtx);
2360cdf0e10cSrcweir 
2361cdf0e10cSrcweir                                 if (!xInterface.is())
2362cdf0e10cSrcweir                                 {
2363cdf0e10cSrcweir                                     uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
2364cdf0e10cSrcweir                                     if ( xFac.is() )
2365cdf0e10cSrcweir                                         xInterface = xFac->createInstance();
2366cdf0e10cSrcweir                                 }
2367cdf0e10cSrcweir 
2368cdf0e10cSrcweir 								uno::Reference<lang::XInitialization> xInit( xInterface, uno::UNO_QUERY );
2369cdf0e10cSrcweir 								if (xInit.is())
2370cdf0e10cSrcweir 								{
2371cdf0e10cSrcweir 									//	initialize
2372cdf0e10cSrcweir 									uno::Sequence<uno::Any> aSeq(4);
2373cdf0e10cSrcweir 									uno::Any* pArray = aSeq.getArray();
2374cdf0e10cSrcweir 									pArray[0] <<= rtl::OUString( rDesc.aParSource );
2375cdf0e10cSrcweir 									pArray[1] <<= rtl::OUString( rDesc.aParName );
2376cdf0e10cSrcweir 									pArray[2] <<= rtl::OUString( rDesc.aParUser );
2377cdf0e10cSrcweir 									pArray[3] <<= rtl::OUString( rDesc.aParPass );
2378cdf0e10cSrcweir 									xInit->initialize( aSeq );
2379cdf0e10cSrcweir 								}
2380cdf0e10cSrcweir 								xRet = uno::Reference<sheet::XDimensionsSupplier>( xInterface, uno::UNO_QUERY );
2381cdf0e10cSrcweir 							}
2382cdf0e10cSrcweir 							catch(uno::Exception&)
2383cdf0e10cSrcweir 							{
2384cdf0e10cSrcweir 							}
2385cdf0e10cSrcweir 						}
2386cdf0e10cSrcweir 					}
2387cdf0e10cSrcweir 				}
2388cdf0e10cSrcweir 			}
2389cdf0e10cSrcweir 		}
2390cdf0e10cSrcweir 	}
2391cdf0e10cSrcweir 
2392cdf0e10cSrcweir 	return xRet;
2393cdf0e10cSrcweir }
2394cdf0e10cSrcweir 
2395cdf0e10cSrcweir // ----------------------------------------------------------------------------
2396cdf0e10cSrcweir 
ScDPCollection(ScDocument * pDocument)2397cdf0e10cSrcweir ScDPCollection::ScDPCollection(ScDocument* pDocument) :
2398cdf0e10cSrcweir 	pDoc( pDocument )
2399cdf0e10cSrcweir {
2400cdf0e10cSrcweir }
2401cdf0e10cSrcweir 
ScDPCollection(const ScDPCollection & r)2402cdf0e10cSrcweir ScDPCollection::ScDPCollection(const ScDPCollection& r) :
2403cdf0e10cSrcweir 	ScCollection(r),
2404cdf0e10cSrcweir     pDoc(r.pDoc)
2405cdf0e10cSrcweir {
2406cdf0e10cSrcweir }
2407cdf0e10cSrcweir 
~ScDPCollection()2408cdf0e10cSrcweir ScDPCollection::~ScDPCollection()
2409cdf0e10cSrcweir {
2410cdf0e10cSrcweir }
2411cdf0e10cSrcweir 
Clone() const2412cdf0e10cSrcweir ScDataObject* ScDPCollection::Clone() const
2413cdf0e10cSrcweir {
2414cdf0e10cSrcweir 	return new ScDPCollection(*this);
2415cdf0e10cSrcweir }
2416cdf0e10cSrcweir 
DeleteOnTab(SCTAB nTab)2417cdf0e10cSrcweir void ScDPCollection::DeleteOnTab( SCTAB nTab )
2418cdf0e10cSrcweir {
2419cdf0e10cSrcweir     sal_uInt16 nPos = 0;
2420cdf0e10cSrcweir     while ( nPos < nCount )
2421cdf0e10cSrcweir     {
2422cdf0e10cSrcweir         // look for output positions on the deleted sheet
2423cdf0e10cSrcweir         if ( static_cast<const ScDPObject*>(At(nPos))->GetOutRange().aStart.Tab() == nTab )
2424cdf0e10cSrcweir             AtFree(nPos);
2425cdf0e10cSrcweir         else
2426cdf0e10cSrcweir             ++nPos;
2427cdf0e10cSrcweir     }
2428cdf0e10cSrcweir }
2429cdf0e10cSrcweir 
UpdateReference(UpdateRefMode eUpdateRefMode,const ScRange & r,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)2430cdf0e10cSrcweir void ScDPCollection::UpdateReference( UpdateRefMode eUpdateRefMode,
2431cdf0e10cSrcweir 										 const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
2432cdf0e10cSrcweir {
2433cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nCount; i++)
2434cdf0e10cSrcweir 		((ScDPObject*)At(i))->UpdateReference( eUpdateRefMode, r, nDx, nDy, nDz );
2435cdf0e10cSrcweir }
2436cdf0e10cSrcweir 
RefsEqual(const ScDPCollection & r) const2437cdf0e10cSrcweir sal_Bool ScDPCollection::RefsEqual( const ScDPCollection& r ) const
2438cdf0e10cSrcweir {
2439cdf0e10cSrcweir 	if ( nCount != r.nCount )
2440cdf0e10cSrcweir 		return sal_False;
2441cdf0e10cSrcweir 
2442cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nCount; i++)
2443cdf0e10cSrcweir 		if ( ! ((const ScDPObject*)At(i))->RefsEqual( *((const ScDPObject*)r.At(i)) ) )
2444cdf0e10cSrcweir 			return sal_False;
2445cdf0e10cSrcweir 
2446cdf0e10cSrcweir 	return sal_True;	// all equal
2447cdf0e10cSrcweir }
2448cdf0e10cSrcweir 
WriteRefsTo(ScDPCollection & r) const2449cdf0e10cSrcweir void ScDPCollection::WriteRefsTo( ScDPCollection& r ) const
2450cdf0e10cSrcweir {
2451cdf0e10cSrcweir 	if ( nCount == r.nCount )
2452cdf0e10cSrcweir 	{
2453cdf0e10cSrcweir 		//!	assert equal names?
2454cdf0e10cSrcweir 		for (sal_uInt16 i=0; i<nCount; i++)
2455cdf0e10cSrcweir 			((const ScDPObject*)At(i))->WriteRefsTo( *((ScDPObject*)r.At(i)) );
2456cdf0e10cSrcweir 	}
2457cdf0e10cSrcweir 	else
2458cdf0e10cSrcweir     {
2459cdf0e10cSrcweir         // #i8180# If data pilot tables were deleted with their sheet,
2460cdf0e10cSrcweir         // this collection contains extra entries that must be restored.
2461cdf0e10cSrcweir         // Matching objects are found by their names.
2462cdf0e10cSrcweir 
2463cdf0e10cSrcweir         DBG_ASSERT( nCount >= r.nCount, "WriteRefsTo: missing entries in document" );
2464cdf0e10cSrcweir         for (sal_uInt16 nSourcePos=0; nSourcePos<nCount; nSourcePos++)
2465cdf0e10cSrcweir         {
2466cdf0e10cSrcweir             const ScDPObject* pSourceObj = static_cast<const ScDPObject*>(At(nSourcePos));
2467cdf0e10cSrcweir             String aName = pSourceObj->GetName();
2468cdf0e10cSrcweir             bool bFound = false;
2469cdf0e10cSrcweir             for (sal_uInt16 nDestPos=0; nDestPos<r.nCount && !bFound; nDestPos++)
2470cdf0e10cSrcweir             {
2471cdf0e10cSrcweir                 ScDPObject* pDestObj = static_cast<ScDPObject*>(r.At(nDestPos));
2472cdf0e10cSrcweir                 if ( pDestObj->GetName() == aName )
2473cdf0e10cSrcweir                 {
2474cdf0e10cSrcweir                     pSourceObj->WriteRefsTo( *pDestObj );     // found object, copy refs
2475cdf0e10cSrcweir                     bFound = true;
2476cdf0e10cSrcweir                 }
2477cdf0e10cSrcweir             }
2478cdf0e10cSrcweir             if ( !bFound )
2479cdf0e10cSrcweir             {
2480cdf0e10cSrcweir                 // none found, re-insert deleted object (see ScUndoDataPilot::Undo)
2481cdf0e10cSrcweir 
2482cdf0e10cSrcweir                 ScDPObject* pDestObj = new ScDPObject( *pSourceObj );
2483cdf0e10cSrcweir                 pDestObj->SetAlive(sal_True);
2484cdf0e10cSrcweir                 if ( !r.InsertNewTable(pDestObj) )
2485cdf0e10cSrcweir                 {
2486cdf0e10cSrcweir                     DBG_ERROR("cannot insert DPObject");
2487cdf0e10cSrcweir                     DELETEZ( pDestObj );
2488cdf0e10cSrcweir                 }
2489cdf0e10cSrcweir             }
2490cdf0e10cSrcweir         }
2491cdf0e10cSrcweir         DBG_ASSERT( nCount == r.nCount, "WriteRefsTo: couldn't restore all entries" );
2492cdf0e10cSrcweir     }
2493cdf0e10cSrcweir }
2494cdf0e10cSrcweir 
GetByName(const String & rName) const2495cdf0e10cSrcweir ScDPObject* ScDPCollection::GetByName(const String& rName) const
2496cdf0e10cSrcweir {
2497cdf0e10cSrcweir     for (sal_uInt16 i=0; i<nCount; i++)
2498cdf0e10cSrcweir         if (static_cast<const ScDPObject*>(pItems[i])->GetName() == rName)
2499cdf0e10cSrcweir             return static_cast<ScDPObject*>(pItems[i]);
2500cdf0e10cSrcweir     return NULL;
2501cdf0e10cSrcweir }
2502cdf0e10cSrcweir 
CreateNewName(sal_uInt16 nMin) const2503cdf0e10cSrcweir String ScDPCollection::CreateNewName( sal_uInt16 nMin ) const
2504cdf0e10cSrcweir {
2505cdf0e10cSrcweir 	String aBase( RTL_CONSTASCII_USTRINGPARAM( "Pivot" ) );
2506cdf0e10cSrcweir 	//!	from Resource?
2507cdf0e10cSrcweir 
2508cdf0e10cSrcweir 	for (sal_uInt16 nAdd=0; nAdd<=nCount; nAdd++)	//	nCount+1 tries
2509cdf0e10cSrcweir 	{
2510cdf0e10cSrcweir 		String aNewName = aBase;
2511cdf0e10cSrcweir 		aNewName += String::CreateFromInt32( nMin + nAdd );
2512cdf0e10cSrcweir 		sal_Bool bFound = sal_False;
2513cdf0e10cSrcweir 		for (sal_uInt16 i=0; i<nCount && !bFound; i++)
2514cdf0e10cSrcweir 			if (((const ScDPObject*)pItems[i])->GetName() == aNewName)
2515cdf0e10cSrcweir 				bFound = sal_True;
2516cdf0e10cSrcweir 		if (!bFound)
2517cdf0e10cSrcweir 			return aNewName;			// found unused Name
2518cdf0e10cSrcweir 	}
2519cdf0e10cSrcweir 	return String();					// should not happen
2520cdf0e10cSrcweir }
2521cdf0e10cSrcweir 
2522cdf0e10cSrcweir 
2523cdf0e10cSrcweir 
2524cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
2525cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
GetCacheId() const2526cdf0e10cSrcweir long ScDPObject::GetCacheId() const
2527cdf0e10cSrcweir {
2528cdf0e10cSrcweir     if ( GetSaveData() )
2529cdf0e10cSrcweir         return GetSaveData()->GetCacheId();
2530cdf0e10cSrcweir     else
2531cdf0e10cSrcweir         return mnCacheId;
2532cdf0e10cSrcweir }
RefreshCache()2533cdf0e10cSrcweir sal_uLong ScDPObject::RefreshCache()
2534cdf0e10cSrcweir {
2535cdf0e10cSrcweir     if ( pServDesc )
2536cdf0e10cSrcweir     {
2537cdf0e10cSrcweir         // cache table isn't used for external service - do nothing, no error
2538cdf0e10cSrcweir         return 0;
2539cdf0e10cSrcweir     }
2540cdf0e10cSrcweir 
2541cdf0e10cSrcweir     CreateObjects();
2542cdf0e10cSrcweir     sal_uLong nErrId = 0;
2543cdf0e10cSrcweir     if ( pSheetDesc)
2544cdf0e10cSrcweir         nErrId =  pSheetDesc->CheckValidate( pDoc );
2545cdf0e10cSrcweir     if ( nErrId == 0 )
2546cdf0e10cSrcweir     {
2547cdf0e10cSrcweir         long nOldId = GetCacheId();
2548cdf0e10cSrcweir         long nNewId = pDoc->GetNewDPObjectCacheId();
2549cdf0e10cSrcweir         if ( nOldId >= 0 )
2550cdf0e10cSrcweir             pDoc->RemoveDPObjectCache( nOldId );
2551cdf0e10cSrcweir 
2552cdf0e10cSrcweir         ScDPTableDataCache* pCache  = NULL;
2553cdf0e10cSrcweir         if ( pSheetDesc )
2554cdf0e10cSrcweir             pCache = pSheetDesc->CreateCache( pDoc, nNewId );
2555cdf0e10cSrcweir         else if ( pImpDesc )
2556cdf0e10cSrcweir             pCache = pImpDesc->CreateCache( pDoc, nNewId );
2557cdf0e10cSrcweir 
2558cdf0e10cSrcweir         if ( pCache == NULL )
2559cdf0e10cSrcweir         {
2560cdf0e10cSrcweir             //cache failed
2561cdf0e10cSrcweir             DBG_ASSERT( pCache , " pCache == NULL" );
2562cdf0e10cSrcweir             return STR_ERR_DATAPILOTSOURCE;
2563cdf0e10cSrcweir         }
2564cdf0e10cSrcweir 
2565cdf0e10cSrcweir         nNewId = pCache->GetId();
2566cdf0e10cSrcweir 
2567cdf0e10cSrcweir         bRefresh = sal_True;
2568cdf0e10cSrcweir         ScDPCollection* pDPCollection = pDoc->GetDPCollection();
2569cdf0e10cSrcweir         sal_uInt16 nCount = pDPCollection->GetCount();
2570cdf0e10cSrcweir         for (sal_uInt16 i=0; i<nCount; i++)
2571cdf0e10cSrcweir         { //set new cache id
2572cdf0e10cSrcweir             if ( (*pDPCollection)[i]->GetCacheId() == nOldId  )
2573cdf0e10cSrcweir             {
2574cdf0e10cSrcweir                 (*pDPCollection)[i]->SetCacheId( nNewId );
2575cdf0e10cSrcweir                 (*pDPCollection)[i]->SetRefresh();
2576cdf0e10cSrcweir 
2577cdf0e10cSrcweir             }
2578cdf0e10cSrcweir         }
2579cdf0e10cSrcweir         DBG_ASSERT( GetCacheId() >= 0, " GetCacheId() >= 0 " );
2580cdf0e10cSrcweir     }
2581cdf0e10cSrcweir     return nErrId;
2582cdf0e10cSrcweir }
SetCacheId(long nCacheId)2583cdf0e10cSrcweir void ScDPObject::SetCacheId( long nCacheId )
2584cdf0e10cSrcweir {
2585cdf0e10cSrcweir     if ( GetCacheId() != nCacheId )
2586cdf0e10cSrcweir     {
2587cdf0e10cSrcweir         InvalidateSource();
2588cdf0e10cSrcweir         if ( GetSaveData() )
2589cdf0e10cSrcweir             GetSaveData()->SetCacheId( nCacheId );
2590cdf0e10cSrcweir 
2591cdf0e10cSrcweir         mnCacheId = nCacheId;
2592cdf0e10cSrcweir     }
2593cdf0e10cSrcweir }
GetCache() const2594cdf0e10cSrcweir const ScDPTableDataCache* ScDPObject::GetCache() const
2595cdf0e10cSrcweir {
2596cdf0e10cSrcweir     return pDoc->GetDPObjectCache( GetCacheId() );
2597cdf0e10cSrcweir }
2598cdf0e10cSrcweir // End Comments
2599cdf0e10cSrcweir 
FreeTable(ScDPObject * pDPObj)2600cdf0e10cSrcweir void ScDPCollection::FreeTable(ScDPObject* pDPObj)
2601cdf0e10cSrcweir {
2602cdf0e10cSrcweir     const ScRange& rOutRange = pDPObj->GetOutRange();
2603cdf0e10cSrcweir     const ScAddress& s = rOutRange.aStart;
2604cdf0e10cSrcweir     const ScAddress& e = rOutRange.aEnd;
2605cdf0e10cSrcweir     pDoc->RemoveFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
2606cdf0e10cSrcweir     Free(pDPObj);
2607cdf0e10cSrcweir }
2608cdf0e10cSrcweir 
InsertNewTable(ScDPObject * pDPObj)2609cdf0e10cSrcweir bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj)
2610cdf0e10cSrcweir {
2611cdf0e10cSrcweir     bool bSuccess = Insert(pDPObj);
2612cdf0e10cSrcweir     if (bSuccess)
2613cdf0e10cSrcweir     {
2614cdf0e10cSrcweir         const ScRange& rOutRange = pDPObj->GetOutRange();
2615cdf0e10cSrcweir         const ScAddress& s = rOutRange.aStart;
2616cdf0e10cSrcweir         const ScAddress& e = rOutRange.aEnd;
2617cdf0e10cSrcweir         pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
2618cdf0e10cSrcweir     }
2619cdf0e10cSrcweir     return bSuccess;
2620cdf0e10cSrcweir }
2621cdf0e10cSrcweir 
HasDPTable(SCCOL nCol,SCROW nRow,SCTAB nTab) const2622cdf0e10cSrcweir bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const
2623cdf0e10cSrcweir {
2624cdf0e10cSrcweir     const ScMergeFlagAttr* pMergeAttr = static_cast<const ScMergeFlagAttr*>(
2625cdf0e10cSrcweir             pDoc->GetAttr(nCol, nRow, nTab, ATTR_MERGE_FLAG));
2626cdf0e10cSrcweir 
2627cdf0e10cSrcweir     if (!pMergeAttr)
2628cdf0e10cSrcweir         return false;
2629cdf0e10cSrcweir 
2630cdf0e10cSrcweir     return pMergeAttr->HasDPTable();
2631cdf0e10cSrcweir }
2632cdf0e10cSrcweir 
2633cdf0e10cSrcweir 
2634