Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <algorithm>
22 : #include <svl/smplhint.hxx>
23 : #include <vcl/svapp.hxx>
24 :
25 : #include "dapiuno.hxx"
26 : #include "datauno.hxx"
27 : #include "miscuno.hxx"
28 : #include "convuno.hxx"
29 : #include "docsh.hxx"
30 : #include "tabvwsh.hxx"
31 : #include "pivot.hxx"
32 : #include "rangeutl.hxx"
33 : #include "dpobject.hxx"
34 : #include "dpshttab.hxx"
35 : #include "dpsdbtab.hxx"
36 : #include "dpsave.hxx"
37 : #include "dbdocfun.hxx"
38 : #include "unonames.hxx"
39 : #include "dpgroup.hxx"
40 : #include "dpdimsave.hxx"
41 : #include "hints.hxx"
42 :
43 : #include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
44 : #include <com/sun/star/sheet/XLevelsSupplier.hpp>
45 : #include <com/sun/star/sheet/XMembersSupplier.hpp>
46 : #include <com/sun/star/beans/PropertyAttribute.hpp>
47 : #include <com/sun/star/sheet/DataImportMode.hpp>
48 : #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
49 : #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
50 : #include <com/sun/star/sheet/DataPilotOutputRangeType.hpp>
51 : #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
52 :
53 : #include <comphelper/extract.hxx>
54 : #include <comphelper/sequence.hxx>
55 : #include <comphelper/servicehelper.hxx>
56 :
57 : using namespace com::sun::star;
58 : using namespace com::sun::star::sheet;
59 :
60 :
61 : using ::com::sun::star::uno::Any;
62 : using ::com::sun::star::uno::Exception;
63 : using ::com::sun::star::uno::Reference;
64 : using ::com::sun::star::uno::RuntimeException;
65 : using ::com::sun::star::uno::Sequence;
66 : using ::com::sun::star::uno::UNO_QUERY;
67 : using ::com::sun::star::uno::UNO_QUERY_THROW;
68 :
69 : using ::com::sun::star::container::ElementExistException;
70 : using ::com::sun::star::container::NoSuchElementException;
71 : using ::com::sun::star::container::XEnumeration;
72 : using ::com::sun::star::container::XIndexAccess;
73 : using ::com::sun::star::container::XNameAccess;
74 : using ::com::sun::star::container::XNamed;
75 :
76 : using ::com::sun::star::beans::PropertyVetoException;
77 : using ::com::sun::star::beans::UnknownPropertyException;
78 : using ::com::sun::star::beans::XPropertyChangeListener;
79 : using ::com::sun::star::beans::XPropertySet;
80 : using ::com::sun::star::beans::XPropertySetInfo;
81 : using ::com::sun::star::beans::XVetoableChangeListener;
82 :
83 : using ::com::sun::star::lang::IllegalArgumentException;
84 : using ::com::sun::star::lang::IndexOutOfBoundsException;
85 : using ::com::sun::star::lang::WrappedTargetException;
86 :
87 : using ::com::sun::star::table::CellAddress;
88 : using ::com::sun::star::table::CellRangeAddress;
89 :
90 : namespace {
91 :
92 54 : const SfxItemPropertyMapEntry* lcl_GetDataPilotDescriptorBaseMap()
93 : {
94 : static const SfxItemPropertyMapEntry aDataPilotDescriptorBaseMap_Impl[] =
95 : {
96 4 : {OUString(SC_UNO_DP_COLGRAND), 0, getBooleanCppuType(), 0, 0 },
97 4 : {OUString(SC_UNO_DP_DRILLDOWN), 0, getBooleanCppuType(), 0, 0 },
98 4 : {OUString(SC_UNO_DP_GRANDTOTAL_NAME),0,getCppuType((OUString*)0), beans::PropertyAttribute::MAYBEVOID, 0 },
99 4 : {OUString(SC_UNO_DP_IGNORE_EMPTYROWS), 0, getBooleanCppuType(), 0, 0 },
100 4 : {OUString(SC_UNO_DP_IMPORTDESC), 0, getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
101 4 : {OUString(SC_UNO_DP_REPEATEMPTY), 0, getBooleanCppuType(), 0, 0 },
102 4 : {OUString(SC_UNO_DP_ROWGRAND), 0, getBooleanCppuType(), 0, 0 },
103 4 : {OUString(SC_UNO_DP_SERVICEARG), 0, getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
104 4 : {OUString(SC_UNO_DP_SHOWFILTER), 0, getBooleanCppuType(), 0, 0 },
105 4 : {OUString(SC_UNO_DP_SOURCESERVICE), 0, getCppuType((OUString*)0), 0, 0 },
106 : { OUString(), 0, css::uno::Type(), 0, 0 }
107 98 : };
108 54 : return aDataPilotDescriptorBaseMap_Impl;
109 : }
110 :
111 126 : const SfxItemPropertyMapEntry* lcl_GetDataPilotFieldMap()
112 : {
113 : using namespace ::com::sun::star::beans::PropertyAttribute;
114 : static const SfxItemPropertyMapEntry aDataPilotFieldMap_Impl[] =
115 : {
116 4 : {OUString(SC_UNONAME_AUTOSHOW), 0, getCppuType((DataPilotFieldAutoShowInfo*)0), MAYBEVOID, 0 },
117 4 : {OUString(SC_UNONAME_FUNCTION), 0, getCppuType((GeneralFunction*)0), 0, 0 },
118 4 : {OUString(SC_UNONAME_GROUPINFO), 0, getCppuType((DataPilotFieldGroupInfo*)0), MAYBEVOID, 0 },
119 4 : {OUString(SC_UNONAME_HASAUTOSHOW), 0, getBooleanCppuType(), 0, 0 },
120 4 : {OUString(SC_UNONAME_HASLAYOUTINFO),0, getBooleanCppuType(), 0, 0 },
121 4 : {OUString(SC_UNONAME_HASREFERENCE), 0, getBooleanCppuType(), 0, 0 },
122 4 : {OUString(SC_UNONAME_HASSORTINFO), 0, getBooleanCppuType(), 0, 0 },
123 4 : {OUString(SC_UNONAME_ISGROUP), 0, getBooleanCppuType(), 0, 0 },
124 4 : {OUString(SC_UNONAME_LAYOUTINFO), 0, getCppuType((DataPilotFieldLayoutInfo*)0), MAYBEVOID, 0 },
125 4 : {OUString(SC_UNONAME_ORIENT), 0, getCppuType((DataPilotFieldOrientation*)0), MAYBEVOID, 0 },
126 4 : {OUString(SC_UNONAME_REFERENCE), 0, getCppuType((DataPilotFieldReference*)0), MAYBEVOID, 0 },
127 4 : {OUString(SC_UNONAME_SELPAGE), 0, getCppuType((OUString*)0), 0, 0 },
128 4 : {OUString(SC_UNONAME_SHOWEMPTY), 0, getBooleanCppuType(), 0, 0 },
129 4 : {OUString(SC_UNONAME_SORTINFO), 0, getCppuType((DataPilotFieldSortInfo*)0), MAYBEVOID, 0 },
130 4 : {OUString(SC_UNONAME_SUBTOTALS), 0, getCppuType((Sequence<GeneralFunction>*)0), 0, 0 },
131 4 : {OUString(SC_UNONAME_USESELPAGE), 0, getBooleanCppuType(), 0, 0 },
132 : { OUString(), 0, css::uno::Type(), 0, 0 }
133 194 : };
134 126 : return aDataPilotFieldMap_Impl;
135 : }
136 :
137 15 : const SfxItemPropertyMapEntry* lcl_GetDataPilotItemMap()
138 : {
139 : static const SfxItemPropertyMapEntry aDataPilotItemMap_Impl[] =
140 : {
141 1 : {OUString(SC_UNONAME_ISHIDDEN), 0, getBooleanCppuType(), 0, 0 },
142 1 : {OUString(SC_UNONAME_POS), 0, getCppuType((sal_Int32*)0), 0, 0 },
143 1 : {OUString(SC_UNONAME_SHOWDETAIL), 0, getBooleanCppuType(), 0, 0 },
144 : { OUString(), 0, css::uno::Type(), 0, 0 }
145 19 : };
146 15 : return aDataPilotItemMap_Impl;
147 : }
148 :
149 0 : inline bool lclCheckValidDouble( double fValue, sal_Bool bAuto )
150 : {
151 0 : return bAuto || ::rtl::math::isFinite( fValue );
152 : }
153 :
154 0 : bool lclCheckMinMaxStep( const DataPilotFieldGroupInfo& rInfo )
155 : {
156 : return
157 0 : lclCheckValidDouble( rInfo.Start, rInfo.HasAutoStart ) &&
158 0 : lclCheckValidDouble( rInfo.End, rInfo.HasAutoEnd ) &&
159 0 : (rInfo.HasAutoStart || rInfo.HasAutoEnd || (rInfo.Start <= rInfo.End)) &&
160 0 : lclCheckValidDouble( rInfo.Step, false ) &&
161 0 : (0.0 <= rInfo.Step);
162 : }
163 :
164 : } // namespace
165 :
166 0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotDescriptor, "ScDataPilotDescriptor", "stardiv::one::sheet::DataPilotDescriptor" )
167 2 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldObj, "ScDataPilotFieldObj", "com.sun.star.sheet.DataPilotField" )
168 0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldsObj, "ScDataPilotFieldsObj", "com.sun.star.sheet.DataPilotFields" )
169 0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotTableObj, "ScDataPilotTableObj", "com.sun.star.sheet.DataPilotTable" )
170 0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotTablesObj, "ScDataPilotTablesObj", "com.sun.star.sheet.DataPilotTables" )
171 1 : SC_SIMPLE_SERVICE_INFO( ScDataPilotItemsObj, "ScDataPilotItemsObj", "com.sun.star.sheet.DataPilotItems" )
172 3 : SC_SIMPLE_SERVICE_INFO( ScDataPilotItemObj, "ScDataPilotItemObj", "com.sun.star.sheet.DataPilotItem" )
173 :
174 1 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupsObj, "ScDataPilotFieldGroupsObj", "com.sun.star.sheet.DataPilotFieldGroups" )
175 1 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupObj, "ScDataPilotFieldGroupObj", "com.sun.star.sheet.DataPilotFieldGroup" )
176 1 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupItemObj, "ScDataPilotFieldGroupItemObj", "com.sun.star.sheet.DataPilotFieldGroupItem" )
177 :
178 : // name that is used in the API for the data layout field
179 : #define SC_DATALAYOUT_NAME "Data"
180 :
181 0 : GeneralFunction ScDataPilotConversion::FirstFunc( sal_uInt16 nBits )
182 : {
183 0 : if ( nBits & PIVOT_FUNC_SUM ) return GeneralFunction_SUM;
184 0 : if ( nBits & PIVOT_FUNC_COUNT ) return GeneralFunction_COUNT;
185 0 : if ( nBits & PIVOT_FUNC_AVERAGE ) return GeneralFunction_AVERAGE;
186 0 : if ( nBits & PIVOT_FUNC_MAX ) return GeneralFunction_MAX;
187 0 : if ( nBits & PIVOT_FUNC_MIN ) return GeneralFunction_MIN;
188 0 : if ( nBits & PIVOT_FUNC_PRODUCT ) return GeneralFunction_PRODUCT;
189 0 : if ( nBits & PIVOT_FUNC_COUNT_NUM ) return GeneralFunction_COUNTNUMS;
190 0 : if ( nBits & PIVOT_FUNC_STD_DEV ) return GeneralFunction_STDEV;
191 0 : if ( nBits & PIVOT_FUNC_STD_DEVP ) return GeneralFunction_STDEVP;
192 0 : if ( nBits & PIVOT_FUNC_STD_VAR ) return GeneralFunction_VAR;
193 0 : if ( nBits & PIVOT_FUNC_STD_VARP ) return GeneralFunction_VARP;
194 0 : if ( nBits & PIVOT_FUNC_AUTO ) return GeneralFunction_AUTO;
195 0 : return GeneralFunction_NONE;
196 : }
197 :
198 0 : sal_uInt16 ScDataPilotConversion::FunctionBit( GeneralFunction eFunc )
199 : {
200 0 : sal_uInt16 nRet = PIVOT_FUNC_NONE; // 0
201 0 : switch (eFunc)
202 : {
203 0 : case GeneralFunction_SUM: nRet = PIVOT_FUNC_SUM; break;
204 0 : case GeneralFunction_COUNT: nRet = PIVOT_FUNC_COUNT; break;
205 0 : case GeneralFunction_AVERAGE: nRet = PIVOT_FUNC_AVERAGE; break;
206 0 : case GeneralFunction_MAX: nRet = PIVOT_FUNC_MAX; break;
207 0 : case GeneralFunction_MIN: nRet = PIVOT_FUNC_MIN; break;
208 0 : case GeneralFunction_PRODUCT: nRet = PIVOT_FUNC_PRODUCT; break;
209 0 : case GeneralFunction_COUNTNUMS: nRet = PIVOT_FUNC_COUNT_NUM; break;
210 0 : case GeneralFunction_STDEV: nRet = PIVOT_FUNC_STD_DEV; break;
211 0 : case GeneralFunction_STDEVP: nRet = PIVOT_FUNC_STD_DEVP; break;
212 0 : case GeneralFunction_VAR: nRet = PIVOT_FUNC_STD_VAR; break;
213 0 : case GeneralFunction_VARP: nRet = PIVOT_FUNC_STD_VARP; break;
214 0 : case GeneralFunction_AUTO: nRet = PIVOT_FUNC_AUTO; break;
215 : default:
216 : {
217 : // added to avoid warnings
218 : }
219 : }
220 0 : return nRet;
221 : }
222 :
223 3 : void ScDataPilotConversion::FillGroupInfo( DataPilotFieldGroupInfo& rInfo, const ScDPNumGroupInfo& rGroupInfo )
224 : {
225 3 : rInfo.HasDateValues = rGroupInfo.mbDateValues;
226 3 : rInfo.HasAutoStart = rGroupInfo.mbAutoStart;
227 3 : rInfo.Start = rGroupInfo.mfStart;
228 3 : rInfo.HasAutoEnd = rGroupInfo.mbAutoEnd;
229 3 : rInfo.End = rGroupInfo.mfEnd;
230 3 : rInfo.Step = rGroupInfo.mfStep;
231 3 : }
232 :
233 641 : static ScDPObject* lcl_GetDPObject( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
234 : {
235 641 : if (pDocShell)
236 : {
237 641 : ScDocument* pDoc = pDocShell->GetDocument();
238 641 : ScDPCollection* pColl = pDoc->GetDPCollection();
239 641 : if ( pColl )
240 : {
241 641 : size_t nCount = pColl->GetCount();
242 1083 : for (size_t i=0; i<nCount; ++i)
243 : {
244 1082 : ScDPObject* pDPObj = (*pColl)[i];
245 2164 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
246 1082 : pDPObj->GetName() == rName )
247 640 : return pDPObj;
248 : }
249 : }
250 : }
251 1 : return NULL; // nicht gefunden
252 : }
253 :
254 0 : static OUString lcl_CreatePivotName( ScDocShell* pDocShell )
255 : {
256 0 : if (pDocShell)
257 : {
258 0 : ScDocument* pDoc = pDocShell->GetDocument();
259 0 : ScDPCollection* pColl = pDoc->GetDPCollection();
260 0 : if ( pColl )
261 0 : return pColl->CreateNewName();
262 : }
263 0 : return OUString(); // sollte nicht vorkommen
264 : }
265 :
266 60 : static sal_Int32 lcl_GetObjectIndex( ScDPObject* pDPObj, const ScFieldIdentifier& rFieldId )
267 : {
268 : // used for items - nRepeat in identifier can be ignored
269 60 : if ( pDPObj )
270 : {
271 60 : sal_Int32 nCount = pDPObj->GetDimCount();
272 60 : for ( sal_Int32 nDim = 0; nDim < nCount; ++nDim )
273 : {
274 60 : bool bIsDataLayout = false;
275 60 : OUString aDimName( pDPObj->GetDimName( nDim, bIsDataLayout ) );
276 60 : if ( rFieldId.mbDataLayout ? bIsDataLayout : (aDimName == rFieldId.maFieldName) )
277 60 : return nDim;
278 0 : }
279 : }
280 0 : return -1; // none
281 : }
282 :
283 44 : ScDataPilotTablesObj::ScDataPilotTablesObj(ScDocShell* pDocSh, SCTAB nT) :
284 : pDocShell( pDocSh ),
285 44 : nTab( nT )
286 : {
287 44 : pDocShell->GetDocument()->AddUnoObject(*this);
288 44 : }
289 :
290 132 : ScDataPilotTablesObj::~ScDataPilotTablesObj()
291 : {
292 44 : if (pDocShell)
293 23 : pDocShell->GetDocument()->RemoveUnoObject(*this);
294 88 : }
295 :
296 245 : void ScDataPilotTablesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
297 : {
298 : //! Referenz-Update
299 :
300 396 : if ( rHint.ISA( SfxSimpleHint ) &&
301 151 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
302 : {
303 21 : pDocShell = NULL; // ungueltig geworden
304 : }
305 245 : }
306 :
307 : // XDataPilotTables
308 :
309 12 : ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nIndex )
310 : {
311 12 : if (pDocShell)
312 : {
313 12 : ScDocument* pDoc = pDocShell->GetDocument();
314 12 : ScDPCollection* pColl = pDoc->GetDPCollection();
315 12 : if ( pColl )
316 : {
317 : // count tables on this sheet
318 12 : sal_Int32 nFound = 0;
319 12 : size_t nCount = pColl->GetCount();
320 14 : for (size_t i=0; i<nCount; ++i)
321 : {
322 12 : ScDPObject* pDPObj = (*pColl)[i];
323 12 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
324 : {
325 12 : if ( nFound == nIndex )
326 : {
327 10 : OUString aName = pDPObj->GetName();
328 10 : return new ScDataPilotTableObj( pDocShell, nTab, aName );
329 : }
330 2 : ++nFound;
331 : }
332 : }
333 : }
334 : }
335 2 : return NULL;
336 : }
337 :
338 28 : ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByName_Impl(const OUString& rName)
339 : {
340 28 : if (hasByName(rName))
341 27 : return new ScDataPilotTableObj( pDocShell, nTab, rName );
342 1 : return 0;
343 : }
344 :
345 17 : Reference<XDataPilotDescriptor> SAL_CALL ScDataPilotTablesObj::createDataPilotDescriptor()
346 : throw(RuntimeException, std::exception)
347 : {
348 17 : SolarMutexGuard aGuard;
349 17 : if (pDocShell)
350 17 : return new ScDataPilotDescriptor(pDocShell);
351 0 : return NULL;
352 : }
353 :
354 391 : static bool lcl_IsDuplicated( const Reference<XPropertySet> xDimProps )
355 : {
356 : try
357 : {
358 391 : Any aAny = xDimProps->getPropertyValue( OUString( SC_UNO_DP_ORIGINAL ) );
359 782 : Reference< XNamed > xOriginal( aAny, UNO_QUERY );
360 782 : return xOriginal.is();
361 : }
362 0 : catch( Exception& )
363 : {
364 : }
365 0 : return false;
366 : }
367 :
368 117 : static OUString lcl_GetOriginalName( const Reference< XNamed > xDim )
369 : {
370 117 : Reference< XNamed > xOriginal;
371 :
372 234 : Reference< XPropertySet > xDimProps( xDim, UNO_QUERY );
373 117 : if ( xDimProps.is() )
374 : {
375 : try
376 : {
377 117 : Any aAny = xDimProps->getPropertyValue(OUString(SC_UNO_DP_ORIGINAL));
378 117 : aAny >>= xOriginal;
379 : }
380 0 : catch( Exception& )
381 : {
382 : }
383 : }
384 :
385 117 : if ( !xOriginal.is() )
386 117 : xOriginal = xDim;
387 :
388 234 : return xOriginal->getName();
389 : }
390 :
391 18 : void SAL_CALL ScDataPilotTablesObj::insertNewByName( const OUString& aNewName,
392 : const CellAddress& aOutputAddress,
393 : const Reference<XDataPilotDescriptor>& xDescriptor )
394 : throw(RuntimeException, std::exception)
395 : {
396 18 : SolarMutexGuard aGuard;
397 35 : if (!xDescriptor.is()) return;
398 :
399 : // inserting with already existing name?
400 18 : if ( !aNewName.isEmpty() && hasByName( aNewName ) )
401 1 : throw RuntimeException(); // no other exceptions specified
402 :
403 17 : sal_Bool bDone = false;
404 17 : ScDataPilotDescriptorBase* pImp = ScDataPilotDescriptorBase::getImplementation( xDescriptor );
405 17 : if ( pDocShell && pImp )
406 : {
407 17 : ScDPObject* pNewObj = pImp->GetDPObject();
408 :
409 17 : if (pNewObj)
410 : {
411 : ScRange aOutputRange((SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet,
412 17 : (SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet);
413 17 : pNewObj->SetOutRange(aOutputRange);
414 17 : OUString aName = aNewName;
415 17 : if (aName.isEmpty())
416 0 : aName = lcl_CreatePivotName( pDocShell );
417 17 : pNewObj->SetName(aName);
418 34 : OUString aTag = xDescriptor->getTag();
419 17 : pNewObj->SetTag(aTag);
420 :
421 : // todo: handle double fields (for more information see ScDPObject
422 :
423 34 : ScDBDocFunc aFunc(*pDocShell);
424 34 : bDone = aFunc.CreatePivotTable(*pNewObj, true, true);
425 : }
426 : }
427 :
428 17 : if (!bDone)
429 0 : throw RuntimeException(); // no other exceptions specified
430 : }
431 :
432 2 : void SAL_CALL ScDataPilotTablesObj::removeByName( const OUString& aName )
433 : throw(RuntimeException, std::exception)
434 : {
435 2 : SolarMutexGuard aGuard;
436 4 : OUString aNameStr(aName);
437 2 : ScDPObject* pDPObj = lcl_GetDPObject( pDocShell, nTab, aNameStr );
438 2 : if (pDPObj && pDocShell)
439 : {
440 1 : ScDBDocFunc aFunc(*pDocShell);
441 1 : aFunc.RemovePivotTable(*pDPObj, true, true); // remove - incl. undo etc.
442 : }
443 : else
444 3 : throw RuntimeException(); // no other exceptions specified
445 1 : }
446 :
447 : // XEnumerationAccess
448 :
449 2 : Reference< XEnumeration > SAL_CALL ScDataPilotTablesObj::createEnumeration() throw(RuntimeException, std::exception)
450 : {
451 2 : SolarMutexGuard aGuard;
452 2 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotTablesEnumeration"));
453 : }
454 :
455 : // XIndexAccess
456 :
457 4 : sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException, std::exception)
458 : {
459 4 : SolarMutexGuard aGuard;
460 4 : if ( pDocShell )
461 : {
462 4 : ScDocument* pDoc = pDocShell->GetDocument();
463 4 : ScDPCollection* pColl = pDoc->GetDPCollection();
464 4 : if ( pColl )
465 : {
466 : // count tables on this sheet
467 :
468 4 : sal_uInt16 nFound = 0;
469 4 : size_t nCount = pColl->GetCount();
470 8 : for (size_t i=0; i<nCount; ++i)
471 : {
472 4 : ScDPObject* pDPObj = (*pColl)[i];
473 4 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
474 4 : ++nFound;
475 : }
476 4 : return nFound;
477 : }
478 : }
479 :
480 0 : return 0;
481 : }
482 :
483 12 : Any SAL_CALL ScDataPilotTablesObj::getByIndex( sal_Int32 nIndex )
484 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
485 : {
486 12 : SolarMutexGuard aGuard;
487 24 : Reference<XDataPilotTable2> xTable(GetObjectByIndex_Impl(nIndex));
488 12 : if (!xTable.is())
489 2 : throw IndexOutOfBoundsException();
490 22 : return Any( xTable );
491 : }
492 :
493 1 : uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(RuntimeException, std::exception)
494 : {
495 1 : SolarMutexGuard aGuard;
496 1 : return getCppuType((Reference<XDataPilotTable2>*)0);
497 : }
498 :
499 1 : sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(RuntimeException, std::exception)
500 : {
501 1 : SolarMutexGuard aGuard;
502 1 : return ( getCount() != 0 );
503 : }
504 :
505 : // XNameAccess
506 :
507 28 : Any SAL_CALL ScDataPilotTablesObj::getByName( const OUString& aName )
508 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
509 : {
510 28 : SolarMutexGuard aGuard;
511 56 : Reference<XDataPilotTable2> xTable(GetObjectByName_Impl(aName));
512 28 : if (!xTable.is())
513 1 : throw NoSuchElementException();
514 55 : return Any( xTable );
515 : }
516 :
517 10 : Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames()
518 : throw(RuntimeException, std::exception)
519 : {
520 10 : SolarMutexGuard aGuard;
521 10 : if (pDocShell)
522 : {
523 10 : ScDocument* pDoc = pDocShell->GetDocument();
524 10 : ScDPCollection* pColl = pDoc->GetDPCollection();
525 10 : if ( pColl )
526 : {
527 : // count tables on this sheet
528 :
529 10 : sal_uInt16 nFound = 0;
530 10 : size_t nCount = pColl->GetCount();
531 : size_t i;
532 20 : for (i=0; i<nCount; ++i)
533 : {
534 10 : ScDPObject* pDPObj = (*pColl)[i];
535 10 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
536 10 : ++nFound;
537 : }
538 :
539 10 : sal_uInt16 nPos = 0;
540 10 : Sequence<OUString> aSeq(nFound);
541 10 : OUString* pAry = aSeq.getArray();
542 20 : for (i=0; i<nCount; ++i)
543 : {
544 10 : ScDPObject* pDPObj = (*pColl)[i];
545 10 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
546 10 : pAry[nPos++] = pDPObj->GetName();
547 : }
548 :
549 10 : return aSeq;
550 : }
551 : }
552 0 : return Sequence<OUString>(0);
553 : }
554 :
555 60 : sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName )
556 : throw(RuntimeException, std::exception)
557 : {
558 60 : SolarMutexGuard aGuard;
559 60 : if (pDocShell)
560 : {
561 60 : ScDocument* pDoc = pDocShell->GetDocument();
562 60 : ScDPCollection* pColl = pDoc->GetDPCollection();
563 60 : if ( pColl )
564 : {
565 60 : size_t nCount = pColl->GetCount();
566 71 : for (size_t i=0; i<nCount; ++i)
567 : {
568 40 : ScDPObject* pDPObj = (*pColl)[i];
569 80 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
570 40 : pDPObj->GetName() == aName )
571 29 : return true;
572 : }
573 : }
574 : }
575 31 : return false;
576 : }
577 :
578 54 : ScDataPilotDescriptorBase::ScDataPilotDescriptorBase(ScDocShell* pDocSh) :
579 : maPropSet( lcl_GetDataPilotDescriptorBaseMap() ),
580 54 : pDocShell( pDocSh )
581 : {
582 54 : pDocShell->GetDocument()->AddUnoObject(*this);
583 54 : }
584 :
585 106 : ScDataPilotDescriptorBase::~ScDataPilotDescriptorBase()
586 : {
587 53 : if (pDocShell)
588 22 : pDocShell->GetDocument()->RemoveUnoObject(*this);
589 53 : }
590 :
591 83 : Any SAL_CALL ScDataPilotDescriptorBase::queryInterface( const uno::Type& rType )
592 : throw(RuntimeException, std::exception)
593 : {
594 83 : SC_QUERYINTERFACE( XDataPilotDescriptor )
595 60 : SC_QUERYINTERFACE( XPropertySet )
596 60 : SC_QUERYINTERFACE( XDataPilotDataLayoutFieldSupplier )
597 60 : SC_QUERYINTERFACE( XNamed ) // base of XDataPilotDescriptor
598 57 : SC_QUERYINTERFACE( lang::XUnoTunnel )
599 40 : SC_QUERYINTERFACE( lang::XTypeProvider )
600 40 : SC_QUERYINTERFACE( lang::XServiceInfo )
601 :
602 40 : return OWeakObject::queryInterface( rType );
603 : }
604 :
605 641 : void SAL_CALL ScDataPilotDescriptorBase::acquire() throw()
606 : {
607 641 : OWeakObject::acquire();
608 641 : }
609 :
610 640 : void SAL_CALL ScDataPilotDescriptorBase::release() throw()
611 : {
612 640 : OWeakObject::release();
613 640 : }
614 :
615 0 : Sequence< uno::Type > SAL_CALL ScDataPilotDescriptorBase::getTypes()
616 : throw(RuntimeException, std::exception)
617 : {
618 0 : static Sequence< uno::Type > aTypes;
619 0 : if ( aTypes.getLength() == 0 )
620 : {
621 0 : aTypes.realloc( 6 );
622 0 : uno::Type* pPtr = aTypes.getArray();
623 0 : pPtr[ 0 ] = getCppuType( (const Reference< XDataPilotDescriptor >*)0 );
624 0 : pPtr[ 1 ] = getCppuType( (const Reference< XPropertySet >*)0 );
625 0 : pPtr[ 2 ] = getCppuType( (const Reference< XDataPilotDataLayoutFieldSupplier >*)0 );
626 0 : pPtr[ 3 ] = getCppuType( (const Reference< lang::XUnoTunnel >*)0 );
627 0 : pPtr[ 4 ] = getCppuType( (const Reference< lang::XTypeProvider >*)0 );
628 0 : pPtr[ 5 ] = getCppuType( (const Reference< lang::XServiceInfo >*)0 );
629 : }
630 0 : return aTypes;
631 : }
632 :
633 0 : Sequence<sal_Int8> SAL_CALL ScDataPilotDescriptorBase::getImplementationId()
634 : throw(RuntimeException, std::exception)
635 : {
636 0 : return css::uno::Sequence<sal_Int8>();
637 : }
638 :
639 492 : void ScDataPilotDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
640 : {
641 : //! Referenz-Update?
642 :
643 794 : if ( rHint.ISA( SfxSimpleHint ) &&
644 302 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
645 : {
646 32 : pDocShell = NULL; // ungueltig geworden
647 : }
648 492 : }
649 :
650 : // XDataPilotDescriptor
651 :
652 4 : CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange()
653 : throw(RuntimeException, std::exception)
654 : {
655 4 : SolarMutexGuard aGuard;
656 :
657 4 : ScDPObject* pDPObject(GetDPObject());
658 4 : if (!pDPObject)
659 0 : throw RuntimeException();
660 :
661 4 : CellRangeAddress aRet;
662 4 : if (pDPObject->IsSheetData())
663 4 : ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->GetSourceRange() );
664 4 : return aRet;
665 : }
666 :
667 19 : void SAL_CALL ScDataPilotDescriptorBase::setSourceRange( const CellRangeAddress& aSourceRange ) throw(RuntimeException, std::exception)
668 : {
669 19 : SolarMutexGuard aGuard;
670 :
671 19 : ScDPObject* pDPObject = GetDPObject();
672 19 : if (!pDPObject)
673 0 : throw RuntimeException();
674 :
675 38 : ScSheetSourceDesc aSheetDesc(pDocShell->GetDocument());
676 19 : if (pDPObject->IsSheetData())
677 19 : aSheetDesc = *pDPObject->GetSheetDesc();
678 :
679 19 : ScRange aRange;
680 19 : ScUnoConversion::FillScRange(aRange, aSourceRange);
681 19 : aSheetDesc.SetSourceRange(aRange);
682 19 : pDPObject->SetSheetDesc( aSheetDesc );
683 38 : SetDPObject( pDPObject );
684 19 : }
685 :
686 3 : Reference<XSheetFilterDescriptor> SAL_CALL ScDataPilotDescriptorBase::getFilterDescriptor()
687 : throw(RuntimeException, std::exception)
688 : {
689 3 : SolarMutexGuard aGuard;
690 3 : return new ScDataPilotFilterDescriptor( pDocShell, this );
691 : }
692 :
693 44 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataPilotFields()
694 : throw(RuntimeException, std::exception)
695 : {
696 44 : SolarMutexGuard aGuard;
697 44 : return new ScDataPilotFieldsObj( *this );
698 : }
699 :
700 2 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getColumnFields()
701 : throw(RuntimeException, std::exception)
702 : {
703 2 : SolarMutexGuard aGuard;
704 2 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_COLUMN );
705 : }
706 :
707 8 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getRowFields()
708 : throw(RuntimeException, std::exception)
709 : {
710 8 : SolarMutexGuard aGuard;
711 8 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_ROW );
712 : }
713 :
714 2 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getPageFields()
715 : throw(RuntimeException, std::exception)
716 : {
717 2 : SolarMutexGuard aGuard;
718 2 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_PAGE );
719 : }
720 :
721 2 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataFields()
722 : throw(RuntimeException, std::exception)
723 : {
724 2 : SolarMutexGuard aGuard;
725 2 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_DATA );
726 : }
727 :
728 1 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getHiddenFields()
729 : throw(RuntimeException, std::exception)
730 : {
731 1 : SolarMutexGuard aGuard;
732 1 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_HIDDEN );
733 : }
734 :
735 : // XPropertySet
736 0 : Reference< XPropertySetInfo > SAL_CALL ScDataPilotDescriptorBase::getPropertySetInfo( )
737 : throw(RuntimeException, std::exception)
738 : {
739 0 : SolarMutexGuard aGuard;
740 : static Reference<XPropertySetInfo> aRef =
741 0 : new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
742 0 : return aRef;
743 : }
744 :
745 0 : void SAL_CALL ScDataPilotDescriptorBase::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
746 : throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException,
747 : WrappedTargetException, RuntimeException, std::exception)
748 : {
749 0 : SolarMutexGuard aGuard;
750 0 : ScDPObject* pDPObject = GetDPObject();
751 0 : if (pDPObject)
752 : {
753 0 : ScDPSaveData* pOldData = pDPObject->GetSaveData();
754 : OSL_ENSURE(pOldData, "Here should be a SaveData");
755 0 : if ( pOldData )
756 : {
757 0 : ScDPSaveData aNewData( *pOldData );
758 :
759 0 : OUString aNameString = aPropertyName;
760 0 : if ( aNameString.equalsAscii( SC_UNO_DP_COLGRAND ) )
761 : {
762 0 : aNewData.SetColumnGrand(::cppu::any2bool( aValue ));
763 : }
764 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_IGNORE_EMPTYROWS ) )
765 : {
766 0 : aNewData.SetIgnoreEmptyRows(::cppu::any2bool( aValue ));
767 : }
768 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_REPEATEMPTY ) )
769 : {
770 0 : aNewData.SetRepeatIfEmpty(::cppu::any2bool( aValue ));
771 : }
772 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_ROWGRAND ) )
773 : {
774 0 : aNewData.SetRowGrand(::cppu::any2bool( aValue ));
775 : }
776 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_SHOWFILTER ) )
777 : {
778 0 : aNewData.SetFilterButton(::cppu::any2bool( aValue ));
779 : }
780 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_DRILLDOWN ) )
781 : {
782 0 : aNewData.SetDrillDown(::cppu::any2bool( aValue ));
783 : }
784 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_GRANDTOTAL_NAME ) )
785 : {
786 0 : OUString aStrVal;
787 0 : if ( aValue >>= aStrVal )
788 0 : aNewData.SetGrandTotalName(aStrVal);
789 : }
790 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_IMPORTDESC ) )
791 : {
792 0 : uno::Sequence<beans::PropertyValue> aArgSeq;
793 0 : if ( aValue >>= aArgSeq )
794 : {
795 0 : ScImportSourceDesc aImportDesc(pDocShell->GetDocument());
796 :
797 0 : const ScImportSourceDesc* pOldDesc = pDPObject->GetImportSourceDesc();
798 0 : if (pOldDesc)
799 0 : aImportDesc = *pOldDesc;
800 :
801 0 : ScImportParam aParam;
802 0 : ScImportDescriptor::FillImportParam( aParam, aArgSeq );
803 :
804 0 : sal_uInt16 nNewType = sheet::DataImportMode_NONE;
805 0 : if ( aParam.bImport )
806 : {
807 0 : if ( aParam.bSql )
808 0 : nNewType = sheet::DataImportMode_SQL;
809 0 : else if ( aParam.nType == ScDbQuery )
810 0 : nNewType = sheet::DataImportMode_QUERY;
811 : else
812 0 : nNewType = sheet::DataImportMode_TABLE;
813 : }
814 0 : aImportDesc.nType = nNewType;
815 0 : aImportDesc.aDBName = aParam.aDBName;
816 0 : aImportDesc.aObject = aParam.aStatement;
817 0 : aImportDesc.bNative = aParam.bNative;
818 :
819 0 : pDPObject->SetImportDesc( aImportDesc );
820 0 : }
821 : }
822 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_SOURCESERVICE ) )
823 : {
824 0 : OUString aStrVal;
825 0 : if ( aValue >>= aStrVal )
826 : {
827 0 : OUString aEmpty;
828 0 : ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
829 :
830 0 : const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
831 0 : if (pOldDesc)
832 0 : aServiceDesc = *pOldDesc;
833 :
834 0 : aServiceDesc.aServiceName = aStrVal;
835 :
836 0 : pDPObject->SetServiceData( aServiceDesc );
837 0 : }
838 : }
839 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_SERVICEARG ) )
840 : {
841 0 : uno::Sequence<beans::PropertyValue> aArgSeq;
842 0 : if ( aValue >>= aArgSeq )
843 : {
844 0 : OUString aEmpty;
845 0 : ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
846 :
847 0 : const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
848 0 : if (pOldDesc)
849 0 : aServiceDesc = *pOldDesc;
850 :
851 0 : OUString aStrVal;
852 0 : sal_Int32 nArgs = aArgSeq.getLength();
853 0 : for (sal_Int32 nArgPos=0; nArgPos<nArgs; ++nArgPos)
854 : {
855 0 : const beans::PropertyValue& rProp = aArgSeq[nArgPos];
856 0 : OUString aPropName(rProp.Name);
857 :
858 0 : if (aPropName.equalsAscii( SC_UNO_DP_SOURCENAME ))
859 : {
860 0 : if ( rProp.Value >>= aStrVal )
861 0 : aServiceDesc.aParSource = aStrVal;
862 : }
863 0 : else if (aPropName.equalsAscii( SC_UNO_DP_OBJECTNAME ))
864 : {
865 0 : if ( rProp.Value >>= aStrVal )
866 0 : aServiceDesc.aParName = aStrVal;
867 : }
868 0 : else if (aPropName.equalsAscii( SC_UNO_DP_USERNAME ))
869 : {
870 0 : if ( rProp.Value >>= aStrVal )
871 0 : aServiceDesc.aParUser = aStrVal;
872 : }
873 0 : else if (aPropName.equalsAscii( SC_UNO_DP_PASSWORD ))
874 : {
875 0 : if ( rProp.Value >>= aStrVal )
876 0 : aServiceDesc.aParPass = aStrVal;
877 : }
878 0 : }
879 :
880 0 : pDPObject->SetServiceData( aServiceDesc );
881 0 : }
882 : }
883 : else
884 0 : throw UnknownPropertyException();
885 :
886 0 : pDPObject->SetSaveData( aNewData );
887 : }
888 :
889 0 : SetDPObject(pDPObject);
890 0 : }
891 0 : }
892 :
893 0 : Any SAL_CALL ScDataPilotDescriptorBase::getPropertyValue( const OUString& aPropertyName )
894 : throw (UnknownPropertyException, WrappedTargetException,
895 : RuntimeException, std::exception)
896 : {
897 0 : SolarMutexGuard aGuard;
898 0 : Any aRet;
899 :
900 0 : ScDPObject* pDPObject(GetDPObject());
901 0 : if (pDPObject)
902 : {
903 0 : ScDPSaveData* pOldData = pDPObject->GetSaveData();
904 : OSL_ENSURE(pOldData, "Here should be a SaveData");
905 0 : if ( pOldData )
906 : {
907 0 : ScDPSaveData aNewData( *pOldData );
908 :
909 0 : OUString aNameString = aPropertyName;
910 0 : if ( aNameString.equalsAscii( SC_UNO_DP_COLGRAND ) )
911 : {
912 0 : aRet <<= aNewData.GetColumnGrand();
913 : }
914 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_IGNORE_EMPTYROWS ) )
915 : {
916 0 : aRet <<= aNewData.GetIgnoreEmptyRows();
917 : }
918 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_REPEATEMPTY ) )
919 : {
920 0 : aRet <<= aNewData.GetRepeatIfEmpty();
921 : }
922 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_ROWGRAND ) )
923 : {
924 0 : aRet <<= aNewData.GetRowGrand();
925 : }
926 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_SHOWFILTER ) )
927 : {
928 0 : aRet <<= aNewData.GetFilterButton();
929 : }
930 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_DRILLDOWN ) )
931 : {
932 0 : aRet <<= aNewData.GetDrillDown();
933 : }
934 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_GRANDTOTAL_NAME ) )
935 : {
936 0 : const OUString* pGrandTotalName = aNewData.GetGrandTotalName();
937 0 : if (pGrandTotalName)
938 0 : aRet <<= *pGrandTotalName; // same behavior as in ScDPSource
939 : }
940 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_IMPORTDESC ) )
941 : {
942 0 : const ScImportSourceDesc* pImportDesc = pDPObject->GetImportSourceDesc();
943 0 : if ( pImportDesc )
944 : {
945 : // fill ScImportParam so ScImportDescriptor::FillProperties can be used
946 0 : ScImportParam aParam;
947 0 : aParam.bImport = ( pImportDesc->nType != sheet::DataImportMode_NONE );
948 0 : aParam.aDBName = pImportDesc->aDBName;
949 0 : aParam.aStatement = pImportDesc->aObject;
950 0 : aParam.bNative = pImportDesc->bNative;
951 0 : aParam.bSql = ( pImportDesc->nType == sheet::DataImportMode_SQL );
952 0 : aParam.nType = static_cast<sal_uInt8>(( pImportDesc->nType == sheet::DataImportMode_QUERY ) ? ScDbQuery : ScDbTable);
953 :
954 0 : uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
955 0 : ScImportDescriptor::FillProperties( aSeq, aParam );
956 0 : aRet <<= aSeq;
957 : }
958 : else
959 : {
960 : // empty sequence
961 0 : uno::Sequence<beans::PropertyValue> aEmpty(0);
962 0 : aRet <<= aEmpty;
963 : }
964 : }
965 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_SOURCESERVICE ) )
966 : {
967 0 : OUString aServiceName;
968 0 : const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
969 0 : if (pServiceDesc)
970 0 : aServiceName = pServiceDesc->aServiceName;
971 0 : aRet <<= aServiceName; // empty string if no ServiceDesc set
972 : }
973 0 : else if ( aNameString.equalsAscii( SC_UNO_DP_SERVICEARG ) )
974 : {
975 0 : const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
976 0 : if (pServiceDesc)
977 : {
978 0 : uno::Sequence<beans::PropertyValue> aSeq( 4 );
979 0 : beans::PropertyValue* pArray = aSeq.getArray();
980 0 : pArray[0].Name = OUString( SC_UNO_DP_SOURCENAME );
981 0 : pArray[0].Value <<= pServiceDesc->aParSource;
982 0 : pArray[1].Name = OUString( SC_UNO_DP_OBJECTNAME );
983 0 : pArray[1].Value <<= pServiceDesc->aParName;
984 0 : pArray[2].Name = OUString( SC_UNO_DP_USERNAME );
985 0 : pArray[2].Value <<= pServiceDesc->aParUser;
986 0 : pArray[3].Name = OUString( SC_UNO_DP_PASSWORD );
987 0 : pArray[3].Value <<= pServiceDesc->aParPass;
988 0 : aRet <<= aSeq;
989 : }
990 : else
991 : {
992 : // empty sequence
993 0 : uno::Sequence<beans::PropertyValue> aEmpty(0);
994 0 : aRet <<= aEmpty;
995 : }
996 : }
997 : else
998 0 : throw UnknownPropertyException();
999 : }
1000 : }
1001 :
1002 0 : return aRet;
1003 : }
1004 :
1005 0 : void SAL_CALL ScDataPilotDescriptorBase::addPropertyChangeListener(
1006 : const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* xListener */ )
1007 : throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
1008 : {
1009 0 : }
1010 :
1011 0 : void SAL_CALL ScDataPilotDescriptorBase::removePropertyChangeListener(
1012 : const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* aListener */ )
1013 : throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
1014 : {
1015 0 : }
1016 :
1017 0 : void SAL_CALL ScDataPilotDescriptorBase::addVetoableChangeListener(
1018 : const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
1019 : throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
1020 : {
1021 0 : }
1022 :
1023 0 : void SAL_CALL ScDataPilotDescriptorBase::removeVetoableChangeListener(
1024 : const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
1025 : throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
1026 : {
1027 0 : }
1028 :
1029 : // XDataPilotDataLayoutFieldSupplier
1030 :
1031 0 : Reference< XDataPilotField > SAL_CALL ScDataPilotDescriptorBase::getDataLayoutField()
1032 : throw (RuntimeException, std::exception)
1033 : {
1034 0 : SolarMutexGuard aGuard;
1035 0 : if( ScDPObject* pDPObject = GetDPObject() )
1036 : {
1037 0 : if( ScDPSaveData* pSaveData = pDPObject->GetSaveData() )
1038 : {
1039 0 : if( pSaveData->GetDataLayoutDimension() )
1040 : {
1041 0 : ScFieldIdentifier aFieldId( OUString( SC_DATALAYOUT_NAME ), 0, true );
1042 0 : return new ScDataPilotFieldObj( *this, aFieldId );
1043 : }
1044 : }
1045 : }
1046 0 : return 0;
1047 : }
1048 :
1049 : // XUnoTunnel
1050 :
1051 17 : sal_Int64 SAL_CALL ScDataPilotDescriptorBase::getSomething(
1052 : const Sequence<sal_Int8 >& rId ) throw(RuntimeException, std::exception)
1053 : {
1054 34 : if ( rId.getLength() == 16 &&
1055 17 : 0 == memcmp( getUnoTunnelId().getConstArray(),
1056 34 : rId.getConstArray(), 16 ) )
1057 : {
1058 17 : return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
1059 : }
1060 0 : return 0;
1061 : }
1062 :
1063 : namespace
1064 : {
1065 : class theScDataPilotDescriptorBaseUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScDataPilotDescriptorBaseUnoTunnelId> {};
1066 : }
1067 :
1068 34 : const Sequence<sal_Int8>& ScDataPilotDescriptorBase::getUnoTunnelId()
1069 : {
1070 34 : return theScDataPilotDescriptorBaseUnoTunnelId::get().getSeq();
1071 : }
1072 :
1073 17 : ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation(
1074 : const Reference<XDataPilotDescriptor> xObj )
1075 : {
1076 17 : ScDataPilotDescriptorBase* pRet = NULL;
1077 17 : Reference<lang::XUnoTunnel> xUT( xObj, UNO_QUERY );
1078 17 : if (xUT.is())
1079 17 : pRet = reinterpret_cast<ScDataPilotDescriptorBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
1080 17 : return pRet;
1081 : }
1082 :
1083 37 : ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const OUString& rN) :
1084 : ScDataPilotDescriptorBase( pDocSh ),
1085 : nTab( nT ),
1086 : aName( rN ),
1087 37 : aModifyListeners( 0 )
1088 : {
1089 37 : }
1090 :
1091 74 : ScDataPilotTableObj::~ScDataPilotTableObj()
1092 : {
1093 74 : }
1094 :
1095 71 : Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType )
1096 : throw(RuntimeException, std::exception)
1097 : {
1098 : // since we manually do resolve the query for XDataPilotTable2
1099 : // we also need to do the same for XDataPilotTable
1100 71 : SC_QUERYINTERFACE( XDataPilotTable )
1101 53 : SC_QUERYINTERFACE( XDataPilotTable2 )
1102 49 : SC_QUERYINTERFACE( XModifyBroadcaster )
1103 :
1104 49 : return ScDataPilotDescriptorBase::queryInterface( rType );
1105 : }
1106 :
1107 392 : void SAL_CALL ScDataPilotTableObj::acquire() throw()
1108 : {
1109 392 : ScDataPilotDescriptorBase::acquire();
1110 392 : }
1111 :
1112 392 : void SAL_CALL ScDataPilotTableObj::release() throw()
1113 : {
1114 392 : ScDataPilotDescriptorBase::release();
1115 392 : }
1116 :
1117 0 : Sequence< uno::Type > SAL_CALL ScDataPilotTableObj::getTypes() throw(RuntimeException, std::exception)
1118 : {
1119 0 : static Sequence< uno::Type > aTypes;
1120 0 : if ( aTypes.getLength() == 0 )
1121 : {
1122 0 : Sequence< uno::Type > aParentTypes = ScDataPilotDescriptorBase::getTypes();
1123 0 : sal_Int32 nParentLen = aParentTypes.getLength();
1124 0 : const uno::Type* pParentPtr = aParentTypes.getConstArray();
1125 :
1126 0 : aTypes.realloc( nParentLen + 2 );
1127 0 : uno::Type* pPtr = aTypes.getArray();
1128 0 : for (sal_Int32 i = 0; i < nParentLen; ++i)
1129 0 : pPtr[ i ] = pParentPtr[ i ]; // parent types first
1130 :
1131 0 : pPtr[ nParentLen ] = getCppuType( (const Reference< XDataPilotTable2 >*)0 );
1132 0 : pPtr[ nParentLen+1 ] = getCppuType( (const Reference< XModifyBroadcaster >*)0 );
1133 : }
1134 0 : return aTypes;
1135 : }
1136 :
1137 0 : Sequence<sal_Int8> SAL_CALL ScDataPilotTableObj::getImplementationId()
1138 : throw(RuntimeException, std::exception)
1139 : {
1140 0 : return css::uno::Sequence<sal_Int8>();
1141 : }
1142 :
1143 :
1144 585 : ScDPObject* ScDataPilotTableObj::GetDPObject() const
1145 : {
1146 585 : return lcl_GetDPObject(GetDocShell(), nTab, aName);
1147 : }
1148 :
1149 21 : void ScDataPilotTableObj::SetDPObject( ScDPObject* pDPObject )
1150 : {
1151 21 : ScDocShell* pDocSh = GetDocShell();
1152 21 : ScDPObject* pDPObj = lcl_GetDPObject(pDocSh, nTab, aName);
1153 21 : if ( pDPObj && pDocSh )
1154 : {
1155 21 : ScDBDocFunc aFunc(*pDocSh);
1156 21 : aFunc.DataPilotUpdate( pDPObj, pDPObject, true, true );
1157 : }
1158 21 : }
1159 :
1160 : // "rest of XDataPilotDescriptor"
1161 :
1162 6 : OUString SAL_CALL ScDataPilotTableObj::getName() throw(RuntimeException, std::exception)
1163 : {
1164 6 : SolarMutexGuard aGuard;
1165 6 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1166 6 : if (pDPObj)
1167 6 : return pDPObj->GetName();
1168 0 : return OUString();
1169 : }
1170 :
1171 4 : void SAL_CALL ScDataPilotTableObj::setName( const OUString& aNewName )
1172 : throw(RuntimeException, std::exception)
1173 : {
1174 4 : SolarMutexGuard aGuard;
1175 4 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1176 4 : if (pDPObj)
1177 : {
1178 : //! test for existing names !!!
1179 :
1180 4 : OUString aString(aNewName);
1181 4 : pDPObj->SetName( aString ); //! Undo - DBDocFunc ???
1182 4 : aName = aString;
1183 :
1184 : // DataPilotUpdate would do too much (output table is not changed)
1185 4 : GetDocShell()->SetDocumentModified();
1186 4 : }
1187 4 : }
1188 :
1189 2 : OUString SAL_CALL ScDataPilotTableObj::getTag() throw(RuntimeException, std::exception)
1190 : {
1191 2 : SolarMutexGuard aGuard;
1192 2 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1193 2 : if (pDPObj)
1194 2 : return pDPObj->GetTag();
1195 0 : return OUString();
1196 : }
1197 :
1198 2 : void SAL_CALL ScDataPilotTableObj::setTag( const OUString& aNewTag )
1199 : throw(RuntimeException, std::exception)
1200 : {
1201 2 : SolarMutexGuard aGuard;
1202 2 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1203 2 : if (pDPObj)
1204 : {
1205 2 : pDPObj->SetTag( aNewTag ); //! Undo - DBDocFunc ???
1206 :
1207 : // DataPilotUpdate would do too much (output table is not changed)
1208 2 : GetDocShell()->SetDocumentModified();
1209 2 : }
1210 2 : }
1211 :
1212 : // XDataPilotTable
1213 :
1214 2 : CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeException, std::exception)
1215 : {
1216 2 : SolarMutexGuard aGuard;
1217 2 : CellRangeAddress aRet;
1218 2 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1219 2 : if (pDPObj)
1220 : {
1221 2 : ScRange aRange(pDPObj->GetOutRange());
1222 2 : aRet.Sheet = aRange.aStart.Tab();
1223 2 : aRet.StartColumn = aRange.aStart.Col();
1224 2 : aRet.StartRow = aRange.aStart.Row();
1225 2 : aRet.EndColumn = aRange.aEnd.Col();
1226 2 : aRet.EndRow = aRange.aEnd.Row();
1227 : }
1228 2 : return aRet;
1229 : }
1230 :
1231 2 : void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException, std::exception)
1232 : {
1233 2 : SolarMutexGuard aGuard;
1234 2 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1235 2 : if (pDPObj)
1236 : {
1237 2 : ScDBDocFunc aFunc(*GetDocShell());
1238 2 : aFunc.RefreshPivotTables(pDPObj, true);
1239 2 : }
1240 2 : }
1241 :
1242 97 : Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr)
1243 : throw (RuntimeException, std::exception)
1244 : {
1245 97 : SolarMutexGuard aGuard;
1246 97 : Sequence< Sequence<Any> > aTabData;
1247 97 : ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1248 97 : ScDPObject* pObj = GetDPObject();
1249 97 : if (!pObj)
1250 0 : throw RuntimeException();
1251 :
1252 97 : pObj->GetDrillDownData(aAddr2, aTabData);
1253 97 : return aTabData;
1254 : }
1255 :
1256 266 : DataPilotTablePositionData SAL_CALL ScDataPilotTableObj::getPositionData(const CellAddress& aAddr)
1257 : throw (RuntimeException, std::exception)
1258 : {
1259 266 : SolarMutexGuard aGuard;
1260 266 : DataPilotTablePositionData aPosData;
1261 266 : ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1262 266 : ScDPObject* pObj = GetDPObject();
1263 266 : if (!pObj)
1264 0 : throw RuntimeException();
1265 :
1266 266 : pObj->GetPositionData(aAddr2, aPosData);
1267 266 : return aPosData;
1268 : }
1269 :
1270 36 : void SAL_CALL ScDataPilotTableObj::insertDrillDownSheet(const CellAddress& aAddr)
1271 : throw (RuntimeException, std::exception)
1272 : {
1273 36 : SolarMutexGuard aGuard;
1274 36 : ScDPObject* pDPObj = GetDPObject();
1275 36 : if (!pDPObj)
1276 0 : throw RuntimeException();
1277 36 : ScTabViewShell* pViewSh = GetDocShell()->GetBestViewShell();
1278 36 : if (!pViewSh)
1279 0 : throw RuntimeException();
1280 :
1281 72 : Sequence<DataPilotFieldFilter> aFilters;
1282 : pDPObj->GetDataFieldPositionData(
1283 36 : ScAddress(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet), aFilters);
1284 72 : pViewSh->ShowDataPilotSourceData(*pDPObj, aFilters);
1285 36 : }
1286 :
1287 19 : CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
1288 : throw (IllegalArgumentException, RuntimeException, std::exception)
1289 : {
1290 19 : SolarMutexGuard aGuard;
1291 19 : if (nType < 0 || nType > DataPilotOutputRangeType::RESULT)
1292 4 : throw IllegalArgumentException();
1293 :
1294 15 : CellRangeAddress aRet;
1295 15 : if (ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName))
1296 15 : ScUnoConversion::FillApiRange( aRet, pDPObj->GetOutputRangeByType( nType ) );
1297 19 : return aRet;
1298 : }
1299 :
1300 0 : void SAL_CALL ScDataPilotTableObj::addModifyListener( const uno::Reference<util::XModifyListener>& aListener )
1301 : throw (uno::RuntimeException, std::exception)
1302 : {
1303 0 : SolarMutexGuard aGuard;
1304 :
1305 0 : uno::Reference<util::XModifyListener> *pObj = new uno::Reference<util::XModifyListener>( aListener );
1306 0 : aModifyListeners.push_back( pObj );
1307 :
1308 0 : if ( aModifyListeners.size() == 1 )
1309 : {
1310 0 : acquire(); // don't lose this object (one ref for all listeners)
1311 0 : }
1312 0 : }
1313 :
1314 0 : void SAL_CALL ScDataPilotTableObj::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
1315 : throw (uno::RuntimeException, std::exception)
1316 : {
1317 0 : SolarMutexGuard aGuard;
1318 :
1319 0 : acquire(); // in case the listeners have the last ref - released below
1320 :
1321 0 : sal_uInt16 nCount = aModifyListeners.size();
1322 0 : for ( sal_uInt16 n=nCount; n--; )
1323 : {
1324 0 : uno::Reference<util::XModifyListener>& rObj = aModifyListeners[n];
1325 0 : if ( rObj == aListener )
1326 : {
1327 0 : aModifyListeners.erase( aModifyListeners.begin() + n );
1328 :
1329 0 : if ( aModifyListeners.empty() )
1330 : {
1331 0 : release(); // release the ref for the listeners
1332 : }
1333 :
1334 0 : break;
1335 : }
1336 : }
1337 :
1338 0 : release(); // might delete this object
1339 0 : }
1340 :
1341 254 : void ScDataPilotTableObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1342 : {
1343 288 : if ( rHint.ISA(ScDataPilotModifiedHint) &&
1344 34 : static_cast<const ScDataPilotModifiedHint&>(rHint).GetName() == aName )
1345 : {
1346 27 : Refreshed_Impl();
1347 : }
1348 227 : else if ( rHint.ISA( ScUpdateRefHint ) )
1349 : {
1350 64 : ScRange aRange( 0, 0, nTab );
1351 64 : ScRangeList aRanges;
1352 64 : aRanges.Append( aRange );
1353 64 : const ScUpdateRefHint& rRef = static_cast< const ScUpdateRefHint& >( rHint );
1354 128 : if ( aRanges.UpdateReference( rRef.GetMode(), GetDocShell()->GetDocument(), rRef.GetRange(),
1355 192 : rRef.GetDx(), rRef.GetDy(), rRef.GetDz() ) &&
1356 64 : aRanges.size() == 1 )
1357 : {
1358 64 : const ScRange* pRange = aRanges.front();
1359 64 : if ( pRange )
1360 : {
1361 64 : nTab = pRange->aStart.Tab();
1362 : }
1363 64 : }
1364 : }
1365 :
1366 254 : ScDataPilotDescriptorBase::Notify( rBC, rHint );
1367 254 : }
1368 :
1369 27 : void ScDataPilotTableObj::Refreshed_Impl()
1370 : {
1371 27 : lang::EventObject aEvent;
1372 27 : aEvent.Source.set((cppu::OWeakObject*)this);
1373 :
1374 : // the EventObject holds a Ref to this object until after the listener calls
1375 :
1376 27 : ScDocument* pDoc = GetDocShell()->GetDocument();
1377 27 : for ( sal_uInt16 n=0; n<aModifyListeners.size(); n++ )
1378 27 : pDoc->AddUnoListenerCall( aModifyListeners[n], aEvent );
1379 27 : }
1380 :
1381 17 : ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) :
1382 : ScDataPilotDescriptorBase( pDocSh ),
1383 17 : mpDPObject(new ScDPObject(pDocSh ? pDocSh->GetDocument() : NULL) )
1384 : {
1385 17 : ScDPSaveData aSaveData;
1386 : // set defaults like in ScPivotParam constructor
1387 17 : aSaveData.SetColumnGrand( true );
1388 17 : aSaveData.SetRowGrand( true );
1389 17 : aSaveData.SetIgnoreEmptyRows( false );
1390 17 : aSaveData.SetRepeatIfEmpty( false );
1391 17 : mpDPObject->SetSaveData(aSaveData);
1392 34 : ScSheetSourceDesc aSheetDesc(pDocSh ? pDocSh->GetDocument() : NULL);
1393 17 : mpDPObject->SetSheetDesc(aSheetDesc);
1394 34 : mpDPObject->GetSource();
1395 17 : }
1396 :
1397 48 : ScDataPilotDescriptor::~ScDataPilotDescriptor()
1398 : {
1399 16 : delete mpDPObject;
1400 32 : }
1401 :
1402 348 : ScDPObject* ScDataPilotDescriptor::GetDPObject() const
1403 : {
1404 348 : return mpDPObject;
1405 : }
1406 :
1407 100 : void ScDataPilotDescriptor::SetDPObject( ScDPObject* pDPObject )
1408 : {
1409 100 : if (mpDPObject != pDPObject)
1410 : {
1411 0 : delete mpDPObject;
1412 0 : mpDPObject = pDPObject;
1413 : OSL_FAIL("replace DPObject should not happen");
1414 : }
1415 100 : }
1416 :
1417 : // "rest of XDataPilotDescriptor"
1418 :
1419 0 : OUString SAL_CALL ScDataPilotDescriptor::getName() throw(RuntimeException, std::exception)
1420 : {
1421 0 : SolarMutexGuard aGuard;
1422 0 : return mpDPObject->GetName();
1423 : }
1424 :
1425 0 : void SAL_CALL ScDataPilotDescriptor::setName( const OUString& aNewName )
1426 : throw(RuntimeException, std::exception)
1427 : {
1428 0 : SolarMutexGuard aGuard;
1429 0 : mpDPObject->SetName( aNewName );
1430 0 : }
1431 :
1432 17 : OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(RuntimeException, std::exception)
1433 : {
1434 17 : SolarMutexGuard aGuard;
1435 17 : return mpDPObject->GetTag();
1436 : }
1437 :
1438 0 : void SAL_CALL ScDataPilotDescriptor::setTag( const OUString& aNewTag )
1439 : throw(RuntimeException, std::exception)
1440 : {
1441 0 : SolarMutexGuard aGuard;
1442 0 : mpDPObject->SetTag( aNewTag );
1443 0 : }
1444 :
1445 59 : ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent ) :
1446 59 : mrParent( rParent )
1447 : {
1448 59 : mrParent.acquire();
1449 59 : }
1450 :
1451 146 : ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1452 : mrParent( rParent ),
1453 146 : maFieldId( rFieldId )
1454 : {
1455 146 : mrParent.acquire();
1456 146 : }
1457 :
1458 408 : ScDataPilotChildObjBase::~ScDataPilotChildObjBase()
1459 : {
1460 204 : mrParent.release();
1461 204 : }
1462 :
1463 492 : ScDPObject* ScDataPilotChildObjBase::GetDPObject() const
1464 : {
1465 492 : return mrParent.GetDPObject();
1466 : }
1467 :
1468 101 : void ScDataPilotChildObjBase::SetDPObject( ScDPObject* pDPObject )
1469 : {
1470 101 : mrParent.SetDPObject( pDPObject );
1471 101 : }
1472 :
1473 254 : ScDPSaveDimension* ScDataPilotChildObjBase::GetDPDimension( ScDPObject** ppDPObject ) const
1474 : {
1475 254 : if( ScDPObject* pDPObj = GetDPObject() )
1476 : {
1477 254 : if( ppDPObject ) *ppDPObject = pDPObj;
1478 254 : if( ScDPSaveData* pSaveData = pDPObj->GetSaveData() )
1479 : {
1480 254 : if( maFieldId.mbDataLayout )
1481 256 : return pSaveData->GetDataLayoutDimension();
1482 :
1483 252 : if( maFieldId.mnFieldIdx == 0 )
1484 252 : return pSaveData->GetDimensionByName( maFieldId.maFieldName );
1485 :
1486 : // find dimension with specified index (search in duplicated dimensions)
1487 0 : const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
1488 :
1489 0 : sal_Int32 nFoundIdx = 0;
1490 0 : boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
1491 0 : for(it = rDimensions.begin(); it != rDimensions.end(); ++it)
1492 : {
1493 0 : if( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
1494 : {
1495 0 : if( nFoundIdx == maFieldId.mnFieldIdx )
1496 0 : return const_cast<ScDPSaveDimension*>(&(*it));
1497 0 : ++nFoundIdx;
1498 : }
1499 : }
1500 : }
1501 : }
1502 0 : return 0;
1503 : }
1504 :
1505 27 : sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
1506 : {
1507 27 : sal_Int32 nRet = 0;
1508 27 : Reference<XNameAccess> xMembersNA = GetMembers();
1509 27 : if (xMembersNA.is())
1510 : {
1511 27 : Reference< XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
1512 27 : nRet = xMembersIA->getCount();
1513 : }
1514 27 : return nRet;
1515 : }
1516 :
1517 58 : Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
1518 : {
1519 58 : Reference< XNameAccess > xMembersNA;
1520 58 : if( ScDPObject* pDPObj = GetDPObject() )
1521 58 : pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
1522 58 : return xMembersNA;
1523 : }
1524 :
1525 4 : ScDocShell* ScDataPilotChildObjBase::GetDocShell() const
1526 : {
1527 4 : return mrParent.GetDocShell();
1528 : }
1529 :
1530 44 : ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent ) :
1531 44 : ScDataPilotChildObjBase( rParent )
1532 : {
1533 44 : }
1534 :
1535 15 : ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent, DataPilotFieldOrientation eOrient ) :
1536 : ScDataPilotChildObjBase( rParent ),
1537 15 : maOrient( eOrient )
1538 : {
1539 15 : }
1540 :
1541 118 : ScDataPilotFieldsObj::~ScDataPilotFieldsObj()
1542 : {
1543 118 : }
1544 :
1545 48 : static sal_Int32 lcl_GetFieldCount( const Reference<XDimensionsSupplier>& rSource, const Any& rOrient )
1546 : {
1547 48 : if (!rSource.is())
1548 0 : throw RuntimeException();
1549 :
1550 48 : sal_Int32 nRet = 0;
1551 :
1552 48 : Reference<XNameAccess> xDimsName(rSource->getDimensions());
1553 96 : Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1554 48 : sal_Int32 nIntCount = xIntDims->getCount();
1555 48 : if (rOrient.hasValue())
1556 : {
1557 : // all fields of the specified orientation, including duplicated
1558 28 : Reference<XPropertySet> xDim;
1559 205 : for (sal_Int32 i = 0; i < nIntCount; ++i)
1560 : {
1561 177 : xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1562 177 : if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1563 39 : ++nRet;
1564 28 : }
1565 : }
1566 : else
1567 : {
1568 : // count all non-duplicated fields
1569 :
1570 20 : Reference<XPropertySet> xDim;
1571 140 : for (sal_Int32 i = 0; i < nIntCount; ++i)
1572 : {
1573 120 : xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1574 120 : if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1575 120 : ++nRet;
1576 20 : }
1577 : }
1578 :
1579 96 : return nRet;
1580 : }
1581 :
1582 119 : static sal_Bool lcl_GetFieldDataByIndex( const Reference<XDimensionsSupplier>& rSource,
1583 : const Any& rOrient, SCSIZE nIndex, ScFieldIdentifier& rFieldId )
1584 : {
1585 119 : if (!rSource.is())
1586 0 : throw RuntimeException();
1587 :
1588 119 : sal_Bool bOk = false;
1589 119 : SCSIZE nPos = 0;
1590 119 : sal_Int32 nDimIndex = 0;
1591 :
1592 119 : Reference<XNameAccess> xDimsName(rSource->getDimensions());
1593 238 : Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1594 119 : sal_Int32 nIntCount = xIntDims->getCount();
1595 238 : Reference<XPropertySet> xDim;
1596 119 : if (rOrient.hasValue())
1597 : {
1598 26 : sal_Int32 i = 0;
1599 139 : while (i < nIntCount && !bOk)
1600 : {
1601 87 : xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1602 87 : if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1603 : {
1604 35 : if (nPos == nIndex)
1605 : {
1606 26 : bOk = sal_True;
1607 26 : nDimIndex = i;
1608 : }
1609 : else
1610 9 : ++nPos;
1611 : }
1612 87 : ++i;
1613 : }
1614 : }
1615 : else
1616 : {
1617 93 : sal_Int32 i = 0;
1618 431 : while (i < nIntCount && !bOk)
1619 : {
1620 245 : xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1621 245 : if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1622 : {
1623 245 : if (nPos == nIndex)
1624 : {
1625 91 : bOk = sal_True;
1626 91 : nDimIndex = i;
1627 : }
1628 : else
1629 154 : ++nPos;
1630 : }
1631 245 : ++i;
1632 : }
1633 : }
1634 :
1635 119 : if ( bOk )
1636 : {
1637 117 : xDim.set( xIntDims->getByIndex(nDimIndex), UNO_QUERY );
1638 117 : Reference<XNamed> xDimName( xDim, UNO_QUERY );
1639 117 : if ( xDimName.is() )
1640 : {
1641 117 : OUString sOriginalName( lcl_GetOriginalName( xDimName ) );
1642 117 : rFieldId.maFieldName = sOriginalName;
1643 : rFieldId.mbDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDim,
1644 117 : OUString(SC_UNO_DP_ISDATALAYOUT) );
1645 :
1646 117 : sal_Int32 nRepeat = 0;
1647 117 : if ( rOrient.hasValue() && lcl_IsDuplicated( xDim ) )
1648 : {
1649 : // find the repeat count
1650 : // (this relies on the original dimension always being before the duplicates)
1651 :
1652 0 : Reference<XNamed> xPrevName;
1653 0 : for (sal_Int32 i = 0; i < nDimIndex; ++i)
1654 : {
1655 0 : xPrevName.set( xIntDims->getByIndex(i), UNO_QUERY );
1656 0 : if ( xPrevName.is() && lcl_GetOriginalName( xPrevName ) == sOriginalName )
1657 0 : ++nRepeat;
1658 0 : }
1659 : }
1660 117 : rFieldId.mnFieldIdx = nRepeat;
1661 : }
1662 : else
1663 0 : bOk = false;
1664 : }
1665 :
1666 238 : return bOk;
1667 : }
1668 :
1669 11 : static sal_Bool lcl_GetFieldDataByName( ScDPObject* pDPObj, const OUString& rFieldName, ScFieldIdentifier& rFieldId )
1670 : {
1671 : // "By name" is always the first match.
1672 : // The name "Data" always refers to the data layout field.
1673 11 : rFieldId.maFieldName = rFieldName;
1674 11 : rFieldId.mnFieldIdx = 0;
1675 11 : rFieldId.mbDataLayout = rFieldName == SC_DATALAYOUT_NAME;
1676 :
1677 11 : pDPObj->GetSource(); // IsDimNameInUse doesn't update source data
1678 :
1679 : // check if the named field exists (not for data layout)
1680 11 : return rFieldId.mbDataLayout || pDPObj->IsDimNameInUse( rFieldName );
1681 : }
1682 :
1683 : // XDataPilotFields
1684 :
1685 119 : ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
1686 : {
1687 : // TODO
1688 119 : if (ScDPObject* pObj = GetDPObject())
1689 : {
1690 119 : ScFieldIdentifier aFieldId;
1691 119 : if (lcl_GetFieldDataByIndex( pObj->GetSource(), maOrient, nIndex, aFieldId ))
1692 117 : return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1693 : }
1694 2 : return 0;
1695 : }
1696 :
1697 11 : ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const OUString& aName) const
1698 : {
1699 11 : if (ScDPObject* pDPObj = GetDPObject())
1700 : {
1701 11 : ScFieldIdentifier aFieldId;
1702 11 : if (lcl_GetFieldDataByName( pDPObj, aName, aFieldId ))
1703 9 : return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1704 : }
1705 2 : return 0;
1706 : }
1707 :
1708 : // XEnumerationAccess
1709 :
1710 2 : Reference<XEnumeration> SAL_CALL ScDataPilotFieldsObj::createEnumeration()
1711 : throw(RuntimeException, std::exception)
1712 : {
1713 2 : SolarMutexGuard aGuard;
1714 2 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotFieldsEnumeration"));
1715 : }
1716 :
1717 : // XIndexAccess
1718 :
1719 47 : sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(RuntimeException, std::exception)
1720 : {
1721 47 : SolarMutexGuard aGuard;
1722 : // TODO
1723 47 : ScDPObject* pDPObj = GetDPObject();
1724 47 : return pDPObj ? lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) : 0;
1725 : }
1726 :
1727 119 : Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex )
1728 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
1729 : {
1730 119 : SolarMutexGuard aGuard;
1731 238 : Reference< XPropertySet > xField( GetObjectByIndex_Impl( nIndex ) );
1732 119 : if (!xField.is())
1733 2 : throw IndexOutOfBoundsException();
1734 236 : return Any( xField );
1735 : }
1736 :
1737 1 : uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(RuntimeException, std::exception)
1738 : {
1739 1 : SolarMutexGuard aGuard;
1740 1 : return getCppuType((Reference<XPropertySet>*)0);
1741 : }
1742 :
1743 1 : sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(RuntimeException, std::exception)
1744 : {
1745 1 : SolarMutexGuard aGuard;
1746 1 : return ( getCount() != 0 );
1747 : }
1748 :
1749 9 : Any SAL_CALL ScDataPilotFieldsObj::getByName( const OUString& aName )
1750 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
1751 : {
1752 9 : SolarMutexGuard aGuard;
1753 18 : Reference<XPropertySet> xField(GetObjectByName_Impl(aName));
1754 9 : if (!xField.is())
1755 1 : throw NoSuchElementException();
1756 17 : return Any( xField );
1757 : }
1758 :
1759 1 : Sequence<OUString> SAL_CALL ScDataPilotFieldsObj::getElementNames()
1760 : throw(RuntimeException, std::exception)
1761 : {
1762 1 : SolarMutexGuard aGuard;
1763 : // TODO
1764 1 : if (ScDPObject* pDPObj = GetDPObject())
1765 : {
1766 1 : Sequence< OUString > aSeq( lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) );
1767 1 : OUString* pAry = aSeq.getArray();
1768 :
1769 1 : const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pDPObj->GetSaveData()->GetDimensions();
1770 1 : boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
1771 1 : for (it = rDimensions.begin(); it != rDimensions.end(); ++it)
1772 : {
1773 0 : if(maOrient.hasValue() && (it->GetOrientation() == maOrient.get< DataPilotFieldOrientation >()))
1774 : {
1775 0 : *pAry = it->GetName();
1776 0 : ++pAry;
1777 : }
1778 : }
1779 1 : return aSeq;
1780 : }
1781 0 : return Sequence<OUString>();
1782 : }
1783 :
1784 2 : sal_Bool SAL_CALL ScDataPilotFieldsObj::hasByName( const OUString& aName )
1785 : throw(RuntimeException, std::exception)
1786 : {
1787 2 : SolarMutexGuard aGuard;
1788 :
1789 2 : return GetObjectByName_Impl(aName) != NULL;
1790 : }
1791 :
1792 0 : ScDataPilotFieldObj::ScDataPilotFieldObj(
1793 : ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1794 : ScDataPilotChildObjBase( rParent, rFieldId ),
1795 0 : maPropSet( lcl_GetDataPilotFieldMap() )
1796 : {
1797 0 : }
1798 :
1799 126 : ScDataPilotFieldObj::ScDataPilotFieldObj( ScDataPilotDescriptorBase& rParent,
1800 : const ScFieldIdentifier& rFieldId, const Any& rOrient ) :
1801 : ScDataPilotChildObjBase( rParent, rFieldId ),
1802 : maPropSet( lcl_GetDataPilotFieldMap() ),
1803 126 : maOrient( rOrient )
1804 : {
1805 126 : }
1806 :
1807 250 : ScDataPilotFieldObj::~ScDataPilotFieldObj()
1808 : {
1809 250 : }
1810 :
1811 : // XNamed
1812 :
1813 55 : OUString SAL_CALL ScDataPilotFieldObj::getName()
1814 : throw (RuntimeException, std::exception)
1815 : {
1816 55 : SolarMutexGuard aGuard;
1817 55 : OUString aName;
1818 55 : if( ScDPSaveDimension* pDim = GetDPDimension() )
1819 : {
1820 55 : if( pDim->IsDataLayout() )
1821 0 : aName = OUString( SC_DATALAYOUT_NAME );
1822 : else
1823 : {
1824 55 : const OUString* pLayoutName = pDim->GetLayoutName();
1825 55 : if (pLayoutName)
1826 2 : aName = *pLayoutName;
1827 : else
1828 53 : aName = pDim->GetName();
1829 : } }
1830 55 : return aName;
1831 : }
1832 :
1833 4 : void SAL_CALL ScDataPilotFieldObj::setName(const OUString& rName)
1834 : throw (RuntimeException, std::exception)
1835 : {
1836 4 : SolarMutexGuard aGuard;
1837 4 : ScDPObject* pDPObj = 0;
1838 4 : ScDPSaveDimension* pDim = GetDPDimension( &pDPObj );
1839 4 : if( pDim && !pDim->IsDataLayout() )
1840 : {
1841 4 : pDim->SetLayoutName(rName);
1842 4 : SetDPObject( pDPObj );
1843 4 : }
1844 4 : }
1845 :
1846 : // XPropertySet
1847 :
1848 2 : Reference<XPropertySetInfo> SAL_CALL ScDataPilotFieldObj::getPropertySetInfo()
1849 : throw(RuntimeException, std::exception)
1850 : {
1851 2 : SolarMutexGuard aGuard;
1852 : static Reference<XPropertySetInfo> aRef(
1853 2 : new SfxItemPropertySetInfo( maPropSet.getPropertyMap() ));
1854 2 : return aRef;
1855 : }
1856 :
1857 102 : void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
1858 : throw (UnknownPropertyException, PropertyVetoException,
1859 : IllegalArgumentException, WrappedTargetException,
1860 : RuntimeException, std::exception)
1861 : {
1862 102 : SolarMutexGuard aGuard;
1863 204 : OUString aNameString(aPropertyName);
1864 102 : if ( aNameString.equalsAscii( SC_UNONAME_FUNCTION ) )
1865 : {
1866 : // #i109350# use GetEnumFromAny because it also allows sal_Int32
1867 : GeneralFunction eFunction = (GeneralFunction)
1868 15 : ScUnoHelpFunctions::GetEnumFromAny( aValue );
1869 15 : setFunction( eFunction );
1870 : }
1871 87 : else if ( aNameString.equalsAscii( SC_UNONAME_SUBTOTALS ) )
1872 : {
1873 4 : Sequence< GeneralFunction > aSubtotals;
1874 4 : if( aValue >>= aSubtotals )
1875 4 : setSubtotals( aSubtotals );
1876 : }
1877 83 : else if ( aNameString.equalsAscii( SC_UNONAME_ORIENT ) )
1878 : {
1879 : //! test for correct enum type?
1880 : DataPilotFieldOrientation eOrient = (DataPilotFieldOrientation)
1881 57 : ScUnoHelpFunctions::GetEnumFromAny( aValue );
1882 57 : setOrientation( eOrient );
1883 : }
1884 26 : else if ( aNameString.equalsAscii( SC_UNONAME_SELPAGE ) )
1885 : {
1886 2 : OUString sCurrentPage;
1887 2 : if (aValue >>= sCurrentPage)
1888 2 : setCurrentPage(sCurrentPage);
1889 : }
1890 24 : else if ( aNameString.equalsAscii( SC_UNONAME_USESELPAGE ) )
1891 : {
1892 2 : setUseCurrentPage(cppu::any2bool(aValue));
1893 : }
1894 22 : else if ( aNameString.equalsAscii( SC_UNONAME_HASAUTOSHOW ) )
1895 : {
1896 3 : if (!cppu::any2bool(aValue))
1897 1 : setAutoShowInfo(NULL);
1898 : }
1899 19 : else if ( aNameString.equalsAscii( SC_UNONAME_AUTOSHOW ) )
1900 : {
1901 1 : DataPilotFieldAutoShowInfo aInfo;
1902 1 : if (aValue >>= aInfo)
1903 1 : setAutoShowInfo(&aInfo);
1904 : }
1905 18 : else if ( aNameString.equalsAscii( SC_UNONAME_HASLAYOUTINFO ) )
1906 : {
1907 3 : if (!cppu::any2bool(aValue))
1908 1 : setLayoutInfo(NULL);
1909 : }
1910 15 : else if ( aNameString.equalsAscii( SC_UNONAME_LAYOUTINFO ) )
1911 : {
1912 1 : DataPilotFieldLayoutInfo aInfo;
1913 1 : if (aValue >>= aInfo)
1914 1 : setLayoutInfo(&aInfo);
1915 : }
1916 14 : else if ( aNameString.equalsAscii( SC_UNONAME_HASREFERENCE ) )
1917 : {
1918 3 : if (!cppu::any2bool(aValue))
1919 1 : setReference(NULL);
1920 : }
1921 11 : else if ( aNameString.equalsAscii( SC_UNONAME_REFERENCE ) )
1922 : {
1923 1 : DataPilotFieldReference aRef;
1924 1 : if (aValue >>= aRef)
1925 1 : setReference(&aRef);
1926 : }
1927 10 : else if ( aNameString.equalsAscii( SC_UNONAME_HASSORTINFO ) )
1928 : {
1929 3 : if (!cppu::any2bool(aValue))
1930 1 : setSortInfo(NULL);
1931 : }
1932 7 : else if ( aNameString.equalsAscii( SC_UNONAME_SORTINFO ) )
1933 : {
1934 1 : DataPilotFieldSortInfo aInfo;
1935 1 : if (aValue >>= aInfo)
1936 1 : setSortInfo(&aInfo);
1937 : }
1938 6 : else if ( aNameString.equalsAscii( SC_UNONAME_ISGROUP ) )
1939 : {
1940 2 : if (!cppu::any2bool(aValue))
1941 0 : setGroupInfo(NULL);
1942 : }
1943 4 : else if ( aNameString.equalsAscii( SC_UNONAME_GROUPINFO ) )
1944 : {
1945 0 : DataPilotFieldGroupInfo aInfo;
1946 0 : if (aValue >>= aInfo)
1947 0 : setGroupInfo(&aInfo);
1948 : }
1949 4 : else if ( aNameString.equalsAscii( SC_UNONAME_SHOWEMPTY ) )
1950 : {
1951 3 : setShowEmpty(cppu::any2bool(aValue));
1952 102 : }
1953 102 : }
1954 :
1955 86 : Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName )
1956 : throw (UnknownPropertyException, WrappedTargetException,
1957 : RuntimeException, std::exception)
1958 : {
1959 86 : SolarMutexGuard aGuard;
1960 172 : OUString aNameString(aPropertyName);
1961 86 : Any aRet;
1962 :
1963 86 : if ( aNameString.equalsAscii( SC_UNONAME_FUNCTION ) )
1964 7 : aRet <<= getFunction();
1965 79 : else if ( aNameString.equalsAscii( SC_UNONAME_SUBTOTALS ) )
1966 10 : aRet <<= getSubtotals();
1967 69 : else if ( aNameString.equalsAscii( SC_UNONAME_ORIENT ) )
1968 12 : aRet <<= getOrientation();
1969 57 : else if ( aNameString.equalsAscii( SC_UNONAME_SELPAGE ) )
1970 4 : aRet <<= getCurrentPage();
1971 53 : else if ( aNameString.equalsAscii( SC_UNONAME_USESELPAGE ) )
1972 4 : aRet <<= getUseCurrentPage();
1973 49 : else if ( aNameString.equalsAscii( SC_UNONAME_HASAUTOSHOW ) )
1974 6 : aRet <<= (getAutoShowInfo() != NULL);
1975 43 : else if ( aNameString.equalsAscii( SC_UNONAME_AUTOSHOW ) )
1976 : {
1977 1 : const DataPilotFieldAutoShowInfo* pInfo = getAutoShowInfo();
1978 1 : if (pInfo)
1979 1 : aRet <<= DataPilotFieldAutoShowInfo(*pInfo);
1980 : }
1981 42 : else if ( aNameString.equalsAscii( SC_UNONAME_HASLAYOUTINFO ) )
1982 6 : aRet <<= (getLayoutInfo() != NULL);
1983 36 : else if ( aNameString.equalsAscii( SC_UNONAME_LAYOUTINFO ) )
1984 : {
1985 1 : const DataPilotFieldLayoutInfo* pInfo = getLayoutInfo();
1986 1 : if (pInfo)
1987 1 : aRet <<= DataPilotFieldLayoutInfo(*pInfo);
1988 : }
1989 35 : else if ( aNameString.equalsAscii( SC_UNONAME_HASREFERENCE ) )
1990 6 : aRet <<= (getReference() != NULL);
1991 29 : else if ( aNameString.equalsAscii( SC_UNONAME_REFERENCE ) )
1992 : {
1993 1 : const DataPilotFieldReference* pRef = getReference();
1994 1 : if (pRef)
1995 1 : aRet <<= DataPilotFieldReference(*pRef);
1996 : }
1997 28 : else if ( aNameString.equalsAscii( SC_UNONAME_HASSORTINFO ) )
1998 6 : aRet <<= (getSortInfo() != NULL);
1999 22 : else if ( aNameString.equalsAscii( SC_UNONAME_SORTINFO ) )
2000 : {
2001 1 : const DataPilotFieldSortInfo* pInfo = getSortInfo();
2002 1 : if (pInfo)
2003 1 : aRet <<= DataPilotFieldSortInfo(*pInfo);
2004 : }
2005 21 : else if ( aNameString.equalsAscii( SC_UNONAME_ISGROUP ) )
2006 11 : aRet <<= (hasGroupInfo());
2007 10 : else if ( aNameString.equalsAscii( SC_UNONAME_GROUPINFO ) )
2008 : {
2009 3 : aRet <<= getGroupInfo();
2010 : }
2011 7 : else if ( aNameString.equalsAscii( SC_UNONAME_SHOWEMPTY ) )
2012 7 : aRet <<= getShowEmpty();
2013 :
2014 172 : return aRet;
2015 : }
2016 :
2017 : // XDatePilotField
2018 :
2019 5 : Reference<XIndexAccess> SAL_CALL ScDataPilotFieldObj::getItems()
2020 : throw (RuntimeException, std::exception)
2021 : {
2022 5 : SolarMutexGuard aGuard;
2023 5 : if (!mxItems.is())
2024 5 : mxItems.set( new ScDataPilotItemsObj( mrParent, maFieldId ) );
2025 5 : return mxItems;
2026 : }
2027 :
2028 0 : SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj )
2029 :
2030 12 : DataPilotFieldOrientation ScDataPilotFieldObj::getOrientation() const
2031 : {
2032 12 : SolarMutexGuard aGuard;
2033 12 : ScDPSaveDimension* pDim = GetDPDimension();
2034 12 : return pDim ? static_cast< DataPilotFieldOrientation >( pDim->GetOrientation() ) : DataPilotFieldOrientation_HIDDEN;
2035 : }
2036 :
2037 57 : void ScDataPilotFieldObj::setOrientation(DataPilotFieldOrientation eNew)
2038 : {
2039 57 : SolarMutexGuard aGuard;
2040 57 : if (maOrient.hasValue() && (eNew == maOrient.get< DataPilotFieldOrientation >()))
2041 57 : return;
2042 :
2043 57 : ScDPObject* pDPObj = 0;
2044 57 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2045 : {
2046 57 : ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2047 :
2048 : /* If the field was taken from getDataPilotFields(), don't reset the
2049 : orientation for an existing use, but create a duplicated field
2050 : instead (for "Data" orientation only). */
2051 228 : if ( !maOrient.hasValue() && !maFieldId.mbDataLayout &&
2052 121 : (pDim->GetOrientation() != DataPilotFieldOrientation_HIDDEN) &&
2053 7 : (eNew == DataPilotFieldOrientation_DATA) )
2054 : {
2055 :
2056 0 : ScDPSaveDimension* pNewDim = 0;
2057 :
2058 : // look for existing duplicate with orientation "hidden"
2059 :
2060 0 : sal_Int32 nFound = 0;
2061 0 : const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
2062 0 : boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
2063 0 : for ( it = rDimensions.begin(); it != rDimensions.end() && !pNewDim; ++it )
2064 : {
2065 0 : if ( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
2066 : {
2067 0 : if ( it->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2068 0 : pNewDim = const_cast<ScDPSaveDimension*>(&(*it)); // use this one
2069 : else
2070 0 : ++nFound; // count existing non-hidden occurrences
2071 : }
2072 : }
2073 :
2074 0 : if ( !pNewDim ) // if none found, create a new duplicated dimension
2075 0 : pNewDim = &pSaveData->DuplicateDimension( *pDim );
2076 :
2077 0 : maFieldId.mnFieldIdx = nFound; // keep accessing the new one
2078 0 : pDim = pNewDim;
2079 : }
2080 :
2081 57 : pDim->SetOrientation(sal::static_int_cast<sal_uInt16>(eNew));
2082 :
2083 : // move changed field behind all other fields (make it the last field in dimension)
2084 57 : pSaveData->SetPosition( pDim, pSaveData->GetDimensions().size() );
2085 :
2086 57 : SetDPObject( pDPObj );
2087 :
2088 57 : maOrient <<= eNew; // modifying the same object's orientation again doesn't create another duplicate
2089 57 : }
2090 : }
2091 :
2092 7 : GeneralFunction ScDataPilotFieldObj::getFunction() const
2093 : {
2094 7 : SolarMutexGuard aGuard;
2095 7 : GeneralFunction eRet = GeneralFunction_NONE;
2096 7 : if( ScDPSaveDimension* pDim = GetDPDimension() )
2097 : {
2098 7 : if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2099 : {
2100 : // for non-data fields, property Function is the subtotals
2101 5 : long nSubCount = pDim->GetSubTotalsCount();
2102 5 : if ( nSubCount > 0 )
2103 4 : eRet = (GeneralFunction)pDim->GetSubTotalFunc(0); // always use the first one
2104 : // else keep NONE
2105 : }
2106 : else
2107 2 : eRet = (GeneralFunction)pDim->GetFunction();
2108 : }
2109 7 : return eRet;
2110 : }
2111 :
2112 15 : void ScDataPilotFieldObj::setFunction(GeneralFunction eNewFunc)
2113 : {
2114 15 : SolarMutexGuard aGuard;
2115 15 : ScDPObject* pDPObj = 0;
2116 15 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2117 : {
2118 15 : if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2119 : {
2120 : // for non-data fields, property Function is the subtotals
2121 14 : if ( eNewFunc == GeneralFunction_NONE )
2122 0 : pDim->SetSubTotals( 0, NULL );
2123 : else
2124 : {
2125 14 : sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( eNewFunc );
2126 14 : pDim->SetSubTotals( 1, &nFunc );
2127 : }
2128 : }
2129 : else
2130 1 : pDim->SetFunction( sal::static_int_cast<sal_uInt16>( eNewFunc ) );
2131 15 : SetDPObject( pDPObj );
2132 15 : }
2133 15 : }
2134 :
2135 10 : Sequence< GeneralFunction > ScDataPilotFieldObj::getSubtotals() const
2136 : {
2137 10 : SolarMutexGuard aGuard;
2138 10 : Sequence< GeneralFunction > aRet;
2139 10 : if( ScDPSaveDimension* pDim = GetDPDimension() )
2140 : {
2141 10 : if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2142 : {
2143 : // for non-data fields, property Functions is the sequence of subtotals
2144 5 : sal_Int32 nCount = static_cast< sal_Int32 >( pDim->GetSubTotalsCount() );
2145 5 : if ( nCount > 0 )
2146 : {
2147 4 : aRet.realloc( nCount );
2148 8 : for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2149 4 : aRet[ nIdx ] = (GeneralFunction)pDim->GetSubTotalFunc( nIdx );
2150 : }
2151 : }
2152 : }
2153 10 : return aRet;
2154 : }
2155 :
2156 4 : void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubtotals )
2157 : {
2158 4 : SolarMutexGuard aGuard;
2159 4 : ScDPObject* pDPObj = 0;
2160 4 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2161 : {
2162 4 : if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2163 : {
2164 2 : sal_Int32 nCount = rSubtotals.getLength();
2165 2 : if( nCount == 1 )
2166 : {
2167 : // count 1: all values are allowed (including NONE and AUTO)
2168 2 : if( rSubtotals[ 0 ] == GeneralFunction_NONE )
2169 1 : pDim->SetSubTotals( 0, NULL );
2170 : else
2171 : {
2172 1 : sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( rSubtotals[ 0 ] );
2173 1 : pDim->SetSubTotals( 1, &nFunc );
2174 : }
2175 : }
2176 0 : else if( nCount > 1 )
2177 : {
2178 : // set multiple functions, ignore NONE and AUTO in this case
2179 0 : ::std::vector< sal_uInt16 > aSubt;
2180 0 : for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2181 : {
2182 0 : GeneralFunction eFunc = rSubtotals[ nIdx ];
2183 0 : if( (eFunc != GeneralFunction_NONE) && (eFunc != GeneralFunction_AUTO) )
2184 : {
2185 : // do not insert functions twice
2186 0 : sal_uInt16 nFunc = static_cast< sal_uInt16 >( eFunc );
2187 0 : if( ::std::find( aSubt.begin(), aSubt.end(), nFunc ) == aSubt.end() )
2188 0 : aSubt.push_back( nFunc );
2189 : }
2190 : }
2191 : // set values from vector to ScDPSaveDimension
2192 0 : if ( aSubt.empty() )
2193 0 : pDim->SetSubTotals( 0, NULL );
2194 : else
2195 0 : pDim->SetSubTotals( static_cast< long >( aSubt.size() ), &aSubt.front() );
2196 : }
2197 : }
2198 4 : SetDPObject( pDPObj );
2199 4 : }
2200 4 : }
2201 :
2202 4 : OUString ScDataPilotFieldObj::getCurrentPage() const
2203 : {
2204 4 : return OUString();
2205 : }
2206 :
2207 2 : void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage )
2208 : {
2209 2 : SolarMutexGuard aGuard;
2210 2 : ScDPObject* pDPObj = 0;
2211 2 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2212 : {
2213 2 : pDim->SetCurrentPage( &rPage );
2214 2 : SetDPObject( pDPObj );
2215 2 : }
2216 2 : }
2217 :
2218 4 : bool ScDataPilotFieldObj::getUseCurrentPage() const
2219 : {
2220 4 : return false;
2221 : }
2222 :
2223 2 : void ScDataPilotFieldObj::setUseCurrentPage( bool bUse )
2224 : {
2225 2 : SolarMutexGuard aGuard;
2226 2 : ScDPObject* pDPObj = 0;
2227 2 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2228 : {
2229 2 : if( bUse )
2230 : {
2231 : /* It is somehow useless to set the property "HasSelectedPage" to
2232 : true, because it is still needed to set an explicit page name. */
2233 2 : const OUString aPage;
2234 2 : pDim->SetCurrentPage( &aPage );
2235 : }
2236 : else
2237 0 : pDim->SetCurrentPage( 0 );
2238 2 : SetDPObject( pDPObj );
2239 2 : }
2240 2 : }
2241 :
2242 7 : const DataPilotFieldAutoShowInfo* ScDataPilotFieldObj::getAutoShowInfo()
2243 : {
2244 7 : SolarMutexGuard aGuard;
2245 7 : ScDPSaveDimension* pDim = GetDPDimension();
2246 7 : return pDim ? pDim->GetAutoShowInfo() : 0;
2247 : }
2248 :
2249 2 : void ScDataPilotFieldObj::setAutoShowInfo( const DataPilotFieldAutoShowInfo* pInfo )
2250 : {
2251 2 : SolarMutexGuard aGuard;
2252 2 : ScDPObject* pDPObj = 0;
2253 2 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2254 : {
2255 2 : pDim->SetAutoShowInfo( pInfo );
2256 2 : SetDPObject( pDPObj );
2257 2 : }
2258 2 : }
2259 :
2260 7 : const DataPilotFieldLayoutInfo* ScDataPilotFieldObj::getLayoutInfo()
2261 : {
2262 7 : SolarMutexGuard aGuard;
2263 7 : ScDPSaveDimension* pDim = GetDPDimension();
2264 7 : return pDim ? pDim->GetLayoutInfo() : 0;
2265 : }
2266 :
2267 2 : void ScDataPilotFieldObj::setLayoutInfo( const DataPilotFieldLayoutInfo* pInfo )
2268 : {
2269 2 : SolarMutexGuard aGuard;
2270 2 : ScDPObject* pDPObj = 0;
2271 2 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2272 : {
2273 2 : pDim->SetLayoutInfo( pInfo );
2274 2 : SetDPObject( pDPObj );
2275 2 : }
2276 2 : }
2277 :
2278 7 : const DataPilotFieldReference* ScDataPilotFieldObj::getReference()
2279 : {
2280 7 : SolarMutexGuard aGuard;
2281 7 : ScDPSaveDimension* pDim = GetDPDimension();
2282 7 : return pDim ? pDim->GetReferenceValue() : 0;
2283 : }
2284 :
2285 2 : void ScDataPilotFieldObj::setReference( const DataPilotFieldReference* pInfo )
2286 : {
2287 2 : SolarMutexGuard aGuard;
2288 2 : ScDPObject* pDPObj = 0;
2289 2 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2290 : {
2291 2 : pDim->SetReferenceValue( pInfo );
2292 2 : SetDPObject( pDPObj );
2293 2 : }
2294 2 : }
2295 :
2296 7 : const DataPilotFieldSortInfo* ScDataPilotFieldObj::getSortInfo()
2297 : {
2298 7 : SolarMutexGuard aGuard;
2299 7 : ScDPSaveDimension* pDim = GetDPDimension();
2300 7 : return pDim ? pDim->GetSortInfo() : 0;
2301 : }
2302 :
2303 2 : void ScDataPilotFieldObj::setSortInfo( const DataPilotFieldSortInfo* pInfo )
2304 : {
2305 2 : SolarMutexGuard aGuard;
2306 2 : ScDPObject* pDPObj = 0;
2307 2 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2308 : {
2309 2 : pDim->SetSortInfo( pInfo );
2310 2 : SetDPObject( pDPObj );
2311 2 : }
2312 2 : }
2313 :
2314 7 : bool ScDataPilotFieldObj::getShowEmpty() const
2315 : {
2316 7 : SolarMutexGuard aGuard;
2317 7 : ScDPSaveDimension* pDim = GetDPDimension();
2318 7 : return pDim && pDim->GetShowEmpty();
2319 : }
2320 :
2321 3 : void ScDataPilotFieldObj::setShowEmpty( bool bShow )
2322 : {
2323 3 : SolarMutexGuard aGuard;
2324 3 : ScDPObject* pDPObj = 0;
2325 3 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2326 : {
2327 3 : pDim->SetShowEmpty( bShow );
2328 3 : SetDPObject( pDPObj );
2329 3 : }
2330 3 : }
2331 :
2332 11 : bool ScDataPilotFieldObj::hasGroupInfo()
2333 : {
2334 11 : SolarMutexGuard aGuard;
2335 11 : ScDPObject* pDPObj = 0;
2336 11 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2337 11 : if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2338 6 : return pDimData->GetNamedGroupDim( pDim->GetName() ) || pDimData->GetNumGroupDim( pDim->GetName() );
2339 5 : return false;
2340 : }
2341 :
2342 3 : DataPilotFieldGroupInfo ScDataPilotFieldObj::getGroupInfo()
2343 : {
2344 3 : SolarMutexGuard aGuard;
2345 3 : DataPilotFieldGroupInfo aInfo;
2346 3 : ScDPObject* pDPObj = 0;
2347 3 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2348 : {
2349 3 : if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2350 : {
2351 3 : if( const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( pDim->GetName() ) )
2352 : {
2353 : // grouped by ...
2354 3 : aInfo.GroupBy = pGroupDim->GetDatePart();
2355 :
2356 : // find source field
2357 : try
2358 : {
2359 3 : Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2360 3 : aInfo.SourceField.set( xFields->getByName( pGroupDim->GetSourceDimName() ), UNO_QUERY );
2361 : }
2362 0 : catch( Exception& )
2363 : {
2364 : }
2365 :
2366 3 : ScDataPilotConversion::FillGroupInfo( aInfo, pGroupDim->GetDateInfo() );
2367 3 : if( pGroupDim->GetDatePart() == 0 )
2368 : {
2369 : // fill vector of group and group member information
2370 3 : ScFieldGroups aGroups;
2371 6 : for( sal_Int32 nIdx = 0, nCount = pGroupDim->GetGroupCount(); nIdx < nCount; ++nIdx )
2372 : {
2373 3 : if( const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( nIdx ) )
2374 : {
2375 3 : ScFieldGroup aGroup;
2376 3 : aGroup.maName = pGroup->GetGroupName();
2377 9 : for( sal_Int32 nMemIdx = 0, nMemCount = pGroup->GetElementCount(); nMemIdx < nMemCount; ++nMemIdx )
2378 6 : if (const OUString* pMem = pGroup->GetElementByIndex(nMemIdx))
2379 6 : aGroup.maMembers.push_back( *pMem );
2380 3 : aGroups.push_back( aGroup );
2381 : }
2382 : }
2383 3 : aInfo.Groups = new ScDataPilotFieldGroupsObj( aGroups );
2384 : }
2385 : }
2386 0 : else if( const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( pDim->GetName() ) )
2387 : {
2388 0 : if (pNumGroupDim->GetDatePart())
2389 : {
2390 0 : ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetDateInfo() );
2391 0 : aInfo.GroupBy = pNumGroupDim->GetDatePart();
2392 : }
2393 : else
2394 : {
2395 0 : ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetInfo() );
2396 : }
2397 : }
2398 : }
2399 : }
2400 3 : return aInfo;
2401 : }
2402 :
2403 0 : void ScDataPilotFieldObj::setGroupInfo( const DataPilotFieldGroupInfo* pInfo )
2404 : {
2405 0 : SolarMutexGuard aGuard;
2406 0 : ScDPObject* pDPObj = 0;
2407 0 : if( /*ScDPSaveDimension* pDim =*/ GetDPDimension( &pDPObj ) )
2408 : {
2409 0 : ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2410 0 : if( pInfo && lclCheckMinMaxStep( *pInfo ) )
2411 : {
2412 0 : ScDPNumGroupInfo aInfo;
2413 0 : aInfo.mbEnable = true;
2414 0 : aInfo.mbDateValues = pInfo->HasDateValues;
2415 0 : aInfo.mbAutoStart = pInfo->HasAutoStart;
2416 0 : aInfo.mbAutoEnd = pInfo->HasAutoEnd;
2417 0 : aInfo.mfStart = pInfo->Start;
2418 0 : aInfo.mfEnd = pInfo->End;
2419 0 : aInfo.mfStep = pInfo->Step;
2420 0 : Reference< XNamed > xNamed( pInfo->SourceField, UNO_QUERY );
2421 0 : if( xNamed.is() )
2422 : {
2423 0 : ScDPSaveGroupDimension aGroupDim( xNamed->getName(), getName() );
2424 0 : if( pInfo->GroupBy )
2425 0 : aGroupDim.SetDateInfo(aInfo, pInfo->GroupBy);
2426 : else
2427 : {
2428 0 : Reference<XIndexAccess> xIndex(pInfo->Groups, UNO_QUERY);
2429 0 : if (xIndex.is())
2430 : {
2431 0 : sal_Int32 nCount(xIndex->getCount());
2432 0 : for(sal_Int32 i = 0; i < nCount; i++)
2433 : {
2434 0 : Reference<XNamed> xGroupNamed(xIndex->getByIndex(i), UNO_QUERY);
2435 0 : if (xGroupNamed.is())
2436 : {
2437 0 : ScDPSaveGroupItem aItem(xGroupNamed->getName());
2438 0 : Reference<XIndexAccess> xGroupIndex(xGroupNamed, UNO_QUERY);
2439 0 : if (xGroupIndex.is())
2440 : {
2441 0 : sal_Int32 nItemCount(xGroupIndex->getCount());
2442 0 : for (sal_Int32 j = 0; j < nItemCount; ++j)
2443 : {
2444 0 : Reference<XNamed> xItemNamed(xGroupIndex->getByIndex(j), UNO_QUERY);
2445 0 : if (xItemNamed.is())
2446 0 : aItem.AddElement(xItemNamed->getName());
2447 0 : }
2448 : }
2449 0 : aGroupDim.AddGroupItem(aItem);
2450 : }
2451 0 : }
2452 0 : }
2453 : }
2454 :
2455 : // get dimension savedata or create new if none
2456 0 : ScDPDimensionSaveData& rDimSaveData = *pSaveData->GetDimensionData();
2457 0 : rDimSaveData.ReplaceGroupDimension( aGroupDim );
2458 : }
2459 : else // no source field in group info -> numeric group
2460 : {
2461 0 : ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData(); // created if not there
2462 :
2463 0 : ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( getName() );
2464 0 : if ( pExisting )
2465 : {
2466 0 : if (pInfo->GroupBy)
2467 0 : pExisting->SetDateInfo(aInfo, pInfo->GroupBy);
2468 : // modify existing group dimension
2469 0 : pExisting->SetGroupInfo( aInfo );
2470 : }
2471 0 : else if (pInfo->GroupBy)
2472 : {
2473 : // create new group dimension
2474 0 : ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo, pInfo->GroupBy );
2475 0 : pDimData->AddNumGroupDimension( aNumGroupDim );
2476 : }
2477 : else
2478 : {
2479 : // create new group dimension
2480 0 : ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo );
2481 0 : pDimData->AddNumGroupDimension( aNumGroupDim );
2482 : }
2483 0 : }
2484 : }
2485 : else // null passed as argument
2486 : {
2487 0 : pSaveData->SetDimensionData( 0 );
2488 : }
2489 :
2490 0 : pDPObj->SetSaveData( *pSaveData );
2491 0 : SetDPObject( pDPObj );
2492 0 : }
2493 0 : }
2494 :
2495 0 : bool ScDataPilotFieldObj::HasString(const Sequence< OUString >& rItems, const OUString& aString)
2496 : {
2497 0 : bool bRet = false;
2498 :
2499 0 : sal_Int32 nCount(rItems.getLength());
2500 0 : sal_Int32 nItem(0);
2501 0 : while (nItem < nCount && !bRet)
2502 : {
2503 0 : bRet = rItems[nItem] == aString;
2504 0 : ++nItem;
2505 : }
2506 :
2507 0 : return bRet;
2508 : }
2509 :
2510 : // XDataPilotFieldGrouping
2511 4 : Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( const Sequence< OUString >& rItems )
2512 : throw (RuntimeException, IllegalArgumentException,
2513 : std::exception)
2514 : {
2515 4 : SolarMutexGuard aGuard;
2516 :
2517 4 : Reference< XDataPilotField > xRet;
2518 8 : OUString sNewDim;
2519 :
2520 4 : if( !rItems.hasElements() )
2521 0 : throw IllegalArgumentException();
2522 :
2523 4 : ScDPObject* pDPObj = 0;
2524 4 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2525 : {
2526 4 : OUString aDimName = pDim->GetName();
2527 :
2528 8 : ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2529 4 : ScDPDimensionSaveData* pDimData = aSaveData.GetDimensionData(); // created if not there
2530 :
2531 : // find original base
2532 8 : OUString aBaseDimName( aDimName );
2533 4 : const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
2534 4 : if ( pBaseGroupDim )
2535 : {
2536 : // any entry's SourceDimName is the original base
2537 0 : aBaseDimName = pBaseGroupDim->GetSourceDimName();
2538 : }
2539 :
2540 : // find existing group dimension
2541 : // (using the selected dim, can be intermediate group dim)
2542 4 : ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
2543 :
2544 : // remove the selected items from their groups
2545 : // (empty groups are removed, too)
2546 4 : sal_Int32 nEntryCount = rItems.getLength();
2547 : sal_Int32 nEntry;
2548 4 : if ( pGroupDimension )
2549 : {
2550 0 : for (nEntry=0; nEntry<nEntryCount; nEntry++)
2551 : {
2552 0 : const OUString& aEntryName = rItems[nEntry];
2553 0 : if ( pBaseGroupDim )
2554 : {
2555 : // for each selected (intermediate) group, remove all its items
2556 : // (same logic as for adding, below)
2557 0 : const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2558 0 : if ( pBaseGroup )
2559 0 : pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements
2560 : else
2561 0 : pGroupDimension->RemoveFromGroups( aEntryName );
2562 : }
2563 : else
2564 0 : pGroupDimension->RemoveFromGroups( aEntryName );
2565 : }
2566 : }
2567 :
2568 4 : ScDPSaveGroupDimension* pNewGroupDim = 0;
2569 4 : if ( !pGroupDimension )
2570 : {
2571 : // create a new group dimension
2572 4 : sNewDim = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
2573 4 : pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, sNewDim );
2574 :
2575 4 : pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
2576 :
2577 4 : if ( pBaseGroupDim )
2578 : {
2579 : // If it's a higher-order group dimension, pre-allocate groups for all
2580 : // non-selected original groups, so the individual base members aren't
2581 : // used for automatic groups (this would make the original groups hard
2582 : // to find).
2583 : //! Also do this when removing groups?
2584 : //! Handle this case dynamically with automatic groups?
2585 :
2586 0 : long nGroupCount = pBaseGroupDim->GetGroupCount();
2587 0 : for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
2588 : {
2589 0 : const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
2590 :
2591 0 : if (!HasString(rItems, pBaseGroup->GetGroupName())) //! ignore case?
2592 : {
2593 : // add an additional group for each item that is not in the selection
2594 0 : ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
2595 0 : aGroup.AddElementsFromGroup( *pBaseGroup );
2596 0 : pGroupDimension->AddGroupItem( aGroup );
2597 : }
2598 : }
2599 : }
2600 : }
2601 8 : OUString aGroupDimName = pGroupDimension->GetGroupDimName();
2602 :
2603 : //! localized prefix string
2604 8 : OUString aGroupName = pGroupDimension->CreateGroupName( OUString( "Group" ) );
2605 8 : ScDPSaveGroupItem aGroup( aGroupName );
2606 8 : Reference< XNameAccess > xMembers = GetMembers();
2607 4 : if (!xMembers.is())
2608 : {
2609 0 : delete pNewGroupDim;
2610 0 : throw RuntimeException();
2611 : }
2612 :
2613 15 : for (nEntry=0; nEntry<nEntryCount; nEntry++)
2614 : {
2615 11 : OUString aEntryName(rItems[nEntry]);
2616 :
2617 11 : if (!xMembers->hasByName(aEntryName))
2618 : {
2619 0 : delete pNewGroupDim;
2620 0 : throw IllegalArgumentException();
2621 : }
2622 :
2623 11 : if ( pBaseGroupDim )
2624 : {
2625 : // for each selected (intermediate) group, add all its items
2626 0 : const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2627 0 : if ( pBaseGroup )
2628 0 : aGroup.AddElementsFromGroup( *pBaseGroup );
2629 : else
2630 0 : aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself
2631 : }
2632 : else
2633 11 : aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
2634 11 : }
2635 :
2636 4 : pGroupDimension->AddGroupItem( aGroup );
2637 :
2638 4 : if ( pNewGroupDim )
2639 : {
2640 4 : pDimData->AddGroupDimension( *pNewGroupDim );
2641 4 : delete pNewGroupDim; // AddGroupDimension copies the object
2642 : // don't access pGroupDimension after here
2643 : }
2644 4 : pGroupDimension = pNewGroupDim = NULL;
2645 :
2646 : // set orientation
2647 4 : ScDPSaveDimension* pSaveDimension = aSaveData.GetDimensionByName( aGroupDimName );
2648 4 : if ( pSaveDimension->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2649 : {
2650 4 : ScDPSaveDimension* pOldDimension = aSaveData.GetDimensionByName( aDimName );
2651 4 : pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
2652 4 : long nPosition = 0; //! before (immediate) base
2653 4 : aSaveData.SetPosition( pSaveDimension, nPosition );
2654 : }
2655 :
2656 : // apply changes
2657 4 : pDPObj->SetSaveData( aSaveData );
2658 8 : ScDBDocFunc(*GetDocShell()).RefreshPivotTableGroups(pDPObj);
2659 : }
2660 :
2661 : // if new grouping field has been created (on first group), return it
2662 4 : if( !sNewDim.isEmpty() )
2663 : {
2664 4 : Reference< XNameAccess > xFields(mrParent.getDataPilotFields(), UNO_QUERY);
2665 4 : if (xFields.is())
2666 : {
2667 : try
2668 : {
2669 4 : xRet.set(xFields->getByName(sNewDim), UNO_QUERY);
2670 : OSL_ENSURE(xRet.is(), "there is a name, so there should be also a field");
2671 : }
2672 0 : catch (const container::NoSuchElementException&)
2673 : {
2674 : // Avoid throwing exception that's not specified in the method signature.
2675 0 : throw RuntimeException();
2676 : }
2677 4 : }
2678 : }
2679 8 : return xRet;
2680 : }
2681 :
2682 0 : Reference < XDataPilotField > SAL_CALL ScDataPilotFieldObj::createDateGroup( const DataPilotFieldGroupInfo& rInfo )
2683 : throw (RuntimeException, IllegalArgumentException,
2684 : std::exception)
2685 : {
2686 0 : SolarMutexGuard aGuard;
2687 : using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
2688 :
2689 : // check min/max/step, HasDateValues must be set always
2690 0 : if( !rInfo.HasDateValues || !lclCheckMinMaxStep( rInfo ) )
2691 0 : throw IllegalArgumentException();
2692 : // only a single date flag is allowed
2693 0 : if( (rInfo.GroupBy == 0) || (rInfo.GroupBy > YEARS) || ((rInfo.GroupBy & (rInfo.GroupBy - 1)) != 0) )
2694 0 : throw IllegalArgumentException();
2695 : // step must be zero, if something else than DAYS is specified
2696 0 : if( rInfo.Step >= ((rInfo.GroupBy == DAYS) ? 32768.0 : 1.0) )
2697 0 : throw IllegalArgumentException();
2698 :
2699 0 : OUString aGroupDimName;
2700 0 : ScDPObject* pDPObj = 0;
2701 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2702 : {
2703 0 : ScDPNumGroupInfo aInfo;
2704 0 : aInfo.mbEnable = true;
2705 0 : aInfo.mbDateValues = (rInfo.GroupBy == DAYS) && (rInfo.Step >= 1.0);
2706 0 : aInfo.mbAutoStart = rInfo.HasAutoStart;
2707 0 : aInfo.mbAutoEnd = rInfo.HasAutoEnd;
2708 0 : aInfo.mfStart = rInfo.Start;
2709 0 : aInfo.mfEnd = rInfo.End;
2710 0 : aInfo.mfStep = static_cast< sal_Int32 >( rInfo.Step );
2711 :
2712 : // create a local copy of the entire save data (will be written back below)
2713 0 : ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2714 : // get or create dimension save data
2715 0 : ScDPDimensionSaveData& rDimData = *aSaveData.GetDimensionData();
2716 :
2717 : // find source dimension name
2718 0 : const OUString& rDimName = pDim->GetName();
2719 0 : const ScDPSaveGroupDimension* pGroupDim = rDimData.GetNamedGroupDim( rDimName );
2720 0 : OUString aSrcDimName = pGroupDim ? pGroupDim->GetSourceDimName() : rDimName;
2721 :
2722 : // find a group dimension for the base field, or get numeric grouping
2723 0 : pGroupDim = rDimData.GetFirstNamedGroupDim( aSrcDimName );
2724 0 : const ScDPSaveNumGroupDimension* pNumGroupDim = rDimData.GetNumGroupDim( aSrcDimName );
2725 :
2726 : // do not group by dates, if named groups or numeric grouping is present
2727 0 : bool bHasNamedGrouping = pGroupDim && !pGroupDim->GetDateInfo().mbEnable;
2728 0 : bool bHasNumGrouping = pNumGroupDim && pNumGroupDim->GetInfo().mbEnable && !pNumGroupDim->GetInfo().mbDateValues && !pNumGroupDim->GetDateInfo().mbEnable;
2729 0 : if( bHasNamedGrouping || bHasNumGrouping )
2730 0 : throw IllegalArgumentException();
2731 :
2732 0 : if( aInfo.mbDateValues ) // create day ranges grouping
2733 : {
2734 : // first remove all named group dimensions
2735 0 : while( pGroupDim )
2736 : {
2737 0 : OUString aGroupDimName2 = pGroupDim->GetGroupDimName();
2738 : // find next group dimension before deleting this group
2739 0 : pGroupDim = rDimData.GetNextNamedGroupDim( aGroupDimName2 );
2740 : // remove from dimension save data
2741 0 : rDimData.RemoveGroupDimension( aGroupDimName2 );
2742 : // also remove save data settings for the dimension that no longer exists
2743 0 : aSaveData.RemoveDimensionByName( aGroupDimName2 );
2744 0 : }
2745 : // create or replace the number grouping dimension
2746 0 : ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo );
2747 0 : rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2748 : }
2749 : else // create date grouping
2750 : {
2751 : // collect all existing date flags
2752 0 : sal_Int32 nDateParts = rDimData.CollectDateParts( aSrcDimName );
2753 0 : if( nDateParts == 0 )
2754 : {
2755 : // insert numeric group dimension, if no date groups exist yet (or replace day range grouping)
2756 0 : ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo, rInfo.GroupBy );
2757 0 : rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2758 : }
2759 0 : else if( (nDateParts & rInfo.GroupBy) == 0 ) // do nothing if date field exists already
2760 : {
2761 : // create new named group dimension for additional date groups
2762 0 : aGroupDimName = rDimData.CreateDateGroupDimName( rInfo.GroupBy, *pDPObj, true, 0 );
2763 0 : ScDPSaveGroupDimension aGroupDim( aSrcDimName, aGroupDimName, aInfo, rInfo.GroupBy );
2764 0 : rDimData.AddGroupDimension( aGroupDim );
2765 :
2766 : // set orientation of new named group dimension
2767 0 : ScDPSaveDimension& rSaveDim = *aSaveData.GetDimensionByName( aGroupDimName );
2768 0 : if( rSaveDim.GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2769 : {
2770 0 : ScDPSaveDimension& rOldDim = *aSaveData.GetDimensionByName( aSrcDimName );
2771 0 : rSaveDim.SetOrientation( rOldDim.GetOrientation() );
2772 0 : aSaveData.SetPosition( &rSaveDim, 0 ); //! before (immediate) base
2773 0 : }
2774 : }
2775 : }
2776 :
2777 : // apply changes
2778 0 : pDPObj->SetSaveData( aSaveData );
2779 0 : SetDPObject( pDPObj );
2780 : }
2781 :
2782 : // return the UNO object of the new dimension, after writing back saved data
2783 0 : Reference< XDataPilotField > xRet;
2784 0 : if( !aGroupDimName.isEmpty() )
2785 : try
2786 : {
2787 0 : Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2788 0 : xRet.set( xFields->getByName( aGroupDimName ), UNO_QUERY );
2789 : }
2790 0 : catch( Exception& )
2791 : {
2792 : }
2793 0 : return xRet;
2794 : }
2795 :
2796 : namespace {
2797 :
2798 0 : bool lclExtractGroupMembers( ScFieldGroupMembers& rMembers, const Any& rElement )
2799 : {
2800 : // allow empty value to create a new group
2801 0 : if( !rElement.hasValue() )
2802 0 : return true;
2803 :
2804 : // try to extract a simple sequence of strings
2805 0 : Sequence< OUString > aSeq;
2806 0 : if( rElement >>= aSeq )
2807 : {
2808 0 : if( aSeq.hasElements() )
2809 0 : rMembers.insert( rMembers.end(), aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength() );
2810 0 : return true;
2811 : }
2812 :
2813 : // try to use XIndexAccess providing objects that support XNamed
2814 0 : Reference< XIndexAccess > xItemsIA( rElement, UNO_QUERY );
2815 0 : if( xItemsIA.is() )
2816 : {
2817 0 : for( sal_Int32 nIdx = 0, nCount = xItemsIA->getCount(); nIdx < nCount; ++nIdx )
2818 : {
2819 : try // getByIndex() should not throw, but we cannot be sure
2820 : {
2821 0 : Reference< XNamed > xItemName( xItemsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
2822 0 : rMembers.push_back( xItemName->getName() );
2823 : }
2824 0 : catch( Exception& )
2825 : {
2826 : // ignore exceptions, go ahead with next element in the array
2827 : }
2828 : }
2829 0 : return true;
2830 : }
2831 :
2832 : // nothing valid inside the Any -> return false
2833 0 : return false;
2834 : }
2835 :
2836 : } // namespace
2837 :
2838 3 : ScDataPilotFieldGroupsObj::ScDataPilotFieldGroupsObj( const ScFieldGroups& rGroups ) :
2839 3 : maGroups( rGroups )
2840 : {
2841 3 : }
2842 :
2843 6 : ScDataPilotFieldGroupsObj::~ScDataPilotFieldGroupsObj()
2844 : {
2845 6 : }
2846 :
2847 : // XNameAccess
2848 :
2849 2 : Any SAL_CALL ScDataPilotFieldGroupsObj::getByName( const OUString& rName )
2850 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2851 : {
2852 2 : SolarMutexGuard aGuard;
2853 2 : if( implFindByName( rName ) == maGroups.end() )
2854 1 : throw NoSuchElementException();
2855 1 : return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, rName ) ) );
2856 : }
2857 :
2858 1 : Sequence< OUString > SAL_CALL ScDataPilotFieldGroupsObj::getElementNames() throw(RuntimeException, std::exception)
2859 : {
2860 1 : SolarMutexGuard aGuard;
2861 1 : Sequence< OUString > aSeq;
2862 1 : if( !maGroups.empty() )
2863 : {
2864 1 : aSeq.realloc( static_cast< sal_Int32 >( maGroups.size() ) );
2865 1 : OUString* pName = aSeq.getArray();
2866 2 : for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt, ++pName )
2867 1 : *pName = aIt->maName;
2868 : }
2869 1 : return aSeq;
2870 : }
2871 :
2872 2 : sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasByName( const OUString& rName ) throw(RuntimeException, std::exception)
2873 : {
2874 2 : SolarMutexGuard aGuard;
2875 2 : return implFindByName( rName ) != maGroups.end();
2876 : }
2877 :
2878 : // XNameReplace
2879 :
2880 0 : void SAL_CALL ScDataPilotFieldGroupsObj::replaceByName( const OUString& rName, const Any& rElement )
2881 : throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2882 : {
2883 0 : SolarMutexGuard aGuard;
2884 :
2885 0 : if( rName.isEmpty() )
2886 0 : throw IllegalArgumentException();
2887 :
2888 0 : ScFieldGroups::iterator aIt = implFindByName( rName );
2889 0 : if( aIt == maGroups.end() )
2890 0 : throw NoSuchElementException();
2891 :
2892 : // read all item names provided by the passed object
2893 0 : ScFieldGroupMembers aMembers;
2894 0 : if( !lclExtractGroupMembers( aMembers, rElement ) )
2895 0 : throw IllegalArgumentException();
2896 :
2897 : // copy and forget, faster than vector assignment
2898 0 : aIt->maMembers.swap( aMembers );
2899 0 : }
2900 :
2901 : // XNameContainer
2902 :
2903 0 : void SAL_CALL ScDataPilotFieldGroupsObj::insertByName( const OUString& rName, const Any& rElement )
2904 : throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
2905 : {
2906 0 : SolarMutexGuard aGuard;
2907 :
2908 0 : if( rName.isEmpty() )
2909 0 : throw IllegalArgumentException();
2910 :
2911 0 : ScFieldGroups::iterator aIt = implFindByName( rName );
2912 0 : if( aIt != maGroups.end() )
2913 0 : throw ElementExistException();
2914 :
2915 : // read all item names provided by the passed object
2916 0 : ScFieldGroupMembers aMembers;
2917 0 : if( !lclExtractGroupMembers( aMembers, rElement ) )
2918 0 : throw IllegalArgumentException();
2919 :
2920 : // create the new entry if no error has been occurred
2921 0 : maGroups.resize( maGroups.size() + 1 );
2922 0 : ScFieldGroup& rGroup = maGroups.back();
2923 0 : rGroup.maName = rName;
2924 0 : rGroup.maMembers.swap( aMembers );
2925 0 : }
2926 :
2927 0 : void SAL_CALL ScDataPilotFieldGroupsObj::removeByName( const OUString& rName )
2928 : throw (NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2929 : {
2930 0 : SolarMutexGuard aGuard;
2931 :
2932 0 : if( rName.isEmpty() )
2933 0 : throw IllegalArgumentException();
2934 :
2935 0 : ScFieldGroups::iterator aIt = implFindByName( rName );
2936 0 : if( aIt == maGroups.end() )
2937 0 : throw NoSuchElementException();
2938 :
2939 0 : maGroups.erase( aIt );
2940 0 : }
2941 :
2942 : // XIndexAccess
2943 :
2944 1 : sal_Int32 SAL_CALL ScDataPilotFieldGroupsObj::getCount() throw(RuntimeException, std::exception)
2945 : {
2946 1 : SolarMutexGuard aGuard;
2947 1 : return static_cast< sal_Int32 >( maGroups.size() );
2948 : }
2949 :
2950 6 : Any SAL_CALL ScDataPilotFieldGroupsObj::getByIndex( sal_Int32 nIndex )
2951 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
2952 : {
2953 6 : SolarMutexGuard aGuard;
2954 6 : if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( maGroups.size() )))
2955 1 : throw IndexOutOfBoundsException();
2956 5 : return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, maGroups[ nIndex ].maName ) ) );
2957 : }
2958 :
2959 : // XEnumerationAccess
2960 :
2961 1 : Reference<XEnumeration> SAL_CALL ScDataPilotFieldGroupsObj::createEnumeration() throw(RuntimeException, std::exception)
2962 : {
2963 1 : SolarMutexGuard aGuard;
2964 1 : return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupsEnumeration" ) );
2965 : }
2966 :
2967 : // XElementAccess
2968 :
2969 1 : uno::Type SAL_CALL ScDataPilotFieldGroupsObj::getElementType() throw(RuntimeException, std::exception)
2970 : {
2971 1 : SolarMutexGuard aGuard;
2972 1 : return getCppuType( (Reference< XNameAccess >*)0 );
2973 : }
2974 :
2975 1 : sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasElements() throw(RuntimeException, std::exception)
2976 : {
2977 1 : SolarMutexGuard aGuard;
2978 1 : return !maGroups.empty();
2979 : }
2980 :
2981 : // implementation
2982 :
2983 9 : ScFieldGroup& ScDataPilotFieldGroupsObj::getFieldGroup( const OUString& rName ) throw(RuntimeException)
2984 : {
2985 9 : SolarMutexGuard aGuard;
2986 9 : ScFieldGroups::iterator aIt = implFindByName( rName );
2987 9 : if( aIt == maGroups.end() )
2988 0 : throw RuntimeException();
2989 9 : return *aIt;
2990 : }
2991 :
2992 2 : void ScDataPilotFieldGroupsObj::renameFieldGroup( const OUString& rOldName, const OUString& rNewName ) throw(RuntimeException)
2993 : {
2994 2 : SolarMutexGuard aGuard;
2995 2 : ScFieldGroups::iterator aOldIt = implFindByName( rOldName );
2996 2 : ScFieldGroups::iterator aNewIt = implFindByName( rNewName );
2997 : // new name must not exist yet
2998 2 : if( (aOldIt == maGroups.end()) || ((aNewIt != maGroups.end()) && (aNewIt != aOldIt)) )
2999 0 : throw RuntimeException();
3000 2 : aOldIt->maName = rNewName;
3001 2 : }
3002 :
3003 17 : ScFieldGroups::iterator ScDataPilotFieldGroupsObj::implFindByName( const OUString& rName )
3004 : {
3005 21 : for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt )
3006 17 : if( aIt->maName == rName )
3007 13 : return aIt;
3008 4 : return maGroups.end();
3009 : }
3010 :
3011 : namespace {
3012 :
3013 2 : OUString lclExtractMember( const Any& rElement )
3014 : {
3015 2 : if( rElement.has< OUString >() )
3016 2 : return rElement.get< OUString >();
3017 :
3018 0 : Reference< XNamed > xNamed( rElement, UNO_QUERY );
3019 0 : if( xNamed.is() )
3020 0 : return xNamed->getName();
3021 :
3022 0 : return OUString();
3023 : }
3024 :
3025 : } // namespace
3026 :
3027 6 : ScDataPilotFieldGroupObj::ScDataPilotFieldGroupObj( ScDataPilotFieldGroupsObj& rParent, const OUString& rGroupName ) :
3028 : mrParent( rParent ),
3029 6 : maGroupName( rGroupName )
3030 : {
3031 6 : mrParent.acquire();
3032 6 : }
3033 :
3034 18 : ScDataPilotFieldGroupObj::~ScDataPilotFieldGroupObj()
3035 : {
3036 6 : mrParent.release();
3037 12 : }
3038 :
3039 : // XNameAccess
3040 :
3041 1 : Any SAL_CALL ScDataPilotFieldGroupObj::getByName( const OUString& rName )
3042 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3043 : {
3044 1 : SolarMutexGuard aGuard;
3045 1 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3046 1 : ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3047 1 : if( aIt == rMembers.end() )
3048 0 : throw NoSuchElementException();
3049 1 : return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, *aIt ) ) );
3050 : }
3051 :
3052 0 : Sequence< OUString > SAL_CALL ScDataPilotFieldGroupObj::getElementNames() throw(RuntimeException, std::exception)
3053 : {
3054 0 : SolarMutexGuard aGuard;
3055 0 : return ::comphelper::containerToSequence( mrParent.getFieldGroup( maGroupName ).maMembers );
3056 : }
3057 :
3058 0 : sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasByName( const OUString& rName ) throw(RuntimeException, std::exception)
3059 : {
3060 0 : SolarMutexGuard aGuard;
3061 0 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3062 0 : return ::std::find( rMembers.begin(), rMembers.end(), rName ) != rMembers.end();
3063 : }
3064 :
3065 : // XNameReplace
3066 :
3067 2 : void SAL_CALL ScDataPilotFieldGroupObj::replaceByName( const OUString& rName, const Any& rElement )
3068 : throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3069 : {
3070 2 : SolarMutexGuard aGuard;
3071 :
3072 : // it should be possible to quickly rename an item -> accept string or XNamed
3073 4 : OUString aNewName = lclExtractMember( rElement );
3074 2 : if( rName.isEmpty() || aNewName.isEmpty() )
3075 0 : throw IllegalArgumentException();
3076 2 : if( rName == aNewName )
3077 2 : return;
3078 :
3079 2 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3080 2 : ScFieldGroupMembers::iterator aOldIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3081 2 : ScFieldGroupMembers::iterator aNewIt = ::std::find( rMembers.begin(), rMembers.end(), aNewName );
3082 : // throw if passed member name does not exist
3083 2 : if( aOldIt == rMembers.end() )
3084 0 : throw NoSuchElementException();
3085 : // throw if new name already exists
3086 2 : if( aNewIt != rMembers.end() )
3087 0 : throw IllegalArgumentException();
3088 4 : *aOldIt = aNewName;
3089 : }
3090 :
3091 : // XNameContainer
3092 :
3093 0 : void SAL_CALL ScDataPilotFieldGroupObj::insertByName( const OUString& rName, const Any& /*rElement*/ )
3094 : throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
3095 : {
3096 0 : SolarMutexGuard aGuard;
3097 :
3098 : // we will ignore the passed element and just try to insert the name
3099 0 : if( rName.isEmpty() )
3100 0 : throw IllegalArgumentException();
3101 :
3102 0 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3103 0 : ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3104 : // throw if passed name already exists
3105 0 : if( aIt != rMembers.end() )
3106 0 : throw IllegalArgumentException();
3107 0 : rMembers.push_back( rName );
3108 0 : }
3109 :
3110 0 : void SAL_CALL ScDataPilotFieldGroupObj::removeByName( const OUString& rName )
3111 : throw (NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3112 : {
3113 0 : SolarMutexGuard aGuard;
3114 :
3115 0 : if( rName.isEmpty() )
3116 0 : throw IllegalArgumentException();
3117 0 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3118 0 : ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3119 : // throw if passed name does not exist
3120 0 : if( aIt == rMembers.end() )
3121 0 : throw NoSuchElementException();
3122 0 : rMembers.erase( aIt );
3123 0 : }
3124 :
3125 : // XIndexAccess
3126 :
3127 1 : sal_Int32 SAL_CALL ScDataPilotFieldGroupObj::getCount() throw(RuntimeException, std::exception)
3128 : {
3129 1 : SolarMutexGuard aGuard;
3130 1 : return static_cast< sal_Int32 >( mrParent.getFieldGroup( maGroupName ).maMembers.size() );
3131 : }
3132 :
3133 4 : Any SAL_CALL ScDataPilotFieldGroupObj::getByIndex( sal_Int32 nIndex )
3134 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
3135 : {
3136 4 : SolarMutexGuard aGuard;
3137 4 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3138 4 : if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( rMembers.size() )))
3139 1 : throw IndexOutOfBoundsException();
3140 3 : return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, rMembers[ nIndex ] ) ) );
3141 : }
3142 :
3143 : // XEnumerationAccess
3144 :
3145 1 : Reference< XEnumeration > SAL_CALL ScDataPilotFieldGroupObj::createEnumeration() throw(RuntimeException, std::exception)
3146 : {
3147 1 : SolarMutexGuard aGuard;
3148 1 : return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupEnumeration" ) );
3149 : }
3150 :
3151 : // XElementAccess
3152 :
3153 1 : uno::Type SAL_CALL ScDataPilotFieldGroupObj::getElementType() throw(RuntimeException, std::exception)
3154 : {
3155 1 : SolarMutexGuard aGuard;
3156 1 : return getCppuType( (Reference< XNamed >*)0 );
3157 : }
3158 :
3159 1 : sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasElements() throw(RuntimeException, std::exception)
3160 : {
3161 1 : SolarMutexGuard aGuard;
3162 1 : return !mrParent.getFieldGroup( maGroupName ).maMembers.empty();
3163 : }
3164 :
3165 : // XNamed
3166 :
3167 3 : OUString SAL_CALL ScDataPilotFieldGroupObj::getName() throw(RuntimeException, std::exception)
3168 : {
3169 3 : SolarMutexGuard aGuard;
3170 3 : return maGroupName;
3171 : }
3172 :
3173 2 : void SAL_CALL ScDataPilotFieldGroupObj::setName( const OUString& rName ) throw(RuntimeException, std::exception)
3174 : {
3175 2 : SolarMutexGuard aGuard;
3176 2 : mrParent.renameFieldGroup( maGroupName, rName );
3177 : // if call to renameFieldGroup() did not throw, remember the new name
3178 2 : maGroupName = rName;
3179 2 : }
3180 :
3181 4 : ScDataPilotFieldGroupItemObj::ScDataPilotFieldGroupItemObj( ScDataPilotFieldGroupObj& rParent, const OUString& rName ) :
3182 : mrParent( rParent ),
3183 4 : maName( rName )
3184 : {
3185 4 : mrParent.acquire();
3186 4 : }
3187 :
3188 12 : ScDataPilotFieldGroupItemObj::~ScDataPilotFieldGroupItemObj()
3189 : {
3190 4 : mrParent.release();
3191 8 : }
3192 :
3193 : // XNamed
3194 :
3195 3 : OUString SAL_CALL ScDataPilotFieldGroupItemObj::getName() throw(RuntimeException, std::exception)
3196 : {
3197 3 : SolarMutexGuard aGuard;
3198 3 : return maName;
3199 : }
3200 :
3201 2 : void SAL_CALL ScDataPilotFieldGroupItemObj::setName( const OUString& rName ) throw(RuntimeException, std::exception)
3202 : {
3203 2 : SolarMutexGuard aGuard;
3204 2 : mrParent.replaceByName( maName, Any( rName ) );
3205 : // if call to replaceByName() did not throw, remember the new name
3206 2 : maName = rName;
3207 2 : }
3208 :
3209 5 : ScDataPilotItemsObj::ScDataPilotItemsObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
3210 5 : ScDataPilotChildObjBase( rParent, rFieldId )
3211 : {
3212 5 : }
3213 :
3214 10 : ScDataPilotItemsObj::~ScDataPilotItemsObj()
3215 : {
3216 10 : }
3217 :
3218 : // XDataPilotItems
3219 :
3220 17 : ScDataPilotItemObj* ScDataPilotItemsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3221 : {
3222 17 : return ((0 <= nIndex) && (nIndex < GetMemberCount())) ?
3223 32 : new ScDataPilotItemObj( mrParent, maFieldId, nIndex ) : 0;
3224 : }
3225 :
3226 : // XNameAccess
3227 :
3228 2 : Any SAL_CALL ScDataPilotItemsObj::getByName( const OUString& aName )
3229 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3230 : {
3231 2 : SolarMutexGuard aGuard;
3232 4 : Reference<XNameAccess> xMembers = GetMembers();
3233 2 : if (xMembers.is())
3234 : {
3235 2 : Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3236 2 : sal_Int32 nCount = xMembersIndex->getCount();
3237 2 : sal_Bool bFound(false);
3238 2 : sal_Int32 nItem = 0;
3239 9 : while (nItem < nCount && !bFound )
3240 : {
3241 6 : Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3242 6 : if (xMember.is() && (aName == xMember->getName()))
3243 1 : return Any( Reference< XPropertySet >( GetObjectByIndex_Impl( nItem ) ) );
3244 5 : ++nItem;
3245 5 : }
3246 1 : if (!bFound)
3247 1 : throw NoSuchElementException();
3248 : }
3249 2 : return Any();
3250 : }
3251 :
3252 2 : Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
3253 : throw(RuntimeException, std::exception)
3254 : {
3255 2 : SolarMutexGuard aGuard;
3256 2 : Sequence< OUString > aSeq;
3257 2 : if( ScDPObject* pDPObj = GetDPObject() )
3258 2 : pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
3259 2 : return aSeq;
3260 : }
3261 :
3262 2 : sal_Bool SAL_CALL ScDataPilotItemsObj::hasByName( const OUString& aName )
3263 : throw(RuntimeException, std::exception)
3264 : {
3265 2 : SolarMutexGuard aGuard;
3266 2 : sal_Bool bFound = false;
3267 4 : Reference<XNameAccess> xMembers = GetMembers();
3268 2 : if (xMembers.is())
3269 : {
3270 2 : Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3271 2 : sal_Int32 nCount = xMembersIndex->getCount();
3272 2 : sal_Int32 nItem = 0;
3273 10 : while (nItem < nCount && !bFound )
3274 : {
3275 6 : Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3276 6 : if (xMember.is() && aName == xMember->getName())
3277 1 : bFound = sal_True;
3278 : else
3279 5 : nItem++;
3280 8 : }
3281 : }
3282 4 : return bFound;
3283 : }
3284 :
3285 : // XEnumerationAccess
3286 :
3287 2 : Reference<XEnumeration> SAL_CALL ScDataPilotItemsObj::createEnumeration()
3288 : throw(RuntimeException, std::exception)
3289 : {
3290 2 : SolarMutexGuard aGuard;
3291 2 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotItemsEnumeration"));
3292 : }
3293 :
3294 : // XIndexAccess
3295 :
3296 10 : sal_Int32 SAL_CALL ScDataPilotItemsObj::getCount() throw(RuntimeException, std::exception)
3297 : {
3298 10 : SolarMutexGuard aGuard;
3299 10 : return GetMemberCount();
3300 : }
3301 :
3302 16 : Any SAL_CALL ScDataPilotItemsObj::getByIndex( sal_Int32 nIndex )
3303 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
3304 : {
3305 16 : SolarMutexGuard aGuard;
3306 32 : Reference< XPropertySet > xItem( GetObjectByIndex_Impl( nIndex ) );
3307 16 : if (!xItem.is())
3308 2 : throw IndexOutOfBoundsException();
3309 30 : return Any( xItem );
3310 : }
3311 :
3312 1 : uno::Type SAL_CALL ScDataPilotItemsObj::getElementType() throw(RuntimeException, std::exception)
3313 : {
3314 1 : SolarMutexGuard aGuard;
3315 1 : return getCppuType((Reference<XPropertySet>*)0);
3316 : }
3317 :
3318 2 : sal_Bool SAL_CALL ScDataPilotItemsObj::hasElements() throw(RuntimeException, std::exception)
3319 : {
3320 2 : SolarMutexGuard aGuard;
3321 2 : return ( getCount() != 0 );
3322 : }
3323 :
3324 15 : ScDataPilotItemObj::ScDataPilotItemObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId, sal_Int32 nIndex ) :
3325 : ScDataPilotChildObjBase( rParent, rFieldId ),
3326 : maPropSet( lcl_GetDataPilotItemMap() ),
3327 15 : mnIndex( nIndex )
3328 : {
3329 15 : }
3330 :
3331 30 : ScDataPilotItemObj::~ScDataPilotItemObj()
3332 : {
3333 30 : }
3334 :
3335 : // XNamed
3336 1 : OUString SAL_CALL ScDataPilotItemObj::getName() throw(RuntimeException, std::exception)
3337 : {
3338 1 : SolarMutexGuard aGuard;
3339 1 : OUString sRet;
3340 2 : Reference<XNameAccess> xMembers = GetMembers();
3341 1 : if (xMembers.is())
3342 : {
3343 1 : Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3344 1 : sal_Int32 nCount = xMembersIndex->getCount();
3345 1 : if (mnIndex < nCount)
3346 : {
3347 1 : Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3348 1 : sRet = xMember->getName();
3349 1 : }
3350 : }
3351 2 : return sRet;
3352 : }
3353 :
3354 0 : void SAL_CALL ScDataPilotItemObj::setName( const OUString& /* aName */ )
3355 : throw(RuntimeException, std::exception)
3356 : {
3357 0 : }
3358 :
3359 : // XPropertySet
3360 : Reference< XPropertySetInfo >
3361 5 : SAL_CALL ScDataPilotItemObj::getPropertySetInfo( )
3362 : throw(RuntimeException, std::exception)
3363 : {
3364 5 : SolarMutexGuard aGuard;
3365 : static Reference<XPropertySetInfo> aRef =
3366 5 : new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
3367 5 : return aRef;
3368 : }
3369 :
3370 7 : void SAL_CALL ScDataPilotItemObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
3371 : throw (UnknownPropertyException, PropertyVetoException,
3372 : IllegalArgumentException, WrappedTargetException,
3373 : RuntimeException, std::exception)
3374 : {
3375 7 : SolarMutexGuard aGuard;
3376 7 : ScDPObject* pDPObj = 0;
3377 7 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
3378 : {
3379 7 : Reference<XNameAccess> xMembers = GetMembers();
3380 7 : if( xMembers.is() )
3381 : {
3382 7 : Reference<XIndexAccess> xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3383 7 : sal_Int32 nCount = xMembersIndex->getCount();
3384 7 : if( mnIndex < nCount )
3385 : {
3386 7 : Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3387 14 : OUString sName(xMember->getName());
3388 7 : ScDPSaveMember* pMember = pDim->GetMemberByName(sName);
3389 7 : if (pMember)
3390 : {
3391 7 : bool bGetNewIndex = false;
3392 7 : if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3393 3 : pMember->SetShowDetails(cppu::any2bool(aValue));
3394 4 : else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3395 3 : pMember->SetIsVisible(!cppu::any2bool(aValue));
3396 1 : else if ( aPropertyName == SC_UNONAME_POS )
3397 : {
3398 1 : sal_Int32 nNewPos = 0;
3399 1 : if ( ( aValue >>= nNewPos ) && nNewPos >= 0 && nNewPos < nCount )
3400 : {
3401 0 : pDim->SetMemberPosition( sName, nNewPos );
3402 : // get new effective index (depends on sorting mode, which isn't modified)
3403 0 : bGetNewIndex = true;
3404 : }
3405 : else
3406 1 : throw IllegalArgumentException();
3407 : }
3408 6 : SetDPObject( pDPObj );
3409 :
3410 6 : if ( bGetNewIndex ) // after SetDPObject, get the new index
3411 : {
3412 0 : OUString aOUName( sName );
3413 0 : Sequence< OUString > aItemNames = xMembers->getElementNames();
3414 0 : sal_Int32 nItemCount = aItemNames.getLength();
3415 0 : for (sal_Int32 nItem=0; nItem<nItemCount; ++nItem)
3416 0 : if (aItemNames[nItem] == aOUName)
3417 0 : mnIndex = nItem;
3418 : }
3419 7 : }
3420 7 : }
3421 7 : }
3422 7 : }
3423 6 : }
3424 :
3425 15 : Any SAL_CALL ScDataPilotItemObj::getPropertyValue( const OUString& aPropertyName )
3426 : throw (UnknownPropertyException, WrappedTargetException,
3427 : RuntimeException, std::exception)
3428 : {
3429 15 : SolarMutexGuard aGuard;
3430 15 : Any aRet;
3431 15 : if( ScDPSaveDimension* pDim = GetDPDimension() )
3432 : {
3433 15 : Reference< XNameAccess > xMembers = GetMembers();
3434 15 : if( xMembers.is() )
3435 : {
3436 15 : Reference< XIndexAccess > xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3437 15 : sal_Int32 nCount = xMembersIndex->getCount();
3438 15 : if( mnIndex < nCount )
3439 : {
3440 15 : Reference< XNamed > xMember( xMembersIndex->getByIndex( mnIndex ), UNO_QUERY );
3441 30 : OUString sName( xMember->getName() );
3442 15 : ScDPSaveMember* pMember = pDim->GetExistingMemberByName( sName );
3443 15 : if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3444 : {
3445 7 : if (pMember && pMember->HasShowDetails())
3446 : {
3447 6 : aRet <<= (bool)pMember->GetShowDetails();
3448 : }
3449 : else
3450 : {
3451 1 : Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3452 1 : if( xMemberProps.is() )
3453 1 : aRet = xMemberProps->getPropertyValue( OUString( SC_UNO_DP_SHOWDETAILS ) );
3454 : else
3455 0 : aRet <<= true;
3456 : }
3457 : }
3458 8 : else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3459 : {
3460 7 : if (pMember && pMember->HasIsVisible())
3461 : {
3462 6 : aRet <<= !pMember->GetIsVisible();
3463 : }
3464 : else
3465 : {
3466 1 : Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3467 1 : if( xMemberProps.is() )
3468 1 : aRet <<= !cppu::any2bool( xMemberProps->getPropertyValue( OUString( SC_UNO_DP_ISVISIBLE ) ) );
3469 : else
3470 0 : aRet <<= false;
3471 : }
3472 : }
3473 1 : else if ( aPropertyName == SC_UNONAME_POS )
3474 : {
3475 1 : aRet <<= mnIndex;
3476 15 : }
3477 15 : }
3478 15 : }
3479 : }
3480 15 : return aRet;
3481 : }
3482 :
3483 0 : void SAL_CALL ScDataPilotItemObj::addPropertyChangeListener(
3484 : const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* xListener */ )
3485 : throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
3486 : {
3487 0 : }
3488 :
3489 0 : void SAL_CALL ScDataPilotItemObj::removePropertyChangeListener(
3490 : const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* aListener */ )
3491 : throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
3492 : {
3493 0 : }
3494 :
3495 0 : void SAL_CALL ScDataPilotItemObj::addVetoableChangeListener(
3496 : const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3497 : throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
3498 : {
3499 0 : }
3500 :
3501 0 : void SAL_CALL ScDataPilotItemObj::removeVetoableChangeListener(
3502 : const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3503 : throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
3504 : {
3505 102 : }
3506 :
3507 :
3508 :
3509 :
3510 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|