bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / unoobj / dapiuno.cxx
blob8e960e0d75bc6e1b99c59c40b28c9480acef2dbe
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <algorithm>
22 #include <svl/smplhint.hxx>
23 #include <vcl/svapp.hxx>
25 #include "dapiuno.hxx"
26 #include "datauno.hxx"
27 #include "miscuno.hxx"
28 #include "convuno.hxx"
29 #include "docsh.hxx"
30 #include "tabvwsh.hxx"
31 #include "pivot.hxx"
32 #include "rangeutl.hxx"
33 #include "dpobject.hxx"
34 #include "dpshttab.hxx"
35 #include "dpsdbtab.hxx"
36 #include "dpsave.hxx"
37 #include "dbdocfun.hxx"
38 #include "unonames.hxx"
39 #include "dpgroup.hxx"
40 #include "dpdimsave.hxx"
41 #include "hints.hxx"
43 #include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
44 #include <com/sun/star/sheet/XLevelsSupplier.hpp>
45 #include <com/sun/star/sheet/XMembersSupplier.hpp>
46 #include <com/sun/star/beans/PropertyAttribute.hpp>
47 #include <com/sun/star/sheet/DataImportMode.hpp>
48 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
49 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
50 #include <com/sun/star/sheet/DataPilotOutputRangeType.hpp>
51 #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
53 #include <comphelper/extract.hxx>
54 #include <comphelper/sequence.hxx>
55 #include <comphelper/servicehelper.hxx>
57 using namespace com::sun::star;
58 using namespace com::sun::star::sheet;
61 using ::com::sun::star::uno::Any;
62 using ::com::sun::star::uno::Exception;
63 using ::com::sun::star::uno::Reference;
64 using ::com::sun::star::uno::RuntimeException;
65 using ::com::sun::star::uno::Sequence;
66 using ::com::sun::star::uno::UNO_QUERY;
67 using ::com::sun::star::uno::UNO_QUERY_THROW;
69 using ::com::sun::star::container::ElementExistException;
70 using ::com::sun::star::container::NoSuchElementException;
71 using ::com::sun::star::container::XEnumeration;
72 using ::com::sun::star::container::XIndexAccess;
73 using ::com::sun::star::container::XNameAccess;
74 using ::com::sun::star::container::XNamed;
76 using ::com::sun::star::beans::PropertyVetoException;
77 using ::com::sun::star::beans::UnknownPropertyException;
78 using ::com::sun::star::beans::XPropertyChangeListener;
79 using ::com::sun::star::beans::XPropertySet;
80 using ::com::sun::star::beans::XPropertySetInfo;
81 using ::com::sun::star::beans::XVetoableChangeListener;
83 using ::com::sun::star::lang::IllegalArgumentException;
84 using ::com::sun::star::lang::IndexOutOfBoundsException;
85 using ::com::sun::star::lang::WrappedTargetException;
87 using ::com::sun::star::table::CellAddress;
88 using ::com::sun::star::table::CellRangeAddress;
90 // ============================================================================
92 namespace {
94 const SfxItemPropertyMapEntry* lcl_GetDataPilotDescriptorBaseMap()
96 static SfxItemPropertyMapEntry aDataPilotDescriptorBaseMap_Impl[] =
98 {MAP_CHAR_LEN(SC_UNO_DP_COLGRAND), 0, &getBooleanCppuType(), 0, 0 },
99 {MAP_CHAR_LEN(SC_UNO_DP_DRILLDOWN), 0, &getBooleanCppuType(), 0, 0 },
100 {MAP_CHAR_LEN(SC_UNO_DP_GRANDTOTAL_NAME),0,&getCppuType((OUString*)0), beans::PropertyAttribute::MAYBEVOID, 0 },
101 {MAP_CHAR_LEN(SC_UNO_DP_IGNORE_EMPTYROWS), 0, &getBooleanCppuType(), 0, 0 },
102 {MAP_CHAR_LEN(SC_UNO_DP_IMPORTDESC), 0, &getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
103 {MAP_CHAR_LEN(SC_UNO_DP_REPEATEMPTY), 0, &getBooleanCppuType(), 0, 0 },
104 {MAP_CHAR_LEN(SC_UNO_DP_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 },
105 {MAP_CHAR_LEN(SC_UNO_DP_SERVICEARG), 0, &getCppuType((uno::Sequence<beans::PropertyValue>*)0), 0, 0 },
106 {MAP_CHAR_LEN(SC_UNO_DP_SHOWFILTER), 0, &getBooleanCppuType(), 0, 0 },
107 {MAP_CHAR_LEN(SC_UNO_DP_SOURCESERVICE), 0, &getCppuType((OUString*)0), 0, 0 },
108 {0,0,0,0,0,0}
110 return aDataPilotDescriptorBaseMap_Impl;
113 // ----------------------------------------------------------------------------
115 const SfxItemPropertyMapEntry* lcl_GetDataPilotFieldMap()
117 using namespace ::com::sun::star::beans::PropertyAttribute;
118 static SfxItemPropertyMapEntry aDataPilotFieldMap_Impl[] =
120 {MAP_CHAR_LEN(SC_UNONAME_AUTOSHOW), 0, &getCppuType((DataPilotFieldAutoShowInfo*)0), MAYBEVOID, 0 },
121 {MAP_CHAR_LEN(SC_UNONAME_FUNCTION), 0, &getCppuType((GeneralFunction*)0), 0, 0 },
122 {MAP_CHAR_LEN(SC_UNONAME_GROUPINFO), 0, &getCppuType((DataPilotFieldGroupInfo*)0), MAYBEVOID, 0 },
123 {MAP_CHAR_LEN(SC_UNONAME_HASAUTOSHOW), 0, &getBooleanCppuType(), 0, 0 },
124 {MAP_CHAR_LEN(SC_UNONAME_HASLAYOUTINFO),0, &getBooleanCppuType(), 0, 0 },
125 {MAP_CHAR_LEN(SC_UNONAME_HASREFERENCE), 0, &getBooleanCppuType(), 0, 0 },
126 {MAP_CHAR_LEN(SC_UNONAME_HASSORTINFO), 0, &getBooleanCppuType(), 0, 0 },
127 {MAP_CHAR_LEN(SC_UNONAME_ISGROUP), 0, &getBooleanCppuType(), 0, 0 },
128 {MAP_CHAR_LEN(SC_UNONAME_LAYOUTINFO), 0, &getCppuType((DataPilotFieldLayoutInfo*)0), MAYBEVOID, 0 },
129 {MAP_CHAR_LEN(SC_UNONAME_ORIENT), 0, &getCppuType((DataPilotFieldOrientation*)0), MAYBEVOID, 0 },
130 {MAP_CHAR_LEN(SC_UNONAME_REFERENCE), 0, &getCppuType((DataPilotFieldReference*)0), MAYBEVOID, 0 },
131 {MAP_CHAR_LEN(SC_UNONAME_SELPAGE), 0, &getCppuType((OUString*)0), 0, 0 },
132 {MAP_CHAR_LEN(SC_UNONAME_SHOWEMPTY), 0, &getBooleanCppuType(), 0, 0 },
133 {MAP_CHAR_LEN(SC_UNONAME_SORTINFO), 0, &getCppuType((DataPilotFieldSortInfo*)0), MAYBEVOID, 0 },
134 {MAP_CHAR_LEN(SC_UNONAME_SUBTOTALS), 0, &getCppuType((Sequence<GeneralFunction>*)0), 0, 0 },
135 {MAP_CHAR_LEN(SC_UNONAME_USESELPAGE), 0, &getBooleanCppuType(), 0, 0 },
136 {0,0,0,0,0,0}
138 return aDataPilotFieldMap_Impl;
141 // ----------------------------------------------------------------------------
143 const SfxItemPropertyMapEntry* lcl_GetDataPilotItemMap()
145 static SfxItemPropertyMapEntry aDataPilotItemMap_Impl[] =
147 {MAP_CHAR_LEN(SC_UNONAME_ISHIDDEN), 0, &getBooleanCppuType(), 0, 0 },
148 {MAP_CHAR_LEN(SC_UNONAME_POS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
149 {MAP_CHAR_LEN(SC_UNONAME_SHOWDETAIL), 0, &getBooleanCppuType(), 0, 0 },
150 {0,0,0,0,0,0}
152 return aDataPilotItemMap_Impl;
155 // ----------------------------------------------------------------------------
157 inline bool lclCheckValidDouble( double fValue, sal_Bool bAuto )
159 return bAuto || ::rtl::math::isFinite( fValue );
162 bool lclCheckMinMaxStep( const DataPilotFieldGroupInfo& rInfo )
164 return
165 lclCheckValidDouble( rInfo.Start, rInfo.HasAutoStart ) &&
166 lclCheckValidDouble( rInfo.End, rInfo.HasAutoEnd ) &&
167 (rInfo.HasAutoStart || rInfo.HasAutoEnd || (rInfo.Start <= rInfo.End)) &&
168 lclCheckValidDouble( rInfo.Step, false ) &&
169 (0.0 <= rInfo.Step);
172 } // namespace
174 // ============================================================================
176 SC_SIMPLE_SERVICE_INFO( ScDataPilotDescriptor, "ScDataPilotDescriptor", "stardiv::one::sheet::DataPilotDescriptor" )
177 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldObj, "ScDataPilotFieldObj", "com.sun.star.sheet.DataPilotField" )
178 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldsObj, "ScDataPilotFieldsObj", "com.sun.star.sheet.DataPilotFields" )
179 SC_SIMPLE_SERVICE_INFO( ScDataPilotTableObj, "ScDataPilotTableObj", "com.sun.star.sheet.DataPilotTable" )
180 SC_SIMPLE_SERVICE_INFO( ScDataPilotTablesObj, "ScDataPilotTablesObj", "com.sun.star.sheet.DataPilotTables" )
181 SC_SIMPLE_SERVICE_INFO( ScDataPilotItemsObj, "ScDataPilotItemsObj", "com.sun.star.sheet.DataPilotItems" )
182 SC_SIMPLE_SERVICE_INFO( ScDataPilotItemObj, "ScDataPilotItemObj", "com.sun.star.sheet.DataPilotItem" )
184 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupsObj, "ScDataPilotFieldGroupsObj", "com.sun.star.sheet.DataPilotFieldGroups" )
185 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupObj, "ScDataPilotFieldGroupObj", "com.sun.star.sheet.DataPilotFieldGroup" )
186 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupItemObj, "ScDataPilotFieldGroupItemObj", "com.sun.star.sheet.DataPilotFieldGroupItem" )
188 //------------------------------------------------------------------------
190 // name that is used in the API for the data layout field
191 #define SC_DATALAYOUT_NAME "Data"
193 //------------------------------------------------------------------------
195 GeneralFunction ScDataPilotConversion::FirstFunc( sal_uInt16 nBits )
197 if ( nBits & PIVOT_FUNC_SUM ) return GeneralFunction_SUM;
198 if ( nBits & PIVOT_FUNC_COUNT ) return GeneralFunction_COUNT;
199 if ( nBits & PIVOT_FUNC_AVERAGE ) return GeneralFunction_AVERAGE;
200 if ( nBits & PIVOT_FUNC_MAX ) return GeneralFunction_MAX;
201 if ( nBits & PIVOT_FUNC_MIN ) return GeneralFunction_MIN;
202 if ( nBits & PIVOT_FUNC_PRODUCT ) return GeneralFunction_PRODUCT;
203 if ( nBits & PIVOT_FUNC_COUNT_NUM ) return GeneralFunction_COUNTNUMS;
204 if ( nBits & PIVOT_FUNC_STD_DEV ) return GeneralFunction_STDEV;
205 if ( nBits & PIVOT_FUNC_STD_DEVP ) return GeneralFunction_STDEVP;
206 if ( nBits & PIVOT_FUNC_STD_VAR ) return GeneralFunction_VAR;
207 if ( nBits & PIVOT_FUNC_STD_VARP ) return GeneralFunction_VARP;
208 if ( nBits & PIVOT_FUNC_AUTO ) return GeneralFunction_AUTO;
209 return GeneralFunction_NONE;
212 sal_uInt16 ScDataPilotConversion::FunctionBit( GeneralFunction eFunc )
214 sal_uInt16 nRet = PIVOT_FUNC_NONE; // 0
215 switch (eFunc)
217 case GeneralFunction_SUM: nRet = PIVOT_FUNC_SUM; break;
218 case GeneralFunction_COUNT: nRet = PIVOT_FUNC_COUNT; break;
219 case GeneralFunction_AVERAGE: nRet = PIVOT_FUNC_AVERAGE; break;
220 case GeneralFunction_MAX: nRet = PIVOT_FUNC_MAX; break;
221 case GeneralFunction_MIN: nRet = PIVOT_FUNC_MIN; break;
222 case GeneralFunction_PRODUCT: nRet = PIVOT_FUNC_PRODUCT; break;
223 case GeneralFunction_COUNTNUMS: nRet = PIVOT_FUNC_COUNT_NUM; break;
224 case GeneralFunction_STDEV: nRet = PIVOT_FUNC_STD_DEV; break;
225 case GeneralFunction_STDEVP: nRet = PIVOT_FUNC_STD_DEVP; break;
226 case GeneralFunction_VAR: nRet = PIVOT_FUNC_STD_VAR; break;
227 case GeneralFunction_VARP: nRet = PIVOT_FUNC_STD_VARP; break;
228 case GeneralFunction_AUTO: nRet = PIVOT_FUNC_AUTO; break;
229 default:
231 // added to avoid warnings
234 return nRet;
237 void ScDataPilotConversion::FillGroupInfo( DataPilotFieldGroupInfo& rInfo, const ScDPNumGroupInfo& rGroupInfo )
239 rInfo.HasDateValues = rGroupInfo.mbDateValues;
240 rInfo.HasAutoStart = rGroupInfo.mbAutoStart;
241 rInfo.Start = rGroupInfo.mfStart;
242 rInfo.HasAutoEnd = rGroupInfo.mbAutoEnd;
243 rInfo.End = rGroupInfo.mfEnd;
244 rInfo.Step = rGroupInfo.mfStep;
247 //------------------------------------------------------------------------
249 static ScDPObject* lcl_GetDPObject( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
251 if (pDocShell)
253 ScDocument* pDoc = pDocShell->GetDocument();
254 ScDPCollection* pColl = pDoc->GetDPCollection();
255 if ( pColl )
257 size_t nCount = pColl->GetCount();
258 for (size_t i=0; i<nCount; ++i)
260 ScDPObject* pDPObj = (*pColl)[i];
261 if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
262 pDPObj->GetName() == rName )
263 return pDPObj;
267 return NULL; // nicht gefunden
270 static String lcl_CreatePivotName( ScDocShell* pDocShell )
272 if (pDocShell)
274 ScDocument* pDoc = pDocShell->GetDocument();
275 ScDPCollection* pColl = pDoc->GetDPCollection();
276 if ( pColl )
277 return pColl->CreateNewName();
279 return String(); // sollte nicht vorkommen
282 static sal_Int32 lcl_GetObjectIndex( ScDPObject* pDPObj, const ScFieldIdentifier& rFieldId )
284 // used for items - nRepeat in identifier can be ignored
285 if ( pDPObj )
287 sal_Int32 nCount = pDPObj->GetDimCount();
288 for ( sal_Int32 nDim = 0; nDim < nCount; ++nDim )
290 bool bIsDataLayout = false;
291 OUString aDimName( pDPObj->GetDimName( nDim, bIsDataLayout ) );
292 if ( rFieldId.mbDataLayout ? bIsDataLayout : (aDimName == rFieldId.maFieldName) )
293 return nDim;
296 return -1; // none
299 //------------------------------------------------------------------------
301 ScDataPilotTablesObj::ScDataPilotTablesObj(ScDocShell* pDocSh, SCTAB nT) :
302 pDocShell( pDocSh ),
303 nTab( nT )
305 pDocShell->GetDocument()->AddUnoObject(*this);
308 ScDataPilotTablesObj::~ScDataPilotTablesObj()
310 if (pDocShell)
311 pDocShell->GetDocument()->RemoveUnoObject(*this);
314 void ScDataPilotTablesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
316 //! Referenz-Update
318 if ( rHint.ISA( SfxSimpleHint ) &&
319 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
321 pDocShell = NULL; // ungueltig geworden
325 // XDataPilotTables
327 ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nIndex )
329 if (pDocShell)
331 ScDocument* pDoc = pDocShell->GetDocument();
332 ScDPCollection* pColl = pDoc->GetDPCollection();
333 if ( pColl )
335 // count tables on this sheet
336 sal_Int32 nFound = 0;
337 size_t nCount = pColl->GetCount();
338 for (size_t i=0; i<nCount; ++i)
340 ScDPObject* pDPObj = (*pColl)[i];
341 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
343 if ( nFound == nIndex )
345 String aName = pDPObj->GetName();
346 return new ScDataPilotTableObj( pDocShell, nTab, aName );
348 ++nFound;
353 return NULL;
356 ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByName_Impl(const OUString& rName)
358 if (hasByName(rName))
359 return new ScDataPilotTableObj( pDocShell, nTab, rName );
360 return 0;
363 Reference<XDataPilotDescriptor> SAL_CALL ScDataPilotTablesObj::createDataPilotDescriptor()
364 throw(RuntimeException)
366 SolarMutexGuard aGuard;
367 if (pDocShell)
368 return new ScDataPilotDescriptor(pDocShell);
369 return NULL;
372 static bool lcl_IsDuplicated( const Reference<XPropertySet> xDimProps )
376 Any aAny = xDimProps->getPropertyValue( OUString( SC_UNO_DP_ORIGINAL ) );
377 Reference< XNamed > xOriginal( aAny, UNO_QUERY );
378 return xOriginal.is();
380 catch( Exception& )
383 return false;
386 static OUString lcl_GetOriginalName( const Reference< XNamed > xDim )
388 Reference< XNamed > xOriginal;
390 Reference< XPropertySet > xDimProps( xDim, UNO_QUERY );
391 if ( xDimProps.is() )
395 Any aAny = xDimProps->getPropertyValue(OUString(SC_UNO_DP_ORIGINAL));
396 aAny >>= xOriginal;
398 catch( Exception& )
403 if ( !xOriginal.is() )
404 xOriginal = xDim;
406 return xOriginal->getName();
409 void SAL_CALL ScDataPilotTablesObj::insertNewByName( const OUString& aNewName,
410 const CellAddress& aOutputAddress,
411 const Reference<XDataPilotDescriptor>& xDescriptor )
412 throw(RuntimeException)
414 SolarMutexGuard aGuard;
415 if (!xDescriptor.is()) return;
417 // inserting with already existing name?
418 if ( !aNewName.isEmpty() && hasByName( aNewName ) )
419 throw RuntimeException(); // no other exceptions specified
421 sal_Bool bDone = false;
422 ScDataPilotDescriptorBase* pImp = ScDataPilotDescriptorBase::getImplementation( xDescriptor );
423 if ( pDocShell && pImp )
425 ScDPObject* pNewObj = pImp->GetDPObject();
427 if (pNewObj)
429 ScRange aOutputRange((SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet,
430 (SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet);
431 pNewObj->SetOutRange(aOutputRange);
432 String aName = aNewName;
433 if (!aName.Len())
434 aName = lcl_CreatePivotName( pDocShell );
435 pNewObj->SetName(aName);
436 String aTag = xDescriptor->getTag();
437 pNewObj->SetTag(aTag);
439 // todo: handle double fields (for more information see ScDPObject
441 ScDBDocFunc aFunc(*pDocShell);
442 bDone = aFunc.CreatePivotTable(*pNewObj, true, true);
446 if (!bDone)
447 throw RuntimeException(); // no other exceptions specified
450 void SAL_CALL ScDataPilotTablesObj::removeByName( const OUString& aName )
451 throw(RuntimeException)
453 SolarMutexGuard aGuard;
454 String aNameStr(aName);
455 ScDPObject* pDPObj = lcl_GetDPObject( pDocShell, nTab, aNameStr );
456 if (pDPObj && pDocShell)
458 ScDBDocFunc aFunc(*pDocShell);
459 aFunc.RemovePivotTable(*pDPObj, true, true); // remove - incl. undo etc.
461 else
462 throw RuntimeException(); // no other exceptions specified
465 // XEnumerationAccess
467 Reference< XEnumeration > SAL_CALL ScDataPilotTablesObj::createEnumeration() throw(RuntimeException)
469 SolarMutexGuard aGuard;
470 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotTablesEnumeration"));
473 // XIndexAccess
475 sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException)
477 SolarMutexGuard aGuard;
478 if ( pDocShell )
480 ScDocument* pDoc = pDocShell->GetDocument();
481 ScDPCollection* pColl = pDoc->GetDPCollection();
482 if ( pColl )
484 // count tables on this sheet
486 sal_uInt16 nFound = 0;
487 size_t nCount = pColl->GetCount();
488 for (size_t i=0; i<nCount; ++i)
490 ScDPObject* pDPObj = (*pColl)[i];
491 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
492 ++nFound;
494 return nFound;
498 return 0;
501 Any SAL_CALL ScDataPilotTablesObj::getByIndex( sal_Int32 nIndex )
502 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
504 SolarMutexGuard aGuard;
505 Reference<XDataPilotTable2> xTable(GetObjectByIndex_Impl(nIndex));
506 if (!xTable.is())
507 throw IndexOutOfBoundsException();
508 return Any( xTable );
511 uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(RuntimeException)
513 SolarMutexGuard aGuard;
514 return getCppuType((Reference<XDataPilotTable2>*)0);
517 sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(RuntimeException)
519 SolarMutexGuard aGuard;
520 return ( getCount() != 0 );
523 // XNameAccess
525 Any SAL_CALL ScDataPilotTablesObj::getByName( const OUString& aName )
526 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
528 SolarMutexGuard aGuard;
529 Reference<XDataPilotTable2> xTable(GetObjectByName_Impl(aName));
530 if (!xTable.is())
531 throw NoSuchElementException();
532 return Any( xTable );
535 Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames()
536 throw(RuntimeException)
538 SolarMutexGuard aGuard;
539 if (pDocShell)
541 ScDocument* pDoc = pDocShell->GetDocument();
542 ScDPCollection* pColl = pDoc->GetDPCollection();
543 if ( pColl )
545 // count tables on this sheet
547 sal_uInt16 nFound = 0;
548 size_t nCount = pColl->GetCount();
549 size_t i;
550 for (i=0; i<nCount; ++i)
552 ScDPObject* pDPObj = (*pColl)[i];
553 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
554 ++nFound;
557 sal_uInt16 nPos = 0;
558 Sequence<OUString> aSeq(nFound);
559 OUString* pAry = aSeq.getArray();
560 for (i=0; i<nCount; ++i)
562 ScDPObject* pDPObj = (*pColl)[i];
563 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
564 pAry[nPos++] = pDPObj->GetName();
567 return aSeq;
570 return Sequence<OUString>(0);
573 sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName )
574 throw(RuntimeException)
576 SolarMutexGuard aGuard;
577 if (pDocShell)
579 ScDocument* pDoc = pDocShell->GetDocument();
580 ScDPCollection* pColl = pDoc->GetDPCollection();
581 if ( pColl )
583 size_t nCount = pColl->GetCount();
584 for (size_t i=0; i<nCount; ++i)
586 ScDPObject* pDPObj = (*pColl)[i];
587 if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
588 pDPObj->GetName() == aName )
589 return true;
593 return false;
596 //------------------------------------------------------------------------
598 ScDataPilotDescriptorBase::ScDataPilotDescriptorBase(ScDocShell* pDocSh) :
599 maPropSet( lcl_GetDataPilotDescriptorBaseMap() ),
600 pDocShell( pDocSh )
602 pDocShell->GetDocument()->AddUnoObject(*this);
605 ScDataPilotDescriptorBase::~ScDataPilotDescriptorBase()
607 if (pDocShell)
608 pDocShell->GetDocument()->RemoveUnoObject(*this);
611 Any SAL_CALL ScDataPilotDescriptorBase::queryInterface( const uno::Type& rType )
612 throw(RuntimeException)
614 SC_QUERYINTERFACE( XDataPilotDescriptor )
615 SC_QUERYINTERFACE( XPropertySet )
616 SC_QUERYINTERFACE( XDataPilotDataLayoutFieldSupplier )
617 SC_QUERYINTERFACE( XNamed ) // base of XDataPilotDescriptor
618 SC_QUERYINTERFACE( lang::XUnoTunnel )
619 SC_QUERYINTERFACE( lang::XTypeProvider )
620 SC_QUERYINTERFACE( lang::XServiceInfo )
622 return OWeakObject::queryInterface( rType );
625 void SAL_CALL ScDataPilotDescriptorBase::acquire() throw()
627 OWeakObject::acquire();
630 void SAL_CALL ScDataPilotDescriptorBase::release() throw()
632 OWeakObject::release();
635 Sequence< uno::Type > SAL_CALL ScDataPilotDescriptorBase::getTypes()
636 throw(RuntimeException)
638 static Sequence< uno::Type > aTypes;
639 if ( aTypes.getLength() == 0 )
641 aTypes.realloc( 6 );
642 uno::Type* pPtr = aTypes.getArray();
643 pPtr[ 0 ] = getCppuType( (const Reference< XDataPilotDescriptor >*)0 );
644 pPtr[ 1 ] = getCppuType( (const Reference< XPropertySet >*)0 );
645 pPtr[ 2 ] = getCppuType( (const Reference< XDataPilotDataLayoutFieldSupplier >*)0 );
646 pPtr[ 3 ] = getCppuType( (const Reference< lang::XUnoTunnel >*)0 );
647 pPtr[ 4 ] = getCppuType( (const Reference< lang::XTypeProvider >*)0 );
648 pPtr[ 5 ] = getCppuType( (const Reference< lang::XServiceInfo >*)0 );
650 return aTypes;
653 namespace
655 class theScDataPilotDescriptorBaseImplementationId : public rtl::Static< UnoTunnelIdInit, theScDataPilotDescriptorBaseImplementationId > {};
658 Sequence<sal_Int8> SAL_CALL ScDataPilotDescriptorBase::getImplementationId()
659 throw(RuntimeException)
661 return theScDataPilotDescriptorBaseImplementationId::get().getSeq();
664 void ScDataPilotDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
666 //! Referenz-Update?
668 if ( rHint.ISA( SfxSimpleHint ) &&
669 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
671 pDocShell = NULL; // ungueltig geworden
675 // XDataPilotDescriptor
677 CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange()
678 throw(RuntimeException)
680 SolarMutexGuard aGuard;
682 ScDPObject* pDPObject(GetDPObject());
683 if (!pDPObject)
684 throw RuntimeException();
686 CellRangeAddress aRet;
687 if (pDPObject->IsSheetData())
688 ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->GetSourceRange() );
689 return aRet;
692 void SAL_CALL ScDataPilotDescriptorBase::setSourceRange( const CellRangeAddress& aSourceRange ) throw(RuntimeException)
694 SolarMutexGuard aGuard;
696 ScDPObject* pDPObject = GetDPObject();
697 if (!pDPObject)
698 throw RuntimeException();
700 ScSheetSourceDesc aSheetDesc(pDocShell->GetDocument());
701 if (pDPObject->IsSheetData())
702 aSheetDesc = *pDPObject->GetSheetDesc();
704 ScRange aRange;
705 ScUnoConversion::FillScRange(aRange, aSourceRange);
706 aSheetDesc.SetSourceRange(aRange);
707 pDPObject->SetSheetDesc( aSheetDesc );
708 SetDPObject( pDPObject );
711 Reference<XSheetFilterDescriptor> SAL_CALL ScDataPilotDescriptorBase::getFilterDescriptor()
712 throw(RuntimeException)
714 SolarMutexGuard aGuard;
715 return new ScDataPilotFilterDescriptor( pDocShell, this );
718 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataPilotFields()
719 throw(RuntimeException)
721 SolarMutexGuard aGuard;
722 return new ScDataPilotFieldsObj( *this );
725 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getColumnFields()
726 throw(RuntimeException)
728 SolarMutexGuard aGuard;
729 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_COLUMN );
732 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getRowFields()
733 throw(RuntimeException)
735 SolarMutexGuard aGuard;
736 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_ROW );
739 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getPageFields()
740 throw(RuntimeException)
742 SolarMutexGuard aGuard;
743 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_PAGE );
746 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataFields()
747 throw(RuntimeException)
749 SolarMutexGuard aGuard;
750 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_DATA );
753 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getHiddenFields()
754 throw(RuntimeException)
756 SolarMutexGuard aGuard;
757 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_HIDDEN );
760 // XPropertySet
761 Reference< XPropertySetInfo > SAL_CALL ScDataPilotDescriptorBase::getPropertySetInfo( )
762 throw(RuntimeException)
764 SolarMutexGuard aGuard;
765 static Reference<XPropertySetInfo> aRef =
766 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
767 return aRef;
770 void SAL_CALL ScDataPilotDescriptorBase::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
771 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException,
772 WrappedTargetException, RuntimeException)
774 SolarMutexGuard aGuard;
775 ScDPObject* pDPObject = GetDPObject();
776 if (pDPObject)
778 ScDPSaveData* pOldData = pDPObject->GetSaveData();
779 OSL_ENSURE(pOldData, "Here should be a SaveData");
780 if ( pOldData )
782 ScDPSaveData aNewData( *pOldData );
784 String aNameString = aPropertyName;
785 if ( aNameString.EqualsAscii( SC_UNO_DP_COLGRAND ) )
787 aNewData.SetColumnGrand(::cppu::any2bool( aValue ));
789 else if ( aNameString.EqualsAscii( SC_UNO_DP_IGNORE_EMPTYROWS ) )
791 aNewData.SetIgnoreEmptyRows(::cppu::any2bool( aValue ));
793 else if ( aNameString.EqualsAscii( SC_UNO_DP_REPEATEMPTY ) )
795 aNewData.SetRepeatIfEmpty(::cppu::any2bool( aValue ));
797 else if ( aNameString.EqualsAscii( SC_UNO_DP_ROWGRAND ) )
799 aNewData.SetRowGrand(::cppu::any2bool( aValue ));
801 else if ( aNameString.EqualsAscii( SC_UNO_DP_SHOWFILTER ) )
803 aNewData.SetFilterButton(::cppu::any2bool( aValue ));
805 else if ( aNameString.EqualsAscii( SC_UNO_DP_DRILLDOWN ) )
807 aNewData.SetDrillDown(::cppu::any2bool( aValue ));
809 else if ( aNameString.EqualsAscii( SC_UNO_DP_GRANDTOTAL_NAME ) )
811 OUString aStrVal;
812 if ( aValue >>= aStrVal )
813 aNewData.SetGrandTotalName(aStrVal);
815 else if ( aNameString.EqualsAscii( SC_UNO_DP_IMPORTDESC ) )
817 uno::Sequence<beans::PropertyValue> aArgSeq;
818 if ( aValue >>= aArgSeq )
820 ScImportSourceDesc aImportDesc(pDocShell->GetDocument());
822 const ScImportSourceDesc* pOldDesc = pDPObject->GetImportSourceDesc();
823 if (pOldDesc)
824 aImportDesc = *pOldDesc;
826 ScImportParam aParam;
827 ScImportDescriptor::FillImportParam( aParam, aArgSeq );
829 sal_uInt16 nNewType = sheet::DataImportMode_NONE;
830 if ( aParam.bImport )
832 if ( aParam.bSql )
833 nNewType = sheet::DataImportMode_SQL;
834 else if ( aParam.nType == ScDbQuery )
835 nNewType = sheet::DataImportMode_QUERY;
836 else
837 nNewType = sheet::DataImportMode_TABLE;
839 aImportDesc.nType = nNewType;
840 aImportDesc.aDBName = aParam.aDBName;
841 aImportDesc.aObject = aParam.aStatement;
842 aImportDesc.bNative = aParam.bNative;
844 pDPObject->SetImportDesc( aImportDesc );
847 else if ( aNameString.EqualsAscii( SC_UNO_DP_SOURCESERVICE ) )
849 OUString aStrVal;
850 if ( aValue >>= aStrVal )
852 String aEmpty;
853 ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
855 const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
856 if (pOldDesc)
857 aServiceDesc = *pOldDesc;
859 aServiceDesc.aServiceName = aStrVal;
861 pDPObject->SetServiceData( aServiceDesc );
864 else if ( aNameString.EqualsAscii( SC_UNO_DP_SERVICEARG ) )
866 uno::Sequence<beans::PropertyValue> aArgSeq;
867 if ( aValue >>= aArgSeq )
869 String aEmpty;
870 ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
872 const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
873 if (pOldDesc)
874 aServiceDesc = *pOldDesc;
876 OUString aStrVal;
877 sal_Int32 nArgs = aArgSeq.getLength();
878 for (sal_Int32 nArgPos=0; nArgPos<nArgs; ++nArgPos)
880 const beans::PropertyValue& rProp = aArgSeq[nArgPos];
881 String aPropName(rProp.Name);
883 if (aPropName.EqualsAscii( SC_UNO_DP_SOURCENAME ))
885 if ( rProp.Value >>= aStrVal )
886 aServiceDesc.aParSource = aStrVal;
888 else if (aPropName.EqualsAscii( SC_UNO_DP_OBJECTNAME ))
890 if ( rProp.Value >>= aStrVal )
891 aServiceDesc.aParName = aStrVal;
893 else if (aPropName.EqualsAscii( SC_UNO_DP_USERNAME ))
895 if ( rProp.Value >>= aStrVal )
896 aServiceDesc.aParUser = aStrVal;
898 else if (aPropName.EqualsAscii( SC_UNO_DP_PASSWORD ))
900 if ( rProp.Value >>= aStrVal )
901 aServiceDesc.aParPass = aStrVal;
905 pDPObject->SetServiceData( aServiceDesc );
908 else
909 throw UnknownPropertyException();
911 pDPObject->SetSaveData( aNewData );
914 SetDPObject(pDPObject);
918 Any SAL_CALL ScDataPilotDescriptorBase::getPropertyValue( const OUString& aPropertyName )
919 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
921 SolarMutexGuard aGuard;
922 Any aRet;
924 ScDPObject* pDPObject(GetDPObject());
925 if (pDPObject)
927 ScDPSaveData* pOldData = pDPObject->GetSaveData();
928 OSL_ENSURE(pOldData, "Here should be a SaveData");
929 if ( pOldData )
931 ScDPSaveData aNewData( *pOldData );
933 String aNameString = aPropertyName;
934 if ( aNameString.EqualsAscii( SC_UNO_DP_COLGRAND ) )
936 aRet = ::cppu::bool2any( aNewData.GetColumnGrand() );
938 else if ( aNameString.EqualsAscii( SC_UNO_DP_IGNORE_EMPTYROWS ) )
940 aRet = ::cppu::bool2any( aNewData.GetIgnoreEmptyRows() );
942 else if ( aNameString.EqualsAscii( SC_UNO_DP_REPEATEMPTY ) )
944 aRet = ::cppu::bool2any( aNewData.GetRepeatIfEmpty() );
946 else if ( aNameString.EqualsAscii( SC_UNO_DP_ROWGRAND ) )
948 aRet = ::cppu::bool2any( aNewData.GetRowGrand() );
950 else if ( aNameString.EqualsAscii( SC_UNO_DP_SHOWFILTER ) )
952 aRet = ::cppu::bool2any( aNewData.GetFilterButton() );
954 else if ( aNameString.EqualsAscii( SC_UNO_DP_DRILLDOWN ) )
956 aRet = ::cppu::bool2any( aNewData.GetDrillDown() );
958 else if ( aNameString.EqualsAscii( SC_UNO_DP_GRANDTOTAL_NAME ) )
960 const OUString* pGrandTotalName = aNewData.GetGrandTotalName();
961 if (pGrandTotalName)
962 aRet <<= *pGrandTotalName; // same behavior as in ScDPSource
964 else if ( aNameString.EqualsAscii( SC_UNO_DP_IMPORTDESC ) )
966 const ScImportSourceDesc* pImportDesc = pDPObject->GetImportSourceDesc();
967 if ( pImportDesc )
969 // fill ScImportParam so ScImportDescriptor::FillProperties can be used
970 ScImportParam aParam;
971 aParam.bImport = ( pImportDesc->nType != sheet::DataImportMode_NONE );
972 aParam.aDBName = pImportDesc->aDBName;
973 aParam.aStatement = pImportDesc->aObject;
974 aParam.bNative = pImportDesc->bNative;
975 aParam.bSql = ( pImportDesc->nType == sheet::DataImportMode_SQL );
976 aParam.nType = static_cast<sal_uInt8>(( pImportDesc->nType == sheet::DataImportMode_QUERY ) ? ScDbQuery : ScDbTable);
978 uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
979 ScImportDescriptor::FillProperties( aSeq, aParam );
980 aRet <<= aSeq;
982 else
984 // empty sequence
985 uno::Sequence<beans::PropertyValue> aEmpty(0);
986 aRet <<= aEmpty;
989 else if ( aNameString.EqualsAscii( SC_UNO_DP_SOURCESERVICE ) )
991 OUString aServiceName;
992 const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
993 if (pServiceDesc)
994 aServiceName = pServiceDesc->aServiceName;
995 aRet <<= aServiceName; // empty string if no ServiceDesc set
997 else if ( aNameString.EqualsAscii( SC_UNO_DP_SERVICEARG ) )
999 const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
1000 if (pServiceDesc)
1002 uno::Sequence<beans::PropertyValue> aSeq( 4 );
1003 beans::PropertyValue* pArray = aSeq.getArray();
1004 pArray[0].Name = OUString( SC_UNO_DP_SOURCENAME );
1005 pArray[0].Value <<= pServiceDesc->aParSource;
1006 pArray[1].Name = OUString( SC_UNO_DP_OBJECTNAME );
1007 pArray[1].Value <<= pServiceDesc->aParName;
1008 pArray[2].Name = OUString( SC_UNO_DP_USERNAME );
1009 pArray[2].Value <<= pServiceDesc->aParUser;
1010 pArray[3].Name = OUString( SC_UNO_DP_PASSWORD );
1011 pArray[3].Value <<= pServiceDesc->aParPass;
1012 aRet <<= aSeq;
1014 else
1016 // empty sequence
1017 uno::Sequence<beans::PropertyValue> aEmpty(0);
1018 aRet <<= aEmpty;
1021 else
1022 throw UnknownPropertyException();
1026 return aRet;
1029 void SAL_CALL ScDataPilotDescriptorBase::addPropertyChangeListener(
1030 const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* xListener */ )
1031 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
1035 void SAL_CALL ScDataPilotDescriptorBase::removePropertyChangeListener(
1036 const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* aListener */ )
1037 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
1041 void SAL_CALL ScDataPilotDescriptorBase::addVetoableChangeListener(
1042 const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
1043 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
1047 void SAL_CALL ScDataPilotDescriptorBase::removeVetoableChangeListener(
1048 const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
1049 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
1053 // XDataPilotDataLayoutFieldSupplier
1055 Reference< XDataPilotField > SAL_CALL ScDataPilotDescriptorBase::getDataLayoutField() throw(RuntimeException)
1057 SolarMutexGuard aGuard;
1058 if( ScDPObject* pDPObject = GetDPObject() )
1060 if( ScDPSaveData* pSaveData = pDPObject->GetSaveData() )
1062 if( pSaveData->GetDataLayoutDimension() )
1064 ScFieldIdentifier aFieldId( OUString( SC_DATALAYOUT_NAME ), 0, true );
1065 return new ScDataPilotFieldObj( *this, aFieldId );
1069 return 0;
1072 // XUnoTunnel
1074 sal_Int64 SAL_CALL ScDataPilotDescriptorBase::getSomething(
1075 const Sequence<sal_Int8 >& rId ) throw(RuntimeException)
1077 if ( rId.getLength() == 16 &&
1078 0 == memcmp( getUnoTunnelId().getConstArray(),
1079 rId.getConstArray(), 16 ) )
1081 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
1083 return 0;
1086 namespace
1088 class theScDataPilotDescriptorBaseUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScDataPilotDescriptorBaseUnoTunnelId> {};
1091 const Sequence<sal_Int8>& ScDataPilotDescriptorBase::getUnoTunnelId()
1093 return theScDataPilotDescriptorBaseUnoTunnelId::get().getSeq();
1096 ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation(
1097 const Reference<XDataPilotDescriptor> xObj )
1099 ScDataPilotDescriptorBase* pRet = NULL;
1100 Reference<lang::XUnoTunnel> xUT( xObj, UNO_QUERY );
1101 if (xUT.is())
1102 pRet = reinterpret_cast<ScDataPilotDescriptorBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
1103 return pRet;
1106 //------------------------------------------------------------------------
1108 ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) :
1109 ScDataPilotDescriptorBase( pDocSh ),
1110 nTab( nT ),
1111 aName( rN ),
1112 aModifyListeners( 0 )
1116 ScDataPilotTableObj::~ScDataPilotTableObj()
1120 Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType )
1121 throw(RuntimeException)
1123 // since we manually do resolve the query for XDataPilotTable2
1124 // we also need to do the same for XDataPilotTable
1125 SC_QUERYINTERFACE( XDataPilotTable )
1126 SC_QUERYINTERFACE( XDataPilotTable2 )
1127 SC_QUERYINTERFACE( XModifyBroadcaster )
1129 return ScDataPilotDescriptorBase::queryInterface( rType );
1132 void SAL_CALL ScDataPilotTableObj::acquire() throw()
1134 ScDataPilotDescriptorBase::acquire();
1137 void SAL_CALL ScDataPilotTableObj::release() throw()
1139 ScDataPilotDescriptorBase::release();
1142 Sequence< uno::Type > SAL_CALL ScDataPilotTableObj::getTypes() throw(RuntimeException)
1144 static Sequence< uno::Type > aTypes;
1145 if ( aTypes.getLength() == 0 )
1147 Sequence< uno::Type > aParentTypes = ScDataPilotDescriptorBase::getTypes();
1148 sal_Int32 nParentLen = aParentTypes.getLength();
1149 const uno::Type* pParentPtr = aParentTypes.getConstArray();
1151 aTypes.realloc( nParentLen + 2 );
1152 uno::Type* pPtr = aTypes.getArray();
1153 for (sal_Int32 i = 0; i < nParentLen; ++i)
1154 pPtr[ i ] = pParentPtr[ i ]; // parent types first
1156 pPtr[ nParentLen ] = getCppuType( (const Reference< XDataPilotTable2 >*)0 );
1157 pPtr[ nParentLen+1 ] = getCppuType( (const Reference< XModifyBroadcaster >*)0 );
1159 return aTypes;
1162 namespace
1164 class theScDataPilotTableObjImplementationId : public rtl::Static< UnoTunnelIdInit, theScDataPilotTableObjImplementationId > {};
1167 Sequence<sal_Int8> SAL_CALL ScDataPilotTableObj::getImplementationId()
1168 throw(RuntimeException)
1170 return theScDataPilotTableObjImplementationId::get().getSeq();
1173 // ---
1174 ScDPObject* ScDataPilotTableObj::GetDPObject() const
1176 return lcl_GetDPObject(GetDocShell(), nTab, aName);
1179 void ScDataPilotTableObj::SetDPObject( ScDPObject* pDPObject )
1181 ScDocShell* pDocSh = GetDocShell();
1182 ScDPObject* pDPObj = lcl_GetDPObject(pDocSh, nTab, aName);
1183 if ( pDPObj && pDocSh )
1185 ScDBDocFunc aFunc(*pDocSh);
1186 aFunc.DataPilotUpdate( pDPObj, pDPObject, true, true );
1190 // "rest of XDataPilotDescriptor"
1192 OUString SAL_CALL ScDataPilotTableObj::getName() throw(RuntimeException)
1194 SolarMutexGuard aGuard;
1195 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1196 if (pDPObj)
1197 return pDPObj->GetName();
1198 return OUString();
1201 void SAL_CALL ScDataPilotTableObj::setName( const OUString& aNewName )
1202 throw(RuntimeException)
1204 SolarMutexGuard aGuard;
1205 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1206 if (pDPObj)
1208 //! test for existing names !!!
1210 String aString(aNewName);
1211 pDPObj->SetName( aString ); //! Undo - DBDocFunc ???
1212 aName = aString;
1214 // DataPilotUpdate would do too much (output table is not changed)
1215 GetDocShell()->SetDocumentModified();
1219 OUString SAL_CALL ScDataPilotTableObj::getTag() throw(RuntimeException)
1221 SolarMutexGuard aGuard;
1222 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1223 if (pDPObj)
1224 return pDPObj->GetTag();
1225 return OUString();
1228 void SAL_CALL ScDataPilotTableObj::setTag( const OUString& aNewTag )
1229 throw(RuntimeException)
1231 SolarMutexGuard aGuard;
1232 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1233 if (pDPObj)
1235 String aString(aNewTag);
1236 pDPObj->SetTag( aString ); //! Undo - DBDocFunc ???
1238 // DataPilotUpdate would do too much (output table is not changed)
1239 GetDocShell()->SetDocumentModified();
1243 // XDataPilotTable
1245 CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeException)
1247 SolarMutexGuard aGuard;
1248 CellRangeAddress aRet;
1249 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1250 if (pDPObj)
1252 ScRange aRange(pDPObj->GetOutRange());
1253 aRet.Sheet = aRange.aStart.Tab();
1254 aRet.StartColumn = aRange.aStart.Col();
1255 aRet.StartRow = aRange.aStart.Row();
1256 aRet.EndColumn = aRange.aEnd.Col();
1257 aRet.EndRow = aRange.aEnd.Row();
1259 return aRet;
1262 void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException)
1264 SolarMutexGuard aGuard;
1265 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1266 if (pDPObj)
1268 ScDBDocFunc aFunc(*GetDocShell());
1269 aFunc.RefreshPivotTables(pDPObj, true);
1273 Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr)
1274 throw (RuntimeException)
1276 SolarMutexGuard aGuard;
1277 Sequence< Sequence<Any> > aTabData;
1278 ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1279 ScDPObject* pObj = GetDPObject();
1280 if (!pObj)
1281 throw RuntimeException();
1283 pObj->GetDrillDownData(aAddr2, aTabData);
1284 return aTabData;
1287 DataPilotTablePositionData SAL_CALL ScDataPilotTableObj::getPositionData(const CellAddress& aAddr)
1288 throw (RuntimeException)
1290 SolarMutexGuard aGuard;
1291 DataPilotTablePositionData aPosData;
1292 ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1293 ScDPObject* pObj = GetDPObject();
1294 if (!pObj)
1295 throw RuntimeException();
1297 pObj->GetPositionData(aAddr2, aPosData);
1298 return aPosData;
1301 void SAL_CALL ScDataPilotTableObj::insertDrillDownSheet(const CellAddress& aAddr)
1302 throw (RuntimeException)
1304 SolarMutexGuard aGuard;
1305 ScDPObject* pDPObj = GetDPObject();
1306 if (!pDPObj)
1307 throw RuntimeException();
1309 Sequence<DataPilotFieldFilter> aFilters;
1310 pDPObj->GetDataFieldPositionData(
1311 ScAddress(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet), aFilters);
1312 GetDocShell()->GetBestViewShell()->ShowDataPilotSourceData(*pDPObj, aFilters);
1315 CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
1316 throw (IllegalArgumentException, RuntimeException)
1318 SolarMutexGuard aGuard;
1319 if (nType < 0 || nType > DataPilotOutputRangeType::RESULT)
1320 throw IllegalArgumentException();
1322 CellRangeAddress aRet;
1323 if (ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName))
1324 ScUnoConversion::FillApiRange( aRet, pDPObj->GetOutputRangeByType( nType ) );
1325 return aRet;
1328 void SAL_CALL ScDataPilotTableObj::addModifyListener( const uno::Reference<util::XModifyListener>& aListener )
1329 throw (uno::RuntimeException)
1331 SolarMutexGuard aGuard;
1333 uno::Reference<util::XModifyListener> *pObj = new uno::Reference<util::XModifyListener>( aListener );
1334 aModifyListeners.push_back( pObj );
1336 if ( aModifyListeners.size() == 1 )
1338 acquire(); // don't lose this object (one ref for all listeners)
1342 void SAL_CALL ScDataPilotTableObj::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
1343 throw (uno::RuntimeException)
1345 SolarMutexGuard aGuard;
1347 acquire(); // in case the listeners have the last ref - released below
1349 sal_uInt16 nCount = aModifyListeners.size();
1350 for ( sal_uInt16 n=nCount; n--; )
1352 uno::Reference<util::XModifyListener>& rObj = aModifyListeners[n];
1353 if ( rObj == aListener )
1355 aModifyListeners.erase( aModifyListeners.begin() + n );
1357 if ( aModifyListeners.empty() )
1359 release(); // release the ref for the listeners
1362 break;
1366 release(); // might delete this object
1369 void ScDataPilotTableObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1371 if ( rHint.ISA(ScDataPilotModifiedHint) &&
1372 static_cast<const ScDataPilotModifiedHint&>(rHint).GetName() == aName )
1374 Refreshed_Impl();
1376 else if ( rHint.ISA( ScUpdateRefHint ) )
1378 ScRange aRange( 0, 0, nTab );
1379 ScRangeList aRanges;
1380 aRanges.Append( aRange );
1381 const ScUpdateRefHint& rRef = static_cast< const ScUpdateRefHint& >( rHint );
1382 if ( aRanges.UpdateReference( rRef.GetMode(), GetDocShell()->GetDocument(), rRef.GetRange(),
1383 rRef.GetDx(), rRef.GetDy(), rRef.GetDz() ) &&
1384 aRanges.size() == 1 )
1386 const ScRange* pRange = aRanges.front();
1387 if ( pRange )
1389 nTab = pRange->aStart.Tab();
1394 ScDataPilotDescriptorBase::Notify( rBC, rHint );
1397 void ScDataPilotTableObj::Refreshed_Impl()
1399 lang::EventObject aEvent;
1400 aEvent.Source.set((cppu::OWeakObject*)this);
1402 // the EventObject holds a Ref to this object until after the listener calls
1404 ScDocument* pDoc = GetDocShell()->GetDocument();
1405 for ( sal_uInt16 n=0; n<aModifyListeners.size(); n++ )
1406 pDoc->AddUnoListenerCall( aModifyListeners[n], aEvent );
1409 // ============================================================================
1411 ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) :
1412 ScDataPilotDescriptorBase( pDocSh ),
1413 mpDPObject(new ScDPObject(pDocSh ? pDocSh->GetDocument() : NULL) )
1415 ScDPSaveData aSaveData;
1416 // set defaults like in ScPivotParam constructor
1417 aSaveData.SetColumnGrand( sal_True );
1418 aSaveData.SetRowGrand( sal_True );
1419 aSaveData.SetIgnoreEmptyRows( false );
1420 aSaveData.SetRepeatIfEmpty( false );
1421 mpDPObject->SetSaveData(aSaveData);
1422 ScSheetSourceDesc aSheetDesc(pDocSh ? pDocSh->GetDocument() : NULL);
1423 mpDPObject->SetSheetDesc(aSheetDesc);
1424 mpDPObject->GetSource();
1427 ScDataPilotDescriptor::~ScDataPilotDescriptor()
1429 delete mpDPObject;
1432 ScDPObject* ScDataPilotDescriptor::GetDPObject() const
1434 return mpDPObject;
1437 void ScDataPilotDescriptor::SetDPObject( ScDPObject* pDPObject )
1439 if (mpDPObject != pDPObject)
1441 delete mpDPObject;
1442 mpDPObject = pDPObject;
1443 OSL_FAIL("replace DPObject should not happen");
1447 // "rest of XDataPilotDescriptor"
1449 OUString SAL_CALL ScDataPilotDescriptor::getName() throw(RuntimeException)
1451 SolarMutexGuard aGuard;
1452 return mpDPObject->GetName();
1455 void SAL_CALL ScDataPilotDescriptor::setName( const OUString& aNewName )
1456 throw(RuntimeException)
1458 SolarMutexGuard aGuard;
1459 mpDPObject->SetName( aNewName );
1462 OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(RuntimeException)
1464 SolarMutexGuard aGuard;
1465 return mpDPObject->GetTag();
1468 void SAL_CALL ScDataPilotDescriptor::setTag( const OUString& aNewTag )
1469 throw(RuntimeException)
1471 SolarMutexGuard aGuard;
1472 mpDPObject->SetTag( aNewTag );
1475 // ============================================================================
1477 ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent ) :
1478 mrParent( rParent )
1480 mrParent.acquire();
1483 ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1484 mrParent( rParent ),
1485 maFieldId( rFieldId )
1487 mrParent.acquire();
1490 ScDataPilotChildObjBase::~ScDataPilotChildObjBase()
1492 mrParent.release();
1495 ScDPObject* ScDataPilotChildObjBase::GetDPObject() const
1497 return mrParent.GetDPObject();
1500 void ScDataPilotChildObjBase::SetDPObject( ScDPObject* pDPObject )
1502 mrParent.SetDPObject( pDPObject );
1505 ScDPSaveDimension* ScDataPilotChildObjBase::GetDPDimension( ScDPObject** ppDPObject ) const
1507 if( ScDPObject* pDPObj = GetDPObject() )
1509 if( ppDPObject ) *ppDPObject = pDPObj;
1510 if( ScDPSaveData* pSaveData = pDPObj->GetSaveData() )
1512 if( maFieldId.mbDataLayout )
1513 return pSaveData->GetDataLayoutDimension();
1515 if( maFieldId.mnFieldIdx == 0 )
1516 return pSaveData->GetDimensionByName( maFieldId.maFieldName );
1518 // find dimension with specified index (search in duplicated dimensions)
1519 const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
1521 sal_Int32 nFoundIdx = 0;
1522 boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
1523 for(it = rDimensions.begin(); it != rDimensions.end(); ++it)
1525 if( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
1527 if( nFoundIdx == maFieldId.mnFieldIdx )
1528 return const_cast<ScDPSaveDimension*>(&(*it));
1529 ++nFoundIdx;
1534 return 0;
1537 sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
1539 sal_Int32 nRet = 0;
1540 Reference<XNameAccess> xMembersNA = GetMembers();
1541 if (xMembersNA.is())
1543 Reference< XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
1544 nRet = xMembersIA->getCount();
1546 return nRet;
1549 Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
1551 Reference< XNameAccess > xMembersNA;
1552 if( ScDPObject* pDPObj = GetDPObject() )
1553 pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
1554 return xMembersNA;
1557 ScDocShell* ScDataPilotChildObjBase::GetDocShell() const
1559 return mrParent.GetDocShell();
1562 // ============================================================================
1564 ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent ) :
1565 ScDataPilotChildObjBase( rParent )
1569 ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent, DataPilotFieldOrientation eOrient ) :
1570 ScDataPilotChildObjBase( rParent ),
1571 maOrient( eOrient )
1575 ScDataPilotFieldsObj::~ScDataPilotFieldsObj()
1579 static sal_Int32 lcl_GetFieldCount( const Reference<XDimensionsSupplier>& rSource, const Any& rOrient )
1581 if (!rSource.is())
1582 throw RuntimeException();
1584 sal_Int32 nRet = 0;
1586 Reference<XNameAccess> xDimsName(rSource->getDimensions());
1587 Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1588 sal_Int32 nIntCount = xIntDims->getCount();
1589 if (rOrient.hasValue())
1591 // all fields of the specified orientation, including duplicated
1592 Reference<XPropertySet> xDim;
1593 for (sal_Int32 i = 0; i < nIntCount; ++i)
1595 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1596 if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1597 ++nRet;
1600 else
1602 // count all non-duplicated fields
1604 Reference<XPropertySet> xDim;
1605 for (sal_Int32 i = 0; i < nIntCount; ++i)
1607 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1608 if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1609 ++nRet;
1613 return nRet;
1616 static sal_Bool lcl_GetFieldDataByIndex( const Reference<XDimensionsSupplier>& rSource,
1617 const Any& rOrient, SCSIZE nIndex, ScFieldIdentifier& rFieldId )
1619 if (!rSource.is())
1620 throw RuntimeException();
1622 sal_Bool bOk = false;
1623 SCSIZE nPos = 0;
1624 sal_Int32 nDimIndex = 0;
1626 Reference<XNameAccess> xDimsName(rSource->getDimensions());
1627 Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1628 sal_Int32 nIntCount = xIntDims->getCount();
1629 Reference<XPropertySet> xDim;
1630 if (rOrient.hasValue())
1632 sal_Int32 i = 0;
1633 while (i < nIntCount && !bOk)
1635 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1636 if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1638 if (nPos == nIndex)
1640 bOk = sal_True;
1641 nDimIndex = i;
1643 else
1644 ++nPos;
1646 ++i;
1649 else
1651 sal_Int32 i = 0;
1652 while (i < nIntCount && !bOk)
1654 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1655 if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1657 if (nPos == nIndex)
1659 bOk = sal_True;
1660 nDimIndex = i;
1662 else
1663 ++nPos;
1665 ++i;
1669 if ( bOk )
1671 xDim.set( xIntDims->getByIndex(nDimIndex), UNO_QUERY );
1672 Reference<XNamed> xDimName( xDim, UNO_QUERY );
1673 if ( xDimName.is() )
1675 OUString sOriginalName( lcl_GetOriginalName( xDimName ) );
1676 rFieldId.maFieldName = sOriginalName;
1677 rFieldId.mbDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDim,
1678 OUString(SC_UNO_DP_ISDATALAYOUT) );
1680 sal_Int32 nRepeat = 0;
1681 if ( rOrient.hasValue() && lcl_IsDuplicated( xDim ) )
1683 // find the repeat count
1684 // (this relies on the original dimension always being before the duplicates)
1686 Reference<XNamed> xPrevName;
1687 for (sal_Int32 i = 0; i < nDimIndex; ++i)
1689 xPrevName.set( xIntDims->getByIndex(i), UNO_QUERY );
1690 if ( xPrevName.is() && lcl_GetOriginalName( xPrevName ) == sOriginalName )
1691 ++nRepeat;
1694 rFieldId.mnFieldIdx = nRepeat;
1696 else
1697 bOk = false;
1700 return bOk;
1703 static sal_Bool lcl_GetFieldDataByName( ScDPObject* pDPObj, const OUString& rFieldName, ScFieldIdentifier& rFieldId )
1705 // "By name" is always the first match.
1706 // The name "Data" always refers to the data layout field.
1707 rFieldId.maFieldName = rFieldName;
1708 rFieldId.mnFieldIdx = 0;
1709 rFieldId.mbDataLayout = rFieldName == SC_DATALAYOUT_NAME;
1711 pDPObj->GetSource(); // IsDimNameInUse doesn't update source data
1713 // check if the named field exists (not for data layout)
1714 return rFieldId.mbDataLayout || pDPObj->IsDimNameInUse( rFieldName );
1717 // XDataPilotFields
1719 ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
1721 // TODO
1722 if (ScDPObject* pObj = GetDPObject())
1724 ScFieldIdentifier aFieldId;
1725 if (lcl_GetFieldDataByIndex( pObj->GetSource(), maOrient, nIndex, aFieldId ))
1726 return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1728 return 0;
1731 ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const OUString& aName) const
1733 if (ScDPObject* pDPObj = GetDPObject())
1735 ScFieldIdentifier aFieldId;
1736 if (lcl_GetFieldDataByName( pDPObj, aName, aFieldId ))
1737 return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1739 return 0;
1742 // XEnumerationAccess
1744 Reference<XEnumeration> SAL_CALL ScDataPilotFieldsObj::createEnumeration()
1745 throw(RuntimeException)
1747 SolarMutexGuard aGuard;
1748 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotFieldsEnumeration"));
1751 // XIndexAccess
1753 sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(RuntimeException)
1755 SolarMutexGuard aGuard;
1756 // TODO
1757 ScDPObject* pDPObj = GetDPObject();
1758 return pDPObj ? lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) : 0;
1761 Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex )
1762 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
1764 SolarMutexGuard aGuard;
1765 Reference< XPropertySet > xField( GetObjectByIndex_Impl( nIndex ) );
1766 if (!xField.is())
1767 throw IndexOutOfBoundsException();
1768 return Any( xField );
1771 uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(RuntimeException)
1773 SolarMutexGuard aGuard;
1774 return getCppuType((Reference<XPropertySet>*)0);
1777 sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(RuntimeException)
1779 SolarMutexGuard aGuard;
1780 return ( getCount() != 0 );
1783 Any SAL_CALL ScDataPilotFieldsObj::getByName( const OUString& aName )
1784 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
1786 SolarMutexGuard aGuard;
1787 Reference<XPropertySet> xField(GetObjectByName_Impl(aName));
1788 if (!xField.is())
1789 throw NoSuchElementException();
1790 return Any( xField );
1793 Sequence<OUString> SAL_CALL ScDataPilotFieldsObj::getElementNames()
1794 throw(RuntimeException)
1796 SolarMutexGuard aGuard;
1797 // TODO
1798 if (ScDPObject* pDPObj = GetDPObject())
1800 Sequence< OUString > aSeq( lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) );
1801 OUString* pAry = aSeq.getArray();
1803 const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pDPObj->GetSaveData()->GetDimensions();
1804 boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
1805 for (it = rDimensions.begin(); it != rDimensions.end(); ++it)
1807 if(maOrient.hasValue() && (it->GetOrientation() == maOrient.get< DataPilotFieldOrientation >()))
1809 *pAry = it->GetName();
1810 ++pAry;
1813 return aSeq;
1815 return Sequence<OUString>();
1818 sal_Bool SAL_CALL ScDataPilotFieldsObj::hasByName( const OUString& aName )
1819 throw(RuntimeException)
1821 SolarMutexGuard aGuard;
1823 return GetObjectByName_Impl(aName) != NULL;
1826 //------------------------------------------------------------------------
1828 ScDataPilotFieldObj::ScDataPilotFieldObj(
1829 ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1830 ScDataPilotChildObjBase( rParent, rFieldId ),
1831 maPropSet( lcl_GetDataPilotFieldMap() )
1835 ScDataPilotFieldObj::ScDataPilotFieldObj( ScDataPilotDescriptorBase& rParent,
1836 const ScFieldIdentifier& rFieldId, const Any& rOrient ) :
1837 ScDataPilotChildObjBase( rParent, rFieldId ),
1838 maPropSet( lcl_GetDataPilotFieldMap() ),
1839 maOrient( rOrient )
1843 ScDataPilotFieldObj::~ScDataPilotFieldObj()
1847 // XNamed
1849 OUString SAL_CALL ScDataPilotFieldObj::getName() throw(RuntimeException)
1851 SolarMutexGuard aGuard;
1852 OUString aName;
1853 if( ScDPSaveDimension* pDim = GetDPDimension() )
1855 if( pDim->IsDataLayout() )
1856 aName = OUString( SC_DATALAYOUT_NAME );
1857 else
1859 const OUString* pLayoutName = pDim->GetLayoutName();
1860 if (pLayoutName)
1861 aName = *pLayoutName;
1862 else
1863 aName = pDim->GetName();
1865 return aName;
1868 void SAL_CALL ScDataPilotFieldObj::setName( const OUString& rName ) throw(RuntimeException)
1870 SolarMutexGuard aGuard;
1871 ScDPObject* pDPObj = 0;
1872 ScDPSaveDimension* pDim = GetDPDimension( &pDPObj );
1873 if( pDim && !pDim->IsDataLayout() )
1875 String aName( rName );
1876 pDim->SetLayoutName(aName);
1877 SetDPObject( pDPObj );
1881 // XPropertySet
1883 Reference<XPropertySetInfo> SAL_CALL ScDataPilotFieldObj::getPropertySetInfo()
1884 throw(RuntimeException)
1886 SolarMutexGuard aGuard;
1887 static Reference<XPropertySetInfo> aRef(
1888 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() ));
1889 return aRef;
1892 void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
1893 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
1895 SolarMutexGuard aGuard;
1896 String aNameString(aPropertyName);
1897 if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) )
1899 // #i109350# use GetEnumFromAny because it also allows sal_Int32
1900 GeneralFunction eFunction = (GeneralFunction)
1901 ScUnoHelpFunctions::GetEnumFromAny( aValue );
1902 setFunction( eFunction );
1904 else if ( aNameString.EqualsAscii( SC_UNONAME_SUBTOTALS ) )
1906 Sequence< GeneralFunction > aSubtotals;
1907 if( aValue >>= aSubtotals )
1908 setSubtotals( aSubtotals );
1910 else if ( aNameString.EqualsAscii( SC_UNONAME_ORIENT ) )
1912 //! test for correct enum type?
1913 DataPilotFieldOrientation eOrient = (DataPilotFieldOrientation)
1914 ScUnoHelpFunctions::GetEnumFromAny( aValue );
1915 setOrientation( eOrient );
1917 else if ( aNameString.EqualsAscii( SC_UNONAME_SELPAGE ) )
1919 OUString sCurrentPage;
1920 if (aValue >>= sCurrentPage)
1921 setCurrentPage(sCurrentPage);
1923 else if ( aNameString.EqualsAscii( SC_UNONAME_USESELPAGE ) )
1925 setUseCurrentPage(cppu::any2bool(aValue));
1927 else if ( aNameString.EqualsAscii( SC_UNONAME_HASAUTOSHOW ) )
1929 if (!cppu::any2bool(aValue))
1930 setAutoShowInfo(NULL);
1932 else if ( aNameString.EqualsAscii( SC_UNONAME_AUTOSHOW ) )
1934 DataPilotFieldAutoShowInfo aInfo;
1935 if (aValue >>= aInfo)
1936 setAutoShowInfo(&aInfo);
1938 else if ( aNameString.EqualsAscii( SC_UNONAME_HASLAYOUTINFO ) )
1940 if (!cppu::any2bool(aValue))
1941 setLayoutInfo(NULL);
1943 else if ( aNameString.EqualsAscii( SC_UNONAME_LAYOUTINFO ) )
1945 DataPilotFieldLayoutInfo aInfo;
1946 if (aValue >>= aInfo)
1947 setLayoutInfo(&aInfo);
1949 else if ( aNameString.EqualsAscii( SC_UNONAME_HASREFERENCE ) )
1951 if (!cppu::any2bool(aValue))
1952 setReference(NULL);
1954 else if ( aNameString.EqualsAscii( SC_UNONAME_REFERENCE ) )
1956 DataPilotFieldReference aRef;
1957 if (aValue >>= aRef)
1958 setReference(&aRef);
1960 else if ( aNameString.EqualsAscii( SC_UNONAME_HASSORTINFO ) )
1962 if (!cppu::any2bool(aValue))
1963 setSortInfo(NULL);
1965 else if ( aNameString.EqualsAscii( SC_UNONAME_SORTINFO ) )
1967 DataPilotFieldSortInfo aInfo;
1968 if (aValue >>= aInfo)
1969 setSortInfo(&aInfo);
1971 else if ( aNameString.EqualsAscii( SC_UNONAME_ISGROUP ) )
1973 if (!cppu::any2bool(aValue))
1974 setGroupInfo(NULL);
1976 else if ( aNameString.EqualsAscii( SC_UNONAME_GROUPINFO ) )
1978 DataPilotFieldGroupInfo aInfo;
1979 if (aValue >>= aInfo)
1980 setGroupInfo(&aInfo);
1982 else if ( aNameString.EqualsAscii( SC_UNONAME_SHOWEMPTY ) )
1984 setShowEmpty(cppu::any2bool(aValue));
1988 Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName )
1989 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
1991 SolarMutexGuard aGuard;
1992 String aNameString(aPropertyName);
1993 Any aRet;
1995 if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) )
1996 aRet <<= getFunction();
1997 else if ( aNameString.EqualsAscii( SC_UNONAME_SUBTOTALS ) )
1998 aRet <<= getSubtotals();
1999 else if ( aNameString.EqualsAscii( SC_UNONAME_ORIENT ) )
2000 aRet <<= getOrientation();
2001 else if ( aNameString.EqualsAscii( SC_UNONAME_SELPAGE ) )
2002 aRet <<= getCurrentPage();
2003 else if ( aNameString.EqualsAscii( SC_UNONAME_USESELPAGE ) )
2004 aRet <<= getUseCurrentPage();
2005 else if ( aNameString.EqualsAscii( SC_UNONAME_HASAUTOSHOW ) )
2006 aRet = ::cppu::bool2any(getAutoShowInfo() != NULL);
2007 else if ( aNameString.EqualsAscii( SC_UNONAME_AUTOSHOW ) )
2009 const DataPilotFieldAutoShowInfo* pInfo = getAutoShowInfo();
2010 if (pInfo)
2011 aRet <<= DataPilotFieldAutoShowInfo(*pInfo);
2013 else if ( aNameString.EqualsAscii( SC_UNONAME_HASLAYOUTINFO ) )
2014 aRet = ::cppu::bool2any(getLayoutInfo() != NULL);
2015 else if ( aNameString.EqualsAscii( SC_UNONAME_LAYOUTINFO ) )
2017 const DataPilotFieldLayoutInfo* pInfo = getLayoutInfo();
2018 if (pInfo)
2019 aRet <<= DataPilotFieldLayoutInfo(*pInfo);
2021 else if ( aNameString.EqualsAscii( SC_UNONAME_HASREFERENCE ) )
2022 aRet = ::cppu::bool2any(getReference() != NULL);
2023 else if ( aNameString.EqualsAscii( SC_UNONAME_REFERENCE ) )
2025 const DataPilotFieldReference* pRef = getReference();
2026 if (pRef)
2027 aRet <<= DataPilotFieldReference(*pRef);
2029 else if ( aNameString.EqualsAscii( SC_UNONAME_HASSORTINFO ) )
2030 aRet = ::cppu::bool2any(getSortInfo() != NULL);
2031 else if ( aNameString.EqualsAscii( SC_UNONAME_SORTINFO ) )
2033 const DataPilotFieldSortInfo* pInfo = getSortInfo();
2034 if (pInfo)
2035 aRet <<= DataPilotFieldSortInfo(*pInfo);
2037 else if ( aNameString.EqualsAscii( SC_UNONAME_ISGROUP ) )
2038 aRet = ::cppu::bool2any(hasGroupInfo());
2039 else if ( aNameString.EqualsAscii( SC_UNONAME_GROUPINFO ) )
2041 aRet <<= getGroupInfo();
2043 else if ( aNameString.EqualsAscii( SC_UNONAME_SHOWEMPTY ) )
2044 aRet <<= getShowEmpty();
2046 return aRet;
2049 // XDatePilotField
2051 Reference<XIndexAccess> SAL_CALL ScDataPilotFieldObj::getItems()
2052 throw (RuntimeException)
2054 SolarMutexGuard aGuard;
2055 if (!mxItems.is())
2056 mxItems.set( new ScDataPilotItemsObj( mrParent, maFieldId ) );
2057 return mxItems;
2060 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj )
2062 DataPilotFieldOrientation ScDataPilotFieldObj::getOrientation() const
2064 SolarMutexGuard aGuard;
2065 ScDPSaveDimension* pDim = GetDPDimension();
2066 return pDim ? static_cast< DataPilotFieldOrientation >( pDim->GetOrientation() ) : DataPilotFieldOrientation_HIDDEN;
2069 void ScDataPilotFieldObj::setOrientation(DataPilotFieldOrientation eNew)
2071 SolarMutexGuard aGuard;
2072 if (maOrient.hasValue() && (eNew == maOrient.get< DataPilotFieldOrientation >()))
2073 return;
2075 ScDPObject* pDPObj = 0;
2076 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2078 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2080 /* If the field was taken from getDataPilotFields(), don't reset the
2081 orientation for an existing use, but create a duplicated field
2082 instead (for "Data" orientation only). */
2083 if ( !maOrient.hasValue() && !maFieldId.mbDataLayout &&
2084 (pDim->GetOrientation() != DataPilotFieldOrientation_HIDDEN) &&
2085 (eNew == DataPilotFieldOrientation_DATA) )
2088 ScDPSaveDimension* pNewDim = 0;
2090 // look for existing duplicate with orientation "hidden"
2092 sal_Int32 nFound = 0;
2093 const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
2094 boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
2095 for ( it = rDimensions.begin(); it != rDimensions.end() && !pNewDim; ++it )
2097 if ( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
2099 if ( it->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2100 pNewDim = const_cast<ScDPSaveDimension*>(&(*it)); // use this one
2101 else
2102 ++nFound; // count existing non-hidden occurrences
2106 if ( !pNewDim ) // if none found, create a new duplicated dimension
2107 pNewDim = &pSaveData->DuplicateDimension( *pDim );
2109 maFieldId.mnFieldIdx = nFound; // keep accessing the new one
2110 pDim = pNewDim;
2113 pDim->SetOrientation(sal::static_int_cast<sal_uInt16>(eNew));
2115 // move changed field behind all other fields (make it the last field in dimension)
2116 pSaveData->SetPosition( pDim, pSaveData->GetDimensions().size() );
2118 SetDPObject( pDPObj );
2120 maOrient <<= eNew; // modifying the same object's orientation again doesn't create another duplicate
2124 GeneralFunction ScDataPilotFieldObj::getFunction() const
2126 SolarMutexGuard aGuard;
2127 GeneralFunction eRet = GeneralFunction_NONE;
2128 if( ScDPSaveDimension* pDim = GetDPDimension() )
2130 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2132 // for non-data fields, property Function is the subtotals
2133 long nSubCount = pDim->GetSubTotalsCount();
2134 if ( nSubCount > 0 )
2135 eRet = (GeneralFunction)pDim->GetSubTotalFunc(0); // always use the first one
2136 // else keep NONE
2138 else
2139 eRet = (GeneralFunction)pDim->GetFunction();
2141 return eRet;
2144 void ScDataPilotFieldObj::setFunction(GeneralFunction eNewFunc)
2146 SolarMutexGuard aGuard;
2147 ScDPObject* pDPObj = 0;
2148 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2150 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2152 // for non-data fields, property Function is the subtotals
2153 if ( eNewFunc == GeneralFunction_NONE )
2154 pDim->SetSubTotals( 0, NULL );
2155 else
2157 sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( eNewFunc );
2158 pDim->SetSubTotals( 1, &nFunc );
2161 else
2162 pDim->SetFunction( sal::static_int_cast<sal_uInt16>( eNewFunc ) );
2163 SetDPObject( pDPObj );
2167 Sequence< GeneralFunction > ScDataPilotFieldObj::getSubtotals() const
2169 SolarMutexGuard aGuard;
2170 Sequence< GeneralFunction > aRet;
2171 if( ScDPSaveDimension* pDim = GetDPDimension() )
2173 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2175 // for non-data fields, property Functions is the sequence of subtotals
2176 sal_Int32 nCount = static_cast< sal_Int32 >( pDim->GetSubTotalsCount() );
2177 if ( nCount > 0 )
2179 aRet.realloc( nCount );
2180 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2181 aRet[ nIdx ] = (GeneralFunction)pDim->GetSubTotalFunc( nIdx );
2185 return aRet;
2188 void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubtotals )
2190 SolarMutexGuard aGuard;
2191 ScDPObject* pDPObj = 0;
2192 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2194 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2196 sal_Int32 nCount = rSubtotals.getLength();
2197 if( nCount == 1 )
2199 // count 1: all values are allowed (including NONE and AUTO)
2200 if( rSubtotals[ 0 ] == GeneralFunction_NONE )
2201 pDim->SetSubTotals( 0, NULL );
2202 else
2204 sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( rSubtotals[ 0 ] );
2205 pDim->SetSubTotals( 1, &nFunc );
2208 else if( nCount > 1 )
2210 // set multiple functions, ignore NONE and AUTO in this case
2211 ::std::vector< sal_uInt16 > aSubt;
2212 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2214 GeneralFunction eFunc = rSubtotals[ nIdx ];
2215 if( (eFunc != GeneralFunction_NONE) && (eFunc != GeneralFunction_AUTO) )
2217 // do not insert functions twice
2218 sal_uInt16 nFunc = static_cast< sal_uInt16 >( eFunc );
2219 if( ::std::find( aSubt.begin(), aSubt.end(), nFunc ) == aSubt.end() )
2220 aSubt.push_back( nFunc );
2223 // set values from vector to ScDPSaveDimension
2224 if ( aSubt.empty() )
2225 pDim->SetSubTotals( 0, NULL );
2226 else
2227 pDim->SetSubTotals( static_cast< long >( aSubt.size() ), &aSubt.front() );
2230 SetDPObject( pDPObj );
2234 OUString ScDataPilotFieldObj::getCurrentPage() const
2236 return OUString();
2239 void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage )
2241 SolarMutexGuard aGuard;
2242 ScDPObject* pDPObj = 0;
2243 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2245 pDim->SetCurrentPage( &rPage );
2246 SetDPObject( pDPObj );
2250 sal_Bool ScDataPilotFieldObj::getUseCurrentPage() const
2252 return false;
2255 void ScDataPilotFieldObj::setUseCurrentPage( sal_Bool bUse )
2257 SolarMutexGuard aGuard;
2258 ScDPObject* pDPObj = 0;
2259 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2261 if( bUse )
2263 /* It is somehow useless to set the property "HasSelectedPage" to
2264 true, because it is still needed to set an explicit page name. */
2265 const OUString aPage;
2266 pDim->SetCurrentPage( &aPage );
2268 else
2269 pDim->SetCurrentPage( 0 );
2270 SetDPObject( pDPObj );
2274 const DataPilotFieldAutoShowInfo* ScDataPilotFieldObj::getAutoShowInfo()
2276 SolarMutexGuard aGuard;
2277 ScDPSaveDimension* pDim = GetDPDimension();
2278 return pDim ? pDim->GetAutoShowInfo() : 0;
2281 void ScDataPilotFieldObj::setAutoShowInfo( const DataPilotFieldAutoShowInfo* pInfo )
2283 SolarMutexGuard aGuard;
2284 ScDPObject* pDPObj = 0;
2285 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2287 pDim->SetAutoShowInfo( pInfo );
2288 SetDPObject( pDPObj );
2292 const DataPilotFieldLayoutInfo* ScDataPilotFieldObj::getLayoutInfo()
2294 SolarMutexGuard aGuard;
2295 ScDPSaveDimension* pDim = GetDPDimension();
2296 return pDim ? pDim->GetLayoutInfo() : 0;
2299 void ScDataPilotFieldObj::setLayoutInfo( const DataPilotFieldLayoutInfo* pInfo )
2301 SolarMutexGuard aGuard;
2302 ScDPObject* pDPObj = 0;
2303 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2305 pDim->SetLayoutInfo( pInfo );
2306 SetDPObject( pDPObj );
2310 const DataPilotFieldReference* ScDataPilotFieldObj::getReference()
2312 SolarMutexGuard aGuard;
2313 ScDPSaveDimension* pDim = GetDPDimension();
2314 return pDim ? pDim->GetReferenceValue() : 0;
2317 void ScDataPilotFieldObj::setReference( const DataPilotFieldReference* pInfo )
2319 SolarMutexGuard aGuard;
2320 ScDPObject* pDPObj = 0;
2321 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2323 pDim->SetReferenceValue( pInfo );
2324 SetDPObject( pDPObj );
2328 const DataPilotFieldSortInfo* ScDataPilotFieldObj::getSortInfo()
2330 SolarMutexGuard aGuard;
2331 ScDPSaveDimension* pDim = GetDPDimension();
2332 return pDim ? pDim->GetSortInfo() : 0;
2335 void ScDataPilotFieldObj::setSortInfo( const DataPilotFieldSortInfo* pInfo )
2337 SolarMutexGuard aGuard;
2338 ScDPObject* pDPObj = 0;
2339 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2341 pDim->SetSortInfo( pInfo );
2342 SetDPObject( pDPObj );
2346 sal_Bool ScDataPilotFieldObj::getShowEmpty() const
2348 SolarMutexGuard aGuard;
2349 ScDPSaveDimension* pDim = GetDPDimension();
2350 return pDim && pDim->GetShowEmpty();
2353 void ScDataPilotFieldObj::setShowEmpty( sal_Bool bShow )
2355 SolarMutexGuard aGuard;
2356 ScDPObject* pDPObj = 0;
2357 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2359 pDim->SetShowEmpty( bShow );
2360 SetDPObject( pDPObj );
2364 sal_Bool ScDataPilotFieldObj::hasGroupInfo()
2366 SolarMutexGuard aGuard;
2367 ScDPObject* pDPObj = 0;
2368 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2369 if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2370 return pDimData->GetNamedGroupDim( pDim->GetName() ) || pDimData->GetNumGroupDim( pDim->GetName() );
2371 return false;
2374 DataPilotFieldGroupInfo ScDataPilotFieldObj::getGroupInfo()
2376 SolarMutexGuard aGuard;
2377 DataPilotFieldGroupInfo aInfo;
2378 ScDPObject* pDPObj = 0;
2379 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2381 if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2383 if( const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( pDim->GetName() ) )
2385 // grouped by ...
2386 aInfo.GroupBy = pGroupDim->GetDatePart();
2388 // find source field
2391 Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2392 aInfo.SourceField.set( xFields->getByName( pGroupDim->GetSourceDimName() ), UNO_QUERY );
2394 catch( Exception& )
2398 ScDataPilotConversion::FillGroupInfo( aInfo, pGroupDim->GetDateInfo() );
2399 if( pGroupDim->GetDatePart() == 0 )
2401 // fill vector of group and group member information
2402 ScFieldGroups aGroups;
2403 for( sal_Int32 nIdx = 0, nCount = pGroupDim->GetGroupCount(); nIdx < nCount; ++nIdx )
2405 if( const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( nIdx ) )
2407 ScFieldGroup aGroup;
2408 aGroup.maName = pGroup->GetGroupName();
2409 for( sal_Int32 nMemIdx = 0, nMemCount = pGroup->GetElementCount(); nMemIdx < nMemCount; ++nMemIdx )
2410 if (const OUString* pMem = pGroup->GetElementByIndex(nMemIdx))
2411 aGroup.maMembers.push_back( *pMem );
2412 aGroups.push_back( aGroup );
2415 aInfo.Groups = new ScDataPilotFieldGroupsObj( aGroups );
2418 else if( const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( pDim->GetName() ) )
2420 if (pNumGroupDim->GetDatePart())
2422 ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetDateInfo() );
2423 aInfo.GroupBy = pNumGroupDim->GetDatePart();
2425 else
2427 ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetInfo() );
2432 return aInfo;
2435 void ScDataPilotFieldObj::setGroupInfo( const DataPilotFieldGroupInfo* pInfo )
2437 SolarMutexGuard aGuard;
2438 ScDPObject* pDPObj = 0;
2439 if( /*ScDPSaveDimension* pDim =*/ GetDPDimension( &pDPObj ) )
2441 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2442 if( pInfo && lclCheckMinMaxStep( *pInfo ) )
2444 ScDPNumGroupInfo aInfo;
2445 aInfo.mbEnable = sal_True;
2446 aInfo.mbDateValues = pInfo->HasDateValues;
2447 aInfo.mbAutoStart = pInfo->HasAutoStart;
2448 aInfo.mbAutoEnd = pInfo->HasAutoEnd;
2449 aInfo.mfStart = pInfo->Start;
2450 aInfo.mfEnd = pInfo->End;
2451 aInfo.mfStep = pInfo->Step;
2452 Reference< XNamed > xNamed( pInfo->SourceField, UNO_QUERY );
2453 if( xNamed.is() )
2455 ScDPSaveGroupDimension aGroupDim( xNamed->getName(), getName() );
2456 if( pInfo->GroupBy )
2457 aGroupDim.SetDateInfo(aInfo, pInfo->GroupBy);
2458 else
2460 Reference<XIndexAccess> xIndex(pInfo->Groups, UNO_QUERY);
2461 if (xIndex.is())
2463 sal_Int32 nCount(xIndex->getCount());
2464 for(sal_Int32 i = 0; i < nCount; i++)
2466 Reference<XNamed> xGroupNamed(xIndex->getByIndex(i), UNO_QUERY);
2467 if (xGroupNamed.is())
2469 ScDPSaveGroupItem aItem(xGroupNamed->getName());
2470 Reference<XIndexAccess> xGroupIndex(xGroupNamed, UNO_QUERY);
2471 if (xGroupIndex.is())
2473 sal_Int32 nItemCount(xGroupIndex->getCount());
2474 for (sal_Int32 j = 0; j < nItemCount; ++j)
2476 Reference<XNamed> xItemNamed(xGroupIndex->getByIndex(j), UNO_QUERY);
2477 if (xItemNamed.is())
2478 aItem.AddElement(xItemNamed->getName());
2481 aGroupDim.AddGroupItem(aItem);
2487 // get dimension savedata or create new if none
2488 ScDPDimensionSaveData& rDimSaveData = *pSaveData->GetDimensionData();
2489 rDimSaveData.ReplaceGroupDimension( aGroupDim );
2491 else // no source field in group info -> numeric group
2493 ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData(); // created if not there
2495 ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( getName() );
2496 if ( pExisting )
2498 if (pInfo->GroupBy)
2499 pExisting->SetDateInfo(aInfo, pInfo->GroupBy);
2500 // modify existing group dimension
2501 pExisting->SetGroupInfo( aInfo );
2503 else if (pInfo->GroupBy)
2505 // create new group dimension
2506 ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo, pInfo->GroupBy );
2507 pDimData->AddNumGroupDimension( aNumGroupDim );
2509 else
2511 // create new group dimension
2512 ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo );
2513 pDimData->AddNumGroupDimension( aNumGroupDim );
2517 else // null passed as argument
2519 pSaveData->SetDimensionData( 0 );
2522 pDPObj->SetSaveData( *pSaveData );
2523 SetDPObject( pDPObj );
2527 sal_Bool ScDataPilotFieldObj::HasString(const Sequence< OUString >& rItems, const OUString& aString)
2529 sal_Bool bRet = false;
2531 sal_Int32 nCount(rItems.getLength());
2532 sal_Int32 nItem(0);
2533 while (nItem < nCount && !bRet)
2535 bRet = rItems[nItem] == aString;
2536 ++nItem;
2539 return bRet;
2542 // XDataPilotFieldGrouping
2543 Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( const Sequence< OUString >& rItems )
2544 throw (RuntimeException, IllegalArgumentException)
2546 SolarMutexGuard aGuard;
2548 Reference< XDataPilotField > xRet;
2549 OUString sNewDim;
2551 if( !rItems.hasElements() )
2552 throw IllegalArgumentException();
2554 ScDPObject* pDPObj = 0;
2555 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2557 OUString aDimName = pDim->GetName();
2559 ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2560 ScDPDimensionSaveData* pDimData = aSaveData.GetDimensionData(); // created if not there
2562 // find original base
2563 OUString aBaseDimName( aDimName );
2564 const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
2565 if ( pBaseGroupDim )
2567 // any entry's SourceDimName is the original base
2568 aBaseDimName = pBaseGroupDim->GetSourceDimName();
2571 // find existing group dimension
2572 // (using the selected dim, can be intermediate group dim)
2573 ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
2575 // remove the selected items from their groups
2576 // (empty groups are removed, too)
2577 sal_Int32 nEntryCount = rItems.getLength();
2578 sal_Int32 nEntry;
2579 if ( pGroupDimension )
2581 for (nEntry=0; nEntry<nEntryCount; nEntry++)
2583 const OUString& aEntryName = rItems[nEntry];
2584 if ( pBaseGroupDim )
2586 // for each selected (intermediate) group, remove all its items
2587 // (same logic as for adding, below)
2588 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2589 if ( pBaseGroup )
2590 pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements
2591 else
2592 pGroupDimension->RemoveFromGroups( aEntryName );
2594 else
2595 pGroupDimension->RemoveFromGroups( aEntryName );
2599 ScDPSaveGroupDimension* pNewGroupDim = 0;
2600 if ( !pGroupDimension )
2602 // create a new group dimension
2603 sNewDim = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
2604 pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, sNewDim );
2606 pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
2608 if ( pBaseGroupDim )
2610 // If it's a higher-order group dimension, pre-allocate groups for all
2611 // non-selected original groups, so the individual base members aren't
2612 // used for automatic groups (this would make the original groups hard
2613 // to find).
2614 //! Also do this when removing groups?
2615 //! Handle this case dynamically with automatic groups?
2617 long nGroupCount = pBaseGroupDim->GetGroupCount();
2618 for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
2620 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
2622 if (!HasString(rItems, pBaseGroup->GetGroupName())) //! ignore case?
2624 // add an additional group for each item that is not in the selection
2625 ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
2626 aGroup.AddElementsFromGroup( *pBaseGroup );
2627 pGroupDimension->AddGroupItem( aGroup );
2632 OUString aGroupDimName = pGroupDimension->GetGroupDimName();
2634 //! localized prefix string
2635 OUString aGroupName = pGroupDimension->CreateGroupName( String( RTL_CONSTASCII_USTRINGPARAM( "Group" ) ) );
2636 ScDPSaveGroupItem aGroup( aGroupName );
2637 Reference< XNameAccess > xMembers = GetMembers();
2638 if (!xMembers.is())
2640 delete pNewGroupDim;
2641 throw RuntimeException();
2644 for (nEntry=0; nEntry<nEntryCount; nEntry++)
2646 String aEntryName(rItems[nEntry]);
2648 if (!xMembers->hasByName(aEntryName))
2650 delete pNewGroupDim;
2651 throw IllegalArgumentException();
2654 if ( pBaseGroupDim )
2656 // for each selected (intermediate) group, add all its items
2657 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2658 if ( pBaseGroup )
2659 aGroup.AddElementsFromGroup( *pBaseGroup );
2660 else
2661 aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself
2663 else
2664 aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
2667 pGroupDimension->AddGroupItem( aGroup );
2669 if ( pNewGroupDim )
2671 pDimData->AddGroupDimension( *pNewGroupDim );
2672 delete pNewGroupDim; // AddGroupDimension copies the object
2673 // don't access pGroupDimension after here
2675 pGroupDimension = pNewGroupDim = NULL;
2677 // set orientation
2678 ScDPSaveDimension* pSaveDimension = aSaveData.GetDimensionByName( aGroupDimName );
2679 if ( pSaveDimension->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2681 ScDPSaveDimension* pOldDimension = aSaveData.GetDimensionByName( aDimName );
2682 pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
2683 long nPosition = 0; //! before (immediate) base
2684 aSaveData.SetPosition( pSaveDimension, nPosition );
2687 // apply changes
2688 pDPObj->SetSaveData( aSaveData );
2689 ScDBDocFunc(*GetDocShell()).RefreshPivotTableGroups(pDPObj);
2692 // if new grouping field has been created (on first group), return it
2693 if( !sNewDim.isEmpty() )
2695 Reference< XNameAccess > xFields(mrParent.getDataPilotFields(), UNO_QUERY);
2696 if (xFields.is())
2700 xRet.set(xFields->getByName(sNewDim), UNO_QUERY);
2701 OSL_ENSURE(xRet.is(), "there is a name, so there should be also a field");
2703 catch (const container::NoSuchElementException&)
2705 // Avoid throwing exception that's not specified in the method signature.
2706 throw RuntimeException();
2710 return xRet;
2713 Reference < XDataPilotField > SAL_CALL ScDataPilotFieldObj::createDateGroup( const DataPilotFieldGroupInfo& rInfo )
2714 throw (RuntimeException, IllegalArgumentException)
2716 SolarMutexGuard aGuard;
2717 using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
2719 // check min/max/step, HasDateValues must be set always
2720 if( !rInfo.HasDateValues || !lclCheckMinMaxStep( rInfo ) )
2721 throw IllegalArgumentException();
2722 // only a single date flag is allowed
2723 if( (rInfo.GroupBy == 0) || (rInfo.GroupBy > YEARS) || ((rInfo.GroupBy & (rInfo.GroupBy - 1)) != 0) )
2724 throw IllegalArgumentException();
2725 // step must be zero, if something else than DAYS is specified
2726 if( rInfo.Step >= ((rInfo.GroupBy == DAYS) ? 32768.0 : 1.0) )
2727 throw IllegalArgumentException();
2729 String aGroupDimName;
2730 ScDPObject* pDPObj = 0;
2731 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2733 ScDPNumGroupInfo aInfo;
2734 aInfo.mbEnable = true;
2735 aInfo.mbDateValues = (rInfo.GroupBy == DAYS) && (rInfo.Step >= 1.0);
2736 aInfo.mbAutoStart = rInfo.HasAutoStart;
2737 aInfo.mbAutoEnd = rInfo.HasAutoEnd;
2738 aInfo.mfStart = rInfo.Start;
2739 aInfo.mfEnd = rInfo.End;
2740 aInfo.mfStep = static_cast< sal_Int32 >( rInfo.Step );
2742 // create a local copy of the entire save data (will be written back below)
2743 ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2744 // get or create dimension save data
2745 ScDPDimensionSaveData& rDimData = *aSaveData.GetDimensionData();
2747 // find source dimension name
2748 const OUString& rDimName = pDim->GetName();
2749 const ScDPSaveGroupDimension* pGroupDim = rDimData.GetNamedGroupDim( rDimName );
2750 OUString aSrcDimName = pGroupDim ? pGroupDim->GetSourceDimName() : rDimName;
2752 // find a group dimension for the base field, or get numeric grouping
2753 pGroupDim = rDimData.GetFirstNamedGroupDim( aSrcDimName );
2754 const ScDPSaveNumGroupDimension* pNumGroupDim = rDimData.GetNumGroupDim( aSrcDimName );
2756 // do not group by dates, if named groups or numeric grouping is present
2757 bool bHasNamedGrouping = pGroupDim && !pGroupDim->GetDateInfo().mbEnable;
2758 bool bHasNumGrouping = pNumGroupDim && pNumGroupDim->GetInfo().mbEnable && !pNumGroupDim->GetInfo().mbDateValues && !pNumGroupDim->GetDateInfo().mbEnable;
2759 if( bHasNamedGrouping || bHasNumGrouping )
2760 throw IllegalArgumentException();
2762 if( aInfo.mbDateValues ) // create day ranges grouping
2764 // first remove all named group dimensions
2765 while( pGroupDim )
2767 String aGroupDimName2 = pGroupDim->GetGroupDimName();
2768 // find next group dimension before deleting this group
2769 pGroupDim = rDimData.GetNextNamedGroupDim( aGroupDimName2 );
2770 // remove from dimension save data
2771 rDimData.RemoveGroupDimension( aGroupDimName2 );
2772 // also remove save data settings for the dimension that no longer exists
2773 aSaveData.RemoveDimensionByName( aGroupDimName2 );
2775 // create or replace the number grouping dimension
2776 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo );
2777 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2779 else // create date grouping
2781 // collect all existing date flags
2782 sal_Int32 nDateParts = rDimData.CollectDateParts( aSrcDimName );
2783 if( nDateParts == 0 )
2785 // insert numeric group dimension, if no date groups exist yet (or replace day range grouping)
2786 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo, rInfo.GroupBy );
2787 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2789 else if( (nDateParts & rInfo.GroupBy) == 0 ) // do nothing if date field exists already
2791 // create new named group dimension for additional date groups
2792 aGroupDimName = rDimData.CreateDateGroupDimName( rInfo.GroupBy, *pDPObj, true, 0 );
2793 ScDPSaveGroupDimension aGroupDim( aSrcDimName, aGroupDimName, aInfo, rInfo.GroupBy );
2794 rDimData.AddGroupDimension( aGroupDim );
2796 // set orientation of new named group dimension
2797 ScDPSaveDimension& rSaveDim = *aSaveData.GetDimensionByName( aGroupDimName );
2798 if( rSaveDim.GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2800 ScDPSaveDimension& rOldDim = *aSaveData.GetDimensionByName( aSrcDimName );
2801 rSaveDim.SetOrientation( rOldDim.GetOrientation() );
2802 aSaveData.SetPosition( &rSaveDim, 0 ); //! before (immediate) base
2807 // apply changes
2808 pDPObj->SetSaveData( aSaveData );
2809 SetDPObject( pDPObj );
2812 // return the UNO object of the new dimension, after writing back saved data
2813 Reference< XDataPilotField > xRet;
2814 if( aGroupDimName.Len() > 0 ) try
2816 Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2817 xRet.set( xFields->getByName( aGroupDimName ), UNO_QUERY );
2819 catch( Exception& )
2822 return xRet;
2825 // ============================================================================
2827 namespace {
2829 bool lclExtractGroupMembers( ScFieldGroupMembers& rMembers, const Any& rElement )
2831 // allow empty value to create a new group
2832 if( !rElement.hasValue() )
2833 return true;
2835 // try to extract a simple sequence of strings
2836 Sequence< OUString > aSeq;
2837 if( rElement >>= aSeq )
2839 if( aSeq.hasElements() )
2840 rMembers.insert( rMembers.end(), aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength() );
2841 return true;
2844 // try to use XIndexAccess providing objects that support XNamed
2845 Reference< XIndexAccess > xItemsIA( rElement, UNO_QUERY );
2846 if( xItemsIA.is() )
2848 for( sal_Int32 nIdx = 0, nCount = xItemsIA->getCount(); nIdx < nCount; ++nIdx )
2850 try // getByIndex() should not throw, but we cannot be sure
2852 Reference< XNamed > xItemName( xItemsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
2853 rMembers.push_back( xItemName->getName() );
2855 catch( Exception& )
2857 // ignore exceptions, go ahead with next element in the array
2860 return true;
2863 // nothing valid inside the Any -> return false
2864 return false;
2867 } // namespace
2869 // ----------------------------------------------------------------------------
2871 ScDataPilotFieldGroupsObj::ScDataPilotFieldGroupsObj( const ScFieldGroups& rGroups ) :
2872 maGroups( rGroups )
2876 ScDataPilotFieldGroupsObj::~ScDataPilotFieldGroupsObj()
2880 // XNameAccess
2882 Any SAL_CALL ScDataPilotFieldGroupsObj::getByName( const OUString& rName )
2883 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2885 SolarMutexGuard aGuard;
2886 if( implFindByName( rName ) == maGroups.end() )
2887 throw NoSuchElementException();
2888 return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, rName ) ) );
2891 Sequence< OUString > SAL_CALL ScDataPilotFieldGroupsObj::getElementNames() throw(RuntimeException)
2893 SolarMutexGuard aGuard;
2894 Sequence< OUString > aSeq;
2895 if( !maGroups.empty() )
2897 aSeq.realloc( static_cast< sal_Int32 >( maGroups.size() ) );
2898 OUString* pName = aSeq.getArray();
2899 for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt, ++pName )
2900 *pName = aIt->maName;
2902 return aSeq;
2905 sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasByName( const OUString& rName ) throw(RuntimeException)
2907 SolarMutexGuard aGuard;
2908 return implFindByName( rName ) != maGroups.end();
2911 // XNameReplace
2913 void SAL_CALL ScDataPilotFieldGroupsObj::replaceByName( const OUString& rName, const Any& rElement )
2914 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2916 SolarMutexGuard aGuard;
2918 if( rName.isEmpty() )
2919 throw IllegalArgumentException();
2921 ScFieldGroups::iterator aIt = implFindByName( rName );
2922 if( aIt == maGroups.end() )
2923 throw NoSuchElementException();
2925 // read all item names provided by the passed object
2926 ScFieldGroupMembers aMembers;
2927 if( !lclExtractGroupMembers( aMembers, rElement ) )
2928 throw IllegalArgumentException();
2930 // copy and forget, faster than vector assignment
2931 aIt->maMembers.swap( aMembers );
2934 // XNameContainer
2936 void SAL_CALL ScDataPilotFieldGroupsObj::insertByName( const OUString& rName, const Any& rElement )
2937 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2939 SolarMutexGuard aGuard;
2941 if( rName.isEmpty() )
2942 throw IllegalArgumentException();
2944 ScFieldGroups::iterator aIt = implFindByName( rName );
2945 if( aIt != maGroups.end() )
2946 throw ElementExistException();
2948 // read all item names provided by the passed object
2949 ScFieldGroupMembers aMembers;
2950 if( !lclExtractGroupMembers( aMembers, rElement ) )
2951 throw IllegalArgumentException();
2953 // create the new entry if no error has been occurred
2954 maGroups.resize( maGroups.size() + 1 );
2955 ScFieldGroup& rGroup = maGroups.back();
2956 rGroup.maName = rName;
2957 rGroup.maMembers.swap( aMembers );
2960 void SAL_CALL ScDataPilotFieldGroupsObj::removeByName( const OUString& rName )
2961 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
2963 SolarMutexGuard aGuard;
2965 if( rName.isEmpty() )
2966 throw IllegalArgumentException();
2968 ScFieldGroups::iterator aIt = implFindByName( rName );
2969 if( aIt == maGroups.end() )
2970 throw NoSuchElementException();
2972 maGroups.erase( aIt );
2975 // XIndexAccess
2977 sal_Int32 SAL_CALL ScDataPilotFieldGroupsObj::getCount() throw(RuntimeException)
2979 SolarMutexGuard aGuard;
2980 return static_cast< sal_Int32 >( maGroups.size() );
2983 Any SAL_CALL ScDataPilotFieldGroupsObj::getByIndex( sal_Int32 nIndex )
2984 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
2986 SolarMutexGuard aGuard;
2987 if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( maGroups.size() )))
2988 throw IndexOutOfBoundsException();
2989 return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, maGroups[ nIndex ].maName ) ) );
2992 // XEnumerationAccess
2994 Reference<XEnumeration> SAL_CALL ScDataPilotFieldGroupsObj::createEnumeration() throw(RuntimeException)
2996 SolarMutexGuard aGuard;
2997 return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupsEnumeration" ) );
3000 // XElementAccess
3002 uno::Type SAL_CALL ScDataPilotFieldGroupsObj::getElementType() throw(RuntimeException)
3004 SolarMutexGuard aGuard;
3005 return getCppuType( (Reference< XNameAccess >*)0 );
3008 sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasElements() throw(RuntimeException)
3010 SolarMutexGuard aGuard;
3011 return !maGroups.empty();
3014 // implementation
3016 ScFieldGroup& ScDataPilotFieldGroupsObj::getFieldGroup( const OUString& rName ) throw(RuntimeException)
3018 SolarMutexGuard aGuard;
3019 ScFieldGroups::iterator aIt = implFindByName( rName );
3020 if( aIt == maGroups.end() )
3021 throw RuntimeException();
3022 return *aIt;
3025 void ScDataPilotFieldGroupsObj::renameFieldGroup( const OUString& rOldName, const OUString& rNewName ) throw(RuntimeException)
3027 SolarMutexGuard aGuard;
3028 ScFieldGroups::iterator aOldIt = implFindByName( rOldName );
3029 ScFieldGroups::iterator aNewIt = implFindByName( rNewName );
3030 // new name must not exist yet
3031 if( (aOldIt == maGroups.end()) || ((aNewIt != maGroups.end()) && (aNewIt != aOldIt)) )
3032 throw RuntimeException();
3033 aOldIt->maName = rNewName;
3036 ScFieldGroups::iterator ScDataPilotFieldGroupsObj::implFindByName( const OUString& rName )
3038 for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt )
3039 if( aIt->maName == rName )
3040 return aIt;
3041 return maGroups.end();
3044 // ============================================================================
3046 namespace {
3048 OUString lclExtractMember( const Any& rElement )
3050 if( rElement.has< OUString >() )
3051 return rElement.get< OUString >();
3053 Reference< XNamed > xNamed( rElement, UNO_QUERY );
3054 if( xNamed.is() )
3055 return xNamed->getName();
3057 return OUString();
3060 } // namespace
3062 // ----------------------------------------------------------------------------
3064 ScDataPilotFieldGroupObj::ScDataPilotFieldGroupObj( ScDataPilotFieldGroupsObj& rParent, const OUString& rGroupName ) :
3065 mrParent( rParent ),
3066 maGroupName( rGroupName )
3068 mrParent.acquire();
3071 ScDataPilotFieldGroupObj::~ScDataPilotFieldGroupObj()
3073 mrParent.release();
3076 // XNameAccess
3078 Any SAL_CALL ScDataPilotFieldGroupObj::getByName( const OUString& rName )
3079 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3081 SolarMutexGuard aGuard;
3082 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3083 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3084 if( aIt == rMembers.end() )
3085 throw NoSuchElementException();
3086 return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, *aIt ) ) );
3089 Sequence< OUString > SAL_CALL ScDataPilotFieldGroupObj::getElementNames() throw(RuntimeException)
3091 SolarMutexGuard aGuard;
3092 return ::comphelper::containerToSequence( mrParent.getFieldGroup( maGroupName ).maMembers );
3095 sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasByName( const OUString& rName ) throw(RuntimeException)
3097 SolarMutexGuard aGuard;
3098 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3099 return ::std::find( rMembers.begin(), rMembers.end(), rName ) != rMembers.end();
3102 // XNameReplace
3104 void SAL_CALL ScDataPilotFieldGroupObj::replaceByName( const OUString& rName, const Any& rElement )
3105 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
3107 SolarMutexGuard aGuard;
3109 // it should be possible to quickly rename an item -> accept string or XNamed
3110 OUString aNewName = lclExtractMember( rElement );
3111 if( rName.isEmpty() || aNewName.isEmpty() )
3112 throw IllegalArgumentException();
3113 if( rName == aNewName )
3114 return;
3116 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3117 ScFieldGroupMembers::iterator aOldIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3118 ScFieldGroupMembers::iterator aNewIt = ::std::find( rMembers.begin(), rMembers.end(), aNewName );
3119 // throw if passed member name does not exist
3120 if( aOldIt == rMembers.end() )
3121 throw NoSuchElementException();
3122 // throw if new name already exists
3123 if( aNewIt != rMembers.end() )
3124 throw IllegalArgumentException();
3125 *aOldIt = aNewName;
3128 // XNameContainer
3130 void SAL_CALL ScDataPilotFieldGroupObj::insertByName( const OUString& rName, const Any& /*rElement*/ )
3131 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
3133 SolarMutexGuard aGuard;
3135 // we will ignore the passed element and just try to insert the name
3136 if( rName.isEmpty() )
3137 throw IllegalArgumentException();
3139 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3140 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3141 // throw if passed name already exists
3142 if( aIt != rMembers.end() )
3143 throw IllegalArgumentException();
3144 rMembers.push_back( rName );
3147 void SAL_CALL ScDataPilotFieldGroupObj::removeByName( const OUString& rName )
3148 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
3150 SolarMutexGuard aGuard;
3152 if( rName.isEmpty() )
3153 throw IllegalArgumentException();
3154 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3155 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3156 // throw if passed name does not exist
3157 if( aIt == rMembers.end() )
3158 throw NoSuchElementException();
3159 rMembers.erase( aIt );
3162 // XIndexAccess
3164 sal_Int32 SAL_CALL ScDataPilotFieldGroupObj::getCount() throw(RuntimeException)
3166 SolarMutexGuard aGuard;
3167 return static_cast< sal_Int32 >( mrParent.getFieldGroup( maGroupName ).maMembers.size() );
3170 Any SAL_CALL ScDataPilotFieldGroupObj::getByIndex( sal_Int32 nIndex )
3171 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
3173 SolarMutexGuard aGuard;
3174 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3175 if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( rMembers.size() )))
3176 throw IndexOutOfBoundsException();
3177 return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, rMembers[ nIndex ] ) ) );
3180 // XEnumerationAccess
3182 Reference< XEnumeration > SAL_CALL ScDataPilotFieldGroupObj::createEnumeration() throw(RuntimeException)
3184 SolarMutexGuard aGuard;
3185 return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupEnumeration" ) );
3188 // XElementAccess
3190 uno::Type SAL_CALL ScDataPilotFieldGroupObj::getElementType() throw(RuntimeException)
3192 SolarMutexGuard aGuard;
3193 return getCppuType( (Reference< XNamed >*)0 );
3196 sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasElements() throw(RuntimeException)
3198 SolarMutexGuard aGuard;
3199 return !mrParent.getFieldGroup( maGroupName ).maMembers.empty();
3202 // XNamed
3204 OUString SAL_CALL ScDataPilotFieldGroupObj::getName() throw(RuntimeException)
3206 SolarMutexGuard aGuard;
3207 return maGroupName;
3210 void SAL_CALL ScDataPilotFieldGroupObj::setName( const OUString& rName ) throw(RuntimeException)
3212 SolarMutexGuard aGuard;
3213 mrParent.renameFieldGroup( maGroupName, rName );
3214 // if call to renameFieldGroup() did not throw, remember the new name
3215 maGroupName = rName;
3218 // ============================================================================
3220 ScDataPilotFieldGroupItemObj::ScDataPilotFieldGroupItemObj( ScDataPilotFieldGroupObj& rParent, const OUString& rName ) :
3221 mrParent( rParent ),
3222 maName( rName )
3224 mrParent.acquire();
3227 ScDataPilotFieldGroupItemObj::~ScDataPilotFieldGroupItemObj()
3229 mrParent.release();
3232 // XNamed
3234 OUString SAL_CALL ScDataPilotFieldGroupItemObj::getName() throw(RuntimeException)
3236 SolarMutexGuard aGuard;
3237 return maName;
3240 void SAL_CALL ScDataPilotFieldGroupItemObj::setName( const OUString& rName ) throw(RuntimeException)
3242 SolarMutexGuard aGuard;
3243 mrParent.replaceByName( maName, Any( rName ) );
3244 // if call to replaceByName() did not throw, remember the new name
3245 maName = rName;
3248 // ============================================================================
3250 ScDataPilotItemsObj::ScDataPilotItemsObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
3251 ScDataPilotChildObjBase( rParent, rFieldId )
3255 ScDataPilotItemsObj::~ScDataPilotItemsObj()
3259 // XDataPilotItems
3261 ScDataPilotItemObj* ScDataPilotItemsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3263 return ((0 <= nIndex) && (nIndex < GetMemberCount())) ?
3264 new ScDataPilotItemObj( mrParent, maFieldId, nIndex ) : 0;
3267 // XNameAccess
3269 Any SAL_CALL ScDataPilotItemsObj::getByName( const OUString& aName )
3270 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3272 SolarMutexGuard aGuard;
3273 Reference<XNameAccess> xMembers = GetMembers();
3274 if (xMembers.is())
3276 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3277 sal_Int32 nCount = xMembersIndex->getCount();
3278 sal_Bool bFound(false);
3279 sal_Int32 nItem = 0;
3280 while (nItem < nCount && !bFound )
3282 Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3283 if (xMember.is() && (aName == xMember->getName()))
3284 return Any( Reference< XPropertySet >( GetObjectByIndex_Impl( nItem ) ) );
3285 ++nItem;
3287 if (!bFound)
3288 throw NoSuchElementException();
3290 return Any();
3293 Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
3294 throw(RuntimeException)
3296 SolarMutexGuard aGuard;
3297 Sequence< OUString > aSeq;
3298 if( ScDPObject* pDPObj = GetDPObject() )
3299 pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
3300 return aSeq;
3303 sal_Bool SAL_CALL ScDataPilotItemsObj::hasByName( const OUString& aName )
3304 throw(RuntimeException)
3306 SolarMutexGuard aGuard;
3307 sal_Bool bFound = false;
3308 Reference<XNameAccess> xMembers = GetMembers();
3309 if (xMembers.is())
3311 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3312 sal_Int32 nCount = xMembersIndex->getCount();
3313 sal_Int32 nItem = 0;
3314 while (nItem < nCount && !bFound )
3316 Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3317 if (xMember.is() && aName == xMember->getName())
3318 bFound = sal_True;
3319 else
3320 nItem++;
3323 return bFound;
3326 // XEnumerationAccess
3328 Reference<XEnumeration> SAL_CALL ScDataPilotItemsObj::createEnumeration()
3329 throw(RuntimeException)
3331 SolarMutexGuard aGuard;
3332 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotItemsEnumeration"));
3335 // XIndexAccess
3337 sal_Int32 SAL_CALL ScDataPilotItemsObj::getCount() throw(RuntimeException)
3339 SolarMutexGuard aGuard;
3340 return GetMemberCount();
3343 Any SAL_CALL ScDataPilotItemsObj::getByIndex( sal_Int32 nIndex )
3344 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
3346 SolarMutexGuard aGuard;
3347 Reference< XPropertySet > xItem( GetObjectByIndex_Impl( nIndex ) );
3348 if (!xItem.is())
3349 throw IndexOutOfBoundsException();
3350 return Any( xItem );
3353 uno::Type SAL_CALL ScDataPilotItemsObj::getElementType() throw(RuntimeException)
3355 SolarMutexGuard aGuard;
3356 return getCppuType((Reference<XPropertySet>*)0);
3359 sal_Bool SAL_CALL ScDataPilotItemsObj::hasElements() throw(RuntimeException)
3361 SolarMutexGuard aGuard;
3362 return ( getCount() != 0 );
3365 //------------------------------------------------------------------------
3367 ScDataPilotItemObj::ScDataPilotItemObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId, sal_Int32 nIndex ) :
3368 ScDataPilotChildObjBase( rParent, rFieldId ),
3369 maPropSet( lcl_GetDataPilotItemMap() ),
3370 mnIndex( nIndex )
3374 ScDataPilotItemObj::~ScDataPilotItemObj()
3378 // XNamed
3379 OUString SAL_CALL ScDataPilotItemObj::getName() throw(RuntimeException)
3381 SolarMutexGuard aGuard;
3382 OUString sRet;
3383 Reference<XNameAccess> xMembers = GetMembers();
3384 if (xMembers.is())
3386 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3387 sal_Int32 nCount = xMembersIndex->getCount();
3388 if (mnIndex < nCount)
3390 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3391 sRet = xMember->getName();
3394 return sRet;
3397 void SAL_CALL ScDataPilotItemObj::setName( const OUString& /* aName */ )
3398 throw(RuntimeException)
3402 // XPropertySet
3403 Reference< XPropertySetInfo >
3404 SAL_CALL ScDataPilotItemObj::getPropertySetInfo( )
3405 throw(RuntimeException)
3407 SolarMutexGuard aGuard;
3408 static Reference<XPropertySetInfo> aRef =
3409 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
3410 return aRef;
3413 void SAL_CALL ScDataPilotItemObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
3414 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
3416 SolarMutexGuard aGuard;
3417 ScDPObject* pDPObj = 0;
3418 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
3420 Reference<XNameAccess> xMembers = GetMembers();
3421 if( xMembers.is() )
3423 Reference<XIndexAccess> xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3424 sal_Int32 nCount = xMembersIndex->getCount();
3425 if( mnIndex < nCount )
3427 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3428 String sName(xMember->getName());
3429 ScDPSaveMember* pMember = pDim->GetMemberByName(sName);
3430 if (pMember)
3432 bool bGetNewIndex = false;
3433 if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3434 pMember->SetShowDetails(cppu::any2bool(aValue));
3435 else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3436 pMember->SetIsVisible(!cppu::any2bool(aValue));
3437 else if ( aPropertyName == SC_UNONAME_POS )
3439 sal_Int32 nNewPos = 0;
3440 if ( ( aValue >>= nNewPos ) && nNewPos >= 0 && nNewPos < nCount )
3442 pDim->SetMemberPosition( sName, nNewPos );
3443 // get new effective index (depends on sorting mode, which isn't modified)
3444 bGetNewIndex = true;
3446 else
3447 throw IllegalArgumentException();
3449 SetDPObject( pDPObj );
3451 if ( bGetNewIndex ) // after SetDPObject, get the new index
3453 OUString aOUName( sName );
3454 Sequence< OUString > aItemNames = xMembers->getElementNames();
3455 sal_Int32 nItemCount = aItemNames.getLength();
3456 for (sal_Int32 nItem=0; nItem<nItemCount; ++nItem)
3457 if (aItemNames[nItem] == aOUName)
3458 mnIndex = nItem;
3466 Any SAL_CALL ScDataPilotItemObj::getPropertyValue( const OUString& aPropertyName )
3467 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3469 SolarMutexGuard aGuard;
3470 Any aRet;
3471 if( ScDPSaveDimension* pDim = GetDPDimension() )
3473 Reference< XNameAccess > xMembers = GetMembers();
3474 if( xMembers.is() )
3476 Reference< XIndexAccess > xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3477 sal_Int32 nCount = xMembersIndex->getCount();
3478 if( mnIndex < nCount )
3480 Reference< XNamed > xMember( xMembersIndex->getByIndex( mnIndex ), UNO_QUERY );
3481 String sName( xMember->getName() );
3482 ScDPSaveMember* pMember = pDim->GetExistingMemberByName( sName );
3483 if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3485 if (pMember && pMember->HasShowDetails())
3487 aRet <<= (bool)pMember->GetShowDetails();
3489 else
3491 Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3492 if( xMemberProps.is() )
3493 aRet = xMemberProps->getPropertyValue( OUString( SC_UNO_DP_SHOWDETAILS ) );
3494 else
3495 aRet <<= true;
3498 else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3500 if (pMember && pMember->HasIsVisible())
3502 aRet <<= !pMember->GetIsVisible();
3504 else
3506 Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3507 if( xMemberProps.is() )
3508 aRet <<= !cppu::any2bool( xMemberProps->getPropertyValue( OUString( SC_UNO_DP_ISVISIBLE ) ) );
3509 else
3510 aRet <<= false;
3513 else if ( aPropertyName == SC_UNONAME_POS )
3515 aRet <<= mnIndex;
3520 return aRet;
3523 void SAL_CALL ScDataPilotItemObj::addPropertyChangeListener(
3524 const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* xListener */ )
3525 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3529 void SAL_CALL ScDataPilotItemObj::removePropertyChangeListener(
3530 const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* aListener */ )
3531 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3535 void SAL_CALL ScDataPilotItemObj::addVetoableChangeListener(
3536 const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3537 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3541 void SAL_CALL ScDataPilotItemObj::removeVetoableChangeListener(
3542 const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3543 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3547 //------------------------------------------------------------------------
3552 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */