Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / unoobj / dapiuno.cxx
blob180c06129c36082032d0f29f67dfe7c20e40ea2f
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 const 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 const 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 const 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 OUString 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 OUString(); // 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 OUString 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 OUString aName = aNewName;
433 if (aName.isEmpty())
434 aName = lcl_CreatePivotName( pDocShell );
435 pNewObj->SetName(aName);
436 OUString 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 OUString 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 OUString 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 OUString 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 OUString 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 OUString 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 OUString 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 OUString& 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 OUString 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 pDPObj->SetTag( aNewTag ); //! Undo - DBDocFunc ???
1237 // DataPilotUpdate would do too much (output table is not changed)
1238 GetDocShell()->SetDocumentModified();
1242 // XDataPilotTable
1244 CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeException)
1246 SolarMutexGuard aGuard;
1247 CellRangeAddress aRet;
1248 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1249 if (pDPObj)
1251 ScRange aRange(pDPObj->GetOutRange());
1252 aRet.Sheet = aRange.aStart.Tab();
1253 aRet.StartColumn = aRange.aStart.Col();
1254 aRet.StartRow = aRange.aStart.Row();
1255 aRet.EndColumn = aRange.aEnd.Col();
1256 aRet.EndRow = aRange.aEnd.Row();
1258 return aRet;
1261 void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException)
1263 SolarMutexGuard aGuard;
1264 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1265 if (pDPObj)
1267 ScDBDocFunc aFunc(*GetDocShell());
1268 aFunc.RefreshPivotTables(pDPObj, true);
1272 Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr)
1273 throw (RuntimeException)
1275 SolarMutexGuard aGuard;
1276 Sequence< Sequence<Any> > aTabData;
1277 ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1278 ScDPObject* pObj = GetDPObject();
1279 if (!pObj)
1280 throw RuntimeException();
1282 pObj->GetDrillDownData(aAddr2, aTabData);
1283 return aTabData;
1286 DataPilotTablePositionData SAL_CALL ScDataPilotTableObj::getPositionData(const CellAddress& aAddr)
1287 throw (RuntimeException)
1289 SolarMutexGuard aGuard;
1290 DataPilotTablePositionData aPosData;
1291 ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1292 ScDPObject* pObj = GetDPObject();
1293 if (!pObj)
1294 throw RuntimeException();
1296 pObj->GetPositionData(aAddr2, aPosData);
1297 return aPosData;
1300 void SAL_CALL ScDataPilotTableObj::insertDrillDownSheet(const CellAddress& aAddr)
1301 throw (RuntimeException)
1303 SolarMutexGuard aGuard;
1304 ScDPObject* pDPObj = GetDPObject();
1305 if (!pDPObj)
1306 throw RuntimeException();
1308 Sequence<DataPilotFieldFilter> aFilters;
1309 pDPObj->GetDataFieldPositionData(
1310 ScAddress(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet), aFilters);
1311 GetDocShell()->GetBestViewShell()->ShowDataPilotSourceData(*pDPObj, aFilters);
1314 CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
1315 throw (IllegalArgumentException, RuntimeException)
1317 SolarMutexGuard aGuard;
1318 if (nType < 0 || nType > DataPilotOutputRangeType::RESULT)
1319 throw IllegalArgumentException();
1321 CellRangeAddress aRet;
1322 if (ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName))
1323 ScUnoConversion::FillApiRange( aRet, pDPObj->GetOutputRangeByType( nType ) );
1324 return aRet;
1327 void SAL_CALL ScDataPilotTableObj::addModifyListener( const uno::Reference<util::XModifyListener>& aListener )
1328 throw (uno::RuntimeException)
1330 SolarMutexGuard aGuard;
1332 uno::Reference<util::XModifyListener> *pObj = new uno::Reference<util::XModifyListener>( aListener );
1333 aModifyListeners.push_back( pObj );
1335 if ( aModifyListeners.size() == 1 )
1337 acquire(); // don't lose this object (one ref for all listeners)
1341 void SAL_CALL ScDataPilotTableObj::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
1342 throw (uno::RuntimeException)
1344 SolarMutexGuard aGuard;
1346 acquire(); // in case the listeners have the last ref - released below
1348 sal_uInt16 nCount = aModifyListeners.size();
1349 for ( sal_uInt16 n=nCount; n--; )
1351 uno::Reference<util::XModifyListener>& rObj = aModifyListeners[n];
1352 if ( rObj == aListener )
1354 aModifyListeners.erase( aModifyListeners.begin() + n );
1356 if ( aModifyListeners.empty() )
1358 release(); // release the ref for the listeners
1361 break;
1365 release(); // might delete this object
1368 void ScDataPilotTableObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1370 if ( rHint.ISA(ScDataPilotModifiedHint) &&
1371 static_cast<const ScDataPilotModifiedHint&>(rHint).GetName() == aName )
1373 Refreshed_Impl();
1375 else if ( rHint.ISA( ScUpdateRefHint ) )
1377 ScRange aRange( 0, 0, nTab );
1378 ScRangeList aRanges;
1379 aRanges.Append( aRange );
1380 const ScUpdateRefHint& rRef = static_cast< const ScUpdateRefHint& >( rHint );
1381 if ( aRanges.UpdateReference( rRef.GetMode(), GetDocShell()->GetDocument(), rRef.GetRange(),
1382 rRef.GetDx(), rRef.GetDy(), rRef.GetDz() ) &&
1383 aRanges.size() == 1 )
1385 const ScRange* pRange = aRanges.front();
1386 if ( pRange )
1388 nTab = pRange->aStart.Tab();
1393 ScDataPilotDescriptorBase::Notify( rBC, rHint );
1396 void ScDataPilotTableObj::Refreshed_Impl()
1398 lang::EventObject aEvent;
1399 aEvent.Source.set((cppu::OWeakObject*)this);
1401 // the EventObject holds a Ref to this object until after the listener calls
1403 ScDocument* pDoc = GetDocShell()->GetDocument();
1404 for ( sal_uInt16 n=0; n<aModifyListeners.size(); n++ )
1405 pDoc->AddUnoListenerCall( aModifyListeners[n], aEvent );
1408 // ============================================================================
1410 ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) :
1411 ScDataPilotDescriptorBase( pDocSh ),
1412 mpDPObject(new ScDPObject(pDocSh ? pDocSh->GetDocument() : NULL) )
1414 ScDPSaveData aSaveData;
1415 // set defaults like in ScPivotParam constructor
1416 aSaveData.SetColumnGrand( sal_True );
1417 aSaveData.SetRowGrand( sal_True );
1418 aSaveData.SetIgnoreEmptyRows( false );
1419 aSaveData.SetRepeatIfEmpty( false );
1420 mpDPObject->SetSaveData(aSaveData);
1421 ScSheetSourceDesc aSheetDesc(pDocSh ? pDocSh->GetDocument() : NULL);
1422 mpDPObject->SetSheetDesc(aSheetDesc);
1423 mpDPObject->GetSource();
1426 ScDataPilotDescriptor::~ScDataPilotDescriptor()
1428 delete mpDPObject;
1431 ScDPObject* ScDataPilotDescriptor::GetDPObject() const
1433 return mpDPObject;
1436 void ScDataPilotDescriptor::SetDPObject( ScDPObject* pDPObject )
1438 if (mpDPObject != pDPObject)
1440 delete mpDPObject;
1441 mpDPObject = pDPObject;
1442 OSL_FAIL("replace DPObject should not happen");
1446 // "rest of XDataPilotDescriptor"
1448 OUString SAL_CALL ScDataPilotDescriptor::getName() throw(RuntimeException)
1450 SolarMutexGuard aGuard;
1451 return mpDPObject->GetName();
1454 void SAL_CALL ScDataPilotDescriptor::setName( const OUString& aNewName )
1455 throw(RuntimeException)
1457 SolarMutexGuard aGuard;
1458 mpDPObject->SetName( aNewName );
1461 OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(RuntimeException)
1463 SolarMutexGuard aGuard;
1464 return mpDPObject->GetTag();
1467 void SAL_CALL ScDataPilotDescriptor::setTag( const OUString& aNewTag )
1468 throw(RuntimeException)
1470 SolarMutexGuard aGuard;
1471 mpDPObject->SetTag( aNewTag );
1474 // ============================================================================
1476 ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent ) :
1477 mrParent( rParent )
1479 mrParent.acquire();
1482 ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1483 mrParent( rParent ),
1484 maFieldId( rFieldId )
1486 mrParent.acquire();
1489 ScDataPilotChildObjBase::~ScDataPilotChildObjBase()
1491 mrParent.release();
1494 ScDPObject* ScDataPilotChildObjBase::GetDPObject() const
1496 return mrParent.GetDPObject();
1499 void ScDataPilotChildObjBase::SetDPObject( ScDPObject* pDPObject )
1501 mrParent.SetDPObject( pDPObject );
1504 ScDPSaveDimension* ScDataPilotChildObjBase::GetDPDimension( ScDPObject** ppDPObject ) const
1506 if( ScDPObject* pDPObj = GetDPObject() )
1508 if( ppDPObject ) *ppDPObject = pDPObj;
1509 if( ScDPSaveData* pSaveData = pDPObj->GetSaveData() )
1511 if( maFieldId.mbDataLayout )
1512 return pSaveData->GetDataLayoutDimension();
1514 if( maFieldId.mnFieldIdx == 0 )
1515 return pSaveData->GetDimensionByName( maFieldId.maFieldName );
1517 // find dimension with specified index (search in duplicated dimensions)
1518 const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
1520 sal_Int32 nFoundIdx = 0;
1521 boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
1522 for(it = rDimensions.begin(); it != rDimensions.end(); ++it)
1524 if( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
1526 if( nFoundIdx == maFieldId.mnFieldIdx )
1527 return const_cast<ScDPSaveDimension*>(&(*it));
1528 ++nFoundIdx;
1533 return 0;
1536 sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
1538 sal_Int32 nRet = 0;
1539 Reference<XNameAccess> xMembersNA = GetMembers();
1540 if (xMembersNA.is())
1542 Reference< XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
1543 nRet = xMembersIA->getCount();
1545 return nRet;
1548 Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
1550 Reference< XNameAccess > xMembersNA;
1551 if( ScDPObject* pDPObj = GetDPObject() )
1552 pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
1553 return xMembersNA;
1556 ScDocShell* ScDataPilotChildObjBase::GetDocShell() const
1558 return mrParent.GetDocShell();
1561 // ============================================================================
1563 ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent ) :
1564 ScDataPilotChildObjBase( rParent )
1568 ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent, DataPilotFieldOrientation eOrient ) :
1569 ScDataPilotChildObjBase( rParent ),
1570 maOrient( eOrient )
1574 ScDataPilotFieldsObj::~ScDataPilotFieldsObj()
1578 static sal_Int32 lcl_GetFieldCount( const Reference<XDimensionsSupplier>& rSource, const Any& rOrient )
1580 if (!rSource.is())
1581 throw RuntimeException();
1583 sal_Int32 nRet = 0;
1585 Reference<XNameAccess> xDimsName(rSource->getDimensions());
1586 Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1587 sal_Int32 nIntCount = xIntDims->getCount();
1588 if (rOrient.hasValue())
1590 // all fields of the specified orientation, including duplicated
1591 Reference<XPropertySet> xDim;
1592 for (sal_Int32 i = 0; i < nIntCount; ++i)
1594 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1595 if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1596 ++nRet;
1599 else
1601 // count all non-duplicated fields
1603 Reference<XPropertySet> xDim;
1604 for (sal_Int32 i = 0; i < nIntCount; ++i)
1606 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1607 if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1608 ++nRet;
1612 return nRet;
1615 static sal_Bool lcl_GetFieldDataByIndex( const Reference<XDimensionsSupplier>& rSource,
1616 const Any& rOrient, SCSIZE nIndex, ScFieldIdentifier& rFieldId )
1618 if (!rSource.is())
1619 throw RuntimeException();
1621 sal_Bool bOk = false;
1622 SCSIZE nPos = 0;
1623 sal_Int32 nDimIndex = 0;
1625 Reference<XNameAccess> xDimsName(rSource->getDimensions());
1626 Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1627 sal_Int32 nIntCount = xIntDims->getCount();
1628 Reference<XPropertySet> xDim;
1629 if (rOrient.hasValue())
1631 sal_Int32 i = 0;
1632 while (i < nIntCount && !bOk)
1634 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1635 if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1637 if (nPos == nIndex)
1639 bOk = sal_True;
1640 nDimIndex = i;
1642 else
1643 ++nPos;
1645 ++i;
1648 else
1650 sal_Int32 i = 0;
1651 while (i < nIntCount && !bOk)
1653 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1654 if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1656 if (nPos == nIndex)
1658 bOk = sal_True;
1659 nDimIndex = i;
1661 else
1662 ++nPos;
1664 ++i;
1668 if ( bOk )
1670 xDim.set( xIntDims->getByIndex(nDimIndex), UNO_QUERY );
1671 Reference<XNamed> xDimName( xDim, UNO_QUERY );
1672 if ( xDimName.is() )
1674 OUString sOriginalName( lcl_GetOriginalName( xDimName ) );
1675 rFieldId.maFieldName = sOriginalName;
1676 rFieldId.mbDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDim,
1677 OUString(SC_UNO_DP_ISDATALAYOUT) );
1679 sal_Int32 nRepeat = 0;
1680 if ( rOrient.hasValue() && lcl_IsDuplicated( xDim ) )
1682 // find the repeat count
1683 // (this relies on the original dimension always being before the duplicates)
1685 Reference<XNamed> xPrevName;
1686 for (sal_Int32 i = 0; i < nDimIndex; ++i)
1688 xPrevName.set( xIntDims->getByIndex(i), UNO_QUERY );
1689 if ( xPrevName.is() && lcl_GetOriginalName( xPrevName ) == sOriginalName )
1690 ++nRepeat;
1693 rFieldId.mnFieldIdx = nRepeat;
1695 else
1696 bOk = false;
1699 return bOk;
1702 static sal_Bool lcl_GetFieldDataByName( ScDPObject* pDPObj, const OUString& rFieldName, ScFieldIdentifier& rFieldId )
1704 // "By name" is always the first match.
1705 // The name "Data" always refers to the data layout field.
1706 rFieldId.maFieldName = rFieldName;
1707 rFieldId.mnFieldIdx = 0;
1708 rFieldId.mbDataLayout = rFieldName == SC_DATALAYOUT_NAME;
1710 pDPObj->GetSource(); // IsDimNameInUse doesn't update source data
1712 // check if the named field exists (not for data layout)
1713 return rFieldId.mbDataLayout || pDPObj->IsDimNameInUse( rFieldName );
1716 // XDataPilotFields
1718 ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
1720 // TODO
1721 if (ScDPObject* pObj = GetDPObject())
1723 ScFieldIdentifier aFieldId;
1724 if (lcl_GetFieldDataByIndex( pObj->GetSource(), maOrient, nIndex, aFieldId ))
1725 return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1727 return 0;
1730 ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const OUString& aName) const
1732 if (ScDPObject* pDPObj = GetDPObject())
1734 ScFieldIdentifier aFieldId;
1735 if (lcl_GetFieldDataByName( pDPObj, aName, aFieldId ))
1736 return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1738 return 0;
1741 // XEnumerationAccess
1743 Reference<XEnumeration> SAL_CALL ScDataPilotFieldsObj::createEnumeration()
1744 throw(RuntimeException)
1746 SolarMutexGuard aGuard;
1747 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotFieldsEnumeration"));
1750 // XIndexAccess
1752 sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(RuntimeException)
1754 SolarMutexGuard aGuard;
1755 // TODO
1756 ScDPObject* pDPObj = GetDPObject();
1757 return pDPObj ? lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) : 0;
1760 Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex )
1761 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
1763 SolarMutexGuard aGuard;
1764 Reference< XPropertySet > xField( GetObjectByIndex_Impl( nIndex ) );
1765 if (!xField.is())
1766 throw IndexOutOfBoundsException();
1767 return Any( xField );
1770 uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(RuntimeException)
1772 SolarMutexGuard aGuard;
1773 return getCppuType((Reference<XPropertySet>*)0);
1776 sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(RuntimeException)
1778 SolarMutexGuard aGuard;
1779 return ( getCount() != 0 );
1782 Any SAL_CALL ScDataPilotFieldsObj::getByName( const OUString& aName )
1783 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
1785 SolarMutexGuard aGuard;
1786 Reference<XPropertySet> xField(GetObjectByName_Impl(aName));
1787 if (!xField.is())
1788 throw NoSuchElementException();
1789 return Any( xField );
1792 Sequence<OUString> SAL_CALL ScDataPilotFieldsObj::getElementNames()
1793 throw(RuntimeException)
1795 SolarMutexGuard aGuard;
1796 // TODO
1797 if (ScDPObject* pDPObj = GetDPObject())
1799 Sequence< OUString > aSeq( lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) );
1800 OUString* pAry = aSeq.getArray();
1802 const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pDPObj->GetSaveData()->GetDimensions();
1803 boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
1804 for (it = rDimensions.begin(); it != rDimensions.end(); ++it)
1806 if(maOrient.hasValue() && (it->GetOrientation() == maOrient.get< DataPilotFieldOrientation >()))
1808 *pAry = it->GetName();
1809 ++pAry;
1812 return aSeq;
1814 return Sequence<OUString>();
1817 sal_Bool SAL_CALL ScDataPilotFieldsObj::hasByName( const OUString& aName )
1818 throw(RuntimeException)
1820 SolarMutexGuard aGuard;
1822 return GetObjectByName_Impl(aName) != NULL;
1825 //------------------------------------------------------------------------
1827 ScDataPilotFieldObj::ScDataPilotFieldObj(
1828 ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1829 ScDataPilotChildObjBase( rParent, rFieldId ),
1830 maPropSet( lcl_GetDataPilotFieldMap() )
1834 ScDataPilotFieldObj::ScDataPilotFieldObj( ScDataPilotDescriptorBase& rParent,
1835 const ScFieldIdentifier& rFieldId, const Any& rOrient ) :
1836 ScDataPilotChildObjBase( rParent, rFieldId ),
1837 maPropSet( lcl_GetDataPilotFieldMap() ),
1838 maOrient( rOrient )
1842 ScDataPilotFieldObj::~ScDataPilotFieldObj()
1846 // XNamed
1848 OUString SAL_CALL ScDataPilotFieldObj::getName() throw(RuntimeException)
1850 SolarMutexGuard aGuard;
1851 OUString aName;
1852 if( ScDPSaveDimension* pDim = GetDPDimension() )
1854 if( pDim->IsDataLayout() )
1855 aName = OUString( SC_DATALAYOUT_NAME );
1856 else
1858 const OUString* pLayoutName = pDim->GetLayoutName();
1859 if (pLayoutName)
1860 aName = *pLayoutName;
1861 else
1862 aName = pDim->GetName();
1864 return aName;
1867 void SAL_CALL ScDataPilotFieldObj::setName( const OUString& rName ) throw(RuntimeException)
1869 SolarMutexGuard aGuard;
1870 ScDPObject* pDPObj = 0;
1871 ScDPSaveDimension* pDim = GetDPDimension( &pDPObj );
1872 if( pDim && !pDim->IsDataLayout() )
1874 pDim->SetLayoutName(rName);
1875 SetDPObject( pDPObj );
1879 // XPropertySet
1881 Reference<XPropertySetInfo> SAL_CALL ScDataPilotFieldObj::getPropertySetInfo()
1882 throw(RuntimeException)
1884 SolarMutexGuard aGuard;
1885 static Reference<XPropertySetInfo> aRef(
1886 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() ));
1887 return aRef;
1890 void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
1891 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
1893 SolarMutexGuard aGuard;
1894 OUString aNameString(aPropertyName);
1895 if ( aNameString.equalsAscii( SC_UNONAME_FUNCTION ) )
1897 // #i109350# use GetEnumFromAny because it also allows sal_Int32
1898 GeneralFunction eFunction = (GeneralFunction)
1899 ScUnoHelpFunctions::GetEnumFromAny( aValue );
1900 setFunction( eFunction );
1902 else if ( aNameString.equalsAscii( SC_UNONAME_SUBTOTALS ) )
1904 Sequence< GeneralFunction > aSubtotals;
1905 if( aValue >>= aSubtotals )
1906 setSubtotals( aSubtotals );
1908 else if ( aNameString.equalsAscii( SC_UNONAME_ORIENT ) )
1910 //! test for correct enum type?
1911 DataPilotFieldOrientation eOrient = (DataPilotFieldOrientation)
1912 ScUnoHelpFunctions::GetEnumFromAny( aValue );
1913 setOrientation( eOrient );
1915 else if ( aNameString.equalsAscii( SC_UNONAME_SELPAGE ) )
1917 OUString sCurrentPage;
1918 if (aValue >>= sCurrentPage)
1919 setCurrentPage(sCurrentPage);
1921 else if ( aNameString.equalsAscii( SC_UNONAME_USESELPAGE ) )
1923 setUseCurrentPage(cppu::any2bool(aValue));
1925 else if ( aNameString.equalsAscii( SC_UNONAME_HASAUTOSHOW ) )
1927 if (!cppu::any2bool(aValue))
1928 setAutoShowInfo(NULL);
1930 else if ( aNameString.equalsAscii( SC_UNONAME_AUTOSHOW ) )
1932 DataPilotFieldAutoShowInfo aInfo;
1933 if (aValue >>= aInfo)
1934 setAutoShowInfo(&aInfo);
1936 else if ( aNameString.equalsAscii( SC_UNONAME_HASLAYOUTINFO ) )
1938 if (!cppu::any2bool(aValue))
1939 setLayoutInfo(NULL);
1941 else if ( aNameString.equalsAscii( SC_UNONAME_LAYOUTINFO ) )
1943 DataPilotFieldLayoutInfo aInfo;
1944 if (aValue >>= aInfo)
1945 setLayoutInfo(&aInfo);
1947 else if ( aNameString.equalsAscii( SC_UNONAME_HASREFERENCE ) )
1949 if (!cppu::any2bool(aValue))
1950 setReference(NULL);
1952 else if ( aNameString.equalsAscii( SC_UNONAME_REFERENCE ) )
1954 DataPilotFieldReference aRef;
1955 if (aValue >>= aRef)
1956 setReference(&aRef);
1958 else if ( aNameString.equalsAscii( SC_UNONAME_HASSORTINFO ) )
1960 if (!cppu::any2bool(aValue))
1961 setSortInfo(NULL);
1963 else if ( aNameString.equalsAscii( SC_UNONAME_SORTINFO ) )
1965 DataPilotFieldSortInfo aInfo;
1966 if (aValue >>= aInfo)
1967 setSortInfo(&aInfo);
1969 else if ( aNameString.equalsAscii( SC_UNONAME_ISGROUP ) )
1971 if (!cppu::any2bool(aValue))
1972 setGroupInfo(NULL);
1974 else if ( aNameString.equalsAscii( SC_UNONAME_GROUPINFO ) )
1976 DataPilotFieldGroupInfo aInfo;
1977 if (aValue >>= aInfo)
1978 setGroupInfo(&aInfo);
1980 else if ( aNameString.equalsAscii( SC_UNONAME_SHOWEMPTY ) )
1982 setShowEmpty(cppu::any2bool(aValue));
1986 Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName )
1987 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
1989 SolarMutexGuard aGuard;
1990 OUString aNameString(aPropertyName);
1991 Any aRet;
1993 if ( aNameString.equalsAscii( SC_UNONAME_FUNCTION ) )
1994 aRet <<= getFunction();
1995 else if ( aNameString.equalsAscii( SC_UNONAME_SUBTOTALS ) )
1996 aRet <<= getSubtotals();
1997 else if ( aNameString.equalsAscii( SC_UNONAME_ORIENT ) )
1998 aRet <<= getOrientation();
1999 else if ( aNameString.equalsAscii( SC_UNONAME_SELPAGE ) )
2000 aRet <<= getCurrentPage();
2001 else if ( aNameString.equalsAscii( SC_UNONAME_USESELPAGE ) )
2002 aRet <<= getUseCurrentPage();
2003 else if ( aNameString.equalsAscii( SC_UNONAME_HASAUTOSHOW ) )
2004 aRet = ::cppu::bool2any(getAutoShowInfo() != NULL);
2005 else if ( aNameString.equalsAscii( SC_UNONAME_AUTOSHOW ) )
2007 const DataPilotFieldAutoShowInfo* pInfo = getAutoShowInfo();
2008 if (pInfo)
2009 aRet <<= DataPilotFieldAutoShowInfo(*pInfo);
2011 else if ( aNameString.equalsAscii( SC_UNONAME_HASLAYOUTINFO ) )
2012 aRet = ::cppu::bool2any(getLayoutInfo() != NULL);
2013 else if ( aNameString.equalsAscii( SC_UNONAME_LAYOUTINFO ) )
2015 const DataPilotFieldLayoutInfo* pInfo = getLayoutInfo();
2016 if (pInfo)
2017 aRet <<= DataPilotFieldLayoutInfo(*pInfo);
2019 else if ( aNameString.equalsAscii( SC_UNONAME_HASREFERENCE ) )
2020 aRet = ::cppu::bool2any(getReference() != NULL);
2021 else if ( aNameString.equalsAscii( SC_UNONAME_REFERENCE ) )
2023 const DataPilotFieldReference* pRef = getReference();
2024 if (pRef)
2025 aRet <<= DataPilotFieldReference(*pRef);
2027 else if ( aNameString.equalsAscii( SC_UNONAME_HASSORTINFO ) )
2028 aRet = ::cppu::bool2any(getSortInfo() != NULL);
2029 else if ( aNameString.equalsAscii( SC_UNONAME_SORTINFO ) )
2031 const DataPilotFieldSortInfo* pInfo = getSortInfo();
2032 if (pInfo)
2033 aRet <<= DataPilotFieldSortInfo(*pInfo);
2035 else if ( aNameString.equalsAscii( SC_UNONAME_ISGROUP ) )
2036 aRet = ::cppu::bool2any(hasGroupInfo());
2037 else if ( aNameString.equalsAscii( SC_UNONAME_GROUPINFO ) )
2039 aRet <<= getGroupInfo();
2041 else if ( aNameString.equalsAscii( SC_UNONAME_SHOWEMPTY ) )
2042 aRet <<= getShowEmpty();
2044 return aRet;
2047 // XDatePilotField
2049 Reference<XIndexAccess> SAL_CALL ScDataPilotFieldObj::getItems()
2050 throw (RuntimeException)
2052 SolarMutexGuard aGuard;
2053 if (!mxItems.is())
2054 mxItems.set( new ScDataPilotItemsObj( mrParent, maFieldId ) );
2055 return mxItems;
2058 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj )
2060 DataPilotFieldOrientation ScDataPilotFieldObj::getOrientation() const
2062 SolarMutexGuard aGuard;
2063 ScDPSaveDimension* pDim = GetDPDimension();
2064 return pDim ? static_cast< DataPilotFieldOrientation >( pDim->GetOrientation() ) : DataPilotFieldOrientation_HIDDEN;
2067 void ScDataPilotFieldObj::setOrientation(DataPilotFieldOrientation eNew)
2069 SolarMutexGuard aGuard;
2070 if (maOrient.hasValue() && (eNew == maOrient.get< DataPilotFieldOrientation >()))
2071 return;
2073 ScDPObject* pDPObj = 0;
2074 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2076 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2078 /* If the field was taken from getDataPilotFields(), don't reset the
2079 orientation for an existing use, but create a duplicated field
2080 instead (for "Data" orientation only). */
2081 if ( !maOrient.hasValue() && !maFieldId.mbDataLayout &&
2082 (pDim->GetOrientation() != DataPilotFieldOrientation_HIDDEN) &&
2083 (eNew == DataPilotFieldOrientation_DATA) )
2086 ScDPSaveDimension* pNewDim = 0;
2088 // look for existing duplicate with orientation "hidden"
2090 sal_Int32 nFound = 0;
2091 const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
2092 boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
2093 for ( it = rDimensions.begin(); it != rDimensions.end() && !pNewDim; ++it )
2095 if ( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
2097 if ( it->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2098 pNewDim = const_cast<ScDPSaveDimension*>(&(*it)); // use this one
2099 else
2100 ++nFound; // count existing non-hidden occurrences
2104 if ( !pNewDim ) // if none found, create a new duplicated dimension
2105 pNewDim = &pSaveData->DuplicateDimension( *pDim );
2107 maFieldId.mnFieldIdx = nFound; // keep accessing the new one
2108 pDim = pNewDim;
2111 pDim->SetOrientation(sal::static_int_cast<sal_uInt16>(eNew));
2113 // move changed field behind all other fields (make it the last field in dimension)
2114 pSaveData->SetPosition( pDim, pSaveData->GetDimensions().size() );
2116 SetDPObject( pDPObj );
2118 maOrient <<= eNew; // modifying the same object's orientation again doesn't create another duplicate
2122 GeneralFunction ScDataPilotFieldObj::getFunction() const
2124 SolarMutexGuard aGuard;
2125 GeneralFunction eRet = GeneralFunction_NONE;
2126 if( ScDPSaveDimension* pDim = GetDPDimension() )
2128 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2130 // for non-data fields, property Function is the subtotals
2131 long nSubCount = pDim->GetSubTotalsCount();
2132 if ( nSubCount > 0 )
2133 eRet = (GeneralFunction)pDim->GetSubTotalFunc(0); // always use the first one
2134 // else keep NONE
2136 else
2137 eRet = (GeneralFunction)pDim->GetFunction();
2139 return eRet;
2142 void ScDataPilotFieldObj::setFunction(GeneralFunction eNewFunc)
2144 SolarMutexGuard aGuard;
2145 ScDPObject* pDPObj = 0;
2146 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2148 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2150 // for non-data fields, property Function is the subtotals
2151 if ( eNewFunc == GeneralFunction_NONE )
2152 pDim->SetSubTotals( 0, NULL );
2153 else
2155 sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( eNewFunc );
2156 pDim->SetSubTotals( 1, &nFunc );
2159 else
2160 pDim->SetFunction( sal::static_int_cast<sal_uInt16>( eNewFunc ) );
2161 SetDPObject( pDPObj );
2165 Sequence< GeneralFunction > ScDataPilotFieldObj::getSubtotals() const
2167 SolarMutexGuard aGuard;
2168 Sequence< GeneralFunction > aRet;
2169 if( ScDPSaveDimension* pDim = GetDPDimension() )
2171 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2173 // for non-data fields, property Functions is the sequence of subtotals
2174 sal_Int32 nCount = static_cast< sal_Int32 >( pDim->GetSubTotalsCount() );
2175 if ( nCount > 0 )
2177 aRet.realloc( nCount );
2178 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2179 aRet[ nIdx ] = (GeneralFunction)pDim->GetSubTotalFunc( nIdx );
2183 return aRet;
2186 void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubtotals )
2188 SolarMutexGuard aGuard;
2189 ScDPObject* pDPObj = 0;
2190 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2192 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2194 sal_Int32 nCount = rSubtotals.getLength();
2195 if( nCount == 1 )
2197 // count 1: all values are allowed (including NONE and AUTO)
2198 if( rSubtotals[ 0 ] == GeneralFunction_NONE )
2199 pDim->SetSubTotals( 0, NULL );
2200 else
2202 sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( rSubtotals[ 0 ] );
2203 pDim->SetSubTotals( 1, &nFunc );
2206 else if( nCount > 1 )
2208 // set multiple functions, ignore NONE and AUTO in this case
2209 ::std::vector< sal_uInt16 > aSubt;
2210 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2212 GeneralFunction eFunc = rSubtotals[ nIdx ];
2213 if( (eFunc != GeneralFunction_NONE) && (eFunc != GeneralFunction_AUTO) )
2215 // do not insert functions twice
2216 sal_uInt16 nFunc = static_cast< sal_uInt16 >( eFunc );
2217 if( ::std::find( aSubt.begin(), aSubt.end(), nFunc ) == aSubt.end() )
2218 aSubt.push_back( nFunc );
2221 // set values from vector to ScDPSaveDimension
2222 if ( aSubt.empty() )
2223 pDim->SetSubTotals( 0, NULL );
2224 else
2225 pDim->SetSubTotals( static_cast< long >( aSubt.size() ), &aSubt.front() );
2228 SetDPObject( pDPObj );
2232 OUString ScDataPilotFieldObj::getCurrentPage() const
2234 return OUString();
2237 void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage )
2239 SolarMutexGuard aGuard;
2240 ScDPObject* pDPObj = 0;
2241 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2243 pDim->SetCurrentPage( &rPage );
2244 SetDPObject( pDPObj );
2248 sal_Bool ScDataPilotFieldObj::getUseCurrentPage() const
2250 return false;
2253 void ScDataPilotFieldObj::setUseCurrentPage( sal_Bool bUse )
2255 SolarMutexGuard aGuard;
2256 ScDPObject* pDPObj = 0;
2257 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2259 if( bUse )
2261 /* It is somehow useless to set the property "HasSelectedPage" to
2262 true, because it is still needed to set an explicit page name. */
2263 const OUString aPage;
2264 pDim->SetCurrentPage( &aPage );
2266 else
2267 pDim->SetCurrentPage( 0 );
2268 SetDPObject( pDPObj );
2272 const DataPilotFieldAutoShowInfo* ScDataPilotFieldObj::getAutoShowInfo()
2274 SolarMutexGuard aGuard;
2275 ScDPSaveDimension* pDim = GetDPDimension();
2276 return pDim ? pDim->GetAutoShowInfo() : 0;
2279 void ScDataPilotFieldObj::setAutoShowInfo( const DataPilotFieldAutoShowInfo* pInfo )
2281 SolarMutexGuard aGuard;
2282 ScDPObject* pDPObj = 0;
2283 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2285 pDim->SetAutoShowInfo( pInfo );
2286 SetDPObject( pDPObj );
2290 const DataPilotFieldLayoutInfo* ScDataPilotFieldObj::getLayoutInfo()
2292 SolarMutexGuard aGuard;
2293 ScDPSaveDimension* pDim = GetDPDimension();
2294 return pDim ? pDim->GetLayoutInfo() : 0;
2297 void ScDataPilotFieldObj::setLayoutInfo( const DataPilotFieldLayoutInfo* pInfo )
2299 SolarMutexGuard aGuard;
2300 ScDPObject* pDPObj = 0;
2301 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2303 pDim->SetLayoutInfo( pInfo );
2304 SetDPObject( pDPObj );
2308 const DataPilotFieldReference* ScDataPilotFieldObj::getReference()
2310 SolarMutexGuard aGuard;
2311 ScDPSaveDimension* pDim = GetDPDimension();
2312 return pDim ? pDim->GetReferenceValue() : 0;
2315 void ScDataPilotFieldObj::setReference( const DataPilotFieldReference* pInfo )
2317 SolarMutexGuard aGuard;
2318 ScDPObject* pDPObj = 0;
2319 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2321 pDim->SetReferenceValue( pInfo );
2322 SetDPObject( pDPObj );
2326 const DataPilotFieldSortInfo* ScDataPilotFieldObj::getSortInfo()
2328 SolarMutexGuard aGuard;
2329 ScDPSaveDimension* pDim = GetDPDimension();
2330 return pDim ? pDim->GetSortInfo() : 0;
2333 void ScDataPilotFieldObj::setSortInfo( const DataPilotFieldSortInfo* pInfo )
2335 SolarMutexGuard aGuard;
2336 ScDPObject* pDPObj = 0;
2337 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2339 pDim->SetSortInfo( pInfo );
2340 SetDPObject( pDPObj );
2344 sal_Bool ScDataPilotFieldObj::getShowEmpty() const
2346 SolarMutexGuard aGuard;
2347 ScDPSaveDimension* pDim = GetDPDimension();
2348 return pDim && pDim->GetShowEmpty();
2351 void ScDataPilotFieldObj::setShowEmpty( sal_Bool bShow )
2353 SolarMutexGuard aGuard;
2354 ScDPObject* pDPObj = 0;
2355 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2357 pDim->SetShowEmpty( bShow );
2358 SetDPObject( pDPObj );
2362 sal_Bool ScDataPilotFieldObj::hasGroupInfo()
2364 SolarMutexGuard aGuard;
2365 ScDPObject* pDPObj = 0;
2366 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2367 if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2368 return pDimData->GetNamedGroupDim( pDim->GetName() ) || pDimData->GetNumGroupDim( pDim->GetName() );
2369 return false;
2372 DataPilotFieldGroupInfo ScDataPilotFieldObj::getGroupInfo()
2374 SolarMutexGuard aGuard;
2375 DataPilotFieldGroupInfo aInfo;
2376 ScDPObject* pDPObj = 0;
2377 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2379 if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2381 if( const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( pDim->GetName() ) )
2383 // grouped by ...
2384 aInfo.GroupBy = pGroupDim->GetDatePart();
2386 // find source field
2389 Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2390 aInfo.SourceField.set( xFields->getByName( pGroupDim->GetSourceDimName() ), UNO_QUERY );
2392 catch( Exception& )
2396 ScDataPilotConversion::FillGroupInfo( aInfo, pGroupDim->GetDateInfo() );
2397 if( pGroupDim->GetDatePart() == 0 )
2399 // fill vector of group and group member information
2400 ScFieldGroups aGroups;
2401 for( sal_Int32 nIdx = 0, nCount = pGroupDim->GetGroupCount(); nIdx < nCount; ++nIdx )
2403 if( const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( nIdx ) )
2405 ScFieldGroup aGroup;
2406 aGroup.maName = pGroup->GetGroupName();
2407 for( sal_Int32 nMemIdx = 0, nMemCount = pGroup->GetElementCount(); nMemIdx < nMemCount; ++nMemIdx )
2408 if (const OUString* pMem = pGroup->GetElementByIndex(nMemIdx))
2409 aGroup.maMembers.push_back( *pMem );
2410 aGroups.push_back( aGroup );
2413 aInfo.Groups = new ScDataPilotFieldGroupsObj( aGroups );
2416 else if( const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( pDim->GetName() ) )
2418 if (pNumGroupDim->GetDatePart())
2420 ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetDateInfo() );
2421 aInfo.GroupBy = pNumGroupDim->GetDatePart();
2423 else
2425 ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetInfo() );
2430 return aInfo;
2433 void ScDataPilotFieldObj::setGroupInfo( const DataPilotFieldGroupInfo* pInfo )
2435 SolarMutexGuard aGuard;
2436 ScDPObject* pDPObj = 0;
2437 if( /*ScDPSaveDimension* pDim =*/ GetDPDimension( &pDPObj ) )
2439 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2440 if( pInfo && lclCheckMinMaxStep( *pInfo ) )
2442 ScDPNumGroupInfo aInfo;
2443 aInfo.mbEnable = sal_True;
2444 aInfo.mbDateValues = pInfo->HasDateValues;
2445 aInfo.mbAutoStart = pInfo->HasAutoStart;
2446 aInfo.mbAutoEnd = pInfo->HasAutoEnd;
2447 aInfo.mfStart = pInfo->Start;
2448 aInfo.mfEnd = pInfo->End;
2449 aInfo.mfStep = pInfo->Step;
2450 Reference< XNamed > xNamed( pInfo->SourceField, UNO_QUERY );
2451 if( xNamed.is() )
2453 ScDPSaveGroupDimension aGroupDim( xNamed->getName(), getName() );
2454 if( pInfo->GroupBy )
2455 aGroupDim.SetDateInfo(aInfo, pInfo->GroupBy);
2456 else
2458 Reference<XIndexAccess> xIndex(pInfo->Groups, UNO_QUERY);
2459 if (xIndex.is())
2461 sal_Int32 nCount(xIndex->getCount());
2462 for(sal_Int32 i = 0; i < nCount; i++)
2464 Reference<XNamed> xGroupNamed(xIndex->getByIndex(i), UNO_QUERY);
2465 if (xGroupNamed.is())
2467 ScDPSaveGroupItem aItem(xGroupNamed->getName());
2468 Reference<XIndexAccess> xGroupIndex(xGroupNamed, UNO_QUERY);
2469 if (xGroupIndex.is())
2471 sal_Int32 nItemCount(xGroupIndex->getCount());
2472 for (sal_Int32 j = 0; j < nItemCount; ++j)
2474 Reference<XNamed> xItemNamed(xGroupIndex->getByIndex(j), UNO_QUERY);
2475 if (xItemNamed.is())
2476 aItem.AddElement(xItemNamed->getName());
2479 aGroupDim.AddGroupItem(aItem);
2485 // get dimension savedata or create new if none
2486 ScDPDimensionSaveData& rDimSaveData = *pSaveData->GetDimensionData();
2487 rDimSaveData.ReplaceGroupDimension( aGroupDim );
2489 else // no source field in group info -> numeric group
2491 ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData(); // created if not there
2493 ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( getName() );
2494 if ( pExisting )
2496 if (pInfo->GroupBy)
2497 pExisting->SetDateInfo(aInfo, pInfo->GroupBy);
2498 // modify existing group dimension
2499 pExisting->SetGroupInfo( aInfo );
2501 else if (pInfo->GroupBy)
2503 // create new group dimension
2504 ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo, pInfo->GroupBy );
2505 pDimData->AddNumGroupDimension( aNumGroupDim );
2507 else
2509 // create new group dimension
2510 ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo );
2511 pDimData->AddNumGroupDimension( aNumGroupDim );
2515 else // null passed as argument
2517 pSaveData->SetDimensionData( 0 );
2520 pDPObj->SetSaveData( *pSaveData );
2521 SetDPObject( pDPObj );
2525 sal_Bool ScDataPilotFieldObj::HasString(const Sequence< OUString >& rItems, const OUString& aString)
2527 sal_Bool bRet = false;
2529 sal_Int32 nCount(rItems.getLength());
2530 sal_Int32 nItem(0);
2531 while (nItem < nCount && !bRet)
2533 bRet = rItems[nItem] == aString;
2534 ++nItem;
2537 return bRet;
2540 // XDataPilotFieldGrouping
2541 Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( const Sequence< OUString >& rItems )
2542 throw (RuntimeException, IllegalArgumentException)
2544 SolarMutexGuard aGuard;
2546 Reference< XDataPilotField > xRet;
2547 OUString sNewDim;
2549 if( !rItems.hasElements() )
2550 throw IllegalArgumentException();
2552 ScDPObject* pDPObj = 0;
2553 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2555 OUString aDimName = pDim->GetName();
2557 ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2558 ScDPDimensionSaveData* pDimData = aSaveData.GetDimensionData(); // created if not there
2560 // find original base
2561 OUString aBaseDimName( aDimName );
2562 const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
2563 if ( pBaseGroupDim )
2565 // any entry's SourceDimName is the original base
2566 aBaseDimName = pBaseGroupDim->GetSourceDimName();
2569 // find existing group dimension
2570 // (using the selected dim, can be intermediate group dim)
2571 ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
2573 // remove the selected items from their groups
2574 // (empty groups are removed, too)
2575 sal_Int32 nEntryCount = rItems.getLength();
2576 sal_Int32 nEntry;
2577 if ( pGroupDimension )
2579 for (nEntry=0; nEntry<nEntryCount; nEntry++)
2581 const OUString& aEntryName = rItems[nEntry];
2582 if ( pBaseGroupDim )
2584 // for each selected (intermediate) group, remove all its items
2585 // (same logic as for adding, below)
2586 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2587 if ( pBaseGroup )
2588 pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements
2589 else
2590 pGroupDimension->RemoveFromGroups( aEntryName );
2592 else
2593 pGroupDimension->RemoveFromGroups( aEntryName );
2597 ScDPSaveGroupDimension* pNewGroupDim = 0;
2598 if ( !pGroupDimension )
2600 // create a new group dimension
2601 sNewDim = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
2602 pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, sNewDim );
2604 pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
2606 if ( pBaseGroupDim )
2608 // If it's a higher-order group dimension, pre-allocate groups for all
2609 // non-selected original groups, so the individual base members aren't
2610 // used for automatic groups (this would make the original groups hard
2611 // to find).
2612 //! Also do this when removing groups?
2613 //! Handle this case dynamically with automatic groups?
2615 long nGroupCount = pBaseGroupDim->GetGroupCount();
2616 for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
2618 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
2620 if (!HasString(rItems, pBaseGroup->GetGroupName())) //! ignore case?
2622 // add an additional group for each item that is not in the selection
2623 ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
2624 aGroup.AddElementsFromGroup( *pBaseGroup );
2625 pGroupDimension->AddGroupItem( aGroup );
2630 OUString aGroupDimName = pGroupDimension->GetGroupDimName();
2632 //! localized prefix string
2633 OUString aGroupName = pGroupDimension->CreateGroupName( OUString( "Group" ) );
2634 ScDPSaveGroupItem aGroup( aGroupName );
2635 Reference< XNameAccess > xMembers = GetMembers();
2636 if (!xMembers.is())
2638 delete pNewGroupDim;
2639 throw RuntimeException();
2642 for (nEntry=0; nEntry<nEntryCount; nEntry++)
2644 OUString aEntryName(rItems[nEntry]);
2646 if (!xMembers->hasByName(aEntryName))
2648 delete pNewGroupDim;
2649 throw IllegalArgumentException();
2652 if ( pBaseGroupDim )
2654 // for each selected (intermediate) group, add all its items
2655 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2656 if ( pBaseGroup )
2657 aGroup.AddElementsFromGroup( *pBaseGroup );
2658 else
2659 aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself
2661 else
2662 aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
2665 pGroupDimension->AddGroupItem( aGroup );
2667 if ( pNewGroupDim )
2669 pDimData->AddGroupDimension( *pNewGroupDim );
2670 delete pNewGroupDim; // AddGroupDimension copies the object
2671 // don't access pGroupDimension after here
2673 pGroupDimension = pNewGroupDim = NULL;
2675 // set orientation
2676 ScDPSaveDimension* pSaveDimension = aSaveData.GetDimensionByName( aGroupDimName );
2677 if ( pSaveDimension->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2679 ScDPSaveDimension* pOldDimension = aSaveData.GetDimensionByName( aDimName );
2680 pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
2681 long nPosition = 0; //! before (immediate) base
2682 aSaveData.SetPosition( pSaveDimension, nPosition );
2685 // apply changes
2686 pDPObj->SetSaveData( aSaveData );
2687 ScDBDocFunc(*GetDocShell()).RefreshPivotTableGroups(pDPObj);
2690 // if new grouping field has been created (on first group), return it
2691 if( !sNewDim.isEmpty() )
2693 Reference< XNameAccess > xFields(mrParent.getDataPilotFields(), UNO_QUERY);
2694 if (xFields.is())
2698 xRet.set(xFields->getByName(sNewDim), UNO_QUERY);
2699 OSL_ENSURE(xRet.is(), "there is a name, so there should be also a field");
2701 catch (const container::NoSuchElementException&)
2703 // Avoid throwing exception that's not specified in the method signature.
2704 throw RuntimeException();
2708 return xRet;
2711 Reference < XDataPilotField > SAL_CALL ScDataPilotFieldObj::createDateGroup( const DataPilotFieldGroupInfo& rInfo )
2712 throw (RuntimeException, IllegalArgumentException)
2714 SolarMutexGuard aGuard;
2715 using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
2717 // check min/max/step, HasDateValues must be set always
2718 if( !rInfo.HasDateValues || !lclCheckMinMaxStep( rInfo ) )
2719 throw IllegalArgumentException();
2720 // only a single date flag is allowed
2721 if( (rInfo.GroupBy == 0) || (rInfo.GroupBy > YEARS) || ((rInfo.GroupBy & (rInfo.GroupBy - 1)) != 0) )
2722 throw IllegalArgumentException();
2723 // step must be zero, if something else than DAYS is specified
2724 if( rInfo.Step >= ((rInfo.GroupBy == DAYS) ? 32768.0 : 1.0) )
2725 throw IllegalArgumentException();
2727 OUString aGroupDimName;
2728 ScDPObject* pDPObj = 0;
2729 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2731 ScDPNumGroupInfo aInfo;
2732 aInfo.mbEnable = true;
2733 aInfo.mbDateValues = (rInfo.GroupBy == DAYS) && (rInfo.Step >= 1.0);
2734 aInfo.mbAutoStart = rInfo.HasAutoStart;
2735 aInfo.mbAutoEnd = rInfo.HasAutoEnd;
2736 aInfo.mfStart = rInfo.Start;
2737 aInfo.mfEnd = rInfo.End;
2738 aInfo.mfStep = static_cast< sal_Int32 >( rInfo.Step );
2740 // create a local copy of the entire save data (will be written back below)
2741 ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2742 // get or create dimension save data
2743 ScDPDimensionSaveData& rDimData = *aSaveData.GetDimensionData();
2745 // find source dimension name
2746 const OUString& rDimName = pDim->GetName();
2747 const ScDPSaveGroupDimension* pGroupDim = rDimData.GetNamedGroupDim( rDimName );
2748 OUString aSrcDimName = pGroupDim ? pGroupDim->GetSourceDimName() : rDimName;
2750 // find a group dimension for the base field, or get numeric grouping
2751 pGroupDim = rDimData.GetFirstNamedGroupDim( aSrcDimName );
2752 const ScDPSaveNumGroupDimension* pNumGroupDim = rDimData.GetNumGroupDim( aSrcDimName );
2754 // do not group by dates, if named groups or numeric grouping is present
2755 bool bHasNamedGrouping = pGroupDim && !pGroupDim->GetDateInfo().mbEnable;
2756 bool bHasNumGrouping = pNumGroupDim && pNumGroupDim->GetInfo().mbEnable && !pNumGroupDim->GetInfo().mbDateValues && !pNumGroupDim->GetDateInfo().mbEnable;
2757 if( bHasNamedGrouping || bHasNumGrouping )
2758 throw IllegalArgumentException();
2760 if( aInfo.mbDateValues ) // create day ranges grouping
2762 // first remove all named group dimensions
2763 while( pGroupDim )
2765 OUString aGroupDimName2 = pGroupDim->GetGroupDimName();
2766 // find next group dimension before deleting this group
2767 pGroupDim = rDimData.GetNextNamedGroupDim( aGroupDimName2 );
2768 // remove from dimension save data
2769 rDimData.RemoveGroupDimension( aGroupDimName2 );
2770 // also remove save data settings for the dimension that no longer exists
2771 aSaveData.RemoveDimensionByName( aGroupDimName2 );
2773 // create or replace the number grouping dimension
2774 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo );
2775 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2777 else // create date grouping
2779 // collect all existing date flags
2780 sal_Int32 nDateParts = rDimData.CollectDateParts( aSrcDimName );
2781 if( nDateParts == 0 )
2783 // insert numeric group dimension, if no date groups exist yet (or replace day range grouping)
2784 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo, rInfo.GroupBy );
2785 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2787 else if( (nDateParts & rInfo.GroupBy) == 0 ) // do nothing if date field exists already
2789 // create new named group dimension for additional date groups
2790 aGroupDimName = rDimData.CreateDateGroupDimName( rInfo.GroupBy, *pDPObj, true, 0 );
2791 ScDPSaveGroupDimension aGroupDim( aSrcDimName, aGroupDimName, aInfo, rInfo.GroupBy );
2792 rDimData.AddGroupDimension( aGroupDim );
2794 // set orientation of new named group dimension
2795 ScDPSaveDimension& rSaveDim = *aSaveData.GetDimensionByName( aGroupDimName );
2796 if( rSaveDim.GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2798 ScDPSaveDimension& rOldDim = *aSaveData.GetDimensionByName( aSrcDimName );
2799 rSaveDim.SetOrientation( rOldDim.GetOrientation() );
2800 aSaveData.SetPosition( &rSaveDim, 0 ); //! before (immediate) base
2805 // apply changes
2806 pDPObj->SetSaveData( aSaveData );
2807 SetDPObject( pDPObj );
2810 // return the UNO object of the new dimension, after writing back saved data
2811 Reference< XDataPilotField > xRet;
2812 if( !aGroupDimName.isEmpty() )
2815 Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2816 xRet.set( xFields->getByName( aGroupDimName ), UNO_QUERY );
2818 catch( Exception& )
2821 return xRet;
2824 // ============================================================================
2826 namespace {
2828 bool lclExtractGroupMembers( ScFieldGroupMembers& rMembers, const Any& rElement )
2830 // allow empty value to create a new group
2831 if( !rElement.hasValue() )
2832 return true;
2834 // try to extract a simple sequence of strings
2835 Sequence< OUString > aSeq;
2836 if( rElement >>= aSeq )
2838 if( aSeq.hasElements() )
2839 rMembers.insert( rMembers.end(), aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength() );
2840 return true;
2843 // try to use XIndexAccess providing objects that support XNamed
2844 Reference< XIndexAccess > xItemsIA( rElement, UNO_QUERY );
2845 if( xItemsIA.is() )
2847 for( sal_Int32 nIdx = 0, nCount = xItemsIA->getCount(); nIdx < nCount; ++nIdx )
2849 try // getByIndex() should not throw, but we cannot be sure
2851 Reference< XNamed > xItemName( xItemsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
2852 rMembers.push_back( xItemName->getName() );
2854 catch( Exception& )
2856 // ignore exceptions, go ahead with next element in the array
2859 return true;
2862 // nothing valid inside the Any -> return false
2863 return false;
2866 } // namespace
2868 // ----------------------------------------------------------------------------
2870 ScDataPilotFieldGroupsObj::ScDataPilotFieldGroupsObj( const ScFieldGroups& rGroups ) :
2871 maGroups( rGroups )
2875 ScDataPilotFieldGroupsObj::~ScDataPilotFieldGroupsObj()
2879 // XNameAccess
2881 Any SAL_CALL ScDataPilotFieldGroupsObj::getByName( const OUString& rName )
2882 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2884 SolarMutexGuard aGuard;
2885 if( implFindByName( rName ) == maGroups.end() )
2886 throw NoSuchElementException();
2887 return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, rName ) ) );
2890 Sequence< OUString > SAL_CALL ScDataPilotFieldGroupsObj::getElementNames() throw(RuntimeException)
2892 SolarMutexGuard aGuard;
2893 Sequence< OUString > aSeq;
2894 if( !maGroups.empty() )
2896 aSeq.realloc( static_cast< sal_Int32 >( maGroups.size() ) );
2897 OUString* pName = aSeq.getArray();
2898 for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt, ++pName )
2899 *pName = aIt->maName;
2901 return aSeq;
2904 sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasByName( const OUString& rName ) throw(RuntimeException)
2906 SolarMutexGuard aGuard;
2907 return implFindByName( rName ) != maGroups.end();
2910 // XNameReplace
2912 void SAL_CALL ScDataPilotFieldGroupsObj::replaceByName( const OUString& rName, const Any& rElement )
2913 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2915 SolarMutexGuard aGuard;
2917 if( rName.isEmpty() )
2918 throw IllegalArgumentException();
2920 ScFieldGroups::iterator aIt = implFindByName( rName );
2921 if( aIt == maGroups.end() )
2922 throw NoSuchElementException();
2924 // read all item names provided by the passed object
2925 ScFieldGroupMembers aMembers;
2926 if( !lclExtractGroupMembers( aMembers, rElement ) )
2927 throw IllegalArgumentException();
2929 // copy and forget, faster than vector assignment
2930 aIt->maMembers.swap( aMembers );
2933 // XNameContainer
2935 void SAL_CALL ScDataPilotFieldGroupsObj::insertByName( const OUString& rName, const Any& rElement )
2936 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2938 SolarMutexGuard aGuard;
2940 if( rName.isEmpty() )
2941 throw IllegalArgumentException();
2943 ScFieldGroups::iterator aIt = implFindByName( rName );
2944 if( aIt != maGroups.end() )
2945 throw ElementExistException();
2947 // read all item names provided by the passed object
2948 ScFieldGroupMembers aMembers;
2949 if( !lclExtractGroupMembers( aMembers, rElement ) )
2950 throw IllegalArgumentException();
2952 // create the new entry if no error has been occurred
2953 maGroups.resize( maGroups.size() + 1 );
2954 ScFieldGroup& rGroup = maGroups.back();
2955 rGroup.maName = rName;
2956 rGroup.maMembers.swap( aMembers );
2959 void SAL_CALL ScDataPilotFieldGroupsObj::removeByName( const OUString& rName )
2960 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
2962 SolarMutexGuard aGuard;
2964 if( rName.isEmpty() )
2965 throw IllegalArgumentException();
2967 ScFieldGroups::iterator aIt = implFindByName( rName );
2968 if( aIt == maGroups.end() )
2969 throw NoSuchElementException();
2971 maGroups.erase( aIt );
2974 // XIndexAccess
2976 sal_Int32 SAL_CALL ScDataPilotFieldGroupsObj::getCount() throw(RuntimeException)
2978 SolarMutexGuard aGuard;
2979 return static_cast< sal_Int32 >( maGroups.size() );
2982 Any SAL_CALL ScDataPilotFieldGroupsObj::getByIndex( sal_Int32 nIndex )
2983 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
2985 SolarMutexGuard aGuard;
2986 if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( maGroups.size() )))
2987 throw IndexOutOfBoundsException();
2988 return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, maGroups[ nIndex ].maName ) ) );
2991 // XEnumerationAccess
2993 Reference<XEnumeration> SAL_CALL ScDataPilotFieldGroupsObj::createEnumeration() throw(RuntimeException)
2995 SolarMutexGuard aGuard;
2996 return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupsEnumeration" ) );
2999 // XElementAccess
3001 uno::Type SAL_CALL ScDataPilotFieldGroupsObj::getElementType() throw(RuntimeException)
3003 SolarMutexGuard aGuard;
3004 return getCppuType( (Reference< XNameAccess >*)0 );
3007 sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasElements() throw(RuntimeException)
3009 SolarMutexGuard aGuard;
3010 return !maGroups.empty();
3013 // implementation
3015 ScFieldGroup& ScDataPilotFieldGroupsObj::getFieldGroup( const OUString& rName ) throw(RuntimeException)
3017 SolarMutexGuard aGuard;
3018 ScFieldGroups::iterator aIt = implFindByName( rName );
3019 if( aIt == maGroups.end() )
3020 throw RuntimeException();
3021 return *aIt;
3024 void ScDataPilotFieldGroupsObj::renameFieldGroup( const OUString& rOldName, const OUString& rNewName ) throw(RuntimeException)
3026 SolarMutexGuard aGuard;
3027 ScFieldGroups::iterator aOldIt = implFindByName( rOldName );
3028 ScFieldGroups::iterator aNewIt = implFindByName( rNewName );
3029 // new name must not exist yet
3030 if( (aOldIt == maGroups.end()) || ((aNewIt != maGroups.end()) && (aNewIt != aOldIt)) )
3031 throw RuntimeException();
3032 aOldIt->maName = rNewName;
3035 ScFieldGroups::iterator ScDataPilotFieldGroupsObj::implFindByName( const OUString& rName )
3037 for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt )
3038 if( aIt->maName == rName )
3039 return aIt;
3040 return maGroups.end();
3043 // ============================================================================
3045 namespace {
3047 OUString lclExtractMember( const Any& rElement )
3049 if( rElement.has< OUString >() )
3050 return rElement.get< OUString >();
3052 Reference< XNamed > xNamed( rElement, UNO_QUERY );
3053 if( xNamed.is() )
3054 return xNamed->getName();
3056 return OUString();
3059 } // namespace
3061 // ----------------------------------------------------------------------------
3063 ScDataPilotFieldGroupObj::ScDataPilotFieldGroupObj( ScDataPilotFieldGroupsObj& rParent, const OUString& rGroupName ) :
3064 mrParent( rParent ),
3065 maGroupName( rGroupName )
3067 mrParent.acquire();
3070 ScDataPilotFieldGroupObj::~ScDataPilotFieldGroupObj()
3072 mrParent.release();
3075 // XNameAccess
3077 Any SAL_CALL ScDataPilotFieldGroupObj::getByName( const OUString& rName )
3078 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3080 SolarMutexGuard aGuard;
3081 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3082 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3083 if( aIt == rMembers.end() )
3084 throw NoSuchElementException();
3085 return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, *aIt ) ) );
3088 Sequence< OUString > SAL_CALL ScDataPilotFieldGroupObj::getElementNames() throw(RuntimeException)
3090 SolarMutexGuard aGuard;
3091 return ::comphelper::containerToSequence( mrParent.getFieldGroup( maGroupName ).maMembers );
3094 sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasByName( const OUString& rName ) throw(RuntimeException)
3096 SolarMutexGuard aGuard;
3097 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3098 return ::std::find( rMembers.begin(), rMembers.end(), rName ) != rMembers.end();
3101 // XNameReplace
3103 void SAL_CALL ScDataPilotFieldGroupObj::replaceByName( const OUString& rName, const Any& rElement )
3104 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
3106 SolarMutexGuard aGuard;
3108 // it should be possible to quickly rename an item -> accept string or XNamed
3109 OUString aNewName = lclExtractMember( rElement );
3110 if( rName.isEmpty() || aNewName.isEmpty() )
3111 throw IllegalArgumentException();
3112 if( rName == aNewName )
3113 return;
3115 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3116 ScFieldGroupMembers::iterator aOldIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3117 ScFieldGroupMembers::iterator aNewIt = ::std::find( rMembers.begin(), rMembers.end(), aNewName );
3118 // throw if passed member name does not exist
3119 if( aOldIt == rMembers.end() )
3120 throw NoSuchElementException();
3121 // throw if new name already exists
3122 if( aNewIt != rMembers.end() )
3123 throw IllegalArgumentException();
3124 *aOldIt = aNewName;
3127 // XNameContainer
3129 void SAL_CALL ScDataPilotFieldGroupObj::insertByName( const OUString& rName, const Any& /*rElement*/ )
3130 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
3132 SolarMutexGuard aGuard;
3134 // we will ignore the passed element and just try to insert the name
3135 if( rName.isEmpty() )
3136 throw IllegalArgumentException();
3138 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3139 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3140 // throw if passed name already exists
3141 if( aIt != rMembers.end() )
3142 throw IllegalArgumentException();
3143 rMembers.push_back( rName );
3146 void SAL_CALL ScDataPilotFieldGroupObj::removeByName( const OUString& rName )
3147 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
3149 SolarMutexGuard aGuard;
3151 if( rName.isEmpty() )
3152 throw IllegalArgumentException();
3153 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3154 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3155 // throw if passed name does not exist
3156 if( aIt == rMembers.end() )
3157 throw NoSuchElementException();
3158 rMembers.erase( aIt );
3161 // XIndexAccess
3163 sal_Int32 SAL_CALL ScDataPilotFieldGroupObj::getCount() throw(RuntimeException)
3165 SolarMutexGuard aGuard;
3166 return static_cast< sal_Int32 >( mrParent.getFieldGroup( maGroupName ).maMembers.size() );
3169 Any SAL_CALL ScDataPilotFieldGroupObj::getByIndex( sal_Int32 nIndex )
3170 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
3172 SolarMutexGuard aGuard;
3173 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3174 if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( rMembers.size() )))
3175 throw IndexOutOfBoundsException();
3176 return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, rMembers[ nIndex ] ) ) );
3179 // XEnumerationAccess
3181 Reference< XEnumeration > SAL_CALL ScDataPilotFieldGroupObj::createEnumeration() throw(RuntimeException)
3183 SolarMutexGuard aGuard;
3184 return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupEnumeration" ) );
3187 // XElementAccess
3189 uno::Type SAL_CALL ScDataPilotFieldGroupObj::getElementType() throw(RuntimeException)
3191 SolarMutexGuard aGuard;
3192 return getCppuType( (Reference< XNamed >*)0 );
3195 sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasElements() throw(RuntimeException)
3197 SolarMutexGuard aGuard;
3198 return !mrParent.getFieldGroup( maGroupName ).maMembers.empty();
3201 // XNamed
3203 OUString SAL_CALL ScDataPilotFieldGroupObj::getName() throw(RuntimeException)
3205 SolarMutexGuard aGuard;
3206 return maGroupName;
3209 void SAL_CALL ScDataPilotFieldGroupObj::setName( const OUString& rName ) throw(RuntimeException)
3211 SolarMutexGuard aGuard;
3212 mrParent.renameFieldGroup( maGroupName, rName );
3213 // if call to renameFieldGroup() did not throw, remember the new name
3214 maGroupName = rName;
3217 // ============================================================================
3219 ScDataPilotFieldGroupItemObj::ScDataPilotFieldGroupItemObj( ScDataPilotFieldGroupObj& rParent, const OUString& rName ) :
3220 mrParent( rParent ),
3221 maName( rName )
3223 mrParent.acquire();
3226 ScDataPilotFieldGroupItemObj::~ScDataPilotFieldGroupItemObj()
3228 mrParent.release();
3231 // XNamed
3233 OUString SAL_CALL ScDataPilotFieldGroupItemObj::getName() throw(RuntimeException)
3235 SolarMutexGuard aGuard;
3236 return maName;
3239 void SAL_CALL ScDataPilotFieldGroupItemObj::setName( const OUString& rName ) throw(RuntimeException)
3241 SolarMutexGuard aGuard;
3242 mrParent.replaceByName( maName, Any( rName ) );
3243 // if call to replaceByName() did not throw, remember the new name
3244 maName = rName;
3247 // ============================================================================
3249 ScDataPilotItemsObj::ScDataPilotItemsObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
3250 ScDataPilotChildObjBase( rParent, rFieldId )
3254 ScDataPilotItemsObj::~ScDataPilotItemsObj()
3258 // XDataPilotItems
3260 ScDataPilotItemObj* ScDataPilotItemsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3262 return ((0 <= nIndex) && (nIndex < GetMemberCount())) ?
3263 new ScDataPilotItemObj( mrParent, maFieldId, nIndex ) : 0;
3266 // XNameAccess
3268 Any SAL_CALL ScDataPilotItemsObj::getByName( const OUString& aName )
3269 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3271 SolarMutexGuard aGuard;
3272 Reference<XNameAccess> xMembers = GetMembers();
3273 if (xMembers.is())
3275 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3276 sal_Int32 nCount = xMembersIndex->getCount();
3277 sal_Bool bFound(false);
3278 sal_Int32 nItem = 0;
3279 while (nItem < nCount && !bFound )
3281 Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3282 if (xMember.is() && (aName == xMember->getName()))
3283 return Any( Reference< XPropertySet >( GetObjectByIndex_Impl( nItem ) ) );
3284 ++nItem;
3286 if (!bFound)
3287 throw NoSuchElementException();
3289 return Any();
3292 Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
3293 throw(RuntimeException)
3295 SolarMutexGuard aGuard;
3296 Sequence< OUString > aSeq;
3297 if( ScDPObject* pDPObj = GetDPObject() )
3298 pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
3299 return aSeq;
3302 sal_Bool SAL_CALL ScDataPilotItemsObj::hasByName( const OUString& aName )
3303 throw(RuntimeException)
3305 SolarMutexGuard aGuard;
3306 sal_Bool bFound = false;
3307 Reference<XNameAccess> xMembers = GetMembers();
3308 if (xMembers.is())
3310 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3311 sal_Int32 nCount = xMembersIndex->getCount();
3312 sal_Int32 nItem = 0;
3313 while (nItem < nCount && !bFound )
3315 Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3316 if (xMember.is() && aName == xMember->getName())
3317 bFound = sal_True;
3318 else
3319 nItem++;
3322 return bFound;
3325 // XEnumerationAccess
3327 Reference<XEnumeration> SAL_CALL ScDataPilotItemsObj::createEnumeration()
3328 throw(RuntimeException)
3330 SolarMutexGuard aGuard;
3331 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotItemsEnumeration"));
3334 // XIndexAccess
3336 sal_Int32 SAL_CALL ScDataPilotItemsObj::getCount() throw(RuntimeException)
3338 SolarMutexGuard aGuard;
3339 return GetMemberCount();
3342 Any SAL_CALL ScDataPilotItemsObj::getByIndex( sal_Int32 nIndex )
3343 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
3345 SolarMutexGuard aGuard;
3346 Reference< XPropertySet > xItem( GetObjectByIndex_Impl( nIndex ) );
3347 if (!xItem.is())
3348 throw IndexOutOfBoundsException();
3349 return Any( xItem );
3352 uno::Type SAL_CALL ScDataPilotItemsObj::getElementType() throw(RuntimeException)
3354 SolarMutexGuard aGuard;
3355 return getCppuType((Reference<XPropertySet>*)0);
3358 sal_Bool SAL_CALL ScDataPilotItemsObj::hasElements() throw(RuntimeException)
3360 SolarMutexGuard aGuard;
3361 return ( getCount() != 0 );
3364 //------------------------------------------------------------------------
3366 ScDataPilotItemObj::ScDataPilotItemObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId, sal_Int32 nIndex ) :
3367 ScDataPilotChildObjBase( rParent, rFieldId ),
3368 maPropSet( lcl_GetDataPilotItemMap() ),
3369 mnIndex( nIndex )
3373 ScDataPilotItemObj::~ScDataPilotItemObj()
3377 // XNamed
3378 OUString SAL_CALL ScDataPilotItemObj::getName() throw(RuntimeException)
3380 SolarMutexGuard aGuard;
3381 OUString sRet;
3382 Reference<XNameAccess> xMembers = GetMembers();
3383 if (xMembers.is())
3385 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3386 sal_Int32 nCount = xMembersIndex->getCount();
3387 if (mnIndex < nCount)
3389 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3390 sRet = xMember->getName();
3393 return sRet;
3396 void SAL_CALL ScDataPilotItemObj::setName( const OUString& /* aName */ )
3397 throw(RuntimeException)
3401 // XPropertySet
3402 Reference< XPropertySetInfo >
3403 SAL_CALL ScDataPilotItemObj::getPropertySetInfo( )
3404 throw(RuntimeException)
3406 SolarMutexGuard aGuard;
3407 static Reference<XPropertySetInfo> aRef =
3408 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
3409 return aRef;
3412 void SAL_CALL ScDataPilotItemObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
3413 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
3415 SolarMutexGuard aGuard;
3416 ScDPObject* pDPObj = 0;
3417 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
3419 Reference<XNameAccess> xMembers = GetMembers();
3420 if( xMembers.is() )
3422 Reference<XIndexAccess> xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3423 sal_Int32 nCount = xMembersIndex->getCount();
3424 if( mnIndex < nCount )
3426 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3427 OUString sName(xMember->getName());
3428 ScDPSaveMember* pMember = pDim->GetMemberByName(sName);
3429 if (pMember)
3431 bool bGetNewIndex = false;
3432 if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3433 pMember->SetShowDetails(cppu::any2bool(aValue));
3434 else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3435 pMember->SetIsVisible(!cppu::any2bool(aValue));
3436 else if ( aPropertyName == SC_UNONAME_POS )
3438 sal_Int32 nNewPos = 0;
3439 if ( ( aValue >>= nNewPos ) && nNewPos >= 0 && nNewPos < nCount )
3441 pDim->SetMemberPosition( sName, nNewPos );
3442 // get new effective index (depends on sorting mode, which isn't modified)
3443 bGetNewIndex = true;
3445 else
3446 throw IllegalArgumentException();
3448 SetDPObject( pDPObj );
3450 if ( bGetNewIndex ) // after SetDPObject, get the new index
3452 OUString aOUName( sName );
3453 Sequence< OUString > aItemNames = xMembers->getElementNames();
3454 sal_Int32 nItemCount = aItemNames.getLength();
3455 for (sal_Int32 nItem=0; nItem<nItemCount; ++nItem)
3456 if (aItemNames[nItem] == aOUName)
3457 mnIndex = nItem;
3465 Any SAL_CALL ScDataPilotItemObj::getPropertyValue( const OUString& aPropertyName )
3466 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3468 SolarMutexGuard aGuard;
3469 Any aRet;
3470 if( ScDPSaveDimension* pDim = GetDPDimension() )
3472 Reference< XNameAccess > xMembers = GetMembers();
3473 if( xMembers.is() )
3475 Reference< XIndexAccess > xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3476 sal_Int32 nCount = xMembersIndex->getCount();
3477 if( mnIndex < nCount )
3479 Reference< XNamed > xMember( xMembersIndex->getByIndex( mnIndex ), UNO_QUERY );
3480 OUString sName( xMember->getName() );
3481 ScDPSaveMember* pMember = pDim->GetExistingMemberByName( sName );
3482 if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3484 if (pMember && pMember->HasShowDetails())
3486 aRet <<= (bool)pMember->GetShowDetails();
3488 else
3490 Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3491 if( xMemberProps.is() )
3492 aRet = xMemberProps->getPropertyValue( OUString( SC_UNO_DP_SHOWDETAILS ) );
3493 else
3494 aRet <<= true;
3497 else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3499 if (pMember && pMember->HasIsVisible())
3501 aRet <<= !pMember->GetIsVisible();
3503 else
3505 Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3506 if( xMemberProps.is() )
3507 aRet <<= !cppu::any2bool( xMemberProps->getPropertyValue( OUString( SC_UNO_DP_ISVISIBLE ) ) );
3508 else
3509 aRet <<= false;
3512 else if ( aPropertyName == SC_UNONAME_POS )
3514 aRet <<= mnIndex;
3519 return aRet;
3522 void SAL_CALL ScDataPilotItemObj::addPropertyChangeListener(
3523 const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* xListener */ )
3524 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3528 void SAL_CALL ScDataPilotItemObj::removePropertyChangeListener(
3529 const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* aListener */ )
3530 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3534 void SAL_CALL ScDataPilotItemObj::addVetoableChangeListener(
3535 const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3536 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3540 void SAL_CALL ScDataPilotItemObj::removeVetoableChangeListener(
3541 const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3542 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3546 //------------------------------------------------------------------------
3551 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */