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