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