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 0 : const SfxItemPropertyMapEntry* lcl_GetDataPilotDescriptorBaseMap()
93 : {
94 : static const SfxItemPropertyMapEntry aDataPilotDescriptorBaseMap_Impl[] =
95 : {
96 0 : {OUString(SC_UNO_DP_COLGRAND), 0, getBooleanCppuType(), 0, 0 },
97 0 : {OUString(SC_UNO_DP_DRILLDOWN), 0, getBooleanCppuType(), 0, 0 },
98 0 : {OUString(SC_UNO_DP_GRANDTOTAL_NAME),0,getCppuType((OUString*)0), beans::PropertyAttribute::MAYBEVOID, 0 },
99 0 : {OUString(SC_UNO_DP_IGNORE_EMPTYROWS), 0, getBooleanCppuType(), 0, 0 },
100 0 : {OUString(SC_UNO_DP_IMPORTDESC), 0, getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
101 0 : {OUString(SC_UNO_DP_REPEATEMPTY), 0, getBooleanCppuType(), 0, 0 },
102 0 : {OUString(SC_UNO_DP_ROWGRAND), 0, getBooleanCppuType(), 0, 0 },
103 0 : {OUString(SC_UNO_DP_SERVICEARG), 0, getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
104 0 : {OUString(SC_UNO_DP_SHOWFILTER), 0, getBooleanCppuType(), 0, 0 },
105 0 : {OUString(SC_UNO_DP_SOURCESERVICE), 0, getCppuType((OUString*)0), 0, 0 },
106 : { OUString(), 0, css::uno::Type(), 0, 0 }
107 0 : };
108 0 : return aDataPilotDescriptorBaseMap_Impl;
109 : }
110 :
111 0 : const SfxItemPropertyMapEntry* lcl_GetDataPilotFieldMap()
112 : {
113 : using namespace ::com::sun::star::beans::PropertyAttribute;
114 : static const SfxItemPropertyMapEntry aDataPilotFieldMap_Impl[] =
115 : {
116 0 : {OUString(SC_UNONAME_AUTOSHOW), 0, getCppuType((DataPilotFieldAutoShowInfo*)0), MAYBEVOID, 0 },
117 0 : {OUString(SC_UNONAME_FUNCTION), 0, getCppuType((GeneralFunction*)0), 0, 0 },
118 0 : {OUString(SC_UNONAME_GROUPINFO), 0, getCppuType((DataPilotFieldGroupInfo*)0), MAYBEVOID, 0 },
119 0 : {OUString(SC_UNONAME_HASAUTOSHOW), 0, getBooleanCppuType(), 0, 0 },
120 0 : {OUString(SC_UNONAME_HASLAYOUTINFO),0, getBooleanCppuType(), 0, 0 },
121 0 : {OUString(SC_UNONAME_HASREFERENCE), 0, getBooleanCppuType(), 0, 0 },
122 0 : {OUString(SC_UNONAME_HASSORTINFO), 0, getBooleanCppuType(), 0, 0 },
123 0 : {OUString(SC_UNONAME_ISGROUP), 0, getBooleanCppuType(), 0, 0 },
124 0 : {OUString(SC_UNONAME_LAYOUTINFO), 0, getCppuType((DataPilotFieldLayoutInfo*)0), MAYBEVOID, 0 },
125 0 : {OUString(SC_UNONAME_ORIENT), 0, getCppuType((DataPilotFieldOrientation*)0), MAYBEVOID, 0 },
126 0 : {OUString(SC_UNONAME_REFERENCE), 0, getCppuType((DataPilotFieldReference*)0), MAYBEVOID, 0 },
127 0 : {OUString(SC_UNONAME_SELPAGE), 0, getCppuType((OUString*)0), 0, 0 },
128 0 : {OUString(SC_UNONAME_SHOWEMPTY), 0, getBooleanCppuType(), 0, 0 },
129 0 : {OUString(SC_UNONAME_SORTINFO), 0, getCppuType((DataPilotFieldSortInfo*)0), MAYBEVOID, 0 },
130 0 : {OUString(SC_UNONAME_SUBTOTALS), 0, getCppuType((Sequence<GeneralFunction>*)0), 0, 0 },
131 0 : {OUString(SC_UNONAME_USESELPAGE), 0, getBooleanCppuType(), 0, 0 },
132 : { OUString(), 0, css::uno::Type(), 0, 0 }
133 0 : };
134 0 : return aDataPilotFieldMap_Impl;
135 : }
136 :
137 0 : const SfxItemPropertyMapEntry* lcl_GetDataPilotItemMap()
138 : {
139 : static const SfxItemPropertyMapEntry aDataPilotItemMap_Impl[] =
140 : {
141 0 : {OUString(SC_UNONAME_ISHIDDEN), 0, getBooleanCppuType(), 0, 0 },
142 0 : {OUString(SC_UNONAME_POS), 0, getCppuType((sal_Int32*)0), 0, 0 },
143 0 : {OUString(SC_UNONAME_SHOWDETAIL), 0, getBooleanCppuType(), 0, 0 },
144 : { OUString(), 0, css::uno::Type(), 0, 0 }
145 0 : };
146 0 : 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 0 : 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 0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotItemsObj, "ScDataPilotItemsObj", "com.sun.star.sheet.DataPilotItems" )
172 0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotItemObj, "ScDataPilotItemObj", "com.sun.star.sheet.DataPilotItem" )
173 :
174 0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupsObj, "ScDataPilotFieldGroupsObj", "com.sun.star.sheet.DataPilotFieldGroups" )
175 0 : SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupObj, "ScDataPilotFieldGroupObj", "com.sun.star.sheet.DataPilotFieldGroup" )
176 0 : 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 0 : void ScDataPilotConversion::FillGroupInfo( DataPilotFieldGroupInfo& rInfo, const ScDPNumGroupInfo& rGroupInfo )
224 : {
225 0 : rInfo.HasDateValues = rGroupInfo.mbDateValues;
226 0 : rInfo.HasAutoStart = rGroupInfo.mbAutoStart;
227 0 : rInfo.Start = rGroupInfo.mfStart;
228 0 : rInfo.HasAutoEnd = rGroupInfo.mbAutoEnd;
229 0 : rInfo.End = rGroupInfo.mfEnd;
230 0 : rInfo.Step = rGroupInfo.mfStep;
231 0 : }
232 :
233 0 : static ScDPObject* lcl_GetDPObject( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
234 : {
235 0 : if (pDocShell)
236 : {
237 0 : ScDocument* pDoc = pDocShell->GetDocument();
238 0 : ScDPCollection* pColl = pDoc->GetDPCollection();
239 0 : if ( pColl )
240 : {
241 0 : size_t nCount = pColl->GetCount();
242 0 : for (size_t i=0; i<nCount; ++i)
243 : {
244 0 : ScDPObject* pDPObj = (*pColl)[i];
245 0 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
246 0 : pDPObj->GetName() == rName )
247 0 : return pDPObj;
248 : }
249 : }
250 : }
251 0 : 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 0 : static sal_Int32 lcl_GetObjectIndex( ScDPObject* pDPObj, const ScFieldIdentifier& rFieldId )
267 : {
268 : // used for items - nRepeat in identifier can be ignored
269 0 : if ( pDPObj )
270 : {
271 0 : sal_Int32 nCount = pDPObj->GetDimCount();
272 0 : for ( sal_Int32 nDim = 0; nDim < nCount; ++nDim )
273 : {
274 0 : bool bIsDataLayout = false;
275 0 : OUString aDimName( pDPObj->GetDimName( nDim, bIsDataLayout ) );
276 0 : if ( rFieldId.mbDataLayout ? bIsDataLayout : (aDimName == rFieldId.maFieldName) )
277 0 : return nDim;
278 0 : }
279 : }
280 0 : return -1; // none
281 : }
282 :
283 0 : ScDataPilotTablesObj::ScDataPilotTablesObj(ScDocShell* pDocSh, SCTAB nT) :
284 : pDocShell( pDocSh ),
285 0 : nTab( nT )
286 : {
287 0 : pDocShell->GetDocument()->AddUnoObject(*this);
288 0 : }
289 :
290 0 : ScDataPilotTablesObj::~ScDataPilotTablesObj()
291 : {
292 0 : if (pDocShell)
293 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
294 0 : }
295 :
296 0 : void ScDataPilotTablesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
297 : {
298 : //! Referenz-Update
299 :
300 0 : if ( rHint.ISA( SfxSimpleHint ) &&
301 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
302 : {
303 0 : pDocShell = NULL; // ungueltig geworden
304 : }
305 0 : }
306 :
307 : // XDataPilotTables
308 :
309 0 : ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nIndex )
310 : {
311 0 : if (pDocShell)
312 : {
313 0 : ScDocument* pDoc = pDocShell->GetDocument();
314 0 : ScDPCollection* pColl = pDoc->GetDPCollection();
315 0 : if ( pColl )
316 : {
317 : // count tables on this sheet
318 0 : sal_Int32 nFound = 0;
319 0 : size_t nCount = pColl->GetCount();
320 0 : for (size_t i=0; i<nCount; ++i)
321 : {
322 0 : ScDPObject* pDPObj = (*pColl)[i];
323 0 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
324 : {
325 0 : if ( nFound == nIndex )
326 : {
327 0 : OUString aName = pDPObj->GetName();
328 0 : return new ScDataPilotTableObj( pDocShell, nTab, aName );
329 : }
330 0 : ++nFound;
331 : }
332 : }
333 : }
334 : }
335 0 : return NULL;
336 : }
337 :
338 0 : ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByName_Impl(const OUString& rName)
339 : {
340 0 : if (hasByName(rName))
341 0 : return new ScDataPilotTableObj( pDocShell, nTab, rName );
342 0 : return 0;
343 : }
344 :
345 0 : Reference<XDataPilotDescriptor> SAL_CALL ScDataPilotTablesObj::createDataPilotDescriptor()
346 : throw(RuntimeException, std::exception)
347 : {
348 0 : SolarMutexGuard aGuard;
349 0 : if (pDocShell)
350 0 : return new ScDataPilotDescriptor(pDocShell);
351 0 : return NULL;
352 : }
353 :
354 0 : static bool lcl_IsDuplicated( const Reference<XPropertySet> xDimProps )
355 : {
356 : try
357 : {
358 0 : Any aAny = xDimProps->getPropertyValue( OUString( SC_UNO_DP_ORIGINAL ) );
359 0 : Reference< XNamed > xOriginal( aAny, UNO_QUERY );
360 0 : return xOriginal.is();
361 : }
362 0 : catch( Exception& )
363 : {
364 : }
365 0 : return false;
366 : }
367 :
368 0 : static OUString lcl_GetOriginalName( const Reference< XNamed > xDim )
369 : {
370 0 : Reference< XNamed > xOriginal;
371 :
372 0 : Reference< XPropertySet > xDimProps( xDim, UNO_QUERY );
373 0 : if ( xDimProps.is() )
374 : {
375 : try
376 : {
377 0 : Any aAny = xDimProps->getPropertyValue(OUString(SC_UNO_DP_ORIGINAL));
378 0 : aAny >>= xOriginal;
379 : }
380 0 : catch( Exception& )
381 : {
382 : }
383 : }
384 :
385 0 : if ( !xOriginal.is() )
386 0 : xOriginal = xDim;
387 :
388 0 : return xOriginal->getName();
389 : }
390 :
391 0 : void SAL_CALL ScDataPilotTablesObj::insertNewByName( const OUString& aNewName,
392 : const CellAddress& aOutputAddress,
393 : const Reference<XDataPilotDescriptor>& xDescriptor )
394 : throw(RuntimeException, std::exception)
395 : {
396 0 : SolarMutexGuard aGuard;
397 0 : if (!xDescriptor.is()) return;
398 :
399 : // inserting with already existing name?
400 0 : if ( !aNewName.isEmpty() && hasByName( aNewName ) )
401 0 : throw RuntimeException(); // no other exceptions specified
402 :
403 0 : sal_Bool bDone = false;
404 0 : ScDataPilotDescriptorBase* pImp = ScDataPilotDescriptorBase::getImplementation( xDescriptor );
405 0 : if ( pDocShell && pImp )
406 : {
407 0 : ScDPObject* pNewObj = pImp->GetDPObject();
408 :
409 0 : if (pNewObj)
410 : {
411 : ScRange aOutputRange((SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet,
412 0 : (SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet);
413 0 : pNewObj->SetOutRange(aOutputRange);
414 0 : OUString aName = aNewName;
415 0 : if (aName.isEmpty())
416 0 : aName = lcl_CreatePivotName( pDocShell );
417 0 : pNewObj->SetName(aName);
418 0 : OUString aTag = xDescriptor->getTag();
419 0 : pNewObj->SetTag(aTag);
420 :
421 : // todo: handle double fields (for more information see ScDPObject
422 :
423 0 : ScDBDocFunc aFunc(*pDocShell);
424 0 : bDone = aFunc.CreatePivotTable(*pNewObj, true, true);
425 : }
426 : }
427 :
428 0 : if (!bDone)
429 0 : throw RuntimeException(); // no other exceptions specified
430 : }
431 :
432 0 : void SAL_CALL ScDataPilotTablesObj::removeByName( const OUString& aName )
433 : throw(RuntimeException, std::exception)
434 : {
435 0 : SolarMutexGuard aGuard;
436 0 : OUString aNameStr(aName);
437 0 : ScDPObject* pDPObj = lcl_GetDPObject( pDocShell, nTab, aNameStr );
438 0 : if (pDPObj && pDocShell)
439 : {
440 0 : ScDBDocFunc aFunc(*pDocShell);
441 0 : aFunc.RemovePivotTable(*pDPObj, true, true); // remove - incl. undo etc.
442 : }
443 : else
444 0 : throw RuntimeException(); // no other exceptions specified
445 0 : }
446 :
447 : // XEnumerationAccess
448 :
449 0 : Reference< XEnumeration > SAL_CALL ScDataPilotTablesObj::createEnumeration() throw(RuntimeException, std::exception)
450 : {
451 0 : SolarMutexGuard aGuard;
452 0 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotTablesEnumeration"));
453 : }
454 :
455 : // XIndexAccess
456 :
457 0 : sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException, std::exception)
458 : {
459 0 : SolarMutexGuard aGuard;
460 0 : if ( pDocShell )
461 : {
462 0 : ScDocument* pDoc = pDocShell->GetDocument();
463 0 : ScDPCollection* pColl = pDoc->GetDPCollection();
464 0 : if ( pColl )
465 : {
466 : // count tables on this sheet
467 :
468 0 : sal_uInt16 nFound = 0;
469 0 : size_t nCount = pColl->GetCount();
470 0 : for (size_t i=0; i<nCount; ++i)
471 : {
472 0 : ScDPObject* pDPObj = (*pColl)[i];
473 0 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
474 0 : ++nFound;
475 : }
476 0 : return nFound;
477 : }
478 : }
479 :
480 0 : return 0;
481 : }
482 :
483 0 : Any SAL_CALL ScDataPilotTablesObj::getByIndex( sal_Int32 nIndex )
484 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
485 : {
486 0 : SolarMutexGuard aGuard;
487 0 : Reference<XDataPilotTable2> xTable(GetObjectByIndex_Impl(nIndex));
488 0 : if (!xTable.is())
489 0 : throw IndexOutOfBoundsException();
490 0 : return Any( xTable );
491 : }
492 :
493 0 : uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(RuntimeException, std::exception)
494 : {
495 0 : SolarMutexGuard aGuard;
496 0 : return getCppuType((Reference<XDataPilotTable2>*)0);
497 : }
498 :
499 0 : sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(RuntimeException, std::exception)
500 : {
501 0 : SolarMutexGuard aGuard;
502 0 : return ( getCount() != 0 );
503 : }
504 :
505 : // XNameAccess
506 :
507 0 : Any SAL_CALL ScDataPilotTablesObj::getByName( const OUString& aName )
508 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
509 : {
510 0 : SolarMutexGuard aGuard;
511 0 : Reference<XDataPilotTable2> xTable(GetObjectByName_Impl(aName));
512 0 : if (!xTable.is())
513 0 : throw NoSuchElementException();
514 0 : return Any( xTable );
515 : }
516 :
517 0 : Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames()
518 : throw(RuntimeException, std::exception)
519 : {
520 0 : SolarMutexGuard aGuard;
521 0 : if (pDocShell)
522 : {
523 0 : ScDocument* pDoc = pDocShell->GetDocument();
524 0 : ScDPCollection* pColl = pDoc->GetDPCollection();
525 0 : if ( pColl )
526 : {
527 : // count tables on this sheet
528 :
529 0 : sal_uInt16 nFound = 0;
530 0 : size_t nCount = pColl->GetCount();
531 : size_t i;
532 0 : for (i=0; i<nCount; ++i)
533 : {
534 0 : ScDPObject* pDPObj = (*pColl)[i];
535 0 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
536 0 : ++nFound;
537 : }
538 :
539 0 : sal_uInt16 nPos = 0;
540 0 : Sequence<OUString> aSeq(nFound);
541 0 : OUString* pAry = aSeq.getArray();
542 0 : for (i=0; i<nCount; ++i)
543 : {
544 0 : ScDPObject* pDPObj = (*pColl)[i];
545 0 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
546 0 : pAry[nPos++] = pDPObj->GetName();
547 : }
548 :
549 0 : return aSeq;
550 : }
551 : }
552 0 : return Sequence<OUString>(0);
553 : }
554 :
555 0 : sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName )
556 : throw(RuntimeException, std::exception)
557 : {
558 0 : SolarMutexGuard aGuard;
559 0 : if (pDocShell)
560 : {
561 0 : ScDocument* pDoc = pDocShell->GetDocument();
562 0 : ScDPCollection* pColl = pDoc->GetDPCollection();
563 0 : if ( pColl )
564 : {
565 0 : size_t nCount = pColl->GetCount();
566 0 : for (size_t i=0; i<nCount; ++i)
567 : {
568 0 : ScDPObject* pDPObj = (*pColl)[i];
569 0 : if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
570 0 : pDPObj->GetName() == aName )
571 0 : return true;
572 : }
573 : }
574 : }
575 0 : return false;
576 : }
577 :
578 0 : ScDataPilotDescriptorBase::ScDataPilotDescriptorBase(ScDocShell* pDocSh) :
579 : maPropSet( lcl_GetDataPilotDescriptorBaseMap() ),
580 0 : pDocShell( pDocSh )
581 : {
582 0 : pDocShell->GetDocument()->AddUnoObject(*this);
583 0 : }
584 :
585 0 : ScDataPilotDescriptorBase::~ScDataPilotDescriptorBase()
586 : {
587 0 : if (pDocShell)
588 0 : pDocShell->GetDocument()->RemoveUnoObject(*this);
589 0 : }
590 :
591 0 : Any SAL_CALL ScDataPilotDescriptorBase::queryInterface( const uno::Type& rType )
592 : throw(RuntimeException, std::exception)
593 : {
594 0 : SC_QUERYINTERFACE( XDataPilotDescriptor )
595 0 : SC_QUERYINTERFACE( XPropertySet )
596 0 : SC_QUERYINTERFACE( XDataPilotDataLayoutFieldSupplier )
597 0 : SC_QUERYINTERFACE( XNamed ) // base of XDataPilotDescriptor
598 0 : SC_QUERYINTERFACE( lang::XUnoTunnel )
599 0 : SC_QUERYINTERFACE( lang::XTypeProvider )
600 0 : SC_QUERYINTERFACE( lang::XServiceInfo )
601 :
602 0 : return OWeakObject::queryInterface( rType );
603 : }
604 :
605 0 : void SAL_CALL ScDataPilotDescriptorBase::acquire() throw()
606 : {
607 0 : OWeakObject::acquire();
608 0 : }
609 :
610 0 : void SAL_CALL ScDataPilotDescriptorBase::release() throw()
611 : {
612 0 : OWeakObject::release();
613 0 : }
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 0 : void ScDataPilotDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
640 : {
641 : //! Referenz-Update?
642 :
643 0 : if ( rHint.ISA( SfxSimpleHint ) &&
644 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
645 : {
646 0 : pDocShell = NULL; // ungueltig geworden
647 : }
648 0 : }
649 :
650 : // XDataPilotDescriptor
651 :
652 0 : CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange()
653 : throw(RuntimeException, std::exception)
654 : {
655 0 : SolarMutexGuard aGuard;
656 :
657 0 : ScDPObject* pDPObject(GetDPObject());
658 0 : if (!pDPObject)
659 0 : throw RuntimeException();
660 :
661 0 : CellRangeAddress aRet;
662 0 : if (pDPObject->IsSheetData())
663 0 : ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->GetSourceRange() );
664 0 : return aRet;
665 : }
666 :
667 0 : void SAL_CALL ScDataPilotDescriptorBase::setSourceRange( const CellRangeAddress& aSourceRange ) throw(RuntimeException, std::exception)
668 : {
669 0 : SolarMutexGuard aGuard;
670 :
671 0 : ScDPObject* pDPObject = GetDPObject();
672 0 : if (!pDPObject)
673 0 : throw RuntimeException();
674 :
675 0 : ScSheetSourceDesc aSheetDesc(pDocShell->GetDocument());
676 0 : if (pDPObject->IsSheetData())
677 0 : aSheetDesc = *pDPObject->GetSheetDesc();
678 :
679 0 : ScRange aRange;
680 0 : ScUnoConversion::FillScRange(aRange, aSourceRange);
681 0 : aSheetDesc.SetSourceRange(aRange);
682 0 : pDPObject->SetSheetDesc( aSheetDesc );
683 0 : SetDPObject( pDPObject );
684 0 : }
685 :
686 0 : Reference<XSheetFilterDescriptor> SAL_CALL ScDataPilotDescriptorBase::getFilterDescriptor()
687 : throw(RuntimeException, std::exception)
688 : {
689 0 : SolarMutexGuard aGuard;
690 0 : return new ScDataPilotFilterDescriptor( pDocShell, this );
691 : }
692 :
693 0 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataPilotFields()
694 : throw(RuntimeException, std::exception)
695 : {
696 0 : SolarMutexGuard aGuard;
697 0 : return new ScDataPilotFieldsObj( *this );
698 : }
699 :
700 0 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getColumnFields()
701 : throw(RuntimeException, std::exception)
702 : {
703 0 : SolarMutexGuard aGuard;
704 0 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_COLUMN );
705 : }
706 :
707 0 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getRowFields()
708 : throw(RuntimeException, std::exception)
709 : {
710 0 : SolarMutexGuard aGuard;
711 0 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_ROW );
712 : }
713 :
714 0 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getPageFields()
715 : throw(RuntimeException, std::exception)
716 : {
717 0 : SolarMutexGuard aGuard;
718 0 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_PAGE );
719 : }
720 :
721 0 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataFields()
722 : throw(RuntimeException, std::exception)
723 : {
724 0 : SolarMutexGuard aGuard;
725 0 : return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_DATA );
726 : }
727 :
728 0 : Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getHiddenFields()
729 : throw(RuntimeException, std::exception)
730 : {
731 0 : SolarMutexGuard aGuard;
732 0 : 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 0 : sal_Int64 SAL_CALL ScDataPilotDescriptorBase::getSomething(
1052 : const Sequence<sal_Int8 >& rId ) throw(RuntimeException, std::exception)
1053 : {
1054 0 : if ( rId.getLength() == 16 &&
1055 0 : 0 == memcmp( getUnoTunnelId().getConstArray(),
1056 0 : rId.getConstArray(), 16 ) )
1057 : {
1058 0 : 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 0 : const Sequence<sal_Int8>& ScDataPilotDescriptorBase::getUnoTunnelId()
1069 : {
1070 0 : return theScDataPilotDescriptorBaseUnoTunnelId::get().getSeq();
1071 : }
1072 :
1073 0 : ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation(
1074 : const Reference<XDataPilotDescriptor> xObj )
1075 : {
1076 0 : ScDataPilotDescriptorBase* pRet = NULL;
1077 0 : Reference<lang::XUnoTunnel> xUT( xObj, UNO_QUERY );
1078 0 : if (xUT.is())
1079 0 : pRet = reinterpret_cast<ScDataPilotDescriptorBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
1080 0 : return pRet;
1081 : }
1082 :
1083 0 : ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const OUString& rN) :
1084 : ScDataPilotDescriptorBase( pDocSh ),
1085 : nTab( nT ),
1086 : aName( rN ),
1087 0 : aModifyListeners( 0 )
1088 : {
1089 0 : }
1090 :
1091 0 : ScDataPilotTableObj::~ScDataPilotTableObj()
1092 : {
1093 0 : }
1094 :
1095 0 : 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 0 : SC_QUERYINTERFACE( XDataPilotTable )
1101 0 : SC_QUERYINTERFACE( XDataPilotTable2 )
1102 0 : SC_QUERYINTERFACE( XModifyBroadcaster )
1103 :
1104 0 : return ScDataPilotDescriptorBase::queryInterface( rType );
1105 : }
1106 :
1107 0 : void SAL_CALL ScDataPilotTableObj::acquire() throw()
1108 : {
1109 0 : ScDataPilotDescriptorBase::acquire();
1110 0 : }
1111 :
1112 0 : void SAL_CALL ScDataPilotTableObj::release() throw()
1113 : {
1114 0 : ScDataPilotDescriptorBase::release();
1115 0 : }
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 0 : ScDPObject* ScDataPilotTableObj::GetDPObject() const
1145 : {
1146 0 : return lcl_GetDPObject(GetDocShell(), nTab, aName);
1147 : }
1148 :
1149 0 : void ScDataPilotTableObj::SetDPObject( ScDPObject* pDPObject )
1150 : {
1151 0 : ScDocShell* pDocSh = GetDocShell();
1152 0 : ScDPObject* pDPObj = lcl_GetDPObject(pDocSh, nTab, aName);
1153 0 : if ( pDPObj && pDocSh )
1154 : {
1155 0 : ScDBDocFunc aFunc(*pDocSh);
1156 0 : aFunc.DataPilotUpdate( pDPObj, pDPObject, true, true );
1157 : }
1158 0 : }
1159 :
1160 : // "rest of XDataPilotDescriptor"
1161 :
1162 0 : OUString SAL_CALL ScDataPilotTableObj::getName() throw(RuntimeException, std::exception)
1163 : {
1164 0 : SolarMutexGuard aGuard;
1165 0 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1166 0 : if (pDPObj)
1167 0 : return pDPObj->GetName();
1168 0 : return OUString();
1169 : }
1170 :
1171 0 : void SAL_CALL ScDataPilotTableObj::setName( const OUString& aNewName )
1172 : throw(RuntimeException, std::exception)
1173 : {
1174 0 : SolarMutexGuard aGuard;
1175 0 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1176 0 : if (pDPObj)
1177 : {
1178 : //! test for existing names !!!
1179 :
1180 0 : OUString aString(aNewName);
1181 0 : pDPObj->SetName( aString ); //! Undo - DBDocFunc ???
1182 0 : aName = aString;
1183 :
1184 : // DataPilotUpdate would do too much (output table is not changed)
1185 0 : GetDocShell()->SetDocumentModified();
1186 0 : }
1187 0 : }
1188 :
1189 0 : OUString SAL_CALL ScDataPilotTableObj::getTag() throw(RuntimeException, std::exception)
1190 : {
1191 0 : SolarMutexGuard aGuard;
1192 0 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1193 0 : if (pDPObj)
1194 0 : return pDPObj->GetTag();
1195 0 : return OUString();
1196 : }
1197 :
1198 0 : void SAL_CALL ScDataPilotTableObj::setTag( const OUString& aNewTag )
1199 : throw(RuntimeException, std::exception)
1200 : {
1201 0 : SolarMutexGuard aGuard;
1202 0 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1203 0 : if (pDPObj)
1204 : {
1205 0 : pDPObj->SetTag( aNewTag ); //! Undo - DBDocFunc ???
1206 :
1207 : // DataPilotUpdate would do too much (output table is not changed)
1208 0 : GetDocShell()->SetDocumentModified();
1209 0 : }
1210 0 : }
1211 :
1212 : // XDataPilotTable
1213 :
1214 0 : CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeException, std::exception)
1215 : {
1216 0 : SolarMutexGuard aGuard;
1217 0 : CellRangeAddress aRet;
1218 0 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1219 0 : if (pDPObj)
1220 : {
1221 0 : ScRange aRange(pDPObj->GetOutRange());
1222 0 : aRet.Sheet = aRange.aStart.Tab();
1223 0 : aRet.StartColumn = aRange.aStart.Col();
1224 0 : aRet.StartRow = aRange.aStart.Row();
1225 0 : aRet.EndColumn = aRange.aEnd.Col();
1226 0 : aRet.EndRow = aRange.aEnd.Row();
1227 : }
1228 0 : return aRet;
1229 : }
1230 :
1231 0 : void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException, std::exception)
1232 : {
1233 0 : SolarMutexGuard aGuard;
1234 0 : ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1235 0 : if (pDPObj)
1236 : {
1237 0 : ScDBDocFunc aFunc(*GetDocShell());
1238 0 : aFunc.RefreshPivotTables(pDPObj, true);
1239 0 : }
1240 0 : }
1241 :
1242 0 : Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr)
1243 : throw (RuntimeException, std::exception)
1244 : {
1245 0 : SolarMutexGuard aGuard;
1246 0 : Sequence< Sequence<Any> > aTabData;
1247 0 : ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1248 0 : ScDPObject* pObj = GetDPObject();
1249 0 : if (!pObj)
1250 0 : throw RuntimeException();
1251 :
1252 0 : pObj->GetDrillDownData(aAddr2, aTabData);
1253 0 : return aTabData;
1254 : }
1255 :
1256 0 : DataPilotTablePositionData SAL_CALL ScDataPilotTableObj::getPositionData(const CellAddress& aAddr)
1257 : throw (RuntimeException, std::exception)
1258 : {
1259 0 : SolarMutexGuard aGuard;
1260 0 : DataPilotTablePositionData aPosData;
1261 0 : ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1262 0 : ScDPObject* pObj = GetDPObject();
1263 0 : if (!pObj)
1264 0 : throw RuntimeException();
1265 :
1266 0 : pObj->GetPositionData(aAddr2, aPosData);
1267 0 : return aPosData;
1268 : }
1269 :
1270 0 : void SAL_CALL ScDataPilotTableObj::insertDrillDownSheet(const CellAddress& aAddr)
1271 : throw (RuntimeException, std::exception)
1272 : {
1273 0 : SolarMutexGuard aGuard;
1274 0 : ScDPObject* pDPObj = GetDPObject();
1275 0 : if (!pDPObj)
1276 0 : throw RuntimeException();
1277 0 : ScTabViewShell* pViewSh = GetDocShell()->GetBestViewShell();
1278 0 : if (!pViewSh)
1279 0 : throw RuntimeException();
1280 :
1281 0 : Sequence<DataPilotFieldFilter> aFilters;
1282 : pDPObj->GetDataFieldPositionData(
1283 0 : ScAddress(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet), aFilters);
1284 0 : pViewSh->ShowDataPilotSourceData(*pDPObj, aFilters);
1285 0 : }
1286 :
1287 0 : CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
1288 : throw (IllegalArgumentException, RuntimeException, std::exception)
1289 : {
1290 0 : SolarMutexGuard aGuard;
1291 0 : if (nType < 0 || nType > DataPilotOutputRangeType::RESULT)
1292 0 : throw IllegalArgumentException();
1293 :
1294 0 : CellRangeAddress aRet;
1295 0 : if (ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName))
1296 0 : ScUnoConversion::FillApiRange( aRet, pDPObj->GetOutputRangeByType( nType ) );
1297 0 : 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 0 : void ScDataPilotTableObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1342 : {
1343 0 : if ( rHint.ISA(ScDataPilotModifiedHint) &&
1344 0 : static_cast<const ScDataPilotModifiedHint&>(rHint).GetName() == aName )
1345 : {
1346 0 : Refreshed_Impl();
1347 : }
1348 0 : else if ( rHint.ISA( ScUpdateRefHint ) )
1349 : {
1350 0 : ScRange aRange( 0, 0, nTab );
1351 0 : ScRangeList aRanges;
1352 0 : aRanges.Append( aRange );
1353 0 : const ScUpdateRefHint& rRef = static_cast< const ScUpdateRefHint& >( rHint );
1354 0 : if ( aRanges.UpdateReference( rRef.GetMode(), GetDocShell()->GetDocument(), rRef.GetRange(),
1355 0 : rRef.GetDx(), rRef.GetDy(), rRef.GetDz() ) &&
1356 0 : aRanges.size() == 1 )
1357 : {
1358 0 : const ScRange* pRange = aRanges.front();
1359 0 : if ( pRange )
1360 : {
1361 0 : nTab = pRange->aStart.Tab();
1362 : }
1363 0 : }
1364 : }
1365 :
1366 0 : ScDataPilotDescriptorBase::Notify( rBC, rHint );
1367 0 : }
1368 :
1369 0 : void ScDataPilotTableObj::Refreshed_Impl()
1370 : {
1371 0 : lang::EventObject aEvent;
1372 0 : aEvent.Source.set((cppu::OWeakObject*)this);
1373 :
1374 : // the EventObject holds a Ref to this object until after the listener calls
1375 :
1376 0 : ScDocument* pDoc = GetDocShell()->GetDocument();
1377 0 : for ( sal_uInt16 n=0; n<aModifyListeners.size(); n++ )
1378 0 : pDoc->AddUnoListenerCall( aModifyListeners[n], aEvent );
1379 0 : }
1380 :
1381 0 : ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) :
1382 : ScDataPilotDescriptorBase( pDocSh ),
1383 0 : mpDPObject(new ScDPObject(pDocSh ? pDocSh->GetDocument() : NULL) )
1384 : {
1385 0 : ScDPSaveData aSaveData;
1386 : // set defaults like in ScPivotParam constructor
1387 0 : aSaveData.SetColumnGrand( true );
1388 0 : aSaveData.SetRowGrand( true );
1389 0 : aSaveData.SetIgnoreEmptyRows( false );
1390 0 : aSaveData.SetRepeatIfEmpty( false );
1391 0 : mpDPObject->SetSaveData(aSaveData);
1392 0 : ScSheetSourceDesc aSheetDesc(pDocSh ? pDocSh->GetDocument() : NULL);
1393 0 : mpDPObject->SetSheetDesc(aSheetDesc);
1394 0 : mpDPObject->GetSource();
1395 0 : }
1396 :
1397 0 : ScDataPilotDescriptor::~ScDataPilotDescriptor()
1398 : {
1399 0 : delete mpDPObject;
1400 0 : }
1401 :
1402 0 : ScDPObject* ScDataPilotDescriptor::GetDPObject() const
1403 : {
1404 0 : return mpDPObject;
1405 : }
1406 :
1407 0 : void ScDataPilotDescriptor::SetDPObject( ScDPObject* pDPObject )
1408 : {
1409 0 : if (mpDPObject != pDPObject)
1410 : {
1411 0 : delete mpDPObject;
1412 0 : mpDPObject = pDPObject;
1413 : OSL_FAIL("replace DPObject should not happen");
1414 : }
1415 0 : }
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 0 : OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(RuntimeException, std::exception)
1433 : {
1434 0 : SolarMutexGuard aGuard;
1435 0 : 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 0 : ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent ) :
1446 0 : mrParent( rParent )
1447 : {
1448 0 : mrParent.acquire();
1449 0 : }
1450 :
1451 0 : ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1452 : mrParent( rParent ),
1453 0 : maFieldId( rFieldId )
1454 : {
1455 0 : mrParent.acquire();
1456 0 : }
1457 :
1458 0 : ScDataPilotChildObjBase::~ScDataPilotChildObjBase()
1459 : {
1460 0 : mrParent.release();
1461 0 : }
1462 :
1463 0 : ScDPObject* ScDataPilotChildObjBase::GetDPObject() const
1464 : {
1465 0 : return mrParent.GetDPObject();
1466 : }
1467 :
1468 0 : void ScDataPilotChildObjBase::SetDPObject( ScDPObject* pDPObject )
1469 : {
1470 0 : mrParent.SetDPObject( pDPObject );
1471 0 : }
1472 :
1473 0 : ScDPSaveDimension* ScDataPilotChildObjBase::GetDPDimension( ScDPObject** ppDPObject ) const
1474 : {
1475 0 : if( ScDPObject* pDPObj = GetDPObject() )
1476 : {
1477 0 : if( ppDPObject ) *ppDPObject = pDPObj;
1478 0 : if( ScDPSaveData* pSaveData = pDPObj->GetSaveData() )
1479 : {
1480 0 : if( maFieldId.mbDataLayout )
1481 0 : return pSaveData->GetDataLayoutDimension();
1482 :
1483 0 : if( maFieldId.mnFieldIdx == 0 )
1484 0 : 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 0 : sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
1506 : {
1507 0 : sal_Int32 nRet = 0;
1508 0 : Reference<XNameAccess> xMembersNA = GetMembers();
1509 0 : if (xMembersNA.is())
1510 : {
1511 0 : Reference< XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
1512 0 : nRet = xMembersIA->getCount();
1513 : }
1514 0 : return nRet;
1515 : }
1516 :
1517 0 : Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
1518 : {
1519 0 : Reference< XNameAccess > xMembersNA;
1520 0 : if( ScDPObject* pDPObj = GetDPObject() )
1521 0 : pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
1522 0 : return xMembersNA;
1523 : }
1524 :
1525 0 : ScDocShell* ScDataPilotChildObjBase::GetDocShell() const
1526 : {
1527 0 : return mrParent.GetDocShell();
1528 : }
1529 :
1530 0 : ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent ) :
1531 0 : ScDataPilotChildObjBase( rParent )
1532 : {
1533 0 : }
1534 :
1535 0 : ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent, DataPilotFieldOrientation eOrient ) :
1536 : ScDataPilotChildObjBase( rParent ),
1537 0 : maOrient( eOrient )
1538 : {
1539 0 : }
1540 :
1541 0 : ScDataPilotFieldsObj::~ScDataPilotFieldsObj()
1542 : {
1543 0 : }
1544 :
1545 0 : static sal_Int32 lcl_GetFieldCount( const Reference<XDimensionsSupplier>& rSource, const Any& rOrient )
1546 : {
1547 0 : if (!rSource.is())
1548 0 : throw RuntimeException();
1549 :
1550 0 : sal_Int32 nRet = 0;
1551 :
1552 0 : Reference<XNameAccess> xDimsName(rSource->getDimensions());
1553 0 : Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1554 0 : sal_Int32 nIntCount = xIntDims->getCount();
1555 0 : if (rOrient.hasValue())
1556 : {
1557 : // all fields of the specified orientation, including duplicated
1558 0 : Reference<XPropertySet> xDim;
1559 0 : for (sal_Int32 i = 0; i < nIntCount; ++i)
1560 : {
1561 0 : xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1562 0 : if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1563 0 : ++nRet;
1564 0 : }
1565 : }
1566 : else
1567 : {
1568 : // count all non-duplicated fields
1569 :
1570 0 : Reference<XPropertySet> xDim;
1571 0 : for (sal_Int32 i = 0; i < nIntCount; ++i)
1572 : {
1573 0 : xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1574 0 : if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1575 0 : ++nRet;
1576 0 : }
1577 : }
1578 :
1579 0 : return nRet;
1580 : }
1581 :
1582 0 : static sal_Bool lcl_GetFieldDataByIndex( const Reference<XDimensionsSupplier>& rSource,
1583 : const Any& rOrient, SCSIZE nIndex, ScFieldIdentifier& rFieldId )
1584 : {
1585 0 : if (!rSource.is())
1586 0 : throw RuntimeException();
1587 :
1588 0 : sal_Bool bOk = false;
1589 0 : SCSIZE nPos = 0;
1590 0 : sal_Int32 nDimIndex = 0;
1591 :
1592 0 : Reference<XNameAccess> xDimsName(rSource->getDimensions());
1593 0 : Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1594 0 : sal_Int32 nIntCount = xIntDims->getCount();
1595 0 : Reference<XPropertySet> xDim;
1596 0 : if (rOrient.hasValue())
1597 : {
1598 0 : sal_Int32 i = 0;
1599 0 : while (i < nIntCount && !bOk)
1600 : {
1601 0 : xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1602 0 : if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1603 : {
1604 0 : if (nPos == nIndex)
1605 : {
1606 0 : bOk = sal_True;
1607 0 : nDimIndex = i;
1608 : }
1609 : else
1610 0 : ++nPos;
1611 : }
1612 0 : ++i;
1613 : }
1614 : }
1615 : else
1616 : {
1617 0 : sal_Int32 i = 0;
1618 0 : while (i < nIntCount && !bOk)
1619 : {
1620 0 : xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1621 0 : if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1622 : {
1623 0 : if (nPos == nIndex)
1624 : {
1625 0 : bOk = sal_True;
1626 0 : nDimIndex = i;
1627 : }
1628 : else
1629 0 : ++nPos;
1630 : }
1631 0 : ++i;
1632 : }
1633 : }
1634 :
1635 0 : if ( bOk )
1636 : {
1637 0 : xDim.set( xIntDims->getByIndex(nDimIndex), UNO_QUERY );
1638 0 : Reference<XNamed> xDimName( xDim, UNO_QUERY );
1639 0 : if ( xDimName.is() )
1640 : {
1641 0 : OUString sOriginalName( lcl_GetOriginalName( xDimName ) );
1642 0 : rFieldId.maFieldName = sOriginalName;
1643 : rFieldId.mbDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDim,
1644 0 : OUString(SC_UNO_DP_ISDATALAYOUT) );
1645 :
1646 0 : sal_Int32 nRepeat = 0;
1647 0 : 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 0 : rFieldId.mnFieldIdx = nRepeat;
1661 : }
1662 : else
1663 0 : bOk = false;
1664 : }
1665 :
1666 0 : return bOk;
1667 : }
1668 :
1669 0 : 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 0 : rFieldId.maFieldName = rFieldName;
1674 0 : rFieldId.mnFieldIdx = 0;
1675 0 : rFieldId.mbDataLayout = rFieldName == SC_DATALAYOUT_NAME;
1676 :
1677 0 : pDPObj->GetSource(); // IsDimNameInUse doesn't update source data
1678 :
1679 : // check if the named field exists (not for data layout)
1680 0 : return rFieldId.mbDataLayout || pDPObj->IsDimNameInUse( rFieldName );
1681 : }
1682 :
1683 : // XDataPilotFields
1684 :
1685 0 : ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
1686 : {
1687 : // TODO
1688 0 : if (ScDPObject* pObj = GetDPObject())
1689 : {
1690 0 : ScFieldIdentifier aFieldId;
1691 0 : if (lcl_GetFieldDataByIndex( pObj->GetSource(), maOrient, nIndex, aFieldId ))
1692 0 : return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1693 : }
1694 0 : return 0;
1695 : }
1696 :
1697 0 : ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const OUString& aName) const
1698 : {
1699 0 : if (ScDPObject* pDPObj = GetDPObject())
1700 : {
1701 0 : ScFieldIdentifier aFieldId;
1702 0 : if (lcl_GetFieldDataByName( pDPObj, aName, aFieldId ))
1703 0 : return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1704 : }
1705 0 : return 0;
1706 : }
1707 :
1708 : // XEnumerationAccess
1709 :
1710 0 : Reference<XEnumeration> SAL_CALL ScDataPilotFieldsObj::createEnumeration()
1711 : throw(RuntimeException, std::exception)
1712 : {
1713 0 : SolarMutexGuard aGuard;
1714 0 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotFieldsEnumeration"));
1715 : }
1716 :
1717 : // XIndexAccess
1718 :
1719 0 : sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(RuntimeException, std::exception)
1720 : {
1721 0 : SolarMutexGuard aGuard;
1722 : // TODO
1723 0 : ScDPObject* pDPObj = GetDPObject();
1724 0 : return pDPObj ? lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) : 0;
1725 : }
1726 :
1727 0 : Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex )
1728 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
1729 : {
1730 0 : SolarMutexGuard aGuard;
1731 0 : Reference< XPropertySet > xField( GetObjectByIndex_Impl( nIndex ) );
1732 0 : if (!xField.is())
1733 0 : throw IndexOutOfBoundsException();
1734 0 : return Any( xField );
1735 : }
1736 :
1737 0 : uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(RuntimeException, std::exception)
1738 : {
1739 0 : SolarMutexGuard aGuard;
1740 0 : return getCppuType((Reference<XPropertySet>*)0);
1741 : }
1742 :
1743 0 : sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(RuntimeException, std::exception)
1744 : {
1745 0 : SolarMutexGuard aGuard;
1746 0 : return ( getCount() != 0 );
1747 : }
1748 :
1749 0 : Any SAL_CALL ScDataPilotFieldsObj::getByName( const OUString& aName )
1750 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
1751 : {
1752 0 : SolarMutexGuard aGuard;
1753 0 : Reference<XPropertySet> xField(GetObjectByName_Impl(aName));
1754 0 : if (!xField.is())
1755 0 : throw NoSuchElementException();
1756 0 : return Any( xField );
1757 : }
1758 :
1759 0 : Sequence<OUString> SAL_CALL ScDataPilotFieldsObj::getElementNames()
1760 : throw(RuntimeException, std::exception)
1761 : {
1762 0 : SolarMutexGuard aGuard;
1763 : // TODO
1764 0 : if (ScDPObject* pDPObj = GetDPObject())
1765 : {
1766 0 : Sequence< OUString > aSeq( lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) );
1767 0 : OUString* pAry = aSeq.getArray();
1768 :
1769 0 : const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pDPObj->GetSaveData()->GetDimensions();
1770 0 : boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
1771 0 : 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 0 : return aSeq;
1780 : }
1781 0 : return Sequence<OUString>();
1782 : }
1783 :
1784 0 : sal_Bool SAL_CALL ScDataPilotFieldsObj::hasByName( const OUString& aName )
1785 : throw(RuntimeException, std::exception)
1786 : {
1787 0 : SolarMutexGuard aGuard;
1788 :
1789 0 : 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 0 : ScDataPilotFieldObj::ScDataPilotFieldObj( ScDataPilotDescriptorBase& rParent,
1800 : const ScFieldIdentifier& rFieldId, const Any& rOrient ) :
1801 : ScDataPilotChildObjBase( rParent, rFieldId ),
1802 : maPropSet( lcl_GetDataPilotFieldMap() ),
1803 0 : maOrient( rOrient )
1804 : {
1805 0 : }
1806 :
1807 0 : ScDataPilotFieldObj::~ScDataPilotFieldObj()
1808 : {
1809 0 : }
1810 :
1811 : // XNamed
1812 :
1813 0 : OUString SAL_CALL ScDataPilotFieldObj::getName()
1814 : throw (RuntimeException, std::exception)
1815 : {
1816 0 : SolarMutexGuard aGuard;
1817 0 : OUString aName;
1818 0 : if( ScDPSaveDimension* pDim = GetDPDimension() )
1819 : {
1820 0 : if( pDim->IsDataLayout() )
1821 0 : aName = OUString( SC_DATALAYOUT_NAME );
1822 : else
1823 : {
1824 0 : const OUString* pLayoutName = pDim->GetLayoutName();
1825 0 : if (pLayoutName)
1826 0 : aName = *pLayoutName;
1827 : else
1828 0 : aName = pDim->GetName();
1829 : } }
1830 0 : return aName;
1831 : }
1832 :
1833 0 : void SAL_CALL ScDataPilotFieldObj::setName(const OUString& rName)
1834 : throw (RuntimeException, std::exception)
1835 : {
1836 0 : SolarMutexGuard aGuard;
1837 0 : ScDPObject* pDPObj = 0;
1838 0 : ScDPSaveDimension* pDim = GetDPDimension( &pDPObj );
1839 0 : if( pDim && !pDim->IsDataLayout() )
1840 : {
1841 0 : pDim->SetLayoutName(rName);
1842 0 : SetDPObject( pDPObj );
1843 0 : }
1844 0 : }
1845 :
1846 : // XPropertySet
1847 :
1848 0 : Reference<XPropertySetInfo> SAL_CALL ScDataPilotFieldObj::getPropertySetInfo()
1849 : throw(RuntimeException, std::exception)
1850 : {
1851 0 : SolarMutexGuard aGuard;
1852 : static Reference<XPropertySetInfo> aRef(
1853 0 : new SfxItemPropertySetInfo( maPropSet.getPropertyMap() ));
1854 0 : return aRef;
1855 : }
1856 :
1857 0 : void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
1858 : throw (UnknownPropertyException, PropertyVetoException,
1859 : IllegalArgumentException, WrappedTargetException,
1860 : RuntimeException, std::exception)
1861 : {
1862 0 : SolarMutexGuard aGuard;
1863 0 : OUString aNameString(aPropertyName);
1864 0 : if ( aNameString.equalsAscii( SC_UNONAME_FUNCTION ) )
1865 : {
1866 : // #i109350# use GetEnumFromAny because it also allows sal_Int32
1867 : GeneralFunction eFunction = (GeneralFunction)
1868 0 : ScUnoHelpFunctions::GetEnumFromAny( aValue );
1869 0 : setFunction( eFunction );
1870 : }
1871 0 : else if ( aNameString.equalsAscii( SC_UNONAME_SUBTOTALS ) )
1872 : {
1873 0 : Sequence< GeneralFunction > aSubtotals;
1874 0 : if( aValue >>= aSubtotals )
1875 0 : setSubtotals( aSubtotals );
1876 : }
1877 0 : else if ( aNameString.equalsAscii( SC_UNONAME_ORIENT ) )
1878 : {
1879 : //! test for correct enum type?
1880 : DataPilotFieldOrientation eOrient = (DataPilotFieldOrientation)
1881 0 : ScUnoHelpFunctions::GetEnumFromAny( aValue );
1882 0 : setOrientation( eOrient );
1883 : }
1884 0 : else if ( aNameString.equalsAscii( SC_UNONAME_SELPAGE ) )
1885 : {
1886 0 : OUString sCurrentPage;
1887 0 : if (aValue >>= sCurrentPage)
1888 0 : setCurrentPage(sCurrentPage);
1889 : }
1890 0 : else if ( aNameString.equalsAscii( SC_UNONAME_USESELPAGE ) )
1891 : {
1892 0 : setUseCurrentPage(cppu::any2bool(aValue));
1893 : }
1894 0 : else if ( aNameString.equalsAscii( SC_UNONAME_HASAUTOSHOW ) )
1895 : {
1896 0 : if (!cppu::any2bool(aValue))
1897 0 : setAutoShowInfo(NULL);
1898 : }
1899 0 : else if ( aNameString.equalsAscii( SC_UNONAME_AUTOSHOW ) )
1900 : {
1901 0 : DataPilotFieldAutoShowInfo aInfo;
1902 0 : if (aValue >>= aInfo)
1903 0 : setAutoShowInfo(&aInfo);
1904 : }
1905 0 : else if ( aNameString.equalsAscii( SC_UNONAME_HASLAYOUTINFO ) )
1906 : {
1907 0 : if (!cppu::any2bool(aValue))
1908 0 : setLayoutInfo(NULL);
1909 : }
1910 0 : else if ( aNameString.equalsAscii( SC_UNONAME_LAYOUTINFO ) )
1911 : {
1912 0 : DataPilotFieldLayoutInfo aInfo;
1913 0 : if (aValue >>= aInfo)
1914 0 : setLayoutInfo(&aInfo);
1915 : }
1916 0 : else if ( aNameString.equalsAscii( SC_UNONAME_HASREFERENCE ) )
1917 : {
1918 0 : if (!cppu::any2bool(aValue))
1919 0 : setReference(NULL);
1920 : }
1921 0 : else if ( aNameString.equalsAscii( SC_UNONAME_REFERENCE ) )
1922 : {
1923 0 : DataPilotFieldReference aRef;
1924 0 : if (aValue >>= aRef)
1925 0 : setReference(&aRef);
1926 : }
1927 0 : else if ( aNameString.equalsAscii( SC_UNONAME_HASSORTINFO ) )
1928 : {
1929 0 : if (!cppu::any2bool(aValue))
1930 0 : setSortInfo(NULL);
1931 : }
1932 0 : else if ( aNameString.equalsAscii( SC_UNONAME_SORTINFO ) )
1933 : {
1934 0 : DataPilotFieldSortInfo aInfo;
1935 0 : if (aValue >>= aInfo)
1936 0 : setSortInfo(&aInfo);
1937 : }
1938 0 : else if ( aNameString.equalsAscii( SC_UNONAME_ISGROUP ) )
1939 : {
1940 0 : if (!cppu::any2bool(aValue))
1941 0 : setGroupInfo(NULL);
1942 : }
1943 0 : else if ( aNameString.equalsAscii( SC_UNONAME_GROUPINFO ) )
1944 : {
1945 0 : DataPilotFieldGroupInfo aInfo;
1946 0 : if (aValue >>= aInfo)
1947 0 : setGroupInfo(&aInfo);
1948 : }
1949 0 : else if ( aNameString.equalsAscii( SC_UNONAME_SHOWEMPTY ) )
1950 : {
1951 0 : setShowEmpty(cppu::any2bool(aValue));
1952 0 : }
1953 0 : }
1954 :
1955 0 : Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName )
1956 : throw (UnknownPropertyException, WrappedTargetException,
1957 : RuntimeException, std::exception)
1958 : {
1959 0 : SolarMutexGuard aGuard;
1960 0 : OUString aNameString(aPropertyName);
1961 0 : Any aRet;
1962 :
1963 0 : if ( aNameString.equalsAscii( SC_UNONAME_FUNCTION ) )
1964 0 : aRet <<= getFunction();
1965 0 : else if ( aNameString.equalsAscii( SC_UNONAME_SUBTOTALS ) )
1966 0 : aRet <<= getSubtotals();
1967 0 : else if ( aNameString.equalsAscii( SC_UNONAME_ORIENT ) )
1968 0 : aRet <<= getOrientation();
1969 0 : else if ( aNameString.equalsAscii( SC_UNONAME_SELPAGE ) )
1970 0 : aRet <<= getCurrentPage();
1971 0 : else if ( aNameString.equalsAscii( SC_UNONAME_USESELPAGE ) )
1972 0 : aRet <<= getUseCurrentPage();
1973 0 : else if ( aNameString.equalsAscii( SC_UNONAME_HASAUTOSHOW ) )
1974 0 : aRet <<= (getAutoShowInfo() != NULL);
1975 0 : else if ( aNameString.equalsAscii( SC_UNONAME_AUTOSHOW ) )
1976 : {
1977 0 : const DataPilotFieldAutoShowInfo* pInfo = getAutoShowInfo();
1978 0 : if (pInfo)
1979 0 : aRet <<= DataPilotFieldAutoShowInfo(*pInfo);
1980 : }
1981 0 : else if ( aNameString.equalsAscii( SC_UNONAME_HASLAYOUTINFO ) )
1982 0 : aRet <<= (getLayoutInfo() != NULL);
1983 0 : else if ( aNameString.equalsAscii( SC_UNONAME_LAYOUTINFO ) )
1984 : {
1985 0 : const DataPilotFieldLayoutInfo* pInfo = getLayoutInfo();
1986 0 : if (pInfo)
1987 0 : aRet <<= DataPilotFieldLayoutInfo(*pInfo);
1988 : }
1989 0 : else if ( aNameString.equalsAscii( SC_UNONAME_HASREFERENCE ) )
1990 0 : aRet <<= (getReference() != NULL);
1991 0 : else if ( aNameString.equalsAscii( SC_UNONAME_REFERENCE ) )
1992 : {
1993 0 : const DataPilotFieldReference* pRef = getReference();
1994 0 : if (pRef)
1995 0 : aRet <<= DataPilotFieldReference(*pRef);
1996 : }
1997 0 : else if ( aNameString.equalsAscii( SC_UNONAME_HASSORTINFO ) )
1998 0 : aRet <<= (getSortInfo() != NULL);
1999 0 : else if ( aNameString.equalsAscii( SC_UNONAME_SORTINFO ) )
2000 : {
2001 0 : const DataPilotFieldSortInfo* pInfo = getSortInfo();
2002 0 : if (pInfo)
2003 0 : aRet <<= DataPilotFieldSortInfo(*pInfo);
2004 : }
2005 0 : else if ( aNameString.equalsAscii( SC_UNONAME_ISGROUP ) )
2006 0 : aRet <<= (hasGroupInfo());
2007 0 : else if ( aNameString.equalsAscii( SC_UNONAME_GROUPINFO ) )
2008 : {
2009 0 : aRet <<= getGroupInfo();
2010 : }
2011 0 : else if ( aNameString.equalsAscii( SC_UNONAME_SHOWEMPTY ) )
2012 0 : aRet <<= getShowEmpty();
2013 :
2014 0 : return aRet;
2015 : }
2016 :
2017 : // XDatePilotField
2018 :
2019 0 : Reference<XIndexAccess> SAL_CALL ScDataPilotFieldObj::getItems()
2020 : throw (RuntimeException, std::exception)
2021 : {
2022 0 : SolarMutexGuard aGuard;
2023 0 : if (!mxItems.is())
2024 0 : mxItems.set( new ScDataPilotItemsObj( mrParent, maFieldId ) );
2025 0 : return mxItems;
2026 : }
2027 :
2028 0 : SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj )
2029 :
2030 0 : DataPilotFieldOrientation ScDataPilotFieldObj::getOrientation() const
2031 : {
2032 0 : SolarMutexGuard aGuard;
2033 0 : ScDPSaveDimension* pDim = GetDPDimension();
2034 0 : return pDim ? static_cast< DataPilotFieldOrientation >( pDim->GetOrientation() ) : DataPilotFieldOrientation_HIDDEN;
2035 : }
2036 :
2037 0 : void ScDataPilotFieldObj::setOrientation(DataPilotFieldOrientation eNew)
2038 : {
2039 0 : SolarMutexGuard aGuard;
2040 0 : if (maOrient.hasValue() && (eNew == maOrient.get< DataPilotFieldOrientation >()))
2041 0 : return;
2042 :
2043 0 : ScDPObject* pDPObj = 0;
2044 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2045 : {
2046 0 : 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 0 : if ( !maOrient.hasValue() && !maFieldId.mbDataLayout &&
2052 0 : (pDim->GetOrientation() != DataPilotFieldOrientation_HIDDEN) &&
2053 0 : (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 0 : 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 0 : pSaveData->SetPosition( pDim, pSaveData->GetDimensions().size() );
2085 :
2086 0 : SetDPObject( pDPObj );
2087 :
2088 0 : maOrient <<= eNew; // modifying the same object's orientation again doesn't create another duplicate
2089 0 : }
2090 : }
2091 :
2092 0 : GeneralFunction ScDataPilotFieldObj::getFunction() const
2093 : {
2094 0 : SolarMutexGuard aGuard;
2095 0 : GeneralFunction eRet = GeneralFunction_NONE;
2096 0 : if( ScDPSaveDimension* pDim = GetDPDimension() )
2097 : {
2098 0 : if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2099 : {
2100 : // for non-data fields, property Function is the subtotals
2101 0 : long nSubCount = pDim->GetSubTotalsCount();
2102 0 : if ( nSubCount > 0 )
2103 0 : eRet = (GeneralFunction)pDim->GetSubTotalFunc(0); // always use the first one
2104 : // else keep NONE
2105 : }
2106 : else
2107 0 : eRet = (GeneralFunction)pDim->GetFunction();
2108 : }
2109 0 : return eRet;
2110 : }
2111 :
2112 0 : void ScDataPilotFieldObj::setFunction(GeneralFunction eNewFunc)
2113 : {
2114 0 : SolarMutexGuard aGuard;
2115 0 : ScDPObject* pDPObj = 0;
2116 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2117 : {
2118 0 : if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2119 : {
2120 : // for non-data fields, property Function is the subtotals
2121 0 : if ( eNewFunc == GeneralFunction_NONE )
2122 0 : pDim->SetSubTotals( 0, NULL );
2123 : else
2124 : {
2125 0 : sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( eNewFunc );
2126 0 : pDim->SetSubTotals( 1, &nFunc );
2127 : }
2128 : }
2129 : else
2130 0 : pDim->SetFunction( sal::static_int_cast<sal_uInt16>( eNewFunc ) );
2131 0 : SetDPObject( pDPObj );
2132 0 : }
2133 0 : }
2134 :
2135 0 : Sequence< GeneralFunction > ScDataPilotFieldObj::getSubtotals() const
2136 : {
2137 0 : SolarMutexGuard aGuard;
2138 0 : Sequence< GeneralFunction > aRet;
2139 0 : if( ScDPSaveDimension* pDim = GetDPDimension() )
2140 : {
2141 0 : if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2142 : {
2143 : // for non-data fields, property Functions is the sequence of subtotals
2144 0 : sal_Int32 nCount = static_cast< sal_Int32 >( pDim->GetSubTotalsCount() );
2145 0 : if ( nCount > 0 )
2146 : {
2147 0 : aRet.realloc( nCount );
2148 0 : for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2149 0 : aRet[ nIdx ] = (GeneralFunction)pDim->GetSubTotalFunc( nIdx );
2150 : }
2151 : }
2152 : }
2153 0 : return aRet;
2154 : }
2155 :
2156 0 : void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubtotals )
2157 : {
2158 0 : SolarMutexGuard aGuard;
2159 0 : ScDPObject* pDPObj = 0;
2160 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2161 : {
2162 0 : if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2163 : {
2164 0 : sal_Int32 nCount = rSubtotals.getLength();
2165 0 : if( nCount == 1 )
2166 : {
2167 : // count 1: all values are allowed (including NONE and AUTO)
2168 0 : if( rSubtotals[ 0 ] == GeneralFunction_NONE )
2169 0 : pDim->SetSubTotals( 0, NULL );
2170 : else
2171 : {
2172 0 : sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( rSubtotals[ 0 ] );
2173 0 : 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 0 : SetDPObject( pDPObj );
2199 0 : }
2200 0 : }
2201 :
2202 0 : OUString ScDataPilotFieldObj::getCurrentPage() const
2203 : {
2204 0 : return OUString();
2205 : }
2206 :
2207 0 : void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage )
2208 : {
2209 0 : SolarMutexGuard aGuard;
2210 0 : ScDPObject* pDPObj = 0;
2211 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2212 : {
2213 0 : pDim->SetCurrentPage( &rPage );
2214 0 : SetDPObject( pDPObj );
2215 0 : }
2216 0 : }
2217 :
2218 0 : bool ScDataPilotFieldObj::getUseCurrentPage() const
2219 : {
2220 0 : return false;
2221 : }
2222 :
2223 0 : void ScDataPilotFieldObj::setUseCurrentPage( bool bUse )
2224 : {
2225 0 : SolarMutexGuard aGuard;
2226 0 : ScDPObject* pDPObj = 0;
2227 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2228 : {
2229 0 : 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 0 : const OUString aPage;
2234 0 : pDim->SetCurrentPage( &aPage );
2235 : }
2236 : else
2237 0 : pDim->SetCurrentPage( 0 );
2238 0 : SetDPObject( pDPObj );
2239 0 : }
2240 0 : }
2241 :
2242 0 : const DataPilotFieldAutoShowInfo* ScDataPilotFieldObj::getAutoShowInfo()
2243 : {
2244 0 : SolarMutexGuard aGuard;
2245 0 : ScDPSaveDimension* pDim = GetDPDimension();
2246 0 : return pDim ? pDim->GetAutoShowInfo() : 0;
2247 : }
2248 :
2249 0 : void ScDataPilotFieldObj::setAutoShowInfo( const DataPilotFieldAutoShowInfo* pInfo )
2250 : {
2251 0 : SolarMutexGuard aGuard;
2252 0 : ScDPObject* pDPObj = 0;
2253 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2254 : {
2255 0 : pDim->SetAutoShowInfo( pInfo );
2256 0 : SetDPObject( pDPObj );
2257 0 : }
2258 0 : }
2259 :
2260 0 : const DataPilotFieldLayoutInfo* ScDataPilotFieldObj::getLayoutInfo()
2261 : {
2262 0 : SolarMutexGuard aGuard;
2263 0 : ScDPSaveDimension* pDim = GetDPDimension();
2264 0 : return pDim ? pDim->GetLayoutInfo() : 0;
2265 : }
2266 :
2267 0 : void ScDataPilotFieldObj::setLayoutInfo( const DataPilotFieldLayoutInfo* pInfo )
2268 : {
2269 0 : SolarMutexGuard aGuard;
2270 0 : ScDPObject* pDPObj = 0;
2271 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2272 : {
2273 0 : pDim->SetLayoutInfo( pInfo );
2274 0 : SetDPObject( pDPObj );
2275 0 : }
2276 0 : }
2277 :
2278 0 : const DataPilotFieldReference* ScDataPilotFieldObj::getReference()
2279 : {
2280 0 : SolarMutexGuard aGuard;
2281 0 : ScDPSaveDimension* pDim = GetDPDimension();
2282 0 : return pDim ? pDim->GetReferenceValue() : 0;
2283 : }
2284 :
2285 0 : void ScDataPilotFieldObj::setReference( const DataPilotFieldReference* pInfo )
2286 : {
2287 0 : SolarMutexGuard aGuard;
2288 0 : ScDPObject* pDPObj = 0;
2289 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2290 : {
2291 0 : pDim->SetReferenceValue( pInfo );
2292 0 : SetDPObject( pDPObj );
2293 0 : }
2294 0 : }
2295 :
2296 0 : const DataPilotFieldSortInfo* ScDataPilotFieldObj::getSortInfo()
2297 : {
2298 0 : SolarMutexGuard aGuard;
2299 0 : ScDPSaveDimension* pDim = GetDPDimension();
2300 0 : return pDim ? pDim->GetSortInfo() : 0;
2301 : }
2302 :
2303 0 : void ScDataPilotFieldObj::setSortInfo( const DataPilotFieldSortInfo* pInfo )
2304 : {
2305 0 : SolarMutexGuard aGuard;
2306 0 : ScDPObject* pDPObj = 0;
2307 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2308 : {
2309 0 : pDim->SetSortInfo( pInfo );
2310 0 : SetDPObject( pDPObj );
2311 0 : }
2312 0 : }
2313 :
2314 0 : bool ScDataPilotFieldObj::getShowEmpty() const
2315 : {
2316 0 : SolarMutexGuard aGuard;
2317 0 : ScDPSaveDimension* pDim = GetDPDimension();
2318 0 : return pDim && pDim->GetShowEmpty();
2319 : }
2320 :
2321 0 : void ScDataPilotFieldObj::setShowEmpty( bool bShow )
2322 : {
2323 0 : SolarMutexGuard aGuard;
2324 0 : ScDPObject* pDPObj = 0;
2325 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2326 : {
2327 0 : pDim->SetShowEmpty( bShow );
2328 0 : SetDPObject( pDPObj );
2329 0 : }
2330 0 : }
2331 :
2332 0 : bool ScDataPilotFieldObj::hasGroupInfo()
2333 : {
2334 0 : SolarMutexGuard aGuard;
2335 0 : ScDPObject* pDPObj = 0;
2336 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2337 0 : if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2338 0 : return pDimData->GetNamedGroupDim( pDim->GetName() ) || pDimData->GetNumGroupDim( pDim->GetName() );
2339 0 : return false;
2340 : }
2341 :
2342 0 : DataPilotFieldGroupInfo ScDataPilotFieldObj::getGroupInfo()
2343 : {
2344 0 : SolarMutexGuard aGuard;
2345 0 : DataPilotFieldGroupInfo aInfo;
2346 0 : ScDPObject* pDPObj = 0;
2347 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2348 : {
2349 0 : if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2350 : {
2351 0 : if( const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( pDim->GetName() ) )
2352 : {
2353 : // grouped by ...
2354 0 : aInfo.GroupBy = pGroupDim->GetDatePart();
2355 :
2356 : // find source field
2357 : try
2358 : {
2359 0 : Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2360 0 : aInfo.SourceField.set( xFields->getByName( pGroupDim->GetSourceDimName() ), UNO_QUERY );
2361 : }
2362 0 : catch( Exception& )
2363 : {
2364 : }
2365 :
2366 0 : ScDataPilotConversion::FillGroupInfo( aInfo, pGroupDim->GetDateInfo() );
2367 0 : if( pGroupDim->GetDatePart() == 0 )
2368 : {
2369 : // fill vector of group and group member information
2370 0 : ScFieldGroups aGroups;
2371 0 : for( sal_Int32 nIdx = 0, nCount = pGroupDim->GetGroupCount(); nIdx < nCount; ++nIdx )
2372 : {
2373 0 : if( const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( nIdx ) )
2374 : {
2375 0 : ScFieldGroup aGroup;
2376 0 : aGroup.maName = pGroup->GetGroupName();
2377 0 : for( sal_Int32 nMemIdx = 0, nMemCount = pGroup->GetElementCount(); nMemIdx < nMemCount; ++nMemIdx )
2378 0 : if (const OUString* pMem = pGroup->GetElementByIndex(nMemIdx))
2379 0 : aGroup.maMembers.push_back( *pMem );
2380 0 : aGroups.push_back( aGroup );
2381 : }
2382 : }
2383 0 : 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 0 : 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 0 : Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( const Sequence< OUString >& rItems )
2512 : throw (RuntimeException, IllegalArgumentException,
2513 : std::exception)
2514 : {
2515 0 : SolarMutexGuard aGuard;
2516 :
2517 0 : Reference< XDataPilotField > xRet;
2518 0 : OUString sNewDim;
2519 :
2520 0 : if( !rItems.hasElements() )
2521 0 : throw IllegalArgumentException();
2522 :
2523 0 : ScDPObject* pDPObj = 0;
2524 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2525 : {
2526 0 : OUString aDimName = pDim->GetName();
2527 :
2528 0 : ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2529 0 : ScDPDimensionSaveData* pDimData = aSaveData.GetDimensionData(); // created if not there
2530 :
2531 : // find original base
2532 0 : OUString aBaseDimName( aDimName );
2533 0 : const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
2534 0 : 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 0 : ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
2543 :
2544 : // remove the selected items from their groups
2545 : // (empty groups are removed, too)
2546 0 : sal_Int32 nEntryCount = rItems.getLength();
2547 : sal_Int32 nEntry;
2548 0 : 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 0 : ScDPSaveGroupDimension* pNewGroupDim = 0;
2569 0 : if ( !pGroupDimension )
2570 : {
2571 : // create a new group dimension
2572 0 : sNewDim = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
2573 0 : pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, sNewDim );
2574 :
2575 0 : pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
2576 :
2577 0 : 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 0 : OUString aGroupDimName = pGroupDimension->GetGroupDimName();
2602 :
2603 : //! localized prefix string
2604 0 : OUString aGroupName = pGroupDimension->CreateGroupName( OUString( "Group" ) );
2605 0 : ScDPSaveGroupItem aGroup( aGroupName );
2606 0 : Reference< XNameAccess > xMembers = GetMembers();
2607 0 : if (!xMembers.is())
2608 : {
2609 0 : delete pNewGroupDim;
2610 0 : throw RuntimeException();
2611 : }
2612 :
2613 0 : for (nEntry=0; nEntry<nEntryCount; nEntry++)
2614 : {
2615 0 : OUString aEntryName(rItems[nEntry]);
2616 :
2617 0 : if (!xMembers->hasByName(aEntryName))
2618 : {
2619 0 : delete pNewGroupDim;
2620 0 : throw IllegalArgumentException();
2621 : }
2622 :
2623 0 : 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 0 : aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
2634 0 : }
2635 :
2636 0 : pGroupDimension->AddGroupItem( aGroup );
2637 :
2638 0 : if ( pNewGroupDim )
2639 : {
2640 0 : pDimData->AddGroupDimension( *pNewGroupDim );
2641 0 : delete pNewGroupDim; // AddGroupDimension copies the object
2642 : // don't access pGroupDimension after here
2643 : }
2644 0 : pGroupDimension = pNewGroupDim = NULL;
2645 :
2646 : // set orientation
2647 0 : ScDPSaveDimension* pSaveDimension = aSaveData.GetDimensionByName( aGroupDimName );
2648 0 : if ( pSaveDimension->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2649 : {
2650 0 : ScDPSaveDimension* pOldDimension = aSaveData.GetDimensionByName( aDimName );
2651 0 : pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
2652 0 : long nPosition = 0; //! before (immediate) base
2653 0 : aSaveData.SetPosition( pSaveDimension, nPosition );
2654 : }
2655 :
2656 : // apply changes
2657 0 : pDPObj->SetSaveData( aSaveData );
2658 0 : ScDBDocFunc(*GetDocShell()).RefreshPivotTableGroups(pDPObj);
2659 : }
2660 :
2661 : // if new grouping field has been created (on first group), return it
2662 0 : if( !sNewDim.isEmpty() )
2663 : {
2664 0 : Reference< XNameAccess > xFields(mrParent.getDataPilotFields(), UNO_QUERY);
2665 0 : if (xFields.is())
2666 : {
2667 : try
2668 : {
2669 0 : 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 0 : }
2678 : }
2679 0 : 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 0 : ScDataPilotFieldGroupsObj::ScDataPilotFieldGroupsObj( const ScFieldGroups& rGroups ) :
2839 0 : maGroups( rGroups )
2840 : {
2841 0 : }
2842 :
2843 0 : ScDataPilotFieldGroupsObj::~ScDataPilotFieldGroupsObj()
2844 : {
2845 0 : }
2846 :
2847 : // XNameAccess
2848 :
2849 0 : Any SAL_CALL ScDataPilotFieldGroupsObj::getByName( const OUString& rName )
2850 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2851 : {
2852 0 : SolarMutexGuard aGuard;
2853 0 : if( implFindByName( rName ) == maGroups.end() )
2854 0 : throw NoSuchElementException();
2855 0 : return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, rName ) ) );
2856 : }
2857 :
2858 0 : Sequence< OUString > SAL_CALL ScDataPilotFieldGroupsObj::getElementNames() throw(RuntimeException, std::exception)
2859 : {
2860 0 : SolarMutexGuard aGuard;
2861 0 : Sequence< OUString > aSeq;
2862 0 : if( !maGroups.empty() )
2863 : {
2864 0 : aSeq.realloc( static_cast< sal_Int32 >( maGroups.size() ) );
2865 0 : OUString* pName = aSeq.getArray();
2866 0 : for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt, ++pName )
2867 0 : *pName = aIt->maName;
2868 : }
2869 0 : return aSeq;
2870 : }
2871 :
2872 0 : sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasByName( const OUString& rName ) throw(RuntimeException, std::exception)
2873 : {
2874 0 : SolarMutexGuard aGuard;
2875 0 : 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 0 : sal_Int32 SAL_CALL ScDataPilotFieldGroupsObj::getCount() throw(RuntimeException, std::exception)
2945 : {
2946 0 : SolarMutexGuard aGuard;
2947 0 : return static_cast< sal_Int32 >( maGroups.size() );
2948 : }
2949 :
2950 0 : Any SAL_CALL ScDataPilotFieldGroupsObj::getByIndex( sal_Int32 nIndex )
2951 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
2952 : {
2953 0 : SolarMutexGuard aGuard;
2954 0 : if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( maGroups.size() )))
2955 0 : throw IndexOutOfBoundsException();
2956 0 : return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, maGroups[ nIndex ].maName ) ) );
2957 : }
2958 :
2959 : // XEnumerationAccess
2960 :
2961 0 : Reference<XEnumeration> SAL_CALL ScDataPilotFieldGroupsObj::createEnumeration() throw(RuntimeException, std::exception)
2962 : {
2963 0 : SolarMutexGuard aGuard;
2964 0 : return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupsEnumeration" ) );
2965 : }
2966 :
2967 : // XElementAccess
2968 :
2969 0 : uno::Type SAL_CALL ScDataPilotFieldGroupsObj::getElementType() throw(RuntimeException, std::exception)
2970 : {
2971 0 : SolarMutexGuard aGuard;
2972 0 : return getCppuType( (Reference< XNameAccess >*)0 );
2973 : }
2974 :
2975 0 : sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasElements() throw(RuntimeException, std::exception)
2976 : {
2977 0 : SolarMutexGuard aGuard;
2978 0 : return !maGroups.empty();
2979 : }
2980 :
2981 : // implementation
2982 :
2983 0 : ScFieldGroup& ScDataPilotFieldGroupsObj::getFieldGroup( const OUString& rName ) throw(RuntimeException)
2984 : {
2985 0 : SolarMutexGuard aGuard;
2986 0 : ScFieldGroups::iterator aIt = implFindByName( rName );
2987 0 : if( aIt == maGroups.end() )
2988 0 : throw RuntimeException();
2989 0 : return *aIt;
2990 : }
2991 :
2992 0 : void ScDataPilotFieldGroupsObj::renameFieldGroup( const OUString& rOldName, const OUString& rNewName ) throw(RuntimeException)
2993 : {
2994 0 : SolarMutexGuard aGuard;
2995 0 : ScFieldGroups::iterator aOldIt = implFindByName( rOldName );
2996 0 : ScFieldGroups::iterator aNewIt = implFindByName( rNewName );
2997 : // new name must not exist yet
2998 0 : if( (aOldIt == maGroups.end()) || ((aNewIt != maGroups.end()) && (aNewIt != aOldIt)) )
2999 0 : throw RuntimeException();
3000 0 : aOldIt->maName = rNewName;
3001 0 : }
3002 :
3003 0 : ScFieldGroups::iterator ScDataPilotFieldGroupsObj::implFindByName( const OUString& rName )
3004 : {
3005 0 : for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt )
3006 0 : if( aIt->maName == rName )
3007 0 : return aIt;
3008 0 : return maGroups.end();
3009 : }
3010 :
3011 : namespace {
3012 :
3013 0 : OUString lclExtractMember( const Any& rElement )
3014 : {
3015 0 : if( rElement.has< OUString >() )
3016 0 : 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 0 : ScDataPilotFieldGroupObj::ScDataPilotFieldGroupObj( ScDataPilotFieldGroupsObj& rParent, const OUString& rGroupName ) :
3028 : mrParent( rParent ),
3029 0 : maGroupName( rGroupName )
3030 : {
3031 0 : mrParent.acquire();
3032 0 : }
3033 :
3034 0 : ScDataPilotFieldGroupObj::~ScDataPilotFieldGroupObj()
3035 : {
3036 0 : mrParent.release();
3037 0 : }
3038 :
3039 : // XNameAccess
3040 :
3041 0 : Any SAL_CALL ScDataPilotFieldGroupObj::getByName( const OUString& rName )
3042 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3043 : {
3044 0 : SolarMutexGuard aGuard;
3045 0 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3046 0 : ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3047 0 : if( aIt == rMembers.end() )
3048 0 : throw NoSuchElementException();
3049 0 : 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 0 : void SAL_CALL ScDataPilotFieldGroupObj::replaceByName( const OUString& rName, const Any& rElement )
3068 : throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3069 : {
3070 0 : SolarMutexGuard aGuard;
3071 :
3072 : // it should be possible to quickly rename an item -> accept string or XNamed
3073 0 : OUString aNewName = lclExtractMember( rElement );
3074 0 : if( rName.isEmpty() || aNewName.isEmpty() )
3075 0 : throw IllegalArgumentException();
3076 0 : if( rName == aNewName )
3077 0 : return;
3078 :
3079 0 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3080 0 : ScFieldGroupMembers::iterator aOldIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3081 0 : ScFieldGroupMembers::iterator aNewIt = ::std::find( rMembers.begin(), rMembers.end(), aNewName );
3082 : // throw if passed member name does not exist
3083 0 : if( aOldIt == rMembers.end() )
3084 0 : throw NoSuchElementException();
3085 : // throw if new name already exists
3086 0 : if( aNewIt != rMembers.end() )
3087 0 : throw IllegalArgumentException();
3088 0 : *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 0 : sal_Int32 SAL_CALL ScDataPilotFieldGroupObj::getCount() throw(RuntimeException, std::exception)
3128 : {
3129 0 : SolarMutexGuard aGuard;
3130 0 : return static_cast< sal_Int32 >( mrParent.getFieldGroup( maGroupName ).maMembers.size() );
3131 : }
3132 :
3133 0 : Any SAL_CALL ScDataPilotFieldGroupObj::getByIndex( sal_Int32 nIndex )
3134 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
3135 : {
3136 0 : SolarMutexGuard aGuard;
3137 0 : ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3138 0 : if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( rMembers.size() )))
3139 0 : throw IndexOutOfBoundsException();
3140 0 : return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, rMembers[ nIndex ] ) ) );
3141 : }
3142 :
3143 : // XEnumerationAccess
3144 :
3145 0 : Reference< XEnumeration > SAL_CALL ScDataPilotFieldGroupObj::createEnumeration() throw(RuntimeException, std::exception)
3146 : {
3147 0 : SolarMutexGuard aGuard;
3148 0 : return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupEnumeration" ) );
3149 : }
3150 :
3151 : // XElementAccess
3152 :
3153 0 : uno::Type SAL_CALL ScDataPilotFieldGroupObj::getElementType() throw(RuntimeException, std::exception)
3154 : {
3155 0 : SolarMutexGuard aGuard;
3156 0 : return getCppuType( (Reference< XNamed >*)0 );
3157 : }
3158 :
3159 0 : sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasElements() throw(RuntimeException, std::exception)
3160 : {
3161 0 : SolarMutexGuard aGuard;
3162 0 : return !mrParent.getFieldGroup( maGroupName ).maMembers.empty();
3163 : }
3164 :
3165 : // XNamed
3166 :
3167 0 : OUString SAL_CALL ScDataPilotFieldGroupObj::getName() throw(RuntimeException, std::exception)
3168 : {
3169 0 : SolarMutexGuard aGuard;
3170 0 : return maGroupName;
3171 : }
3172 :
3173 0 : void SAL_CALL ScDataPilotFieldGroupObj::setName( const OUString& rName ) throw(RuntimeException, std::exception)
3174 : {
3175 0 : SolarMutexGuard aGuard;
3176 0 : mrParent.renameFieldGroup( maGroupName, rName );
3177 : // if call to renameFieldGroup() did not throw, remember the new name
3178 0 : maGroupName = rName;
3179 0 : }
3180 :
3181 0 : ScDataPilotFieldGroupItemObj::ScDataPilotFieldGroupItemObj( ScDataPilotFieldGroupObj& rParent, const OUString& rName ) :
3182 : mrParent( rParent ),
3183 0 : maName( rName )
3184 : {
3185 0 : mrParent.acquire();
3186 0 : }
3187 :
3188 0 : ScDataPilotFieldGroupItemObj::~ScDataPilotFieldGroupItemObj()
3189 : {
3190 0 : mrParent.release();
3191 0 : }
3192 :
3193 : // XNamed
3194 :
3195 0 : OUString SAL_CALL ScDataPilotFieldGroupItemObj::getName() throw(RuntimeException, std::exception)
3196 : {
3197 0 : SolarMutexGuard aGuard;
3198 0 : return maName;
3199 : }
3200 :
3201 0 : void SAL_CALL ScDataPilotFieldGroupItemObj::setName( const OUString& rName ) throw(RuntimeException, std::exception)
3202 : {
3203 0 : SolarMutexGuard aGuard;
3204 0 : mrParent.replaceByName( maName, Any( rName ) );
3205 : // if call to replaceByName() did not throw, remember the new name
3206 0 : maName = rName;
3207 0 : }
3208 :
3209 0 : ScDataPilotItemsObj::ScDataPilotItemsObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
3210 0 : ScDataPilotChildObjBase( rParent, rFieldId )
3211 : {
3212 0 : }
3213 :
3214 0 : ScDataPilotItemsObj::~ScDataPilotItemsObj()
3215 : {
3216 0 : }
3217 :
3218 : // XDataPilotItems
3219 :
3220 0 : ScDataPilotItemObj* ScDataPilotItemsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3221 : {
3222 0 : return ((0 <= nIndex) && (nIndex < GetMemberCount())) ?
3223 0 : new ScDataPilotItemObj( mrParent, maFieldId, nIndex ) : 0;
3224 : }
3225 :
3226 : // XNameAccess
3227 :
3228 0 : Any SAL_CALL ScDataPilotItemsObj::getByName( const OUString& aName )
3229 : throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3230 : {
3231 0 : SolarMutexGuard aGuard;
3232 0 : Reference<XNameAccess> xMembers = GetMembers();
3233 0 : if (xMembers.is())
3234 : {
3235 0 : Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3236 0 : sal_Int32 nCount = xMembersIndex->getCount();
3237 0 : sal_Bool bFound(false);
3238 0 : sal_Int32 nItem = 0;
3239 0 : while (nItem < nCount && !bFound )
3240 : {
3241 0 : Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3242 0 : if (xMember.is() && (aName == xMember->getName()))
3243 0 : return Any( Reference< XPropertySet >( GetObjectByIndex_Impl( nItem ) ) );
3244 0 : ++nItem;
3245 0 : }
3246 0 : if (!bFound)
3247 0 : throw NoSuchElementException();
3248 : }
3249 0 : return Any();
3250 : }
3251 :
3252 0 : Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
3253 : throw(RuntimeException, std::exception)
3254 : {
3255 0 : SolarMutexGuard aGuard;
3256 0 : Sequence< OUString > aSeq;
3257 0 : if( ScDPObject* pDPObj = GetDPObject() )
3258 0 : pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
3259 0 : return aSeq;
3260 : }
3261 :
3262 0 : sal_Bool SAL_CALL ScDataPilotItemsObj::hasByName( const OUString& aName )
3263 : throw(RuntimeException, std::exception)
3264 : {
3265 0 : SolarMutexGuard aGuard;
3266 0 : sal_Bool bFound = false;
3267 0 : Reference<XNameAccess> xMembers = GetMembers();
3268 0 : if (xMembers.is())
3269 : {
3270 0 : Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3271 0 : sal_Int32 nCount = xMembersIndex->getCount();
3272 0 : sal_Int32 nItem = 0;
3273 0 : while (nItem < nCount && !bFound )
3274 : {
3275 0 : Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3276 0 : if (xMember.is() && aName == xMember->getName())
3277 0 : bFound = sal_True;
3278 : else
3279 0 : nItem++;
3280 0 : }
3281 : }
3282 0 : return bFound;
3283 : }
3284 :
3285 : // XEnumerationAccess
3286 :
3287 0 : Reference<XEnumeration> SAL_CALL ScDataPilotItemsObj::createEnumeration()
3288 : throw(RuntimeException, std::exception)
3289 : {
3290 0 : SolarMutexGuard aGuard;
3291 0 : return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotItemsEnumeration"));
3292 : }
3293 :
3294 : // XIndexAccess
3295 :
3296 0 : sal_Int32 SAL_CALL ScDataPilotItemsObj::getCount() throw(RuntimeException, std::exception)
3297 : {
3298 0 : SolarMutexGuard aGuard;
3299 0 : return GetMemberCount();
3300 : }
3301 :
3302 0 : Any SAL_CALL ScDataPilotItemsObj::getByIndex( sal_Int32 nIndex )
3303 : throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
3304 : {
3305 0 : SolarMutexGuard aGuard;
3306 0 : Reference< XPropertySet > xItem( GetObjectByIndex_Impl( nIndex ) );
3307 0 : if (!xItem.is())
3308 0 : throw IndexOutOfBoundsException();
3309 0 : return Any( xItem );
3310 : }
3311 :
3312 0 : uno::Type SAL_CALL ScDataPilotItemsObj::getElementType() throw(RuntimeException, std::exception)
3313 : {
3314 0 : SolarMutexGuard aGuard;
3315 0 : return getCppuType((Reference<XPropertySet>*)0);
3316 : }
3317 :
3318 0 : sal_Bool SAL_CALL ScDataPilotItemsObj::hasElements() throw(RuntimeException, std::exception)
3319 : {
3320 0 : SolarMutexGuard aGuard;
3321 0 : return ( getCount() != 0 );
3322 : }
3323 :
3324 0 : ScDataPilotItemObj::ScDataPilotItemObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId, sal_Int32 nIndex ) :
3325 : ScDataPilotChildObjBase( rParent, rFieldId ),
3326 : maPropSet( lcl_GetDataPilotItemMap() ),
3327 0 : mnIndex( nIndex )
3328 : {
3329 0 : }
3330 :
3331 0 : ScDataPilotItemObj::~ScDataPilotItemObj()
3332 : {
3333 0 : }
3334 :
3335 : // XNamed
3336 0 : OUString SAL_CALL ScDataPilotItemObj::getName() throw(RuntimeException, std::exception)
3337 : {
3338 0 : SolarMutexGuard aGuard;
3339 0 : OUString sRet;
3340 0 : Reference<XNameAccess> xMembers = GetMembers();
3341 0 : if (xMembers.is())
3342 : {
3343 0 : Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3344 0 : sal_Int32 nCount = xMembersIndex->getCount();
3345 0 : if (mnIndex < nCount)
3346 : {
3347 0 : Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3348 0 : sRet = xMember->getName();
3349 0 : }
3350 : }
3351 0 : 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 0 : SAL_CALL ScDataPilotItemObj::getPropertySetInfo( )
3362 : throw(RuntimeException, std::exception)
3363 : {
3364 0 : SolarMutexGuard aGuard;
3365 : static Reference<XPropertySetInfo> aRef =
3366 0 : new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
3367 0 : return aRef;
3368 : }
3369 :
3370 0 : void SAL_CALL ScDataPilotItemObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
3371 : throw (UnknownPropertyException, PropertyVetoException,
3372 : IllegalArgumentException, WrappedTargetException,
3373 : RuntimeException, std::exception)
3374 : {
3375 0 : SolarMutexGuard aGuard;
3376 0 : ScDPObject* pDPObj = 0;
3377 0 : if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
3378 : {
3379 0 : Reference<XNameAccess> xMembers = GetMembers();
3380 0 : if( xMembers.is() )
3381 : {
3382 0 : Reference<XIndexAccess> xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3383 0 : sal_Int32 nCount = xMembersIndex->getCount();
3384 0 : if( mnIndex < nCount )
3385 : {
3386 0 : Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3387 0 : OUString sName(xMember->getName());
3388 0 : ScDPSaveMember* pMember = pDim->GetMemberByName(sName);
3389 0 : if (pMember)
3390 : {
3391 0 : bool bGetNewIndex = false;
3392 0 : if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3393 0 : pMember->SetShowDetails(cppu::any2bool(aValue));
3394 0 : else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3395 0 : pMember->SetIsVisible(!cppu::any2bool(aValue));
3396 0 : else if ( aPropertyName == SC_UNONAME_POS )
3397 : {
3398 0 : sal_Int32 nNewPos = 0;
3399 0 : 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 0 : throw IllegalArgumentException();
3407 : }
3408 0 : SetDPObject( pDPObj );
3409 :
3410 0 : 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 0 : }
3420 0 : }
3421 0 : }
3422 0 : }
3423 0 : }
3424 :
3425 0 : Any SAL_CALL ScDataPilotItemObj::getPropertyValue( const OUString& aPropertyName )
3426 : throw (UnknownPropertyException, WrappedTargetException,
3427 : RuntimeException, std::exception)
3428 : {
3429 0 : SolarMutexGuard aGuard;
3430 0 : Any aRet;
3431 0 : if( ScDPSaveDimension* pDim = GetDPDimension() )
3432 : {
3433 0 : Reference< XNameAccess > xMembers = GetMembers();
3434 0 : if( xMembers.is() )
3435 : {
3436 0 : Reference< XIndexAccess > xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3437 0 : sal_Int32 nCount = xMembersIndex->getCount();
3438 0 : if( mnIndex < nCount )
3439 : {
3440 0 : Reference< XNamed > xMember( xMembersIndex->getByIndex( mnIndex ), UNO_QUERY );
3441 0 : OUString sName( xMember->getName() );
3442 0 : ScDPSaveMember* pMember = pDim->GetExistingMemberByName( sName );
3443 0 : if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3444 : {
3445 0 : if (pMember && pMember->HasShowDetails())
3446 : {
3447 0 : aRet <<= (bool)pMember->GetShowDetails();
3448 : }
3449 : else
3450 : {
3451 0 : Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3452 0 : if( xMemberProps.is() )
3453 0 : aRet = xMemberProps->getPropertyValue( OUString( SC_UNO_DP_SHOWDETAILS ) );
3454 : else
3455 0 : aRet <<= true;
3456 : }
3457 : }
3458 0 : else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3459 : {
3460 0 : if (pMember && pMember->HasIsVisible())
3461 : {
3462 0 : aRet <<= !pMember->GetIsVisible();
3463 : }
3464 : else
3465 : {
3466 0 : Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3467 0 : if( xMemberProps.is() )
3468 0 : aRet <<= !cppu::any2bool( xMemberProps->getPropertyValue( OUString( SC_UNO_DP_ISVISIBLE ) ) );
3469 : else
3470 0 : aRet <<= false;
3471 : }
3472 : }
3473 0 : else if ( aPropertyName == SC_UNONAME_POS )
3474 : {
3475 0 : aRet <<= mnIndex;
3476 0 : }
3477 0 : }
3478 0 : }
3479 : }
3480 0 : 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 0 : }
3506 :
3507 :
3508 :
3509 :
3510 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|