fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / unoobj / dapiuno.cxx
blobfccb164a672f6c386f5454ba6b87c2f230ececa9
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 .
20 #include <algorithm>
21 #include <svl/smplhint.hxx>
22 #include <vcl/svapp.hxx>
24 #include "dapiuno.hxx"
25 #include "datauno.hxx"
26 #include "miscuno.hxx"
27 #include "convuno.hxx"
28 #include "docsh.hxx"
29 #include "tabvwsh.hxx"
30 #include "pivot.hxx"
31 #include "rangeutl.hxx"
32 #include "dpobject.hxx"
33 #include "dpshttab.hxx"
34 #include "dpsdbtab.hxx"
35 #include "dpsave.hxx"
36 #include "dbdocfun.hxx"
37 #include "unonames.hxx"
38 #include "dpgroup.hxx"
39 #include "dpdimsave.hxx"
40 #include "hints.hxx"
41 #include <dputil.hxx>
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;
60 using ::com::sun::star::uno::Any;
61 using ::com::sun::star::uno::Exception;
62 using ::com::sun::star::uno::Reference;
63 using ::com::sun::star::uno::RuntimeException;
64 using ::com::sun::star::uno::Sequence;
65 using ::com::sun::star::uno::UNO_QUERY;
66 using ::com::sun::star::uno::UNO_QUERY_THROW;
68 using ::com::sun::star::container::ElementExistException;
69 using ::com::sun::star::container::NoSuchElementException;
70 using ::com::sun::star::container::XEnumeration;
71 using ::com::sun::star::container::XIndexAccess;
72 using ::com::sun::star::container::XNameAccess;
73 using ::com::sun::star::container::XNamed;
75 using ::com::sun::star::beans::PropertyVetoException;
76 using ::com::sun::star::beans::UnknownPropertyException;
77 using ::com::sun::star::beans::XPropertyChangeListener;
78 using ::com::sun::star::beans::XPropertySet;
79 using ::com::sun::star::beans::XPropertySetInfo;
80 using ::com::sun::star::beans::XVetoableChangeListener;
82 using ::com::sun::star::lang::IllegalArgumentException;
83 using ::com::sun::star::lang::IndexOutOfBoundsException;
84 using ::com::sun::star::lang::WrappedTargetException;
86 using ::com::sun::star::table::CellAddress;
87 using ::com::sun::star::table::CellRangeAddress;
89 namespace {
91 const SfxItemPropertyMapEntry* lcl_GetDataPilotDescriptorBaseMap()
93 static const SfxItemPropertyMapEntry aDataPilotDescriptorBaseMap_Impl[] =
95 {OUString(SC_UNO_DP_COLGRAND), 0, cppu::UnoType<bool>::get(), 0, 0 },
96 {OUString(SC_UNO_DP_DRILLDOWN), 0, cppu::UnoType<bool>::get(), 0, 0 },
97 {OUString(SC_UNO_DP_GRANDTOTAL_NAME),0,cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 },
98 {OUString(SC_UNO_DP_IGNORE_EMPTYROWS), 0, cppu::UnoType<bool>::get(), 0, 0 },
99 {OUString(SC_UNO_DP_IMPORTDESC), 0, cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get(), 0, 0 },
100 {OUString(SC_UNO_DP_REPEATEMPTY), 0, cppu::UnoType<bool>::get(), 0, 0 },
101 {OUString(SC_UNO_DP_ROWGRAND), 0, cppu::UnoType<bool>::get(), 0, 0 },
102 {OUString(SC_UNO_DP_SERVICEARG), 0, cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get(), 0, 0 },
103 {OUString(SC_UNO_DP_SHOWFILTER), 0, cppu::UnoType<bool>::get(), 0, 0 },
104 {OUString(SC_UNO_DP_SOURCESERVICE), 0, cppu::UnoType<OUString>::get(), 0, 0 },
105 { OUString(), 0, css::uno::Type(), 0, 0 }
107 return aDataPilotDescriptorBaseMap_Impl;
110 const SfxItemPropertyMapEntry* lcl_GetDataPilotFieldMap()
112 using namespace ::com::sun::star::beans::PropertyAttribute;
113 static const SfxItemPropertyMapEntry aDataPilotFieldMap_Impl[] =
115 {OUString(SC_UNONAME_AUTOSHOW), 0, cppu::UnoType<DataPilotFieldAutoShowInfo>::get(), MAYBEVOID, 0 },
116 {OUString(SC_UNONAME_FUNCTION), 0, cppu::UnoType<GeneralFunction>::get(), 0, 0 },
117 {OUString(SC_UNONAME_GROUPINFO), 0, cppu::UnoType<DataPilotFieldGroupInfo>::get(), MAYBEVOID, 0 },
118 {OUString(SC_UNONAME_HASAUTOSHOW), 0, cppu::UnoType<bool>::get(), 0, 0 },
119 {OUString(SC_UNONAME_HASLAYOUTINFO),0, cppu::UnoType<bool>::get(), 0, 0 },
120 {OUString(SC_UNONAME_HASREFERENCE), 0, cppu::UnoType<bool>::get(), 0, 0 },
121 {OUString(SC_UNONAME_HASSORTINFO), 0, cppu::UnoType<bool>::get(), 0, 0 },
122 {OUString(SC_UNONAME_ISGROUP), 0, cppu::UnoType<bool>::get(), 0, 0 },
123 {OUString(SC_UNONAME_LAYOUTINFO), 0, cppu::UnoType<DataPilotFieldLayoutInfo>::get(), MAYBEVOID, 0 },
124 {OUString(SC_UNONAME_ORIENT), 0, cppu::UnoType<DataPilotFieldOrientation>::get(), MAYBEVOID, 0 },
125 {OUString(SC_UNONAME_REFERENCE), 0, cppu::UnoType<DataPilotFieldReference>::get(), MAYBEVOID, 0 },
126 {OUString(SC_UNONAME_SELPAGE), 0, cppu::UnoType<OUString>::get(), 0, 0 },
127 {OUString(SC_UNONAME_SHOWEMPTY), 0, cppu::UnoType<bool>::get(), 0, 0 },
128 {OUString(SC_UNONAME_REPEATITEMLABELS), 0, cppu::UnoType<bool>::get(), 0, 0 },
129 {OUString(SC_UNONAME_SORTINFO), 0, cppu::UnoType<DataPilotFieldSortInfo>::get(), MAYBEVOID, 0 },
130 {OUString(SC_UNONAME_SUBTOTALS), 0, cppu::UnoType<Sequence<GeneralFunction>>::get(), 0, 0 },
131 {OUString(SC_UNONAME_USESELPAGE), 0, cppu::UnoType<bool>::get(), 0, 0 },
132 { OUString(), 0, css::uno::Type(), 0, 0 }
134 return aDataPilotFieldMap_Impl;
137 const SfxItemPropertyMapEntry* lcl_GetDataPilotItemMap()
139 static const SfxItemPropertyMapEntry aDataPilotItemMap_Impl[] =
141 {OUString(SC_UNONAME_ISHIDDEN), 0, cppu::UnoType<bool>::get(), 0, 0 },
142 {OUString(SC_UNONAME_POS), 0, cppu::UnoType<sal_Int32>::get(), 0, 0 },
143 {OUString(SC_UNONAME_SHOWDETAIL), 0, cppu::UnoType<bool>::get(), 0, 0 },
144 { OUString(), 0, css::uno::Type(), 0, 0 }
146 return aDataPilotItemMap_Impl;
149 inline bool lclCheckValidDouble( double fValue, bool bAuto )
151 return bAuto || ::rtl::math::isFinite( fValue );
154 bool lclCheckMinMaxStep( const DataPilotFieldGroupInfo& rInfo )
156 return
157 lclCheckValidDouble( rInfo.Start, rInfo.HasAutoStart ) &&
158 lclCheckValidDouble( rInfo.End, rInfo.HasAutoEnd ) &&
159 (rInfo.HasAutoStart || rInfo.HasAutoEnd || (rInfo.Start <= rInfo.End)) &&
160 lclCheckValidDouble( rInfo.Step, false ) &&
161 (0.0 <= rInfo.Step);
164 } // namespace
166 SC_SIMPLE_SERVICE_INFO( ScDataPilotDescriptor, "ScDataPilotDescriptor", "stardiv::one::sheet::DataPilotDescriptor" )
167 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldObj, "ScDataPilotFieldObj", "com.sun.star.sheet.DataPilotField" )
168 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldsObj, "ScDataPilotFieldsObj", "com.sun.star.sheet.DataPilotFields" )
169 SC_SIMPLE_SERVICE_INFO( ScDataPilotTableObj, "ScDataPilotTableObj", "com.sun.star.sheet.DataPilotTable" )
170 SC_SIMPLE_SERVICE_INFO( ScDataPilotTablesObj, "ScDataPilotTablesObj", "com.sun.star.sheet.DataPilotTables" )
171 SC_SIMPLE_SERVICE_INFO( ScDataPilotItemsObj, "ScDataPilotItemsObj", "com.sun.star.sheet.DataPilotItems" )
172 SC_SIMPLE_SERVICE_INFO( ScDataPilotItemObj, "ScDataPilotItemObj", "com.sun.star.sheet.DataPilotItem" )
174 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupsObj, "ScDataPilotFieldGroupsObj", "com.sun.star.sheet.DataPilotFieldGroups" )
175 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupObj, "ScDataPilotFieldGroupObj", "com.sun.star.sheet.DataPilotFieldGroup" )
176 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupItemObj, "ScDataPilotFieldGroupItemObj", "com.sun.star.sheet.DataPilotFieldGroupItem" )
178 // name that is used in the API for the data layout field
179 #define SC_DATALAYOUT_NAME "Data"
181 GeneralFunction ScDataPilotConversion::FirstFunc( sal_uInt16 nBits )
183 if ( nBits & PIVOT_FUNC_SUM ) return GeneralFunction_SUM;
184 if ( nBits & PIVOT_FUNC_COUNT ) return GeneralFunction_COUNT;
185 if ( nBits & PIVOT_FUNC_AVERAGE ) return GeneralFunction_AVERAGE;
186 if ( nBits & PIVOT_FUNC_MAX ) return GeneralFunction_MAX;
187 if ( nBits & PIVOT_FUNC_MIN ) return GeneralFunction_MIN;
188 if ( nBits & PIVOT_FUNC_PRODUCT ) return GeneralFunction_PRODUCT;
189 if ( nBits & PIVOT_FUNC_COUNT_NUM ) return GeneralFunction_COUNTNUMS;
190 if ( nBits & PIVOT_FUNC_STD_DEV ) return GeneralFunction_STDEV;
191 if ( nBits & PIVOT_FUNC_STD_DEVP ) return GeneralFunction_STDEVP;
192 if ( nBits & PIVOT_FUNC_STD_VAR ) return GeneralFunction_VAR;
193 if ( nBits & PIVOT_FUNC_STD_VARP ) return GeneralFunction_VARP;
194 if ( nBits & PIVOT_FUNC_AUTO ) return GeneralFunction_AUTO;
195 return GeneralFunction_NONE;
198 sal_uInt16 ScDataPilotConversion::FunctionBit( GeneralFunction eFunc )
200 sal_uInt16 nRet = PIVOT_FUNC_NONE; // 0
201 switch (eFunc)
203 case GeneralFunction_SUM: nRet = PIVOT_FUNC_SUM; break;
204 case GeneralFunction_COUNT: nRet = PIVOT_FUNC_COUNT; break;
205 case GeneralFunction_AVERAGE: nRet = PIVOT_FUNC_AVERAGE; break;
206 case GeneralFunction_MAX: nRet = PIVOT_FUNC_MAX; break;
207 case GeneralFunction_MIN: nRet = PIVOT_FUNC_MIN; break;
208 case GeneralFunction_PRODUCT: nRet = PIVOT_FUNC_PRODUCT; break;
209 case GeneralFunction_COUNTNUMS: nRet = PIVOT_FUNC_COUNT_NUM; break;
210 case GeneralFunction_STDEV: nRet = PIVOT_FUNC_STD_DEV; break;
211 case GeneralFunction_STDEVP: nRet = PIVOT_FUNC_STD_DEVP; break;
212 case GeneralFunction_VAR: nRet = PIVOT_FUNC_STD_VAR; break;
213 case GeneralFunction_VARP: nRet = PIVOT_FUNC_STD_VARP; break;
214 case GeneralFunction_AUTO: nRet = PIVOT_FUNC_AUTO; break;
215 default:
217 // added to avoid warnings
220 return nRet;
223 void ScDataPilotConversion::FillGroupInfo( DataPilotFieldGroupInfo& rInfo, const ScDPNumGroupInfo& rGroupInfo )
225 rInfo.HasDateValues = rGroupInfo.mbDateValues;
226 rInfo.HasAutoStart = rGroupInfo.mbAutoStart;
227 rInfo.Start = rGroupInfo.mfStart;
228 rInfo.HasAutoEnd = rGroupInfo.mbAutoEnd;
229 rInfo.End = rGroupInfo.mfEnd;
230 rInfo.Step = rGroupInfo.mfStep;
233 static ScDPObject* lcl_GetDPObject( ScDocShell* pDocShell, SCTAB nTab, const OUString& rName )
235 if (pDocShell)
237 ScDocument& rDoc = pDocShell->GetDocument();
238 ScDPCollection* pColl = rDoc.GetDPCollection();
239 if ( pColl )
241 size_t nCount = pColl->GetCount();
242 for (size_t i=0; i<nCount; ++i)
244 ScDPObject* pDPObj = (*pColl)[i];
245 if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
246 pDPObj->GetName() == rName )
247 return pDPObj;
251 return NULL; // nicht gefunden
254 static OUString lcl_CreatePivotName( ScDocShell* pDocShell )
256 if (pDocShell)
258 ScDocument& rDoc = pDocShell->GetDocument();
259 ScDPCollection* pColl = rDoc.GetDPCollection();
260 if ( pColl )
261 return pColl->CreateNewName();
263 return OUString(); // sollte nicht vorkommen
266 static sal_Int32 lcl_GetObjectIndex( ScDPObject* pDPObj, const ScFieldIdentifier& rFieldId )
268 // used for items - nRepeat in identifier can be ignored
269 if ( pDPObj )
271 sal_Int32 nCount = pDPObj->GetDimCount();
272 for ( sal_Int32 nDim = 0; nDim < nCount; ++nDim )
274 bool bIsDataLayout = false;
275 OUString aDimName( pDPObj->GetDimName( nDim, bIsDataLayout ) );
276 if ( rFieldId.mbDataLayout ? bIsDataLayout : (aDimName == rFieldId.maFieldName) )
277 return nDim;
280 return -1; // none
283 ScDataPilotTablesObj::ScDataPilotTablesObj(ScDocShell* pDocSh, SCTAB nT) :
284 pDocShell( pDocSh ),
285 nTab( nT )
287 pDocShell->GetDocument().AddUnoObject(*this);
290 ScDataPilotTablesObj::~ScDataPilotTablesObj()
292 SolarMutexGuard g;
294 if (pDocShell)
295 pDocShell->GetDocument().RemoveUnoObject(*this);
298 void ScDataPilotTablesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
300 //! Referenz-Update
302 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
303 if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
305 pDocShell = NULL; // ungueltig geworden
309 // XDataPilotTables
311 ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nIndex )
313 if (pDocShell)
315 ScDocument& rDoc = pDocShell->GetDocument();
316 ScDPCollection* pColl = rDoc.GetDPCollection();
317 if ( pColl )
319 // count tables on this sheet
320 sal_Int32 nFound = 0;
321 size_t nCount = pColl->GetCount();
322 for (size_t i=0; i<nCount; ++i)
324 ScDPObject* pDPObj = (*pColl)[i];
325 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
327 if ( nFound == nIndex )
329 OUString aName = pDPObj->GetName();
330 return new ScDataPilotTableObj( pDocShell, nTab, aName );
332 ++nFound;
337 return NULL;
340 ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByName_Impl(const OUString& rName)
342 if (hasByName(rName))
343 return new ScDataPilotTableObj( pDocShell, nTab, rName );
344 return 0;
347 Reference<XDataPilotDescriptor> SAL_CALL ScDataPilotTablesObj::createDataPilotDescriptor()
348 throw(RuntimeException, std::exception)
350 SolarMutexGuard aGuard;
351 if (pDocShell)
352 return new ScDataPilotDescriptor(pDocShell);
353 return NULL;
356 static bool lcl_IsDuplicated(const Reference<XPropertySet>& rDimProps)
360 Any aAny = rDimProps->getPropertyValue( OUString( SC_UNO_DP_ORIGINAL ) );
361 Reference< XNamed > xOriginal( aAny, UNO_QUERY );
362 return xOriginal.is();
364 catch( Exception& )
367 return false;
370 static OUString lcl_GetOriginalName(const Reference< XNamed >& rDim)
372 Reference< XNamed > xOriginal;
374 Reference< XPropertySet > xDimProps(rDim, UNO_QUERY);
375 if ( xDimProps.is() )
379 Any aAny = xDimProps->getPropertyValue(OUString(SC_UNO_DP_ORIGINAL));
380 aAny >>= xOriginal;
382 catch( Exception& )
387 if ( !xOriginal.is() )
388 xOriginal = rDim;
390 return xOriginal->getName();
393 void SAL_CALL ScDataPilotTablesObj::insertNewByName( const OUString& aNewName,
394 const CellAddress& aOutputAddress,
395 const Reference<XDataPilotDescriptor>& xDescriptor )
396 throw(RuntimeException, std::exception)
398 SolarMutexGuard aGuard;
399 if (!xDescriptor.is()) return;
401 // inserting with already existing name?
402 if ( !aNewName.isEmpty() && hasByName( aNewName ) )
403 throw RuntimeException(); // no other exceptions specified
405 bool bDone = false;
406 ScDataPilotDescriptorBase* pImp = ScDataPilotDescriptorBase::getImplementation( xDescriptor );
407 if ( pDocShell && pImp )
409 ScDPObject* pNewObj = pImp->GetDPObject();
411 if (pNewObj)
413 ScRange aOutputRange((SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet,
414 (SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet);
415 pNewObj->SetOutRange(aOutputRange);
416 OUString aName = aNewName;
417 if (aName.isEmpty())
418 aName = lcl_CreatePivotName( pDocShell );
419 pNewObj->SetName(aName);
420 OUString aTag = xDescriptor->getTag();
421 pNewObj->SetTag(aTag);
423 // todo: handle double fields (for more information see ScDPObject
425 ScDBDocFunc aFunc(*pDocShell);
426 bDone = aFunc.CreatePivotTable(*pNewObj, true, true);
430 if (!bDone)
431 throw RuntimeException(); // no other exceptions specified
434 void SAL_CALL ScDataPilotTablesObj::removeByName( const OUString& aName )
435 throw(RuntimeException, std::exception)
437 SolarMutexGuard aGuard;
438 OUString aNameStr(aName);
439 ScDPObject* pDPObj = lcl_GetDPObject( pDocShell, nTab, aNameStr );
440 if (pDPObj && pDocShell)
442 ScDBDocFunc aFunc(*pDocShell);
443 aFunc.RemovePivotTable(*pDPObj, true, true); // remove - incl. undo etc.
445 else
446 throw RuntimeException(); // no other exceptions specified
449 // XEnumerationAccess
451 Reference< XEnumeration > SAL_CALL ScDataPilotTablesObj::createEnumeration() throw(RuntimeException, std::exception)
453 SolarMutexGuard aGuard;
454 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotTablesEnumeration"));
457 // XIndexAccess
459 sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException, std::exception)
461 SolarMutexGuard aGuard;
462 if ( pDocShell )
464 ScDocument& rDoc = pDocShell->GetDocument();
465 ScDPCollection* pColl = rDoc.GetDPCollection();
466 if ( pColl )
468 // count tables on this sheet
470 sal_uInt16 nFound = 0;
471 size_t nCount = pColl->GetCount();
472 for (size_t i=0; i<nCount; ++i)
474 ScDPObject* pDPObj = (*pColl)[i];
475 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
476 ++nFound;
478 return nFound;
482 return 0;
485 Any SAL_CALL ScDataPilotTablesObj::getByIndex( sal_Int32 nIndex )
486 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
488 SolarMutexGuard aGuard;
489 Reference<XDataPilotTable2> xTable(GetObjectByIndex_Impl(nIndex));
490 if (!xTable.is())
491 throw IndexOutOfBoundsException();
492 return Any( xTable );
495 uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(RuntimeException, std::exception)
497 SolarMutexGuard aGuard;
498 return cppu::UnoType<XDataPilotTable2>::get();
501 sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(RuntimeException, std::exception)
503 SolarMutexGuard aGuard;
504 return ( getCount() != 0 );
507 // XNameAccess
509 Any SAL_CALL ScDataPilotTablesObj::getByName( const OUString& aName )
510 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
512 SolarMutexGuard aGuard;
513 Reference<XDataPilotTable2> xTable(GetObjectByName_Impl(aName));
514 if (!xTable.is())
515 throw NoSuchElementException();
516 return Any( xTable );
519 Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames()
520 throw(RuntimeException, std::exception)
522 SolarMutexGuard aGuard;
523 if (pDocShell)
525 ScDocument& rDoc = pDocShell->GetDocument();
526 ScDPCollection* pColl = rDoc.GetDPCollection();
527 if ( pColl )
529 // count tables on this sheet
531 sal_uInt16 nFound = 0;
532 size_t nCount = pColl->GetCount();
533 size_t i;
534 for (i=0; i<nCount; ++i)
536 ScDPObject* pDPObj = (*pColl)[i];
537 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
538 ++nFound;
541 sal_uInt16 nPos = 0;
542 Sequence<OUString> aSeq(nFound);
543 OUString* pAry = aSeq.getArray();
544 for (i=0; i<nCount; ++i)
546 ScDPObject* pDPObj = (*pColl)[i];
547 if ( pDPObj->GetOutRange().aStart.Tab() == nTab )
548 pAry[nPos++] = pDPObj->GetName();
551 return aSeq;
554 return Sequence<OUString>(0);
557 sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName )
558 throw(RuntimeException, std::exception)
560 SolarMutexGuard aGuard;
561 if (pDocShell)
563 ScDocument& rDoc = pDocShell->GetDocument();
564 ScDPCollection* pColl = rDoc.GetDPCollection();
565 if ( pColl )
567 size_t nCount = pColl->GetCount();
568 for (size_t i=0; i<nCount; ++i)
570 ScDPObject* pDPObj = (*pColl)[i];
571 if ( pDPObj->GetOutRange().aStart.Tab() == nTab &&
572 pDPObj->GetName() == aName )
573 return true;
577 return false;
580 ScDataPilotDescriptorBase::ScDataPilotDescriptorBase(ScDocShell* pDocSh) :
581 maPropSet( lcl_GetDataPilotDescriptorBaseMap() ),
582 pDocShell( pDocSh )
584 pDocShell->GetDocument().AddUnoObject(*this);
587 ScDataPilotDescriptorBase::~ScDataPilotDescriptorBase()
589 SolarMutexGuard g;
591 if (pDocShell)
592 pDocShell->GetDocument().RemoveUnoObject(*this);
595 Any SAL_CALL ScDataPilotDescriptorBase::queryInterface( const uno::Type& rType )
596 throw(RuntimeException, std::exception)
598 SC_QUERYINTERFACE( XDataPilotDescriptor )
599 SC_QUERYINTERFACE( XPropertySet )
600 SC_QUERYINTERFACE( XDataPilotDataLayoutFieldSupplier )
601 SC_QUERYINTERFACE( XNamed ) // base of XDataPilotDescriptor
602 SC_QUERYINTERFACE( lang::XUnoTunnel )
603 SC_QUERYINTERFACE( lang::XTypeProvider )
604 SC_QUERYINTERFACE( lang::XServiceInfo )
606 return OWeakObject::queryInterface( rType );
609 void SAL_CALL ScDataPilotDescriptorBase::acquire() throw()
611 OWeakObject::acquire();
614 void SAL_CALL ScDataPilotDescriptorBase::release() throw()
616 OWeakObject::release();
619 Sequence< uno::Type > SAL_CALL ScDataPilotDescriptorBase::getTypes()
620 throw(RuntimeException, std::exception)
622 static Sequence< uno::Type > aTypes;
623 if ( aTypes.getLength() == 0 )
625 aTypes.realloc( 6 );
626 uno::Type* pPtr = aTypes.getArray();
627 pPtr[ 0 ] = cppu::UnoType<XDataPilotDescriptor>::get();
628 pPtr[ 1 ] = cppu::UnoType<XPropertySet>::get();
629 pPtr[ 2 ] = cppu::UnoType<XDataPilotDataLayoutFieldSupplier>::get();
630 pPtr[ 3 ] = cppu::UnoType<lang::XUnoTunnel>::get();
631 pPtr[ 4 ] = cppu::UnoType<lang::XTypeProvider>::get();
632 pPtr[ 5 ] = cppu::UnoType<lang::XServiceInfo>::get();
634 return aTypes;
637 Sequence<sal_Int8> SAL_CALL ScDataPilotDescriptorBase::getImplementationId()
638 throw(RuntimeException, std::exception)
640 return css::uno::Sequence<sal_Int8>();
643 void ScDataPilotDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
645 //! Referenz-Update?
647 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
648 if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING )
650 pDocShell = NULL; // ungueltig geworden
654 // XDataPilotDescriptor
656 CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange()
657 throw(RuntimeException, std::exception)
659 SolarMutexGuard aGuard;
661 ScDPObject* pDPObject(GetDPObject());
662 if (!pDPObject)
663 throw RuntimeException();
665 CellRangeAddress aRet;
666 if (pDPObject->IsSheetData())
667 ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->GetSourceRange() );
668 return aRet;
671 void SAL_CALL ScDataPilotDescriptorBase::setSourceRange( const CellRangeAddress& aSourceRange ) throw(RuntimeException, std::exception)
673 SolarMutexGuard aGuard;
675 ScDPObject* pDPObject = GetDPObject();
676 if (!pDPObject)
677 throw RuntimeException();
679 ScSheetSourceDesc aSheetDesc(&pDocShell->GetDocument());
680 if (pDPObject->IsSheetData())
681 aSheetDesc = *pDPObject->GetSheetDesc();
683 ScRange aRange;
684 ScUnoConversion::FillScRange(aRange, aSourceRange);
685 aSheetDesc.SetSourceRange(aRange);
686 pDPObject->SetSheetDesc( aSheetDesc );
687 SetDPObject( pDPObject );
690 Reference<XSheetFilterDescriptor> SAL_CALL ScDataPilotDescriptorBase::getFilterDescriptor()
691 throw(RuntimeException, std::exception)
693 SolarMutexGuard aGuard;
694 return new ScDataPilotFilterDescriptor( pDocShell, this );
697 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataPilotFields()
698 throw(RuntimeException, std::exception)
700 SolarMutexGuard aGuard;
701 return new ScDataPilotFieldsObj( *this );
704 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getColumnFields()
705 throw(RuntimeException, std::exception)
707 SolarMutexGuard aGuard;
708 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_COLUMN );
711 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getRowFields()
712 throw(RuntimeException, std::exception)
714 SolarMutexGuard aGuard;
715 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_ROW );
718 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getPageFields()
719 throw(RuntimeException, std::exception)
721 SolarMutexGuard aGuard;
722 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_PAGE );
725 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataFields()
726 throw(RuntimeException, std::exception)
728 SolarMutexGuard aGuard;
729 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_DATA );
732 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getHiddenFields()
733 throw(RuntimeException, std::exception)
735 SolarMutexGuard aGuard;
736 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_HIDDEN );
739 // XPropertySet
740 Reference< XPropertySetInfo > SAL_CALL ScDataPilotDescriptorBase::getPropertySetInfo( )
741 throw(RuntimeException, std::exception)
743 SolarMutexGuard aGuard;
744 static Reference<XPropertySetInfo> aRef =
745 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
746 return aRef;
749 void SAL_CALL ScDataPilotDescriptorBase::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
750 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException,
751 WrappedTargetException, RuntimeException, std::exception)
753 SolarMutexGuard aGuard;
754 ScDPObject* pDPObject = GetDPObject();
755 if (pDPObject)
757 ScDPSaveData* pOldData = pDPObject->GetSaveData();
758 OSL_ENSURE(pOldData, "Here should be a SaveData");
759 if ( pOldData )
761 ScDPSaveData aNewData( *pOldData );
763 OUString aNameString = aPropertyName;
764 if ( aNameString == SC_UNO_DP_COLGRAND )
766 aNewData.SetColumnGrand(::cppu::any2bool( aValue ));
768 else if ( aNameString == SC_UNO_DP_IGNORE_EMPTYROWS )
770 aNewData.SetIgnoreEmptyRows(::cppu::any2bool( aValue ));
772 else if ( aNameString == SC_UNO_DP_REPEATEMPTY )
774 aNewData.SetRepeatIfEmpty(::cppu::any2bool( aValue ));
776 else if ( aNameString == SC_UNO_DP_ROWGRAND )
778 aNewData.SetRowGrand(::cppu::any2bool( aValue ));
780 else if ( aNameString == SC_UNO_DP_SHOWFILTER )
782 aNewData.SetFilterButton(::cppu::any2bool( aValue ));
784 else if ( aNameString == SC_UNO_DP_DRILLDOWN )
786 aNewData.SetDrillDown(::cppu::any2bool( aValue ));
788 else if ( aNameString == SC_UNO_DP_GRANDTOTAL_NAME )
790 OUString aStrVal;
791 if ( aValue >>= aStrVal )
792 aNewData.SetGrandTotalName(aStrVal);
794 else if ( aNameString == SC_UNO_DP_IMPORTDESC )
796 uno::Sequence<beans::PropertyValue> aArgSeq;
797 if ( aValue >>= aArgSeq )
799 ScImportSourceDesc aImportDesc(&pDocShell->GetDocument());
801 const ScImportSourceDesc* pOldDesc = pDPObject->GetImportSourceDesc();
802 if (pOldDesc)
803 aImportDesc = *pOldDesc;
805 ScImportParam aParam;
806 ScImportDescriptor::FillImportParam( aParam, aArgSeq );
808 sal_uInt16 nNewType = sheet::DataImportMode_NONE;
809 if ( aParam.bImport )
811 if ( aParam.bSql )
812 nNewType = sheet::DataImportMode_SQL;
813 else if ( aParam.nType == ScDbQuery )
814 nNewType = sheet::DataImportMode_QUERY;
815 else
816 nNewType = sheet::DataImportMode_TABLE;
818 aImportDesc.nType = nNewType;
819 aImportDesc.aDBName = aParam.aDBName;
820 aImportDesc.aObject = aParam.aStatement;
821 aImportDesc.bNative = aParam.bNative;
823 pDPObject->SetImportDesc( aImportDesc );
826 else if ( aNameString == SC_UNO_DP_SOURCESERVICE )
828 OUString aStrVal;
829 if ( aValue >>= aStrVal )
831 OUString aEmpty;
832 ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
834 const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
835 if (pOldDesc)
836 aServiceDesc = *pOldDesc;
838 aServiceDesc.aServiceName = aStrVal;
840 pDPObject->SetServiceData( aServiceDesc );
843 else if ( aNameString == SC_UNO_DP_SERVICEARG )
845 uno::Sequence<beans::PropertyValue> aArgSeq;
846 if ( aValue >>= aArgSeq )
848 OUString aEmpty;
849 ScDPServiceDesc aServiceDesc(aEmpty, aEmpty, aEmpty, aEmpty, aEmpty);
851 const ScDPServiceDesc* pOldDesc = pDPObject->GetDPServiceDesc();
852 if (pOldDesc)
853 aServiceDesc = *pOldDesc;
855 OUString aStrVal;
856 sal_Int32 nArgs = aArgSeq.getLength();
857 for (sal_Int32 nArgPos=0; nArgPos<nArgs; ++nArgPos)
859 const beans::PropertyValue& rProp = aArgSeq[nArgPos];
860 OUString aPropName(rProp.Name);
862 if (aPropName == SC_UNO_DP_SOURCENAME)
864 if ( rProp.Value >>= aStrVal )
865 aServiceDesc.aParSource = aStrVal;
867 else if (aPropName == SC_UNO_DP_OBJECTNAME)
869 if ( rProp.Value >>= aStrVal )
870 aServiceDesc.aParName = aStrVal;
872 else if (aPropName == SC_UNO_DP_USERNAME)
874 if ( rProp.Value >>= aStrVal )
875 aServiceDesc.aParUser = aStrVal;
877 else if (aPropName == SC_UNO_DP_PASSWORD)
879 if ( rProp.Value >>= aStrVal )
880 aServiceDesc.aParPass = aStrVal;
884 pDPObject->SetServiceData( aServiceDesc );
887 else
888 throw UnknownPropertyException();
890 pDPObject->SetSaveData( aNewData );
893 SetDPObject(pDPObject);
897 Any SAL_CALL ScDataPilotDescriptorBase::getPropertyValue( const OUString& aPropertyName )
898 throw (UnknownPropertyException, WrappedTargetException,
899 RuntimeException, std::exception)
901 SolarMutexGuard aGuard;
902 Any aRet;
904 ScDPObject* pDPObject(GetDPObject());
905 if (pDPObject)
907 ScDPSaveData* pOldData = pDPObject->GetSaveData();
908 OSL_ENSURE(pOldData, "Here should be a SaveData");
909 if ( pOldData )
911 ScDPSaveData aNewData( *pOldData );
913 OUString aNameString = aPropertyName;
914 if ( aNameString == SC_UNO_DP_COLGRAND )
916 aRet <<= aNewData.GetColumnGrand();
918 else if ( aNameString == SC_UNO_DP_IGNORE_EMPTYROWS )
920 aRet <<= aNewData.GetIgnoreEmptyRows();
922 else if ( aNameString == SC_UNO_DP_REPEATEMPTY )
924 aRet <<= aNewData.GetRepeatIfEmpty();
926 else if ( aNameString == SC_UNO_DP_ROWGRAND )
928 aRet <<= aNewData.GetRowGrand();
930 else if ( aNameString == SC_UNO_DP_SHOWFILTER )
932 aRet <<= aNewData.GetFilterButton();
934 else if ( aNameString == SC_UNO_DP_DRILLDOWN )
936 aRet <<= aNewData.GetDrillDown();
938 else if ( aNameString == SC_UNO_DP_GRANDTOTAL_NAME )
940 const OUString* pGrandTotalName = aNewData.GetGrandTotalName();
941 if (pGrandTotalName)
942 aRet <<= *pGrandTotalName; // same behavior as in ScDPSource
944 else if ( aNameString == SC_UNO_DP_IMPORTDESC )
946 const ScImportSourceDesc* pImportDesc = pDPObject->GetImportSourceDesc();
947 if ( pImportDesc )
949 // fill ScImportParam so ScImportDescriptor::FillProperties can be used
950 ScImportParam aParam;
951 aParam.bImport = ( pImportDesc->nType != sheet::DataImportMode_NONE );
952 aParam.aDBName = pImportDesc->aDBName;
953 aParam.aStatement = pImportDesc->aObject;
954 aParam.bNative = pImportDesc->bNative;
955 aParam.bSql = ( pImportDesc->nType == sheet::DataImportMode_SQL );
956 aParam.nType = static_cast<sal_uInt8>(( pImportDesc->nType == sheet::DataImportMode_QUERY ) ? ScDbQuery : ScDbTable);
958 uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
959 ScImportDescriptor::FillProperties( aSeq, aParam );
960 aRet <<= aSeq;
962 else
964 // empty sequence
965 uno::Sequence<beans::PropertyValue> aEmpty(0);
966 aRet <<= aEmpty;
969 else if ( aNameString == SC_UNO_DP_SOURCESERVICE )
971 OUString aServiceName;
972 const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
973 if (pServiceDesc)
974 aServiceName = pServiceDesc->aServiceName;
975 aRet <<= aServiceName; // empty string if no ServiceDesc set
977 else if ( aNameString == SC_UNO_DP_SERVICEARG )
979 const ScDPServiceDesc* pServiceDesc = pDPObject->GetDPServiceDesc();
980 if (pServiceDesc)
982 uno::Sequence<beans::PropertyValue> aSeq( 4 );
983 beans::PropertyValue* pArray = aSeq.getArray();
984 pArray[0].Name = SC_UNO_DP_SOURCENAME;
985 pArray[0].Value <<= pServiceDesc->aParSource;
986 pArray[1].Name = SC_UNO_DP_OBJECTNAME;
987 pArray[1].Value <<= pServiceDesc->aParName;
988 pArray[2].Name = SC_UNO_DP_USERNAME;
989 pArray[2].Value <<= pServiceDesc->aParUser;
990 pArray[3].Name = SC_UNO_DP_PASSWORD;
991 pArray[3].Value <<= pServiceDesc->aParPass;
992 aRet <<= aSeq;
994 else
996 // empty sequence
997 uno::Sequence<beans::PropertyValue> aEmpty(0);
998 aRet <<= aEmpty;
1001 else
1002 throw UnknownPropertyException();
1006 return aRet;
1009 void SAL_CALL ScDataPilotDescriptorBase::addPropertyChangeListener(
1010 const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* xListener */ )
1011 throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
1015 void SAL_CALL ScDataPilotDescriptorBase::removePropertyChangeListener(
1016 const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* aListener */ )
1017 throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
1021 void SAL_CALL ScDataPilotDescriptorBase::addVetoableChangeListener(
1022 const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
1023 throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
1027 void SAL_CALL ScDataPilotDescriptorBase::removeVetoableChangeListener(
1028 const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
1029 throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
1033 // XDataPilotDataLayoutFieldSupplier
1035 Reference< XDataPilotField > SAL_CALL ScDataPilotDescriptorBase::getDataLayoutField()
1036 throw (RuntimeException, std::exception)
1038 SolarMutexGuard aGuard;
1039 if( ScDPObject* pDPObject = GetDPObject() )
1041 if( ScDPSaveData* pSaveData = pDPObject->GetSaveData() )
1043 if( pSaveData->GetDataLayoutDimension() )
1045 ScFieldIdentifier aFieldId( OUString( SC_DATALAYOUT_NAME ), 0, true );
1046 return new ScDataPilotFieldObj( *this, aFieldId );
1050 return 0;
1053 // XUnoTunnel
1055 sal_Int64 SAL_CALL ScDataPilotDescriptorBase::getSomething(
1056 const Sequence<sal_Int8 >& rId ) throw(RuntimeException, std::exception)
1058 if ( rId.getLength() == 16 &&
1059 0 == memcmp( getUnoTunnelId().getConstArray(),
1060 rId.getConstArray(), 16 ) )
1062 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
1064 return 0;
1067 namespace
1069 class theScDataPilotDescriptorBaseUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScDataPilotDescriptorBaseUnoTunnelId> {};
1072 const Sequence<sal_Int8>& ScDataPilotDescriptorBase::getUnoTunnelId()
1074 return theScDataPilotDescriptorBaseUnoTunnelId::get().getSeq();
1077 ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation(const Reference<XDataPilotDescriptor>& rObj )
1079 ScDataPilotDescriptorBase* pRet = NULL;
1080 Reference<lang::XUnoTunnel> xUT(rObj, UNO_QUERY);
1081 if (xUT.is())
1082 pRet = reinterpret_cast<ScDataPilotDescriptorBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
1083 return pRet;
1086 ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const OUString& rN) :
1087 ScDataPilotDescriptorBase( pDocSh ),
1088 nTab( nT ),
1089 aName( rN ),
1090 aModifyListeners( 0 )
1094 ScDataPilotTableObj::~ScDataPilotTableObj()
1098 Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType )
1099 throw(RuntimeException, std::exception)
1101 // since we manually do resolve the query for XDataPilotTable2
1102 // we also need to do the same for XDataPilotTable
1103 SC_QUERYINTERFACE( XDataPilotTable )
1104 SC_QUERYINTERFACE( XDataPilotTable2 )
1105 SC_QUERYINTERFACE( XModifyBroadcaster )
1107 return ScDataPilotDescriptorBase::queryInterface( rType );
1110 void SAL_CALL ScDataPilotTableObj::acquire() throw()
1112 ScDataPilotDescriptorBase::acquire();
1115 void SAL_CALL ScDataPilotTableObj::release() throw()
1117 ScDataPilotDescriptorBase::release();
1120 Sequence< uno::Type > SAL_CALL ScDataPilotTableObj::getTypes() throw(RuntimeException, std::exception)
1122 static Sequence< uno::Type > aTypes;
1123 if ( aTypes.getLength() == 0 )
1125 Sequence< uno::Type > aParentTypes = ScDataPilotDescriptorBase::getTypes();
1126 sal_Int32 nParentLen = aParentTypes.getLength();
1127 const uno::Type* pParentPtr = aParentTypes.getConstArray();
1129 aTypes.realloc( nParentLen + 2 );
1130 uno::Type* pPtr = aTypes.getArray();
1131 for (sal_Int32 i = 0; i < nParentLen; ++i)
1132 pPtr[ i ] = pParentPtr[ i ]; // parent types first
1134 pPtr[ nParentLen ] = cppu::UnoType<XDataPilotTable2>::get();
1135 pPtr[ nParentLen+1 ] = cppu::UnoType<XModifyBroadcaster>::get();
1137 return aTypes;
1140 Sequence<sal_Int8> SAL_CALL ScDataPilotTableObj::getImplementationId()
1141 throw(RuntimeException, std::exception)
1143 return css::uno::Sequence<sal_Int8>();
1146 ScDPObject* ScDataPilotTableObj::GetDPObject() const
1148 return lcl_GetDPObject(GetDocShell(), nTab, aName);
1151 void ScDataPilotTableObj::SetDPObject( ScDPObject* pDPObject )
1153 ScDocShell* pDocSh = GetDocShell();
1154 ScDPObject* pDPObj = lcl_GetDPObject(pDocSh, nTab, aName);
1155 if ( pDPObj && pDocSh )
1157 ScDBDocFunc aFunc(*pDocSh);
1158 aFunc.DataPilotUpdate( pDPObj, pDPObject, true, true );
1162 // "rest of XDataPilotDescriptor"
1164 OUString SAL_CALL ScDataPilotTableObj::getName() throw(RuntimeException, std::exception)
1166 SolarMutexGuard aGuard;
1167 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1168 if (pDPObj)
1169 return pDPObj->GetName();
1170 return OUString();
1173 void SAL_CALL ScDataPilotTableObj::setName( const OUString& aNewName )
1174 throw(RuntimeException, std::exception)
1176 SolarMutexGuard aGuard;
1177 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1178 if (pDPObj)
1180 //! test for existing names !!!
1182 OUString aString(aNewName);
1183 pDPObj->SetName( aString ); //! Undo - DBDocFunc ???
1184 aName = aString;
1186 // DataPilotUpdate would do too much (output table is not changed)
1187 GetDocShell()->SetDocumentModified();
1191 OUString SAL_CALL ScDataPilotTableObj::getTag() throw(RuntimeException, std::exception)
1193 SolarMutexGuard aGuard;
1194 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1195 if (pDPObj)
1196 return pDPObj->GetTag();
1197 return OUString();
1200 void SAL_CALL ScDataPilotTableObj::setTag( const OUString& aNewTag )
1201 throw(RuntimeException, std::exception)
1203 SolarMutexGuard aGuard;
1204 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1205 if (pDPObj)
1207 pDPObj->SetTag( aNewTag ); //! Undo - DBDocFunc ???
1209 // DataPilotUpdate would do too much (output table is not changed)
1210 GetDocShell()->SetDocumentModified();
1214 // XDataPilotTable
1216 CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeException, std::exception)
1218 SolarMutexGuard aGuard;
1219 CellRangeAddress aRet;
1220 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1221 if (pDPObj)
1223 ScRange aRange(pDPObj->GetOutRange());
1224 aRet.Sheet = aRange.aStart.Tab();
1225 aRet.StartColumn = aRange.aStart.Col();
1226 aRet.StartRow = aRange.aStart.Row();
1227 aRet.EndColumn = aRange.aEnd.Col();
1228 aRet.EndRow = aRange.aEnd.Row();
1230 return aRet;
1233 void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException, std::exception)
1235 SolarMutexGuard aGuard;
1236 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1237 if (pDPObj)
1239 ScDBDocFunc aFunc(*GetDocShell());
1240 aFunc.RefreshPivotTables(pDPObj, true);
1244 Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr)
1245 throw (RuntimeException, std::exception)
1247 SolarMutexGuard aGuard;
1248 Sequence< Sequence<Any> > aTabData;
1249 ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1250 ScDPObject* pObj = GetDPObject();
1251 if (!pObj)
1252 throw RuntimeException();
1254 pObj->GetDrillDownData(aAddr2, aTabData);
1255 return aTabData;
1258 DataPilotTablePositionData SAL_CALL ScDataPilotTableObj::getPositionData(const CellAddress& aAddr)
1259 throw (RuntimeException, std::exception)
1261 SolarMutexGuard aGuard;
1262 DataPilotTablePositionData aPosData;
1263 ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1264 ScDPObject* pObj = GetDPObject();
1265 if (!pObj)
1266 throw RuntimeException();
1268 pObj->GetPositionData(aAddr2, aPosData);
1269 return aPosData;
1272 void SAL_CALL ScDataPilotTableObj::insertDrillDownSheet(const CellAddress& aAddr)
1273 throw (RuntimeException, std::exception)
1275 SolarMutexGuard aGuard;
1276 ScDPObject* pDPObj = GetDPObject();
1277 if (!pDPObj)
1278 throw RuntimeException();
1279 ScTabViewShell* pViewSh = GetDocShell()->GetBestViewShell();
1280 if (!pViewSh)
1281 throw RuntimeException();
1283 Sequence<DataPilotFieldFilter> aFilters;
1284 pDPObj->GetDataFieldPositionData(
1285 ScAddress(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet), aFilters);
1286 pViewSh->ShowDataPilotSourceData(*pDPObj, aFilters);
1289 CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
1290 throw (IllegalArgumentException, RuntimeException, std::exception)
1292 SolarMutexGuard aGuard;
1293 if (nType < 0 || nType > DataPilotOutputRangeType::RESULT)
1294 throw IllegalArgumentException();
1296 CellRangeAddress aRet;
1297 if (ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName))
1298 ScUnoConversion::FillApiRange( aRet, pDPObj->GetOutputRangeByType( nType ) );
1299 return aRet;
1302 void SAL_CALL ScDataPilotTableObj::addModifyListener( const uno::Reference<util::XModifyListener>& aListener )
1303 throw (uno::RuntimeException, std::exception)
1305 SolarMutexGuard aGuard;
1307 uno::Reference<util::XModifyListener> *pObj = new uno::Reference<util::XModifyListener>( aListener );
1308 aModifyListeners.push_back( pObj );
1310 if ( aModifyListeners.size() == 1 )
1312 acquire(); // don't lose this object (one ref for all listeners)
1316 void SAL_CALL ScDataPilotTableObj::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
1317 throw (uno::RuntimeException, std::exception)
1319 SolarMutexGuard aGuard;
1321 acquire(); // in case the listeners have the last ref - released below
1323 sal_uInt16 nCount = aModifyListeners.size();
1324 for ( sal_uInt16 n=nCount; n--; )
1326 uno::Reference<util::XModifyListener>& rObj = aModifyListeners[n];
1327 if ( rObj == aListener )
1329 aModifyListeners.erase( aModifyListeners.begin() + n );
1331 if ( aModifyListeners.empty() )
1333 release(); // release the ref for the listeners
1336 break;
1340 release(); // might delete this object
1343 void ScDataPilotTableObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1345 if ( dynamic_cast<const ScDataPilotModifiedHint*>(&rHint) &&
1346 static_cast<const ScDataPilotModifiedHint&>(rHint).GetName() == aName )
1348 Refreshed_Impl();
1350 else if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) )
1352 ScRange aRange( 0, 0, nTab );
1353 ScRangeList aRanges;
1354 aRanges.Append( aRange );
1355 const ScUpdateRefHint& rRef = static_cast< const ScUpdateRefHint& >( rHint );
1356 if ( aRanges.UpdateReference( rRef.GetMode(), &GetDocShell()->GetDocument(), rRef.GetRange(),
1357 rRef.GetDx(), rRef.GetDy(), rRef.GetDz() ) &&
1358 aRanges.size() == 1 )
1360 const ScRange* pRange = aRanges.front();
1361 if ( pRange )
1363 nTab = pRange->aStart.Tab();
1368 ScDataPilotDescriptorBase::Notify( rBC, rHint );
1371 void ScDataPilotTableObj::Refreshed_Impl()
1373 lang::EventObject aEvent;
1374 aEvent.Source.set((cppu::OWeakObject*)this);
1376 // the EventObject holds a Ref to this object until after the listener calls
1378 ScDocument& rDoc = GetDocShell()->GetDocument();
1379 for ( sal_uInt16 n=0; n<aModifyListeners.size(); n++ )
1380 rDoc.AddUnoListenerCall( aModifyListeners[n], aEvent );
1383 ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) :
1384 ScDataPilotDescriptorBase( pDocSh ),
1385 mpDPObject(new ScDPObject(pDocSh ? &pDocSh->GetDocument() : NULL) )
1387 ScDPSaveData aSaveData;
1388 // set defaults like in ScPivotParam constructor
1389 aSaveData.SetColumnGrand( true );
1390 aSaveData.SetRowGrand( true );
1391 aSaveData.SetIgnoreEmptyRows( false );
1392 aSaveData.SetRepeatIfEmpty( false );
1393 mpDPObject->SetSaveData(aSaveData);
1394 ScSheetSourceDesc aSheetDesc(pDocSh ? &pDocSh->GetDocument() : NULL);
1395 mpDPObject->SetSheetDesc(aSheetDesc);
1396 mpDPObject->GetSource();
1399 ScDataPilotDescriptor::~ScDataPilotDescriptor()
1401 delete mpDPObject;
1404 ScDPObject* ScDataPilotDescriptor::GetDPObject() const
1406 return mpDPObject;
1409 void ScDataPilotDescriptor::SetDPObject( ScDPObject* pDPObject )
1411 if (mpDPObject != pDPObject)
1413 delete mpDPObject;
1414 mpDPObject = pDPObject;
1415 OSL_FAIL("replace DPObject should not happen");
1419 // "rest of XDataPilotDescriptor"
1421 OUString SAL_CALL ScDataPilotDescriptor::getName() throw(RuntimeException, std::exception)
1423 SolarMutexGuard aGuard;
1424 return mpDPObject->GetName();
1427 void SAL_CALL ScDataPilotDescriptor::setName( const OUString& aNewName )
1428 throw(RuntimeException, std::exception)
1430 SolarMutexGuard aGuard;
1431 mpDPObject->SetName( aNewName );
1434 OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(RuntimeException, std::exception)
1436 SolarMutexGuard aGuard;
1437 return mpDPObject->GetTag();
1440 void SAL_CALL ScDataPilotDescriptor::setTag( const OUString& aNewTag )
1441 throw(RuntimeException, std::exception)
1443 SolarMutexGuard aGuard;
1444 mpDPObject->SetTag( aNewTag );
1447 ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent ) :
1448 mrParent( rParent )
1450 mrParent.acquire();
1453 ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1454 mrParent( rParent ),
1455 maFieldId( rFieldId )
1457 mrParent.acquire();
1460 ScDataPilotChildObjBase::~ScDataPilotChildObjBase()
1462 mrParent.release();
1465 ScDPObject* ScDataPilotChildObjBase::GetDPObject() const
1467 return mrParent.GetDPObject();
1470 void ScDataPilotChildObjBase::SetDPObject( ScDPObject* pDPObject )
1472 mrParent.SetDPObject( pDPObject );
1475 ScDPSaveDimension* ScDataPilotChildObjBase::GetDPDimension( ScDPObject** ppDPObject ) const
1477 if( ScDPObject* pDPObj = GetDPObject() )
1479 if( ppDPObject ) *ppDPObject = pDPObj;
1480 if( ScDPSaveData* pSaveData = pDPObj->GetSaveData() )
1482 if( maFieldId.mbDataLayout )
1483 return pSaveData->GetDataLayoutDimension();
1485 if( maFieldId.mnFieldIdx == 0 )
1486 return pSaveData->GetDimensionByName( maFieldId.maFieldName );
1488 // find dimension with specified index (search in duplicated dimensions)
1489 const ScDPSaveData::DimsType& rDims = pSaveData->GetDimensions();
1491 sal_Int32 nFoundIdx = 0;
1492 ScDPSaveData::DimsType::const_iterator it;
1493 for (it = rDims.begin(); it != rDims.end(); ++it)
1495 if (it->IsDataLayout())
1496 continue;
1498 OUString aSrcName = ScDPUtil::getSourceDimensionName(it->GetName());
1499 if (aSrcName == maFieldId.maFieldName)
1501 if( nFoundIdx == maFieldId.mnFieldIdx )
1502 return const_cast<ScDPSaveDimension*>(&(*it));
1503 ++nFoundIdx;
1508 return 0;
1511 sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
1513 sal_Int32 nRet = 0;
1514 Reference<XNameAccess> xMembersNA = GetMembers();
1515 if (xMembersNA.is())
1517 Reference< XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
1518 nRet = xMembersIA->getCount();
1520 return nRet;
1523 Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
1525 Reference< XNameAccess > xMembersNA;
1526 if( ScDPObject* pDPObj = GetDPObject() )
1527 pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
1528 return xMembersNA;
1531 ScDocShell* ScDataPilotChildObjBase::GetDocShell() const
1533 return mrParent.GetDocShell();
1536 ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent ) :
1537 ScDataPilotChildObjBase( rParent )
1541 ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent, DataPilotFieldOrientation eOrient ) :
1542 ScDataPilotChildObjBase( rParent ),
1543 maOrient( eOrient )
1547 ScDataPilotFieldsObj::~ScDataPilotFieldsObj()
1551 static sal_Int32 lcl_GetFieldCount( const Reference<XDimensionsSupplier>& rSource, const Any& rOrient )
1553 if (!rSource.is())
1554 throw RuntimeException();
1556 sal_Int32 nRet = 0;
1558 Reference<XNameAccess> xDimsName(rSource->getDimensions());
1559 Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1560 sal_Int32 nIntCount = xIntDims->getCount();
1561 if (rOrient.hasValue())
1563 // all fields of the specified orientation, including duplicated
1564 Reference<XPropertySet> xDim;
1565 for (sal_Int32 i = 0; i < nIntCount; ++i)
1567 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1568 if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1569 ++nRet;
1572 else
1574 // count all non-duplicated fields
1576 Reference<XPropertySet> xDim;
1577 for (sal_Int32 i = 0; i < nIntCount; ++i)
1579 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1580 if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1581 ++nRet;
1585 return nRet;
1588 static bool lcl_GetFieldDataByIndex( const Reference<XDimensionsSupplier>& rSource,
1589 const Any& rOrient, SCSIZE nIndex, ScFieldIdentifier& rFieldId )
1591 if (!rSource.is())
1592 throw RuntimeException();
1594 bool bOk = false;
1595 SCSIZE nPos = 0;
1596 sal_Int32 nDimIndex = 0;
1598 Reference<XNameAccess> xDimsName(rSource->getDimensions());
1599 Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1600 sal_Int32 nIntCount = xIntDims->getCount();
1601 Reference<XPropertySet> xDim;
1602 if (rOrient.hasValue())
1604 sal_Int32 i = 0;
1605 while (i < nIntCount && !bOk)
1607 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1608 if (xDim.is() && (xDim->getPropertyValue(OUString(SC_UNO_DP_ORIENTATION)) == rOrient))
1610 if (nPos == nIndex)
1612 bOk = true;
1613 nDimIndex = i;
1615 else
1616 ++nPos;
1618 ++i;
1621 else
1623 sal_Int32 i = 0;
1624 while (i < nIntCount && !bOk)
1626 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1627 if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1629 if (nPos == nIndex)
1631 bOk = true;
1632 nDimIndex = i;
1634 else
1635 ++nPos;
1637 ++i;
1641 if ( bOk )
1643 xDim.set( xIntDims->getByIndex(nDimIndex), UNO_QUERY );
1644 Reference<XNamed> xDimName( xDim, UNO_QUERY );
1645 if ( xDimName.is() )
1647 OUString sOriginalName( lcl_GetOriginalName( xDimName ) );
1648 rFieldId.maFieldName = sOriginalName;
1649 rFieldId.mbDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDim,
1650 OUString(SC_UNO_DP_ISDATALAYOUT) );
1652 sal_Int32 nRepeat = 0;
1653 if ( rOrient.hasValue() && lcl_IsDuplicated( xDim ) )
1655 // find the repeat count
1656 // (this relies on the original dimension always being before the duplicates)
1658 Reference<XNamed> xPrevName;
1659 for (sal_Int32 i = 0; i < nDimIndex; ++i)
1661 xPrevName.set( xIntDims->getByIndex(i), UNO_QUERY );
1662 if ( xPrevName.is() && lcl_GetOriginalName( xPrevName ) == sOriginalName )
1663 ++nRepeat;
1666 rFieldId.mnFieldIdx = nRepeat;
1668 else
1669 bOk = false;
1672 return bOk;
1675 static bool lcl_GetFieldDataByName( ScDPObject* pDPObj, const OUString& rFieldName, ScFieldIdentifier& rFieldId )
1677 // "By name" is always the first match.
1678 // The name "Data" always refers to the data layout field.
1679 rFieldId.maFieldName = rFieldName;
1680 rFieldId.mnFieldIdx = 0;
1681 rFieldId.mbDataLayout = rFieldName == SC_DATALAYOUT_NAME;
1683 pDPObj->GetSource(); // IsDimNameInUse doesn't update source data
1685 // check if the named field exists (not for data layout)
1686 return rFieldId.mbDataLayout || pDPObj->IsDimNameInUse( rFieldName );
1689 // XDataPilotFields
1691 ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
1693 // TODO
1694 if (ScDPObject* pObj = GetDPObject())
1696 ScFieldIdentifier aFieldId;
1697 if (lcl_GetFieldDataByIndex( pObj->GetSource(), maOrient, nIndex, aFieldId ))
1698 return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1700 return 0;
1703 ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const OUString& aName) const
1705 if (ScDPObject* pDPObj = GetDPObject())
1707 ScFieldIdentifier aFieldId;
1708 if (lcl_GetFieldDataByName( pDPObj, aName, aFieldId ))
1709 return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1711 return 0;
1714 // XEnumerationAccess
1716 Reference<XEnumeration> SAL_CALL ScDataPilotFieldsObj::createEnumeration()
1717 throw(RuntimeException, std::exception)
1719 SolarMutexGuard aGuard;
1720 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotFieldsEnumeration"));
1723 // XIndexAccess
1725 sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(RuntimeException, std::exception)
1727 SolarMutexGuard aGuard;
1728 // TODO
1729 ScDPObject* pDPObj = GetDPObject();
1730 return pDPObj ? lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) : 0;
1733 Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex )
1734 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
1736 SolarMutexGuard aGuard;
1737 Reference< XPropertySet > xField( GetObjectByIndex_Impl( nIndex ) );
1738 if (!xField.is())
1739 throw IndexOutOfBoundsException();
1740 return Any( xField );
1743 uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(RuntimeException, std::exception)
1745 SolarMutexGuard aGuard;
1746 return cppu::UnoType<XPropertySet>::get();
1749 sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(RuntimeException, std::exception)
1751 SolarMutexGuard aGuard;
1752 return ( getCount() != 0 );
1755 Any SAL_CALL ScDataPilotFieldsObj::getByName( const OUString& aName )
1756 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
1758 SolarMutexGuard aGuard;
1759 Reference<XPropertySet> xField(GetObjectByName_Impl(aName));
1760 if (!xField.is())
1761 throw NoSuchElementException();
1762 return Any( xField );
1765 Sequence<OUString> SAL_CALL ScDataPilotFieldsObj::getElementNames()
1766 throw(RuntimeException, std::exception)
1768 SolarMutexGuard aGuard;
1769 // TODO
1770 if (ScDPObject* pDPObj = GetDPObject())
1772 Sequence< OUString > aSeq( lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) );
1773 OUString* pAry = aSeq.getArray();
1775 const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pDPObj->GetSaveData()->GetDimensions();
1776 boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
1777 for (it = rDimensions.begin(); it != rDimensions.end(); ++it)
1779 if(maOrient.hasValue() && (it->GetOrientation() == maOrient.get< DataPilotFieldOrientation >()))
1781 *pAry = it->GetName();
1782 ++pAry;
1785 return aSeq;
1787 return Sequence<OUString>();
1790 sal_Bool SAL_CALL ScDataPilotFieldsObj::hasByName( const OUString& aName )
1791 throw(RuntimeException, std::exception)
1793 SolarMutexGuard aGuard;
1795 return GetObjectByName_Impl(aName) != NULL;
1798 ScDataPilotFieldObj::ScDataPilotFieldObj(
1799 ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1800 ScDataPilotChildObjBase( rParent, rFieldId ),
1801 maPropSet( lcl_GetDataPilotFieldMap() )
1805 ScDataPilotFieldObj::ScDataPilotFieldObj( ScDataPilotDescriptorBase& rParent,
1806 const ScFieldIdentifier& rFieldId, const Any& rOrient ) :
1807 ScDataPilotChildObjBase( rParent, rFieldId ),
1808 maPropSet( lcl_GetDataPilotFieldMap() ),
1809 maOrient( rOrient )
1813 ScDataPilotFieldObj::~ScDataPilotFieldObj()
1817 // XNamed
1819 OUString SAL_CALL ScDataPilotFieldObj::getName()
1820 throw (RuntimeException, std::exception)
1822 SolarMutexGuard aGuard;
1823 OUString aName;
1824 if( ScDPSaveDimension* pDim = GetDPDimension() )
1826 if( pDim->IsDataLayout() )
1827 aName = SC_DATALAYOUT_NAME;
1828 else
1830 const OUString* pLayoutName = pDim->GetLayoutName();
1831 if (pLayoutName)
1832 aName = *pLayoutName;
1833 else
1834 aName = pDim->GetName();
1836 return aName;
1839 void SAL_CALL ScDataPilotFieldObj::setName(const OUString& rName)
1840 throw (RuntimeException, std::exception)
1842 SolarMutexGuard aGuard;
1843 ScDPObject* pDPObj = 0;
1844 ScDPSaveDimension* pDim = GetDPDimension( &pDPObj );
1845 if( pDim && !pDim->IsDataLayout() )
1847 pDim->SetLayoutName(rName);
1848 SetDPObject( pDPObj );
1852 // XPropertySet
1854 Reference<XPropertySetInfo> SAL_CALL ScDataPilotFieldObj::getPropertySetInfo()
1855 throw(RuntimeException, std::exception)
1857 SolarMutexGuard aGuard;
1858 static Reference<XPropertySetInfo> aRef(
1859 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() ));
1860 return aRef;
1863 void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
1864 throw (UnknownPropertyException, PropertyVetoException,
1865 IllegalArgumentException, WrappedTargetException,
1866 RuntimeException, std::exception)
1868 SolarMutexGuard aGuard;
1869 OUString aNameString(aPropertyName);
1870 if ( aNameString == SC_UNONAME_FUNCTION )
1872 // #i109350# use GetEnumFromAny because it also allows sal_Int32
1873 GeneralFunction eFunction = (GeneralFunction)
1874 ScUnoHelpFunctions::GetEnumFromAny( aValue );
1875 setFunction( eFunction );
1877 else if ( aNameString == SC_UNONAME_SUBTOTALS )
1879 Sequence< GeneralFunction > aSubtotals;
1880 if( aValue >>= aSubtotals )
1881 setSubtotals( aSubtotals );
1883 else if ( aNameString == SC_UNONAME_ORIENT )
1885 //! test for correct enum type?
1886 DataPilotFieldOrientation eOrient = (DataPilotFieldOrientation)
1887 ScUnoHelpFunctions::GetEnumFromAny( aValue );
1888 setOrientation( eOrient );
1890 else if ( aNameString == SC_UNONAME_SELPAGE )
1892 OUString sCurrentPage;
1893 if (aValue >>= sCurrentPage)
1894 setCurrentPage(sCurrentPage);
1896 else if ( aNameString == SC_UNONAME_USESELPAGE )
1898 setUseCurrentPage(cppu::any2bool(aValue));
1900 else if ( aNameString == SC_UNONAME_HASAUTOSHOW )
1902 if (!cppu::any2bool(aValue))
1903 setAutoShowInfo(NULL);
1905 else if ( aNameString == SC_UNONAME_AUTOSHOW )
1907 DataPilotFieldAutoShowInfo aInfo;
1908 if (aValue >>= aInfo)
1909 setAutoShowInfo(&aInfo);
1911 else if ( aNameString == SC_UNONAME_HASLAYOUTINFO )
1913 if (!cppu::any2bool(aValue))
1914 setLayoutInfo(NULL);
1916 else if ( aNameString == SC_UNONAME_LAYOUTINFO )
1918 DataPilotFieldLayoutInfo aInfo;
1919 if (aValue >>= aInfo)
1920 setLayoutInfo(&aInfo);
1922 else if ( aNameString == SC_UNONAME_HASREFERENCE )
1924 if (!cppu::any2bool(aValue))
1925 setReference(NULL);
1927 else if ( aNameString == SC_UNONAME_REFERENCE )
1929 DataPilotFieldReference aRef;
1930 if (aValue >>= aRef)
1931 setReference(&aRef);
1933 else if ( aNameString == SC_UNONAME_HASSORTINFO )
1935 if (!cppu::any2bool(aValue))
1936 setSortInfo(NULL);
1938 else if ( aNameString == SC_UNONAME_SORTINFO )
1940 DataPilotFieldSortInfo aInfo;
1941 if (aValue >>= aInfo)
1942 setSortInfo(&aInfo);
1944 else if ( aNameString == SC_UNONAME_ISGROUP )
1946 if (!cppu::any2bool(aValue))
1947 setGroupInfo(NULL);
1949 else if ( aNameString == SC_UNONAME_GROUPINFO )
1951 DataPilotFieldGroupInfo aInfo;
1952 if (aValue >>= aInfo)
1953 setGroupInfo(&aInfo);
1955 else if ( aNameString == SC_UNONAME_SHOWEMPTY )
1957 setShowEmpty(cppu::any2bool(aValue));
1959 else if ( aNameString == SC_UNONAME_REPEATITEMLABELS )
1961 setRepeatItemLabels(cppu::any2bool(aValue));
1965 Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName )
1966 throw (UnknownPropertyException, WrappedTargetException,
1967 RuntimeException, std::exception)
1969 SolarMutexGuard aGuard;
1970 OUString aNameString(aPropertyName);
1971 Any aRet;
1973 if ( aNameString == SC_UNONAME_FUNCTION )
1974 aRet <<= getFunction();
1975 else if ( aNameString == SC_UNONAME_SUBTOTALS )
1976 aRet <<= getSubtotals();
1977 else if ( aNameString == SC_UNONAME_ORIENT )
1978 aRet <<= getOrientation();
1979 else if ( aNameString == SC_UNONAME_SELPAGE )
1980 aRet <<= getCurrentPage();
1981 else if ( aNameString == SC_UNONAME_USESELPAGE )
1982 aRet <<= false;
1983 else if ( aNameString == SC_UNONAME_HASAUTOSHOW )
1984 aRet <<= (getAutoShowInfo() != NULL);
1985 else if ( aNameString == SC_UNONAME_AUTOSHOW )
1987 const DataPilotFieldAutoShowInfo* pInfo = getAutoShowInfo();
1988 if (pInfo)
1989 aRet <<= DataPilotFieldAutoShowInfo(*pInfo);
1991 else if ( aNameString == SC_UNONAME_HASLAYOUTINFO )
1992 aRet <<= (getLayoutInfo() != NULL);
1993 else if ( aNameString == SC_UNONAME_LAYOUTINFO )
1995 const DataPilotFieldLayoutInfo* pInfo = getLayoutInfo();
1996 if (pInfo)
1997 aRet <<= DataPilotFieldLayoutInfo(*pInfo);
1999 else if ( aNameString == SC_UNONAME_HASREFERENCE )
2000 aRet <<= (getReference() != NULL);
2001 else if ( aNameString == SC_UNONAME_REFERENCE )
2003 const DataPilotFieldReference* pRef = getReference();
2004 if (pRef)
2005 aRet <<= DataPilotFieldReference(*pRef);
2007 else if ( aNameString == SC_UNONAME_HASSORTINFO )
2008 aRet <<= (getSortInfo() != NULL);
2009 else if ( aNameString == SC_UNONAME_SORTINFO )
2011 const DataPilotFieldSortInfo* pInfo = getSortInfo();
2012 if (pInfo)
2013 aRet <<= DataPilotFieldSortInfo(*pInfo);
2015 else if ( aNameString == SC_UNONAME_ISGROUP )
2016 aRet <<= (hasGroupInfo());
2017 else if ( aNameString == SC_UNONAME_GROUPINFO )
2019 aRet <<= getGroupInfo();
2021 else if ( aNameString == SC_UNONAME_SHOWEMPTY )
2022 aRet <<= getShowEmpty();
2023 else if ( aNameString == SC_UNONAME_REPEATITEMLABELS )
2024 aRet <<= getRepeatItemLabels();
2026 return aRet;
2029 // XDatePilotField
2031 Reference<XIndexAccess> SAL_CALL ScDataPilotFieldObj::getItems()
2032 throw (RuntimeException, std::exception)
2034 SolarMutexGuard aGuard;
2035 if (!mxItems.is())
2036 mxItems.set( new ScDataPilotItemsObj( mrParent, maFieldId ) );
2037 return mxItems;
2040 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj )
2042 DataPilotFieldOrientation ScDataPilotFieldObj::getOrientation() const
2044 SolarMutexGuard aGuard;
2045 ScDPSaveDimension* pDim = GetDPDimension();
2046 return pDim ? static_cast< DataPilotFieldOrientation >( pDim->GetOrientation() ) : DataPilotFieldOrientation_HIDDEN;
2049 void ScDataPilotFieldObj::setOrientation(DataPilotFieldOrientation eNew)
2051 SolarMutexGuard aGuard;
2052 if (maOrient.hasValue() && (eNew == maOrient.get< DataPilotFieldOrientation >()))
2053 return;
2055 ScDPObject* pDPObj = 0;
2056 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2058 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2060 /* If the field was taken from getDataPilotFields(), don't reset the
2061 orientation for an existing use, but create a duplicated field
2062 instead (for "Data" orientation only). */
2063 if ( !maOrient.hasValue() && !maFieldId.mbDataLayout &&
2064 (pDim->GetOrientation() != DataPilotFieldOrientation_HIDDEN) &&
2065 (eNew == DataPilotFieldOrientation_DATA) )
2068 ScDPSaveDimension* pNewDim = 0;
2070 // look for existing duplicate with orientation "hidden"
2072 sal_Int32 nFound = 0;
2073 const boost::ptr_vector<ScDPSaveDimension>& rDimensions = pSaveData->GetDimensions();
2074 boost::ptr_vector<ScDPSaveDimension>::const_iterator it;
2075 for ( it = rDimensions.begin(); it != rDimensions.end() && !pNewDim; ++it )
2077 if ( !it->IsDataLayout() && (it->GetName() == maFieldId.maFieldName) )
2079 if ( it->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2080 pNewDim = const_cast<ScDPSaveDimension*>(&(*it)); // use this one
2081 else
2082 ++nFound; // count existing non-hidden occurrences
2086 if ( !pNewDim ) // if none found, create a new duplicated dimension
2087 pNewDim = &pSaveData->DuplicateDimension( *pDim );
2089 maFieldId.mnFieldIdx = nFound; // keep accessing the new one
2090 pDim = pNewDim;
2093 pDim->SetOrientation(sal::static_int_cast<sal_uInt16>(eNew));
2095 // move changed field behind all other fields (make it the last field in dimension)
2096 pSaveData->SetPosition( pDim, pSaveData->GetDimensions().size() );
2098 SetDPObject( pDPObj );
2100 maOrient <<= eNew; // modifying the same object's orientation again doesn't create another duplicate
2104 GeneralFunction ScDataPilotFieldObj::getFunction() const
2106 SolarMutexGuard aGuard;
2107 GeneralFunction eRet = GeneralFunction_NONE;
2108 if( ScDPSaveDimension* pDim = GetDPDimension() )
2110 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2112 // for non-data fields, property Function is the subtotals
2113 long nSubCount = pDim->GetSubTotalsCount();
2114 if ( nSubCount > 0 )
2115 eRet = (GeneralFunction)pDim->GetSubTotalFunc(0); // always use the first one
2116 // else keep NONE
2118 else
2119 eRet = (GeneralFunction)pDim->GetFunction();
2121 return eRet;
2124 void ScDataPilotFieldObj::setFunction(GeneralFunction eNewFunc)
2126 SolarMutexGuard aGuard;
2127 ScDPObject* pDPObj = 0;
2128 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2130 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2132 // for non-data fields, property Function is the subtotals
2133 if ( eNewFunc == GeneralFunction_NONE )
2134 pDim->SetSubTotals( 0, NULL );
2135 else
2137 sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( eNewFunc );
2138 pDim->SetSubTotals( 1, &nFunc );
2141 else
2142 pDim->SetFunction( sal::static_int_cast<sal_uInt16>( eNewFunc ) );
2143 SetDPObject( pDPObj );
2147 Sequence< GeneralFunction > ScDataPilotFieldObj::getSubtotals() const
2149 SolarMutexGuard aGuard;
2150 Sequence< GeneralFunction > aRet;
2151 if( ScDPSaveDimension* pDim = GetDPDimension() )
2153 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2155 // for non-data fields, property Functions is the sequence of subtotals
2156 sal_Int32 nCount = static_cast< sal_Int32 >( pDim->GetSubTotalsCount() );
2157 if ( nCount > 0 )
2159 aRet.realloc( nCount );
2160 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2161 aRet[ nIdx ] = (GeneralFunction)pDim->GetSubTotalFunc( nIdx );
2165 return aRet;
2168 void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubtotals )
2170 SolarMutexGuard aGuard;
2171 ScDPObject* pDPObj = 0;
2172 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2174 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
2176 sal_Int32 nCount = rSubtotals.getLength();
2177 if( nCount == 1 )
2179 // count 1: all values are allowed (including NONE and AUTO)
2180 if( rSubtotals[ 0 ] == GeneralFunction_NONE )
2181 pDim->SetSubTotals( 0, NULL );
2182 else
2184 sal_uInt16 nFunc = sal::static_int_cast<sal_uInt16>( rSubtotals[ 0 ] );
2185 pDim->SetSubTotals( 1, &nFunc );
2188 else if( nCount > 1 )
2190 // set multiple functions, ignore NONE and AUTO in this case
2191 ::std::vector< sal_uInt16 > aSubt;
2192 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
2194 GeneralFunction eFunc = rSubtotals[ nIdx ];
2195 if( (eFunc != GeneralFunction_NONE) && (eFunc != GeneralFunction_AUTO) )
2197 // do not insert functions twice
2198 sal_uInt16 nFunc = static_cast< sal_uInt16 >( eFunc );
2199 if( ::std::find( aSubt.begin(), aSubt.end(), nFunc ) == aSubt.end() )
2200 aSubt.push_back( nFunc );
2203 // set values from vector to ScDPSaveDimension
2204 if ( aSubt.empty() )
2205 pDim->SetSubTotals( 0, NULL );
2206 else
2207 pDim->SetSubTotals( static_cast< long >( aSubt.size() ), &aSubt.front() );
2210 SetDPObject( pDPObj );
2214 OUString ScDataPilotFieldObj::getCurrentPage()
2216 return OUString();
2219 void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage )
2221 SolarMutexGuard aGuard;
2222 ScDPObject* pDPObj = 0;
2223 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2225 pDim->SetCurrentPage( &rPage );
2226 SetDPObject( pDPObj );
2230 void ScDataPilotFieldObj::setUseCurrentPage( bool bUse )
2232 SolarMutexGuard aGuard;
2233 ScDPObject* pDPObj = 0;
2234 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2236 if( bUse )
2238 /* It is somehow useless to set the property "HasSelectedPage" to
2239 true, because it is still needed to set an explicit page name. */
2240 const OUString aPage;
2241 pDim->SetCurrentPage( &aPage );
2243 else
2244 pDim->SetCurrentPage( 0 );
2245 SetDPObject( pDPObj );
2249 const DataPilotFieldAutoShowInfo* ScDataPilotFieldObj::getAutoShowInfo()
2251 SolarMutexGuard aGuard;
2252 ScDPSaveDimension* pDim = GetDPDimension();
2253 return pDim ? pDim->GetAutoShowInfo() : 0;
2256 void ScDataPilotFieldObj::setAutoShowInfo( const DataPilotFieldAutoShowInfo* pInfo )
2258 SolarMutexGuard aGuard;
2259 ScDPObject* pDPObj = 0;
2260 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2262 pDim->SetAutoShowInfo( pInfo );
2263 SetDPObject( pDPObj );
2267 const DataPilotFieldLayoutInfo* ScDataPilotFieldObj::getLayoutInfo()
2269 SolarMutexGuard aGuard;
2270 ScDPSaveDimension* pDim = GetDPDimension();
2271 return pDim ? pDim->GetLayoutInfo() : 0;
2274 void ScDataPilotFieldObj::setLayoutInfo( const DataPilotFieldLayoutInfo* pInfo )
2276 SolarMutexGuard aGuard;
2277 ScDPObject* pDPObj = 0;
2278 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2280 pDim->SetLayoutInfo( pInfo );
2281 SetDPObject( pDPObj );
2285 const DataPilotFieldReference* ScDataPilotFieldObj::getReference()
2287 SolarMutexGuard aGuard;
2288 ScDPSaveDimension* pDim = GetDPDimension();
2289 return pDim ? pDim->GetReferenceValue() : 0;
2292 void ScDataPilotFieldObj::setReference( const DataPilotFieldReference* pInfo )
2294 SolarMutexGuard aGuard;
2295 ScDPObject* pDPObj = 0;
2296 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2298 pDim->SetReferenceValue( pInfo );
2299 SetDPObject( pDPObj );
2303 const DataPilotFieldSortInfo* ScDataPilotFieldObj::getSortInfo()
2305 SolarMutexGuard aGuard;
2306 ScDPSaveDimension* pDim = GetDPDimension();
2307 return pDim ? pDim->GetSortInfo() : 0;
2310 void ScDataPilotFieldObj::setSortInfo( const DataPilotFieldSortInfo* pInfo )
2312 SolarMutexGuard aGuard;
2313 ScDPObject* pDPObj = 0;
2314 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2316 pDim->SetSortInfo( pInfo );
2317 SetDPObject( pDPObj );
2321 bool ScDataPilotFieldObj::getShowEmpty() const
2323 SolarMutexGuard aGuard;
2324 ScDPSaveDimension* pDim = GetDPDimension();
2325 return pDim && pDim->GetShowEmpty();
2328 void ScDataPilotFieldObj::setShowEmpty( bool bShow )
2330 SolarMutexGuard aGuard;
2331 ScDPObject* pDPObj = 0;
2332 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2334 pDim->SetShowEmpty( bShow );
2335 SetDPObject( pDPObj );
2339 bool ScDataPilotFieldObj::getRepeatItemLabels() const
2341 SolarMutexGuard aGuard;
2342 ScDPSaveDimension* pDim = GetDPDimension();
2343 return pDim && pDim->GetRepeatItemLabels();
2346 void ScDataPilotFieldObj::setRepeatItemLabels( bool bShow )
2348 SolarMutexGuard aGuard;
2349 ScDPObject* pDPObj = 0;
2350 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2352 pDim->SetRepeatItemLabels( bShow );
2353 SetDPObject( pDPObj );
2357 bool ScDataPilotFieldObj::hasGroupInfo()
2359 SolarMutexGuard aGuard;
2360 ScDPObject* pDPObj = 0;
2361 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2362 if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2363 return pDimData->GetNamedGroupDim( pDim->GetName() ) || pDimData->GetNumGroupDim( pDim->GetName() );
2364 return false;
2367 DataPilotFieldGroupInfo ScDataPilotFieldObj::getGroupInfo()
2369 SolarMutexGuard aGuard;
2370 DataPilotFieldGroupInfo aInfo;
2371 ScDPObject* pDPObj = 0;
2372 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2374 if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2376 if( const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( pDim->GetName() ) )
2378 // grouped by ...
2379 aInfo.GroupBy = pGroupDim->GetDatePart();
2381 // find source field
2384 Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2385 aInfo.SourceField.set( xFields->getByName( pGroupDim->GetSourceDimName() ), UNO_QUERY );
2387 catch( Exception& )
2391 ScDataPilotConversion::FillGroupInfo( aInfo, pGroupDim->GetDateInfo() );
2392 if( pGroupDim->GetDatePart() == 0 )
2394 // fill vector of group and group member information
2395 ScFieldGroups aGroups;
2396 for( sal_Int32 nIdx = 0, nCount = pGroupDim->GetGroupCount(); nIdx < nCount; ++nIdx )
2398 if( const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( nIdx ) )
2400 ScFieldGroup aGroup;
2401 aGroup.maName = pGroup->GetGroupName();
2402 for( sal_Int32 nMemIdx = 0, nMemCount = pGroup->GetElementCount(); nMemIdx < nMemCount; ++nMemIdx )
2403 if (const OUString* pMem = pGroup->GetElementByIndex(nMemIdx))
2404 aGroup.maMembers.push_back( *pMem );
2405 aGroups.push_back( aGroup );
2408 aInfo.Groups = new ScDataPilotFieldGroupsObj( aGroups );
2411 else if( const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( pDim->GetName() ) )
2413 if (pNumGroupDim->GetDatePart())
2415 ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetDateInfo() );
2416 aInfo.GroupBy = pNumGroupDim->GetDatePart();
2418 else
2420 ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetInfo() );
2425 return aInfo;
2428 void ScDataPilotFieldObj::setGroupInfo( const DataPilotFieldGroupInfo* pInfo )
2430 SolarMutexGuard aGuard;
2431 ScDPObject* pDPObj = 0;
2432 if( /*ScDPSaveDimension* pDim =*/ GetDPDimension( &pDPObj ) )
2434 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2435 if( pInfo && lclCheckMinMaxStep( *pInfo ) )
2437 ScDPNumGroupInfo aInfo;
2438 aInfo.mbEnable = true;
2439 aInfo.mbDateValues = pInfo->HasDateValues;
2440 aInfo.mbAutoStart = pInfo->HasAutoStart;
2441 aInfo.mbAutoEnd = pInfo->HasAutoEnd;
2442 aInfo.mfStart = pInfo->Start;
2443 aInfo.mfEnd = pInfo->End;
2444 aInfo.mfStep = pInfo->Step;
2445 Reference< XNamed > xNamed( pInfo->SourceField, UNO_QUERY );
2446 if( xNamed.is() )
2448 ScDPSaveGroupDimension aGroupDim( xNamed->getName(), getName() );
2449 if( pInfo->GroupBy )
2450 aGroupDim.SetDateInfo(aInfo, pInfo->GroupBy);
2451 else
2453 Reference<XIndexAccess> xIndex(pInfo->Groups, UNO_QUERY);
2454 if (xIndex.is())
2456 sal_Int32 nCount(xIndex->getCount());
2457 for(sal_Int32 i = 0; i < nCount; i++)
2459 Reference<XNamed> xGroupNamed(xIndex->getByIndex(i), UNO_QUERY);
2460 if (xGroupNamed.is())
2462 ScDPSaveGroupItem aItem(xGroupNamed->getName());
2463 Reference<XIndexAccess> xGroupIndex(xGroupNamed, UNO_QUERY);
2464 if (xGroupIndex.is())
2466 sal_Int32 nItemCount(xGroupIndex->getCount());
2467 for (sal_Int32 j = 0; j < nItemCount; ++j)
2469 Reference<XNamed> xItemNamed(xGroupIndex->getByIndex(j), UNO_QUERY);
2470 if (xItemNamed.is())
2471 aItem.AddElement(xItemNamed->getName());
2474 aGroupDim.AddGroupItem(aItem);
2480 // get dimension savedata or create new if none
2481 ScDPDimensionSaveData& rDimSaveData = *pSaveData->GetDimensionData();
2482 rDimSaveData.ReplaceGroupDimension( aGroupDim );
2484 else // no source field in group info -> numeric group
2486 ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData(); // created if not there
2488 ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( getName() );
2489 if ( pExisting )
2491 if (pInfo->GroupBy)
2492 pExisting->SetDateInfo(aInfo, pInfo->GroupBy);
2493 // modify existing group dimension
2494 pExisting->SetGroupInfo( aInfo );
2496 else if (pInfo->GroupBy)
2498 // create new group dimension
2499 ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo, pInfo->GroupBy );
2500 pDimData->AddNumGroupDimension( aNumGroupDim );
2502 else
2504 // create new group dimension
2505 ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo );
2506 pDimData->AddNumGroupDimension( aNumGroupDim );
2510 else // null passed as argument
2512 pSaveData->SetDimensionData( 0 );
2515 pDPObj->SetSaveData( *pSaveData );
2516 SetDPObject( pDPObj );
2520 bool ScDataPilotFieldObj::HasString(const Sequence< OUString >& rItems, const OUString& aString)
2522 bool bRet = false;
2524 sal_Int32 nCount(rItems.getLength());
2525 sal_Int32 nItem(0);
2526 while (nItem < nCount && !bRet)
2528 bRet = rItems[nItem] == aString;
2529 ++nItem;
2532 return bRet;
2535 // XDataPilotFieldGrouping
2536 Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( const Sequence< OUString >& rItems )
2537 throw (RuntimeException, IllegalArgumentException,
2538 std::exception)
2540 SolarMutexGuard aGuard;
2542 Reference< XDataPilotField > xRet;
2543 OUString sNewDim;
2545 if( !rItems.hasElements() )
2546 throw IllegalArgumentException();
2548 ScDPObject* pDPObj = 0;
2549 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2551 OUString aDimName = pDim->GetName();
2553 ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2554 ScDPDimensionSaveData* pDimData = aSaveData.GetDimensionData(); // created if not there
2556 // find original base
2557 OUString aBaseDimName( aDimName );
2558 const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
2559 if ( pBaseGroupDim )
2561 // any entry's SourceDimName is the original base
2562 aBaseDimName = pBaseGroupDim->GetSourceDimName();
2565 // find existing group dimension
2566 // (using the selected dim, can be intermediate group dim)
2567 ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
2569 // remove the selected items from their groups
2570 // (empty groups are removed, too)
2571 sal_Int32 nEntryCount = rItems.getLength();
2572 sal_Int32 nEntry;
2573 if ( pGroupDimension )
2575 for (nEntry=0; nEntry<nEntryCount; nEntry++)
2577 const OUString& aEntryName = rItems[nEntry];
2578 if ( pBaseGroupDim )
2580 // for each selected (intermediate) group, remove all its items
2581 // (same logic as for adding, below)
2582 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2583 if ( pBaseGroup )
2584 pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements
2585 else
2586 pGroupDimension->RemoveFromGroups( aEntryName );
2588 else
2589 pGroupDimension->RemoveFromGroups( aEntryName );
2593 ScDPSaveGroupDimension* pNewGroupDim = 0;
2594 if ( !pGroupDimension )
2596 // create a new group dimension
2597 sNewDim = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
2598 pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, sNewDim );
2600 pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
2602 if ( pBaseGroupDim )
2604 // If it's a higher-order group dimension, pre-allocate groups for all
2605 // non-selected original groups, so the individual base members aren't
2606 // used for automatic groups (this would make the original groups hard
2607 // to find).
2608 //! Also do this when removing groups?
2609 //! Handle this case dynamically with automatic groups?
2611 long nGroupCount = pBaseGroupDim->GetGroupCount();
2612 for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
2614 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
2616 if (!HasString(rItems, pBaseGroup->GetGroupName())) //! ignore case?
2618 // add an additional group for each item that is not in the selection
2619 ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
2620 aGroup.AddElementsFromGroup( *pBaseGroup );
2621 pGroupDimension->AddGroupItem( aGroup );
2626 OUString aGroupDimName = pGroupDimension->GetGroupDimName();
2628 //! localized prefix string
2629 OUString aGroupName = pGroupDimension->CreateGroupName( OUString( "Group" ) );
2630 ScDPSaveGroupItem aGroup( aGroupName );
2631 Reference< XNameAccess > xMembers = GetMembers();
2632 if (!xMembers.is())
2634 delete pNewGroupDim;
2635 throw RuntimeException();
2638 for (nEntry=0; nEntry<nEntryCount; nEntry++)
2640 OUString aEntryName(rItems[nEntry]);
2642 if (!xMembers->hasByName(aEntryName))
2644 delete pNewGroupDim;
2645 throw IllegalArgumentException();
2648 if ( pBaseGroupDim )
2650 // for each selected (intermediate) group, add all its items
2651 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2652 if ( pBaseGroup )
2653 aGroup.AddElementsFromGroup( *pBaseGroup );
2654 else
2655 aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself
2657 else
2658 aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
2661 pGroupDimension->AddGroupItem( aGroup );
2663 if ( pNewGroupDim )
2665 pDimData->AddGroupDimension( *pNewGroupDim );
2666 delete pNewGroupDim; // AddGroupDimension copies the object
2667 // don't access pGroupDimension after here
2669 pGroupDimension = pNewGroupDim = NULL;
2671 // set orientation
2672 ScDPSaveDimension* pSaveDimension = aSaveData.GetDimensionByName( aGroupDimName );
2673 if ( pSaveDimension->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2675 ScDPSaveDimension* pOldDimension = aSaveData.GetDimensionByName( aDimName );
2676 pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
2677 long nPosition = 0; //! before (immediate) base
2678 aSaveData.SetPosition( pSaveDimension, nPosition );
2681 // apply changes
2682 pDPObj->SetSaveData( aSaveData );
2683 ScDBDocFunc(*GetDocShell()).RefreshPivotTableGroups(pDPObj);
2686 // if new grouping field has been created (on first group), return it
2687 if( !sNewDim.isEmpty() )
2689 Reference< XNameAccess > xFields(mrParent.getDataPilotFields(), UNO_QUERY);
2690 if (xFields.is())
2694 xRet.set(xFields->getByName(sNewDim), UNO_QUERY);
2695 OSL_ENSURE(xRet.is(), "there is a name, so there should be also a field");
2697 catch (const container::NoSuchElementException&)
2699 // Avoid throwing exception that's not specified in the method signature.
2700 throw RuntimeException();
2704 return xRet;
2707 Reference < XDataPilotField > SAL_CALL ScDataPilotFieldObj::createDateGroup( const DataPilotFieldGroupInfo& rInfo )
2708 throw (RuntimeException, IllegalArgumentException,
2709 std::exception)
2711 SolarMutexGuard aGuard;
2712 using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
2714 // check min/max/step, HasDateValues must be set always
2715 if( !rInfo.HasDateValues || !lclCheckMinMaxStep( rInfo ) )
2716 throw IllegalArgumentException();
2717 // only a single date flag is allowed
2718 if( (rInfo.GroupBy == 0) || (rInfo.GroupBy > YEARS) || ((rInfo.GroupBy & (rInfo.GroupBy - 1)) != 0) )
2719 throw IllegalArgumentException();
2720 // step must be zero, if something else than DAYS is specified
2721 if( rInfo.Step >= ((rInfo.GroupBy == DAYS) ? 32768.0 : 1.0) )
2722 throw IllegalArgumentException();
2724 OUString aGroupDimName;
2725 ScDPObject* pDPObj = 0;
2726 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2728 ScDPNumGroupInfo aInfo;
2729 aInfo.mbEnable = true;
2730 aInfo.mbDateValues = (rInfo.GroupBy == DAYS) && (rInfo.Step >= 1.0);
2731 aInfo.mbAutoStart = rInfo.HasAutoStart;
2732 aInfo.mbAutoEnd = rInfo.HasAutoEnd;
2733 aInfo.mfStart = rInfo.Start;
2734 aInfo.mfEnd = rInfo.End;
2735 aInfo.mfStep = static_cast< sal_Int32 >( rInfo.Step );
2737 // create a local copy of the entire save data (will be written back below)
2738 ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2739 // get or create dimension save data
2740 ScDPDimensionSaveData& rDimData = *aSaveData.GetDimensionData();
2742 // find source dimension name
2743 const OUString& rDimName = pDim->GetName();
2744 const ScDPSaveGroupDimension* pGroupDim = rDimData.GetNamedGroupDim( rDimName );
2745 OUString aSrcDimName = pGroupDim ? pGroupDim->GetSourceDimName() : rDimName;
2747 // find a group dimension for the base field, or get numeric grouping
2748 pGroupDim = rDimData.GetFirstNamedGroupDim( aSrcDimName );
2749 const ScDPSaveNumGroupDimension* pNumGroupDim = rDimData.GetNumGroupDim( aSrcDimName );
2751 // do not group by dates, if named groups or numeric grouping is present
2752 bool bHasNamedGrouping = pGroupDim && !pGroupDim->GetDateInfo().mbEnable;
2753 bool bHasNumGrouping = pNumGroupDim && pNumGroupDim->GetInfo().mbEnable && !pNumGroupDim->GetInfo().mbDateValues && !pNumGroupDim->GetDateInfo().mbEnable;
2754 if( bHasNamedGrouping || bHasNumGrouping )
2755 throw IllegalArgumentException();
2757 if( aInfo.mbDateValues ) // create day ranges grouping
2759 // first remove all named group dimensions
2760 while( pGroupDim )
2762 OUString aGroupDimName2 = pGroupDim->GetGroupDimName();
2763 // find next group dimension before deleting this group
2764 pGroupDim = rDimData.GetNextNamedGroupDim( aGroupDimName2 );
2765 // remove from dimension save data
2766 rDimData.RemoveGroupDimension( aGroupDimName2 );
2767 // also remove save data settings for the dimension that no longer exists
2768 aSaveData.RemoveDimensionByName( aGroupDimName2 );
2770 // create or replace the number grouping dimension
2771 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo );
2772 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2774 else // create date grouping
2776 // collect all existing date flags
2777 sal_Int32 nDateParts = rDimData.CollectDateParts( aSrcDimName );
2778 if( nDateParts == 0 )
2780 // insert numeric group dimension, if no date groups exist yet (or replace day range grouping)
2781 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo, rInfo.GroupBy );
2782 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2784 else if( (nDateParts & rInfo.GroupBy) == 0 ) // do nothing if date field exists already
2786 // create new named group dimension for additional date groups
2787 aGroupDimName = rDimData.CreateDateGroupDimName( rInfo.GroupBy, *pDPObj, true, 0 );
2788 ScDPSaveGroupDimension aGroupDim( aSrcDimName, aGroupDimName, aInfo, rInfo.GroupBy );
2789 rDimData.AddGroupDimension( aGroupDim );
2791 // set orientation of new named group dimension
2792 ScDPSaveDimension& rSaveDim = *aSaveData.GetDimensionByName( aGroupDimName );
2793 if( rSaveDim.GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2795 ScDPSaveDimension& rOldDim = *aSaveData.GetDimensionByName( aSrcDimName );
2796 rSaveDim.SetOrientation( rOldDim.GetOrientation() );
2797 aSaveData.SetPosition( &rSaveDim, 0 ); //! before (immediate) base
2802 // apply changes
2803 pDPObj->SetSaveData( aSaveData );
2804 SetDPObject( pDPObj );
2807 // return the UNO object of the new dimension, after writing back saved data
2808 Reference< XDataPilotField > xRet;
2809 if( !aGroupDimName.isEmpty() )
2812 Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2813 xRet.set( xFields->getByName( aGroupDimName ), UNO_QUERY );
2815 catch( Exception& )
2818 return xRet;
2821 namespace {
2823 bool lclExtractGroupMembers( ScFieldGroupMembers& rMembers, const Any& rElement )
2825 // allow empty value to create a new group
2826 if( !rElement.hasValue() )
2827 return true;
2829 // try to extract a simple sequence of strings
2830 Sequence< OUString > aSeq;
2831 if( rElement >>= aSeq )
2833 if( aSeq.hasElements() )
2834 rMembers.insert( rMembers.end(), aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength() );
2835 return true;
2838 // try to use XIndexAccess providing objects that support XNamed
2839 Reference< XIndexAccess > xItemsIA( rElement, UNO_QUERY );
2840 if( xItemsIA.is() )
2842 for( sal_Int32 nIdx = 0, nCount = xItemsIA->getCount(); nIdx < nCount; ++nIdx )
2844 try // getByIndex() should not throw, but we cannot be sure
2846 Reference< XNamed > xItemName( xItemsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
2847 rMembers.push_back( xItemName->getName() );
2849 catch( Exception& )
2851 // ignore exceptions, go ahead with next element in the array
2854 return true;
2857 // nothing valid inside the Any -> return false
2858 return false;
2861 } // namespace
2863 ScDataPilotFieldGroupsObj::ScDataPilotFieldGroupsObj( const ScFieldGroups& rGroups ) :
2864 maGroups( rGroups )
2868 ScDataPilotFieldGroupsObj::~ScDataPilotFieldGroupsObj()
2872 // XNameAccess
2874 Any SAL_CALL ScDataPilotFieldGroupsObj::getByName( const OUString& rName )
2875 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2877 SolarMutexGuard aGuard;
2878 if( implFindByName( rName ) == maGroups.end() )
2879 throw NoSuchElementException();
2880 return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, rName ) ) );
2883 Sequence< OUString > SAL_CALL ScDataPilotFieldGroupsObj::getElementNames() throw(RuntimeException, std::exception)
2885 SolarMutexGuard aGuard;
2886 Sequence< OUString > aSeq;
2887 if( !maGroups.empty() )
2889 aSeq.realloc( static_cast< sal_Int32 >( maGroups.size() ) );
2890 OUString* pName = aSeq.getArray();
2891 for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt, ++pName )
2892 *pName = aIt->maName;
2894 return aSeq;
2897 sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasByName( const OUString& rName ) throw(RuntimeException, std::exception)
2899 SolarMutexGuard aGuard;
2900 return implFindByName( rName ) != maGroups.end();
2903 // XNameReplace
2905 void SAL_CALL ScDataPilotFieldGroupsObj::replaceByName( const OUString& rName, const Any& rElement )
2906 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2908 SolarMutexGuard aGuard;
2910 if( rName.isEmpty() )
2911 throw IllegalArgumentException();
2913 ScFieldGroups::iterator aIt = implFindByName( rName );
2914 if( aIt == maGroups.end() )
2915 throw NoSuchElementException();
2917 // read all item names provided by the passed object
2918 ScFieldGroupMembers aMembers;
2919 if( !lclExtractGroupMembers( aMembers, rElement ) )
2920 throw IllegalArgumentException();
2922 // copy and forget, faster than vector assignment
2923 aIt->maMembers.swap( aMembers );
2926 // XNameContainer
2928 void SAL_CALL ScDataPilotFieldGroupsObj::insertByName( const OUString& rName, const Any& rElement )
2929 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
2931 SolarMutexGuard aGuard;
2933 if( rName.isEmpty() )
2934 throw IllegalArgumentException();
2936 ScFieldGroups::iterator aIt = implFindByName( rName );
2937 if( aIt != maGroups.end() )
2938 throw ElementExistException();
2940 // read all item names provided by the passed object
2941 ScFieldGroupMembers aMembers;
2942 if( !lclExtractGroupMembers( aMembers, rElement ) )
2943 throw IllegalArgumentException();
2945 // create the new entry if no error has been occurred
2946 maGroups.resize( maGroups.size() + 1 );
2947 ScFieldGroup& rGroup = maGroups.back();
2948 rGroup.maName = rName;
2949 rGroup.maMembers.swap( aMembers );
2952 void SAL_CALL ScDataPilotFieldGroupsObj::removeByName( const OUString& rName )
2953 throw (NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
2955 SolarMutexGuard aGuard;
2957 if( rName.isEmpty() )
2958 throw IllegalArgumentException();
2960 ScFieldGroups::iterator aIt = implFindByName( rName );
2961 if( aIt == maGroups.end() )
2962 throw NoSuchElementException();
2964 maGroups.erase( aIt );
2967 // XIndexAccess
2969 sal_Int32 SAL_CALL ScDataPilotFieldGroupsObj::getCount() throw(RuntimeException, std::exception)
2971 SolarMutexGuard aGuard;
2972 return static_cast< sal_Int32 >( maGroups.size() );
2975 Any SAL_CALL ScDataPilotFieldGroupsObj::getByIndex( sal_Int32 nIndex )
2976 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
2978 SolarMutexGuard aGuard;
2979 if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( maGroups.size() )))
2980 throw IndexOutOfBoundsException();
2981 return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, maGroups[ nIndex ].maName ) ) );
2984 // XEnumerationAccess
2986 Reference<XEnumeration> SAL_CALL ScDataPilotFieldGroupsObj::createEnumeration() throw(RuntimeException, std::exception)
2988 SolarMutexGuard aGuard;
2989 return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupsEnumeration" ) );
2992 // XElementAccess
2994 uno::Type SAL_CALL ScDataPilotFieldGroupsObj::getElementType() throw(RuntimeException, std::exception)
2996 SolarMutexGuard aGuard;
2997 return cppu::UnoType<XNameAccess>::get();
3000 sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasElements() throw(RuntimeException, std::exception)
3002 SolarMutexGuard aGuard;
3003 return !maGroups.empty();
3006 // implementation
3008 ScFieldGroup& ScDataPilotFieldGroupsObj::getFieldGroup( const OUString& rName ) throw(RuntimeException)
3010 SolarMutexGuard aGuard;
3011 ScFieldGroups::iterator aIt = implFindByName( rName );
3012 if( aIt == maGroups.end() )
3013 throw RuntimeException();
3014 return *aIt;
3017 void ScDataPilotFieldGroupsObj::renameFieldGroup( const OUString& rOldName, const OUString& rNewName ) throw(RuntimeException)
3019 SolarMutexGuard aGuard;
3020 ScFieldGroups::iterator aOldIt = implFindByName( rOldName );
3021 ScFieldGroups::iterator aNewIt = implFindByName( rNewName );
3022 // new name must not exist yet
3023 if( (aOldIt == maGroups.end()) || ((aNewIt != maGroups.end()) && (aNewIt != aOldIt)) )
3024 throw RuntimeException();
3025 aOldIt->maName = rNewName;
3028 ScFieldGroups::iterator ScDataPilotFieldGroupsObj::implFindByName( const OUString& rName )
3030 for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt )
3031 if( aIt->maName == rName )
3032 return aIt;
3033 return maGroups.end();
3036 namespace {
3038 OUString lclExtractMember( const Any& rElement )
3040 if( rElement.has< OUString >() )
3041 return rElement.get< OUString >();
3043 Reference< XNamed > xNamed( rElement, UNO_QUERY );
3044 if( xNamed.is() )
3045 return xNamed->getName();
3047 return OUString();
3050 } // namespace
3052 ScDataPilotFieldGroupObj::ScDataPilotFieldGroupObj( ScDataPilotFieldGroupsObj& rParent, const OUString& rGroupName ) :
3053 mrParent( rParent ),
3054 maGroupName( rGroupName )
3056 mrParent.acquire();
3059 ScDataPilotFieldGroupObj::~ScDataPilotFieldGroupObj()
3061 mrParent.release();
3064 // XNameAccess
3066 Any SAL_CALL ScDataPilotFieldGroupObj::getByName( const OUString& rName )
3067 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3069 SolarMutexGuard aGuard;
3070 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3071 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3072 if( aIt == rMembers.end() )
3073 throw NoSuchElementException();
3074 return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, *aIt ) ) );
3077 Sequence< OUString > SAL_CALL ScDataPilotFieldGroupObj::getElementNames() throw(RuntimeException, std::exception)
3079 SolarMutexGuard aGuard;
3080 return ::comphelper::containerToSequence( mrParent.getFieldGroup( maGroupName ).maMembers );
3083 sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasByName( const OUString& rName ) throw(RuntimeException, std::exception)
3085 SolarMutexGuard aGuard;
3086 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3087 return ::std::find( rMembers.begin(), rMembers.end(), rName ) != rMembers.end();
3090 // XNameReplace
3092 void SAL_CALL ScDataPilotFieldGroupObj::replaceByName( const OUString& rName, const Any& rElement )
3093 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3095 SolarMutexGuard aGuard;
3097 // it should be possible to quickly rename an item -> accept string or XNamed
3098 OUString aNewName = lclExtractMember( rElement );
3099 if( rName.isEmpty() || aNewName.isEmpty() )
3100 throw IllegalArgumentException();
3101 if( rName == aNewName )
3102 return;
3104 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3105 ScFieldGroupMembers::iterator aOldIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3106 ScFieldGroupMembers::iterator aNewIt = ::std::find( rMembers.begin(), rMembers.end(), aNewName );
3107 // throw if passed member name does not exist
3108 if( aOldIt == rMembers.end() )
3109 throw NoSuchElementException();
3110 // throw if new name already exists
3111 if( aNewIt != rMembers.end() )
3112 throw IllegalArgumentException();
3113 *aOldIt = aNewName;
3116 // XNameContainer
3118 void SAL_CALL ScDataPilotFieldGroupObj::insertByName( const OUString& rName, const Any& /*rElement*/ )
3119 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception)
3121 SolarMutexGuard aGuard;
3123 // we will ignore the passed element and just try to insert the name
3124 if( rName.isEmpty() )
3125 throw IllegalArgumentException();
3127 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3128 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3129 // throw if passed name already exists
3130 if( aIt != rMembers.end() )
3131 throw IllegalArgumentException();
3132 rMembers.push_back( rName );
3135 void SAL_CALL ScDataPilotFieldGroupObj::removeByName( const OUString& rName )
3136 throw (NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3138 SolarMutexGuard aGuard;
3140 if( rName.isEmpty() )
3141 throw IllegalArgumentException();
3142 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3143 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
3144 // throw if passed name does not exist
3145 if( aIt == rMembers.end() )
3146 throw NoSuchElementException();
3147 rMembers.erase( aIt );
3150 // XIndexAccess
3152 sal_Int32 SAL_CALL ScDataPilotFieldGroupObj::getCount() throw(RuntimeException, std::exception)
3154 SolarMutexGuard aGuard;
3155 return static_cast< sal_Int32 >( mrParent.getFieldGroup( maGroupName ).maMembers.size() );
3158 Any SAL_CALL ScDataPilotFieldGroupObj::getByIndex( sal_Int32 nIndex )
3159 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
3161 SolarMutexGuard aGuard;
3162 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
3163 if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( rMembers.size() )))
3164 throw IndexOutOfBoundsException();
3165 return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, rMembers[ nIndex ] ) ) );
3168 // XEnumerationAccess
3170 Reference< XEnumeration > SAL_CALL ScDataPilotFieldGroupObj::createEnumeration() throw(RuntimeException, std::exception)
3172 SolarMutexGuard aGuard;
3173 return new ScIndexEnumeration( this, OUString( "com.sun.star.sheet.DataPilotFieldGroupEnumeration" ) );
3176 // XElementAccess
3178 uno::Type SAL_CALL ScDataPilotFieldGroupObj::getElementType() throw(RuntimeException, std::exception)
3180 SolarMutexGuard aGuard;
3181 return cppu::UnoType<XNamed>::get();
3184 sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasElements() throw(RuntimeException, std::exception)
3186 SolarMutexGuard aGuard;
3187 return !mrParent.getFieldGroup( maGroupName ).maMembers.empty();
3190 // XNamed
3192 OUString SAL_CALL ScDataPilotFieldGroupObj::getName() throw(RuntimeException, std::exception)
3194 SolarMutexGuard aGuard;
3195 return maGroupName;
3198 void SAL_CALL ScDataPilotFieldGroupObj::setName( const OUString& rName ) throw(RuntimeException, std::exception)
3200 SolarMutexGuard aGuard;
3201 mrParent.renameFieldGroup( maGroupName, rName );
3202 // if call to renameFieldGroup() did not throw, remember the new name
3203 maGroupName = rName;
3206 ScDataPilotFieldGroupItemObj::ScDataPilotFieldGroupItemObj( ScDataPilotFieldGroupObj& rParent, const OUString& rName ) :
3207 mrParent( rParent ),
3208 maName( rName )
3210 mrParent.acquire();
3213 ScDataPilotFieldGroupItemObj::~ScDataPilotFieldGroupItemObj()
3215 mrParent.release();
3218 // XNamed
3220 OUString SAL_CALL ScDataPilotFieldGroupItemObj::getName() throw(RuntimeException, std::exception)
3222 SolarMutexGuard aGuard;
3223 return maName;
3226 void SAL_CALL ScDataPilotFieldGroupItemObj::setName( const OUString& rName ) throw(RuntimeException, std::exception)
3228 SolarMutexGuard aGuard;
3229 mrParent.replaceByName( maName, Any( rName ) );
3230 // if call to replaceByName() did not throw, remember the new name
3231 maName = rName;
3234 ScDataPilotItemsObj::ScDataPilotItemsObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
3235 ScDataPilotChildObjBase( rParent, rFieldId )
3239 ScDataPilotItemsObj::~ScDataPilotItemsObj()
3243 // XDataPilotItems
3245 ScDataPilotItemObj* ScDataPilotItemsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3247 return ((0 <= nIndex) && (nIndex < GetMemberCount())) ?
3248 new ScDataPilotItemObj( mrParent, maFieldId, nIndex ) : 0;
3251 // XNameAccess
3253 Any SAL_CALL ScDataPilotItemsObj::getByName( const OUString& aName )
3254 throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
3256 SolarMutexGuard aGuard;
3257 Reference<XNameAccess> xMembers = GetMembers();
3258 if (xMembers.is())
3260 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3261 sal_Int32 nCount = xMembersIndex->getCount();
3262 sal_Int32 nItem = 0;
3263 while (nItem < nCount)
3265 Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3266 if (xMember.is() && (aName == xMember->getName()))
3268 return Any( Reference< XPropertySet >( GetObjectByIndex_Impl( nItem ) ) );
3270 ++nItem;
3272 throw NoSuchElementException();
3274 return Any();
3277 Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
3278 throw(RuntimeException, std::exception)
3280 SolarMutexGuard aGuard;
3281 Sequence< OUString > aSeq;
3282 if( ScDPObject* pDPObj = GetDPObject() )
3283 pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
3284 return aSeq;
3287 sal_Bool SAL_CALL ScDataPilotItemsObj::hasByName( const OUString& aName )
3288 throw(RuntimeException, std::exception)
3290 SolarMutexGuard aGuard;
3291 bool bFound = false;
3292 Reference<XNameAccess> xMembers = GetMembers();
3293 if (xMembers.is())
3295 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3296 sal_Int32 nCount = xMembersIndex->getCount();
3297 sal_Int32 nItem = 0;
3298 while (nItem < nCount && !bFound )
3300 Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3301 if (xMember.is() && aName == xMember->getName())
3302 bFound = true;
3303 else
3304 nItem++;
3307 return bFound;
3310 // XEnumerationAccess
3312 Reference<XEnumeration> SAL_CALL ScDataPilotItemsObj::createEnumeration()
3313 throw(RuntimeException, std::exception)
3315 SolarMutexGuard aGuard;
3316 return new ScIndexEnumeration(this, OUString("com.sun.star.sheet.DataPilotItemsEnumeration"));
3319 // XIndexAccess
3321 sal_Int32 SAL_CALL ScDataPilotItemsObj::getCount() throw(RuntimeException, std::exception)
3323 SolarMutexGuard aGuard;
3324 return GetMemberCount();
3327 Any SAL_CALL ScDataPilotItemsObj::getByIndex( sal_Int32 nIndex )
3328 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
3330 SolarMutexGuard aGuard;
3331 Reference< XPropertySet > xItem( GetObjectByIndex_Impl( nIndex ) );
3332 if (!xItem.is())
3333 throw IndexOutOfBoundsException();
3334 return Any( xItem );
3337 uno::Type SAL_CALL ScDataPilotItemsObj::getElementType() throw(RuntimeException, std::exception)
3339 SolarMutexGuard aGuard;
3340 return cppu::UnoType<XPropertySet>::get();
3343 sal_Bool SAL_CALL ScDataPilotItemsObj::hasElements() throw(RuntimeException, std::exception)
3345 SolarMutexGuard aGuard;
3346 return ( getCount() != 0 );
3349 ScDataPilotItemObj::ScDataPilotItemObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId, sal_Int32 nIndex ) :
3350 ScDataPilotChildObjBase( rParent, rFieldId ),
3351 maPropSet( lcl_GetDataPilotItemMap() ),
3352 mnIndex( nIndex )
3356 ScDataPilotItemObj::~ScDataPilotItemObj()
3360 // XNamed
3361 OUString SAL_CALL ScDataPilotItemObj::getName() throw(RuntimeException, std::exception)
3363 SolarMutexGuard aGuard;
3364 OUString sRet;
3365 Reference<XNameAccess> xMembers = GetMembers();
3366 if (xMembers.is())
3368 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3369 sal_Int32 nCount = xMembersIndex->getCount();
3370 if (mnIndex < nCount)
3372 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3373 sRet = xMember->getName();
3376 return sRet;
3379 void SAL_CALL ScDataPilotItemObj::setName( const OUString& /* aName */ )
3380 throw(RuntimeException, std::exception)
3384 // XPropertySet
3385 Reference< XPropertySetInfo >
3386 SAL_CALL ScDataPilotItemObj::getPropertySetInfo( )
3387 throw(RuntimeException, std::exception)
3389 SolarMutexGuard aGuard;
3390 static Reference<XPropertySetInfo> aRef =
3391 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
3392 return aRef;
3395 void SAL_CALL ScDataPilotItemObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
3396 throw (UnknownPropertyException, PropertyVetoException,
3397 IllegalArgumentException, WrappedTargetException,
3398 RuntimeException, std::exception)
3400 SolarMutexGuard aGuard;
3401 ScDPObject* pDPObj = 0;
3402 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
3404 Reference<XNameAccess> xMembers = GetMembers();
3405 if( xMembers.is() )
3407 Reference<XIndexAccess> xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3408 sal_Int32 nCount = xMembersIndex->getCount();
3409 if( mnIndex < nCount )
3411 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3412 OUString sName(xMember->getName());
3413 ScDPSaveMember* pMember = pDim->GetMemberByName(sName);
3414 if (pMember)
3416 bool bGetNewIndex = false;
3417 if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3418 pMember->SetShowDetails(cppu::any2bool(aValue));
3419 else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3420 pMember->SetIsVisible(!cppu::any2bool(aValue));
3421 else if ( aPropertyName == SC_UNONAME_POS )
3423 sal_Int32 nNewPos = 0;
3424 if ( ( aValue >>= nNewPos ) && nNewPos >= 0 && nNewPos < nCount )
3426 pDim->SetMemberPosition( sName, nNewPos );
3427 // get new effective index (depends on sorting mode, which isn't modified)
3428 bGetNewIndex = true;
3430 else
3431 throw IllegalArgumentException();
3433 SetDPObject( pDPObj );
3435 if ( bGetNewIndex ) // after SetDPObject, get the new index
3437 OUString aOUName( sName );
3438 Sequence< OUString > aItemNames = xMembers->getElementNames();
3439 sal_Int32 nItemCount = aItemNames.getLength();
3440 for (sal_Int32 nItem=0; nItem<nItemCount; ++nItem)
3441 if (aItemNames[nItem] == aOUName)
3442 mnIndex = nItem;
3450 Any SAL_CALL ScDataPilotItemObj::getPropertyValue( const OUString& aPropertyName )
3451 throw (UnknownPropertyException, WrappedTargetException,
3452 RuntimeException, std::exception)
3454 SolarMutexGuard aGuard;
3455 Any aRet;
3456 if( ScDPSaveDimension* pDim = GetDPDimension() )
3458 Reference< XNameAccess > xMembers = GetMembers();
3459 if( xMembers.is() )
3461 Reference< XIndexAccess > xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3462 sal_Int32 nCount = xMembersIndex->getCount();
3463 if( mnIndex < nCount )
3465 Reference< XNamed > xMember( xMembersIndex->getByIndex( mnIndex ), UNO_QUERY );
3466 OUString sName( xMember->getName() );
3467 ScDPSaveMember* pMember = pDim->GetExistingMemberByName( sName );
3468 if ( aPropertyName == SC_UNONAME_SHOWDETAIL )
3470 if (pMember && pMember->HasShowDetails())
3472 aRet <<= (bool)pMember->GetShowDetails();
3474 else
3476 Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3477 if( xMemberProps.is() )
3478 aRet = xMemberProps->getPropertyValue( OUString( SC_UNO_DP_SHOWDETAILS ) );
3479 else
3480 aRet <<= true;
3483 else if ( aPropertyName == SC_UNONAME_ISHIDDEN )
3485 if (pMember && pMember->HasIsVisible())
3487 aRet <<= !pMember->GetIsVisible();
3489 else
3491 Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3492 if( xMemberProps.is() )
3493 aRet <<= !cppu::any2bool( xMemberProps->getPropertyValue( OUString( SC_UNO_DP_ISVISIBLE ) ) );
3494 else
3495 aRet <<= false;
3498 else if ( aPropertyName == SC_UNONAME_POS )
3500 aRet <<= mnIndex;
3505 return aRet;
3508 void SAL_CALL ScDataPilotItemObj::addPropertyChangeListener(
3509 const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* xListener */ )
3510 throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
3514 void SAL_CALL ScDataPilotItemObj::removePropertyChangeListener(
3515 const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* aListener */ )
3516 throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
3520 void SAL_CALL ScDataPilotItemObj::addVetoableChangeListener(
3521 const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3522 throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
3526 void SAL_CALL ScDataPilotItemObj::removeVetoableChangeListener(
3527 const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3528 throw(UnknownPropertyException, WrappedTargetException, RuntimeException, std::exception)
3532 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */