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