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