update dev300-m58
[ooovba.git] / sc / source / ui / unoobj / dapiuno.cxx
blob2039ea008000349084b65dbcb7cf57bdf0aafec3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dapiuno.cxx,v $
10 * $Revision: 1.21.30.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include <algorithm>
35 #include <svtools/smplhint.hxx>
36 #include <rtl/uuid.h>
38 #include "dapiuno.hxx"
39 #include "datauno.hxx"
40 #include "miscuno.hxx"
41 #include "convuno.hxx"
42 #include "docsh.hxx"
43 #include "tabvwsh.hxx"
44 #include "pivot.hxx"
45 #include "rangeutl.hxx"
46 #include "unoguard.hxx"
47 #include "dpobject.hxx"
48 #include "dpshttab.hxx"
49 #include "dpsave.hxx"
50 #include "dbdocfun.hxx"
51 #include "unonames.hxx"
52 #include "dpgroup.hxx"
53 #include "dpdimsave.hxx"
54 #include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
55 #include <com/sun/star/sheet/XLevelsSupplier.hpp>
56 #include <com/sun/star/sheet/XMembersSupplier.hpp>
57 #include <com/sun/star/beans/PropertyAttribute.hpp>
58 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
59 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
60 #include <com/sun/star/sheet/DataPilotOutputRangeType.hpp>
61 #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
63 #include <comphelper/extract.hxx>
64 #include <comphelper/sequence.hxx>
66 using namespace com::sun::star;
67 using namespace com::sun::star::sheet;
69 using ::rtl::OUString;
71 using ::com::sun::star::uno::Any;
72 using ::com::sun::star::uno::Exception;
73 using ::com::sun::star::uno::Reference;
74 using ::com::sun::star::uno::RuntimeException;
75 using ::com::sun::star::uno::Sequence;
76 using ::com::sun::star::uno::UNO_QUERY;
77 using ::com::sun::star::uno::UNO_QUERY_THROW;
79 using ::com::sun::star::container::ElementExistException;
80 using ::com::sun::star::container::NoSuchElementException;
81 using ::com::sun::star::container::XEnumeration;
82 using ::com::sun::star::container::XIndexAccess;
83 using ::com::sun::star::container::XNameAccess;
84 using ::com::sun::star::container::XNamed;
86 using ::com::sun::star::beans::PropertyVetoException;
87 using ::com::sun::star::beans::UnknownPropertyException;
88 using ::com::sun::star::beans::XPropertyChangeListener;
89 using ::com::sun::star::beans::XPropertySet;
90 using ::com::sun::star::beans::XPropertySetInfo;
91 using ::com::sun::star::beans::XVetoableChangeListener;
93 using ::com::sun::star::lang::IllegalArgumentException;
94 using ::com::sun::star::lang::IndexOutOfBoundsException;
95 using ::com::sun::star::lang::WrappedTargetException;
97 using ::com::sun::star::table::CellAddress;
98 using ::com::sun::star::table::CellRangeAddress;
100 // ============================================================================
102 namespace {
104 const SfxItemPropertyMapEntry* lcl_GetDataPilotDescriptorBaseMap()
106 static SfxItemPropertyMapEntry aDataPilotDescriptorBaseMap_Impl[] =
108 {MAP_CHAR_LEN(SC_UNO_COLGRAND), 0, &getBooleanCppuType(), 0, 0 },
109 {MAP_CHAR_LEN(SC_UNO_DRILLDOWN), 0, &getBooleanCppuType(), 0, 0 },
110 {MAP_CHAR_LEN(SC_UNO_IGNEMPROWS), 0, &getBooleanCppuType(), 0, 0 },
111 {MAP_CHAR_LEN(SC_UNO_RPTEMPTY), 0, &getBooleanCppuType(), 0, 0 },
112 {MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 },
113 {MAP_CHAR_LEN(SC_UNO_SHOWFILT), 0, &getBooleanCppuType(), 0, 0 },
114 {0,0,0,0,0,0}
116 return aDataPilotDescriptorBaseMap_Impl;
119 // ----------------------------------------------------------------------------
121 const SfxItemPropertyMapEntry* lcl_GetDataPilotFieldMap()
123 using namespace ::com::sun::star::beans::PropertyAttribute;
124 static SfxItemPropertyMapEntry aDataPilotFieldMap_Impl[] =
126 {MAP_CHAR_LEN(SC_UNONAME_AUTOSHOW), 0, &getCppuType((DataPilotFieldAutoShowInfo*)0), MAYBEVOID, 0 },
127 {MAP_CHAR_LEN(SC_UNONAME_FUNCTION), 0, &getCppuType((GeneralFunction*)0), 0, 0 },
128 {MAP_CHAR_LEN(SC_UNONAME_GROUPINFO), 0, &getCppuType((DataPilotFieldGroupInfo*)0), MAYBEVOID, 0 },
129 {MAP_CHAR_LEN(SC_UNONAME_HASAUTOSHOW), 0, &getBooleanCppuType(), 0, 0 },
130 {MAP_CHAR_LEN(SC_UNONAME_HASLAYOUTINFO),0, &getBooleanCppuType(), 0, 0 },
131 {MAP_CHAR_LEN(SC_UNONAME_HASREFERENCE), 0, &getBooleanCppuType(), 0, 0 },
132 {MAP_CHAR_LEN(SC_UNONAME_HASSORTINFO), 0, &getBooleanCppuType(), 0, 0 },
133 {MAP_CHAR_LEN(SC_UNONAME_ISGROUP), 0, &getBooleanCppuType(), 0, 0 },
134 {MAP_CHAR_LEN(SC_UNONAME_LAYOUTINFO), 0, &getCppuType((DataPilotFieldLayoutInfo*)0), MAYBEVOID, 0 },
135 {MAP_CHAR_LEN(SC_UNONAME_ORIENT), 0, &getCppuType((DataPilotFieldOrientation*)0), MAYBEVOID, 0 },
136 {MAP_CHAR_LEN(SC_UNONAME_REFERENCE), 0, &getCppuType((DataPilotFieldReference*)0), MAYBEVOID, 0 },
137 {MAP_CHAR_LEN(SC_UNONAME_SELPAGE), 0, &getCppuType((OUString*)0), 0, 0 },
138 {MAP_CHAR_LEN(SC_UNONAME_SHOWEMPTY), 0, &getBooleanCppuType(), 0, 0 },
139 {MAP_CHAR_LEN(SC_UNONAME_SORTINFO), 0, &getCppuType((DataPilotFieldSortInfo*)0), MAYBEVOID, 0 },
140 {MAP_CHAR_LEN(SC_UNONAME_SUBTOTALS), 0, &getCppuType((Sequence<GeneralFunction>*)0), 0, 0 },
141 {MAP_CHAR_LEN(SC_UNONAME_USESELPAGE), 0, &getBooleanCppuType(), 0, 0 },
142 {0,0,0,0,0,0}
144 return aDataPilotFieldMap_Impl;
147 // ----------------------------------------------------------------------------
149 const SfxItemPropertyMapEntry* lcl_GetDataPilotItemMap()
151 static SfxItemPropertyMapEntry aDataPilotItemMap_Impl[] =
153 {MAP_CHAR_LEN(SC_UNONAME_ISHIDDEN), 0, &getBooleanCppuType(), 0, 0 },
154 {MAP_CHAR_LEN(SC_UNONAME_POS), 0, &getCppuType((sal_Int32*)0), 0, 0 },
155 {MAP_CHAR_LEN(SC_UNONAME_SHOWDETAIL), 0, &getBooleanCppuType(), 0, 0 },
156 {0,0,0,0,0,0}
158 return aDataPilotItemMap_Impl;
161 // ----------------------------------------------------------------------------
163 inline bool lclCheckValidDouble( double fValue, sal_Bool bAuto )
165 return bAuto || ::rtl::math::isFinite( fValue );
168 bool lclCheckMinMaxStep( const DataPilotFieldGroupInfo& rInfo )
170 return
171 lclCheckValidDouble( rInfo.Start, rInfo.HasAutoStart ) &&
172 lclCheckValidDouble( rInfo.End, rInfo.HasAutoEnd ) &&
173 (rInfo.HasAutoStart || rInfo.HasAutoEnd || (rInfo.Start <= rInfo.End)) &&
174 lclCheckValidDouble( rInfo.Step, sal_False ) &&
175 (0.0 <= rInfo.Step);
178 } // namespace
180 // ============================================================================
182 SC_SIMPLE_SERVICE_INFO( ScDataPilotDescriptor, "ScDataPilotDescriptor", "stardiv::one::sheet::DataPilotDescriptor" )
183 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldObj, "ScDataPilotFieldObj", "com.sun.star.sheet.DataPilotField" )
184 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldsObj, "ScDataPilotFieldsObj", "com.sun.star.sheet.DataPilotFields" )
185 SC_SIMPLE_SERVICE_INFO( ScDataPilotTableObj, "ScDataPilotTableObj", "com.sun.star.sheet.DataPilotTable" )
186 SC_SIMPLE_SERVICE_INFO( ScDataPilotTablesObj, "ScDataPilotTablesObj", "com.sun.star.sheet.DataPilotTables" )
187 SC_SIMPLE_SERVICE_INFO( ScDataPilotItemsObj, "ScDataPilotItemsObj", "com.sun.star.sheet.DataPilotItems" )
188 SC_SIMPLE_SERVICE_INFO( ScDataPilotItemObj, "ScDataPilotItemObj", "com.sun.star.sheet.DataPilotItem" )
190 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupsObj, "ScDataPilotFieldGroupsObj", "com.sun.star.sheet.DataPilotFieldGroups" )
191 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupObj, "ScDataPilotFieldGroupObj", "com.sun.star.sheet.DataPilotFieldGroup" )
192 SC_SIMPLE_SERVICE_INFO( ScDataPilotFieldGroupItemObj, "ScDataPilotFieldGroupItemObj", "com.sun.star.sheet.DataPilotFieldGroupItem" )
194 //------------------------------------------------------------------------
196 // name that is used in the API for the data layout field
197 #define SC_DATALAYOUT_NAME "Data"
199 //------------------------------------------------------------------------
201 GeneralFunction ScDataPilotConversion::FirstFunc( USHORT nBits )
203 if ( nBits & PIVOT_FUNC_SUM ) return GeneralFunction_SUM;
204 if ( nBits & PIVOT_FUNC_COUNT ) return GeneralFunction_COUNT;
205 if ( nBits & PIVOT_FUNC_AVERAGE ) return GeneralFunction_AVERAGE;
206 if ( nBits & PIVOT_FUNC_MAX ) return GeneralFunction_MAX;
207 if ( nBits & PIVOT_FUNC_MIN ) return GeneralFunction_MIN;
208 if ( nBits & PIVOT_FUNC_PRODUCT ) return GeneralFunction_PRODUCT;
209 if ( nBits & PIVOT_FUNC_COUNT_NUM ) return GeneralFunction_COUNTNUMS;
210 if ( nBits & PIVOT_FUNC_STD_DEV ) return GeneralFunction_STDEV;
211 if ( nBits & PIVOT_FUNC_STD_DEVP ) return GeneralFunction_STDEVP;
212 if ( nBits & PIVOT_FUNC_STD_VAR ) return GeneralFunction_VAR;
213 if ( nBits & PIVOT_FUNC_STD_VARP ) return GeneralFunction_VARP;
214 if ( nBits & PIVOT_FUNC_AUTO ) return GeneralFunction_AUTO;
215 return GeneralFunction_NONE;
218 USHORT ScDataPilotConversion::FunctionBit( GeneralFunction eFunc )
220 USHORT nRet = PIVOT_FUNC_NONE; // 0
221 switch (eFunc)
223 case GeneralFunction_SUM: nRet = PIVOT_FUNC_SUM; break;
224 case GeneralFunction_COUNT: nRet = PIVOT_FUNC_COUNT; break;
225 case GeneralFunction_AVERAGE: nRet = PIVOT_FUNC_AVERAGE; break;
226 case GeneralFunction_MAX: nRet = PIVOT_FUNC_MAX; break;
227 case GeneralFunction_MIN: nRet = PIVOT_FUNC_MIN; break;
228 case GeneralFunction_PRODUCT: nRet = PIVOT_FUNC_PRODUCT; break;
229 case GeneralFunction_COUNTNUMS: nRet = PIVOT_FUNC_COUNT_NUM; break;
230 case GeneralFunction_STDEV: nRet = PIVOT_FUNC_STD_DEV; break;
231 case GeneralFunction_STDEVP: nRet = PIVOT_FUNC_STD_DEVP; break;
232 case GeneralFunction_VAR: nRet = PIVOT_FUNC_STD_VAR; break;
233 case GeneralFunction_VARP: nRet = PIVOT_FUNC_STD_VARP; break;
234 case GeneralFunction_AUTO: nRet = PIVOT_FUNC_AUTO; break;
235 default:
237 // added to avoid warnings
240 return nRet;
243 void ScDataPilotConversion::FillGroupInfo( DataPilotFieldGroupInfo& rInfo, const ScDPNumGroupInfo& rGroupInfo )
245 rInfo.HasDateValues = rGroupInfo.DateValues;
246 rInfo.HasAutoStart = rGroupInfo.AutoStart;
247 rInfo.Start = rGroupInfo.Start;
248 rInfo.HasAutoEnd = rGroupInfo.AutoEnd;
249 rInfo.End = rGroupInfo.End;
250 rInfo.Step = rGroupInfo.Step;
253 //------------------------------------------------------------------------
255 ScDPObject* lcl_GetDPObject( ScDocShell* pDocShell, SCTAB nTab, const String& rName )
257 if (pDocShell)
259 ScDocument* pDoc = pDocShell->GetDocument();
260 ScDPCollection* pColl = pDoc->GetDPCollection();
261 if ( pColl )
263 USHORT nCount = pColl->GetCount();
264 for (USHORT i=0; i<nCount; i++)
266 ScDPObject* pDPObj = (*pColl)[i];
267 if ( pDPObj->IsSheetData() &&
268 pDPObj->GetOutRange().aStart.Tab() == nTab &&
269 pDPObj->GetName() == rName )
270 return pDPObj;
274 return NULL; // nicht gefunden
277 String lcl_CreatePivotName( ScDocShell* pDocShell )
279 if (pDocShell)
281 ScDocument* pDoc = pDocShell->GetDocument();
282 ScDPCollection* pColl = pDoc->GetDPCollection();
283 if ( pColl )
284 return pColl->CreateNewName();
286 return String(); // sollte nicht vorkommen
289 sal_Int32 lcl_GetObjectIndex( ScDPObject* pDPObj, const ScFieldIdentifier& rFieldId )
291 // used for items - nRepeat in identifier can be ignored
292 if ( pDPObj )
294 sal_Int32 nCount = pDPObj->GetDimCount();
295 for ( sal_Int32 nDim = 0; nDim < nCount; ++nDim )
297 BOOL bIsDataLayout = FALSE;
298 OUString aDimName( pDPObj->GetDimName( nDim, bIsDataLayout ) );
299 if ( rFieldId.mbDataLayout ? bIsDataLayout : (aDimName == rFieldId.maFieldName) )
300 return nDim;
303 return -1; // none
306 //------------------------------------------------------------------------
308 ScDataPilotTablesObj::ScDataPilotTablesObj(ScDocShell* pDocSh, SCTAB nT) :
309 pDocShell( pDocSh ),
310 nTab( nT )
312 pDocShell->GetDocument()->AddUnoObject(*this);
315 ScDataPilotTablesObj::~ScDataPilotTablesObj()
317 if (pDocShell)
318 pDocShell->GetDocument()->RemoveUnoObject(*this);
321 void ScDataPilotTablesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
323 //! Referenz-Update
325 if ( rHint.ISA( SfxSimpleHint ) &&
326 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
328 pDocShell = NULL; // ungueltig geworden
332 // XDataPilotTables
334 ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByIndex_Impl( sal_Int32 nIndex )
336 if (pDocShell)
338 ScDocument* pDoc = pDocShell->GetDocument();
339 ScDPCollection* pColl = pDoc->GetDPCollection();
340 if ( pColl )
342 // count tables on this sheet
343 // api only handles sheet data at this time
344 //! allow all data sources!!!
345 sal_Int32 nFound = 0;
346 USHORT nCount = pColl->GetCount();
347 for (USHORT i=0; i<nCount; i++)
349 ScDPObject* pDPObj = (*pColl)[i];
350 if ( pDPObj->IsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab )
352 if ( nFound == nIndex )
354 String aName = pDPObj->GetName();
355 return new ScDataPilotTableObj( pDocShell, nTab, aName );
357 ++nFound;
362 return NULL;
365 ScDataPilotTableObj* ScDataPilotTablesObj::GetObjectByName_Impl(const OUString& rName)
367 if (hasByName(rName))
368 return new ScDataPilotTableObj( pDocShell, nTab, rName );
369 return 0;
372 Reference<XDataPilotDescriptor> SAL_CALL ScDataPilotTablesObj::createDataPilotDescriptor()
373 throw(RuntimeException)
375 ScUnoGuard aGuard;
376 if (pDocShell)
377 return new ScDataPilotDescriptor(pDocShell);
378 return NULL;
381 bool lcl_IsDuplicated( const Reference<XPropertySet> xDimProps )
385 Any aAny = xDimProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ORIGINAL ) ) );
386 Reference< XNamed > xOriginal( aAny, UNO_QUERY );
387 return xOriginal.is();
389 catch( Exception& )
392 return false;
395 OUString lcl_GetOriginalName( const Reference< XNamed > xDim )
397 Reference< XNamed > xOriginal;
399 Reference< XPropertySet > xDimProps( xDim, UNO_QUERY );
400 if ( xDimProps.is() )
404 Any aAny = xDimProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ORIGINAL)));
405 aAny >>= xOriginal;
407 catch( Exception& )
412 if ( !xOriginal.is() )
413 xOriginal = xDim;
415 return xOriginal->getName();
418 void SAL_CALL ScDataPilotTablesObj::insertNewByName( const OUString& aNewName,
419 const CellAddress& aOutputAddress,
420 const Reference<XDataPilotDescriptor>& xDescriptor )
421 throw(RuntimeException)
423 ScUnoGuard aGuard;
424 if (!xDescriptor.is()) return;
426 // inserting with already existing name?
427 if ( aNewName.getLength() && hasByName( aNewName ) )
428 throw RuntimeException(); // no other exceptions specified
430 BOOL bDone = FALSE;
431 ScDataPilotDescriptorBase* pImp = ScDataPilotDescriptorBase::getImplementation( xDescriptor );
432 if ( pDocShell && pImp )
434 ScDPObject* pNewObj = pImp->GetDPObject();
436 if (pNewObj)
438 ScRange aOutputRange((SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet,
439 (SCCOL)aOutputAddress.Column, (SCROW)aOutputAddress.Row, (SCTAB)aOutputAddress.Sheet);
440 pNewObj->SetOutRange(aOutputRange);
441 String aName = aNewName;
442 if (!aName.Len())
443 aName = lcl_CreatePivotName( pDocShell );
444 pNewObj->SetName(aName);
445 String aTag = xDescriptor->getTag();
446 pNewObj->SetTag(aTag);
448 // todo: handle double fields (for more information see ScDPObject
450 ScDBDocFunc aFunc(*pDocShell);
451 bDone = aFunc.DataPilotUpdate( NULL, pNewObj, TRUE, TRUE );
455 if (!bDone)
456 throw RuntimeException(); // no other exceptions specified
459 void SAL_CALL ScDataPilotTablesObj::removeByName( const OUString& aName )
460 throw(RuntimeException)
462 ScUnoGuard aGuard;
463 String aNameStr(aName);
464 ScDPObject* pDPObj = lcl_GetDPObject( pDocShell, nTab, aNameStr );
465 if (pDPObj && pDocShell)
467 ScDBDocFunc aFunc(*pDocShell);
468 aFunc.DataPilotUpdate( pDPObj, NULL, TRUE, TRUE ); // remove - incl. undo etc.
470 else
471 throw RuntimeException(); // no other exceptions specified
474 // XEnumerationAccess
476 Reference< XEnumeration > SAL_CALL ScDataPilotTablesObj::createEnumeration() throw(RuntimeException)
478 ScUnoGuard aGuard;
479 return new ScIndexEnumeration(this, OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DataPilotTablesEnumeration")));
482 // XIndexAccess
484 sal_Int32 SAL_CALL ScDataPilotTablesObj::getCount() throw(RuntimeException)
486 ScUnoGuard aGuard;
487 if ( pDocShell )
489 ScDocument* pDoc = pDocShell->GetDocument();
490 ScDPCollection* pColl = pDoc->GetDPCollection();
491 if ( pColl )
493 // count tables on this sheet
494 // api only handles sheet data at this time
495 //! allow all data sources!!!
497 USHORT nFound = 0;
498 USHORT nCount = pColl->GetCount();
499 for (USHORT i=0; i<nCount; i++)
501 ScDPObject* pDPObj = (*pColl)[i];
502 if ( pDPObj->IsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab )
503 ++nFound;
505 return nFound;
509 return 0;
512 Any SAL_CALL ScDataPilotTablesObj::getByIndex( sal_Int32 nIndex )
513 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
515 ScUnoGuard aGuard;
516 Reference<XDataPilotTable2> xTable(GetObjectByIndex_Impl(nIndex));
517 if (!xTable.is())
518 throw IndexOutOfBoundsException();
519 return Any( xTable );
522 uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(RuntimeException)
524 ScUnoGuard aGuard;
525 return getCppuType((Reference<XDataPilotTable2>*)0);
528 sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(RuntimeException)
530 ScUnoGuard aGuard;
531 return ( getCount() != 0 );
534 // XNameAccess
536 Any SAL_CALL ScDataPilotTablesObj::getByName( const OUString& aName )
537 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
539 ScUnoGuard aGuard;
540 Reference<XDataPilotTable2> xTable(GetObjectByName_Impl(aName));
541 if (!xTable.is())
542 throw NoSuchElementException();
543 return Any( xTable );
546 Sequence<OUString> SAL_CALL ScDataPilotTablesObj::getElementNames()
547 throw(RuntimeException)
549 ScUnoGuard aGuard;
550 if (pDocShell)
552 ScDocument* pDoc = pDocShell->GetDocument();
553 ScDPCollection* pColl = pDoc->GetDPCollection();
554 if ( pColl )
556 // count tables on this sheet
557 // api only handles sheet data at this time
558 //! allow all data sources!!!
560 USHORT nFound = 0;
561 USHORT nCount = pColl->GetCount();
562 USHORT i;
563 for (i=0; i<nCount; i++)
565 ScDPObject* pDPObj = (*pColl)[i];
566 if ( pDPObj->IsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab )
567 ++nFound;
570 USHORT nPos = 0;
571 Sequence<OUString> aSeq(nFound);
572 OUString* pAry = aSeq.getArray();
573 for (i=0; i<nCount; i++)
575 ScDPObject* pDPObj = (*pColl)[i];
576 if ( pDPObj->IsSheetData() && pDPObj->GetOutRange().aStart.Tab() == nTab )
577 pAry[nPos++] = pDPObj->GetName();
580 return aSeq;
583 return Sequence<OUString>(0);
586 sal_Bool SAL_CALL ScDataPilotTablesObj::hasByName( const OUString& aName )
587 throw(RuntimeException)
589 ScUnoGuard aGuard;
590 if (pDocShell)
592 ScDocument* pDoc = pDocShell->GetDocument();
593 ScDPCollection* pColl = pDoc->GetDPCollection();
594 if ( pColl )
596 String aNamStr(aName);
597 USHORT nCount = pColl->GetCount();
598 for (USHORT i=0; i<nCount; i++)
600 // api only handles sheet data at this time
601 //! allow all data sources!!!
603 ScDPObject* pDPObj = (*pColl)[i];
604 if ( pDPObj->IsSheetData() &&
605 pDPObj->GetOutRange().aStart.Tab() == nTab &&
606 pDPObj->GetName() == aNamStr )
607 return TRUE;
611 return FALSE;
614 //------------------------------------------------------------------------
616 ScDataPilotDescriptorBase::ScDataPilotDescriptorBase(ScDocShell* pDocSh) :
617 maPropSet( lcl_GetDataPilotDescriptorBaseMap() ),
618 pDocShell( pDocSh )
620 pDocShell->GetDocument()->AddUnoObject(*this);
623 ScDataPilotDescriptorBase::~ScDataPilotDescriptorBase()
625 if (pDocShell)
626 pDocShell->GetDocument()->RemoveUnoObject(*this);
629 Any SAL_CALL ScDataPilotDescriptorBase::queryInterface( const uno::Type& rType )
630 throw(RuntimeException)
632 SC_QUERYINTERFACE( XDataPilotDescriptor )
633 SC_QUERYINTERFACE( XPropertySet )
634 SC_QUERYINTERFACE( XDataPilotDataLayoutFieldSupplier )
635 SC_QUERYINTERFACE( XNamed ) // base of XDataPilotDescriptor
636 SC_QUERYINTERFACE( lang::XUnoTunnel )
637 SC_QUERYINTERFACE( lang::XTypeProvider )
638 SC_QUERYINTERFACE( lang::XServiceInfo )
640 return OWeakObject::queryInterface( rType );
643 void SAL_CALL ScDataPilotDescriptorBase::acquire() throw()
645 OWeakObject::acquire();
648 void SAL_CALL ScDataPilotDescriptorBase::release() throw()
650 OWeakObject::release();
653 Sequence< uno::Type > SAL_CALL ScDataPilotDescriptorBase::getTypes()
654 throw(RuntimeException)
656 static Sequence< uno::Type > aTypes;
657 if ( aTypes.getLength() == 0 )
659 aTypes.realloc( 6 );
660 uno::Type* pPtr = aTypes.getArray();
661 pPtr[ 0 ] = getCppuType( (const Reference< XDataPilotDescriptor >*)0 );
662 pPtr[ 1 ] = getCppuType( (const Reference< XPropertySet >*)0 );
663 pPtr[ 2 ] = getCppuType( (const Reference< XDataPilotDataLayoutFieldSupplier >*)0 );
664 pPtr[ 3 ] = getCppuType( (const Reference< lang::XUnoTunnel >*)0 );
665 pPtr[ 4 ] = getCppuType( (const Reference< lang::XTypeProvider >*)0 );
666 pPtr[ 5 ] = getCppuType( (const Reference< lang::XServiceInfo >*)0 );
668 return aTypes;
671 Sequence<sal_Int8> SAL_CALL ScDataPilotDescriptorBase::getImplementationId()
672 throw(RuntimeException)
674 static Sequence< sal_Int8 > aId;
675 if( aId.getLength() == 0 )
677 aId.realloc( 16 );
678 rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
680 return aId;
683 void ScDataPilotDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
685 //! Referenz-Update?
687 if ( rHint.ISA( SfxSimpleHint ) &&
688 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
690 pDocShell = NULL; // ungueltig geworden
694 // XDataPilotDescriptor
696 CellRangeAddress SAL_CALL ScDataPilotDescriptorBase::getSourceRange()
697 throw(RuntimeException)
699 ScUnoGuard aGuard;
701 ScDPObject* pDPObject(GetDPObject());
702 if (!pDPObject || !pDPObject->IsSheetData())
703 throw RuntimeException();
705 CellRangeAddress aRet;
706 ScUnoConversion::FillApiRange( aRet, pDPObject->GetSheetDesc()->aSourceRange );
707 return aRet;
710 void SAL_CALL ScDataPilotDescriptorBase::setSourceRange( const CellRangeAddress& aSourceRange ) throw(RuntimeException)
712 ScUnoGuard aGuard;
714 ScDPObject* pDPObject = GetDPObject();
715 if (!pDPObject)
716 throw RuntimeException();
718 ScSheetSourceDesc aSheetDesc;
719 if (pDPObject->IsSheetData())
720 aSheetDesc = *pDPObject->GetSheetDesc();
721 ScUnoConversion::FillScRange( aSheetDesc.aSourceRange, aSourceRange );
722 pDPObject->SetSheetDesc( aSheetDesc );
723 SetDPObject( pDPObject );
726 Reference<XSheetFilterDescriptor> SAL_CALL ScDataPilotDescriptorBase::getFilterDescriptor()
727 throw(RuntimeException)
729 ScUnoGuard aGuard;
730 return new ScDataPilotFilterDescriptor( pDocShell, this );
733 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataPilotFields()
734 throw(RuntimeException)
736 ScUnoGuard aGuard;
737 return new ScDataPilotFieldsObj( *this );
740 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getColumnFields()
741 throw(RuntimeException)
743 ScUnoGuard aGuard;
744 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_COLUMN );
747 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getRowFields()
748 throw(RuntimeException)
750 ScUnoGuard aGuard;
751 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_ROW );
754 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getPageFields()
755 throw(RuntimeException)
757 ScUnoGuard aGuard;
758 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_PAGE );
761 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getDataFields()
762 throw(RuntimeException)
764 ScUnoGuard aGuard;
765 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_DATA );
768 Reference<XIndexAccess> SAL_CALL ScDataPilotDescriptorBase::getHiddenFields()
769 throw(RuntimeException)
771 ScUnoGuard aGuard;
772 return new ScDataPilotFieldsObj( *this, DataPilotFieldOrientation_HIDDEN );
775 // XPropertySet
776 Reference< XPropertySetInfo > SAL_CALL ScDataPilotDescriptorBase::getPropertySetInfo( )
777 throw(RuntimeException)
779 ScUnoGuard aGuard;
780 static Reference<XPropertySetInfo> aRef =
781 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
782 return aRef;
785 void SAL_CALL ScDataPilotDescriptorBase::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
786 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException,
787 WrappedTargetException, RuntimeException)
789 ScUnoGuard aGuard;
790 ScDPObject* pDPObject = GetDPObject();
791 if (pDPObject)
793 ScDPSaveData* pOldData = pDPObject->GetSaveData();
794 DBG_ASSERT(pOldData, "Here should be a SaveData");
795 if ( pOldData )
797 ScDPSaveData aNewData( *pOldData );
799 String aNameString = aPropertyName;
800 if ( aNameString.EqualsAscii( SC_UNO_COLGRAND ) )
802 aNewData.SetColumnGrand(::cppu::any2bool( aValue ));
804 else if ( aNameString.EqualsAscii( SC_UNO_IGNEMPROWS ) )
806 aNewData.SetIgnoreEmptyRows(::cppu::any2bool( aValue ));
808 else if ( aNameString.EqualsAscii( SC_UNO_RPTEMPTY ) )
810 aNewData.SetRepeatIfEmpty(::cppu::any2bool( aValue ));
812 else if ( aNameString.EqualsAscii( SC_UNO_ROWGRAND ) )
814 aNewData.SetRowGrand(::cppu::any2bool( aValue ));
816 else if ( aNameString.EqualsAscii( SC_UNO_SHOWFILT ) )
818 aNewData.SetFilterButton(::cppu::any2bool( aValue ));
820 else if ( aNameString.EqualsAscii( SC_UNO_DRILLDOWN ) )
822 aNewData.SetDrillDown(::cppu::any2bool( aValue ));
824 else
825 throw UnknownPropertyException();
827 pDPObject->SetSaveData( aNewData );
830 SetDPObject(pDPObject);
834 Any SAL_CALL ScDataPilotDescriptorBase::getPropertyValue( const OUString& aPropertyName )
835 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
837 ScUnoGuard aGuard;
838 Any aRet;
840 ScDPObject* pDPObject(GetDPObject());
841 if (pDPObject)
843 ScDPSaveData* pOldData = pDPObject->GetSaveData();
844 DBG_ASSERT(pOldData, "Here should be a SaveData");
845 if ( pOldData )
847 ScDPSaveData aNewData( *pOldData );
849 String aNameString = aPropertyName;
850 if ( aNameString.EqualsAscii( SC_UNO_COLGRAND ) )
852 aRet = ::cppu::bool2any( aNewData.GetColumnGrand() );
854 else if ( aNameString.EqualsAscii( SC_UNO_IGNEMPROWS ) )
856 aRet = ::cppu::bool2any( aNewData.GetIgnoreEmptyRows() );
858 else if ( aNameString.EqualsAscii( SC_UNO_RPTEMPTY ) )
860 aRet = ::cppu::bool2any( aNewData.GetRepeatIfEmpty() );
862 else if ( aNameString.EqualsAscii( SC_UNO_ROWGRAND ) )
864 aRet = ::cppu::bool2any( aNewData.GetRowGrand() );
866 else if ( aNameString.EqualsAscii( SC_UNO_SHOWFILT ) )
868 aRet = ::cppu::bool2any( aNewData.GetFilterButton() );
870 else if ( aNameString.EqualsAscii( SC_UNO_DRILLDOWN ) )
872 aRet = ::cppu::bool2any( aNewData.GetDrillDown() );
874 else
875 throw UnknownPropertyException();
879 return aRet;
882 void SAL_CALL ScDataPilotDescriptorBase::addPropertyChangeListener(
883 const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* xListener */ )
884 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
888 void SAL_CALL ScDataPilotDescriptorBase::removePropertyChangeListener(
889 const OUString& /* aPropertyName */, const Reference<XPropertyChangeListener >& /* aListener */ )
890 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
894 void SAL_CALL ScDataPilotDescriptorBase::addVetoableChangeListener(
895 const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
896 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
900 void SAL_CALL ScDataPilotDescriptorBase::removeVetoableChangeListener(
901 const OUString& /* PropertyName */, const Reference<XVetoableChangeListener >& /* aListener */ )
902 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
906 // XDataPilotDataLayoutFieldSupplier
908 Reference< XDataPilotField > SAL_CALL ScDataPilotDescriptorBase::getDataLayoutField() throw(RuntimeException)
910 ScUnoGuard aGuard;
911 if( ScDPObject* pDPObject = GetDPObject() )
913 if( ScDPSaveData* pSaveData = pDPObject->GetSaveData() )
915 if( /*ScDPSaveDimension* pDataDim =*/ pSaveData->GetDataLayoutDimension() )
917 ScFieldIdentifier aFieldId( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_DATALAYOUT_NAME ) ), 0, true );
918 return new ScDataPilotFieldObj( *this, aFieldId );
922 return 0;
925 // XUnoTunnel
927 sal_Int64 SAL_CALL ScDataPilotDescriptorBase::getSomething(
928 const Sequence<sal_Int8 >& rId ) throw(RuntimeException)
930 if ( rId.getLength() == 16 &&
931 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
932 rId.getConstArray(), 16 ) )
934 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
936 return 0;
939 // static
940 const Sequence<sal_Int8>& ScDataPilotDescriptorBase::getUnoTunnelId()
942 static Sequence<sal_Int8> * pSeq = 0;
943 if( !pSeq )
945 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
946 if( !pSeq )
948 static Sequence< sal_Int8 > aSeq( 16 );
949 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
950 pSeq = &aSeq;
953 return *pSeq;
956 // static
957 ScDataPilotDescriptorBase* ScDataPilotDescriptorBase::getImplementation(
958 const Reference<XDataPilotDescriptor> xObj )
960 ScDataPilotDescriptorBase* pRet = NULL;
961 Reference<lang::XUnoTunnel> xUT( xObj, UNO_QUERY );
962 if (xUT.is())
963 pRet = reinterpret_cast<ScDataPilotDescriptorBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
964 return pRet;
967 //------------------------------------------------------------------------
969 ScDataPilotTableObj::ScDataPilotTableObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) :
970 ScDataPilotDescriptorBase( pDocSh ),
971 nTab( nT ),
972 aName( rN )
976 ScDataPilotTableObj::~ScDataPilotTableObj()
980 Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType )
981 throw(RuntimeException)
983 // since we manually do resolve the query for XDataPilotTable2
984 // we also need to do the same for XDataPilotTable
985 SC_QUERYINTERFACE( XDataPilotTable )
986 SC_QUERYINTERFACE( XDataPilotTable2 )
988 return ScDataPilotDescriptorBase::queryInterface( rType );
991 void SAL_CALL ScDataPilotTableObj::acquire() throw()
993 ScDataPilotDescriptorBase::acquire();
996 void SAL_CALL ScDataPilotTableObj::release() throw()
998 ScDataPilotDescriptorBase::release();
1001 Sequence< uno::Type > SAL_CALL ScDataPilotTableObj::getTypes() throw(RuntimeException)
1003 static Sequence< uno::Type > aTypes;
1004 if ( aTypes.getLength() == 0 )
1006 Sequence< uno::Type > aParentTypes = ScDataPilotDescriptorBase::getTypes();
1007 sal_Int32 nParentLen = aParentTypes.getLength();
1008 const uno::Type* pParentPtr = aParentTypes.getConstArray();
1010 aTypes.realloc( nParentLen + 1 );
1011 uno::Type* pPtr = aTypes.getArray();
1012 for (sal_Int32 i = 0; i < nParentLen; ++i)
1013 pPtr[ i ] = pParentPtr[ i ]; // parent types first
1015 pPtr[ nParentLen ] = getCppuType( (const Reference< XDataPilotTable2 >*)0 );
1017 return aTypes;
1020 Sequence<sal_Int8> SAL_CALL ScDataPilotTableObj::getImplementationId()
1021 throw(RuntimeException)
1023 static Sequence< sal_Int8 > aId;
1024 if( aId.getLength() == 0 )
1026 aId.realloc( 16 );
1027 rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
1029 return aId;
1032 // ---
1033 ScDPObject* ScDataPilotTableObj::GetDPObject() const
1035 return lcl_GetDPObject(GetDocShell(), nTab, aName);
1038 void ScDataPilotTableObj::SetDPObject( ScDPObject* pDPObject )
1040 ScDocShell* pDocSh = GetDocShell();
1041 ScDPObject* pDPObj = lcl_GetDPObject(pDocSh, nTab, aName);
1042 if ( pDPObj && pDocSh )
1044 ScDBDocFunc aFunc(*pDocSh);
1045 aFunc.DataPilotUpdate( pDPObj, pDPObject, TRUE, TRUE );
1049 // "rest of XDataPilotDescriptor"
1051 OUString SAL_CALL ScDataPilotTableObj::getName() throw(RuntimeException)
1053 ScUnoGuard aGuard;
1054 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1055 if (pDPObj)
1056 return pDPObj->GetName();
1057 return OUString();
1060 void SAL_CALL ScDataPilotTableObj::setName( const OUString& aNewName )
1061 throw(RuntimeException)
1063 ScUnoGuard aGuard;
1064 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1065 if (pDPObj)
1067 //! test for existing names !!!
1069 String aString(aNewName);
1070 pDPObj->SetName( aString ); //! Undo - DBDocFunc ???
1071 aName = aString;
1073 // DataPilotUpdate would do too much (output table is not changed)
1074 GetDocShell()->SetDocumentModified();
1078 OUString SAL_CALL ScDataPilotTableObj::getTag() throw(RuntimeException)
1080 ScUnoGuard aGuard;
1081 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1082 if (pDPObj)
1083 return pDPObj->GetTag();
1084 return OUString();
1087 void SAL_CALL ScDataPilotTableObj::setTag( const OUString& aNewTag )
1088 throw(RuntimeException)
1090 ScUnoGuard aGuard;
1091 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1092 if (pDPObj)
1094 String aString(aNewTag);
1095 pDPObj->SetTag( aString ); //! Undo - DBDocFunc ???
1097 // DataPilotUpdate would do too much (output table is not changed)
1098 GetDocShell()->SetDocumentModified();
1102 // XDataPilotTable
1104 CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeException)
1106 ScUnoGuard aGuard;
1107 CellRangeAddress aRet;
1108 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1109 if (pDPObj)
1111 ScRange aRange(pDPObj->GetOutRange());
1112 aRet.Sheet = aRange.aStart.Tab();
1113 aRet.StartColumn = aRange.aStart.Col();
1114 aRet.StartRow = aRange.aStart.Row();
1115 aRet.EndColumn = aRange.aEnd.Col();
1116 aRet.EndRow = aRange.aEnd.Row();
1118 return aRet;
1121 void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException)
1123 ScUnoGuard aGuard;
1124 ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
1125 if (pDPObj)
1127 ScDPObject* pNew = new ScDPObject(*pDPObj);
1128 ScDBDocFunc aFunc(*GetDocShell());
1129 aFunc.DataPilotUpdate( pDPObj, pNew, TRUE, TRUE );
1130 delete pNew; // DataPilotUpdate copies settings from "new" object
1134 Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr)
1135 throw (RuntimeException)
1137 ScUnoGuard aGuard;
1138 Sequence< Sequence<Any> > aTabData;
1139 ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1140 ScDPObject* pObj = GetDPObject();
1141 if (!pObj)
1142 throw RuntimeException();
1144 pObj->GetDrillDownData(aAddr2, aTabData);
1145 return aTabData;
1148 DataPilotTablePositionData SAL_CALL ScDataPilotTableObj::getPositionData(const CellAddress& aAddr)
1149 throw (RuntimeException)
1151 ScUnoGuard aGuard;
1152 DataPilotTablePositionData aPosData;
1153 ScAddress aAddr2(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet);
1154 ScDPObject* pObj = GetDPObject();
1155 if (!pObj)
1156 throw RuntimeException();
1158 pObj->GetPositionData(aAddr2, aPosData);
1159 return aPosData;
1162 void SAL_CALL ScDataPilotTableObj::insertDrillDownSheet(const CellAddress& aAddr)
1163 throw (RuntimeException)
1165 ScUnoGuard aGuard;
1166 ScDPObject* pDPObj = GetDPObject();
1167 if (!pDPObj)
1168 throw RuntimeException();
1170 Sequence<DataPilotFieldFilter> aFilters;
1171 pDPObj->GetDataFieldPositionData(
1172 ScAddress(static_cast<SCCOL>(aAddr.Column), static_cast<SCROW>(aAddr.Row), aAddr.Sheet), aFilters);
1173 GetDocShell()->GetBestViewShell()->ShowDataPilotSourceData(*pDPObj, aFilters);
1176 CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
1177 throw (IllegalArgumentException, RuntimeException)
1179 ScUnoGuard aGuard;
1180 if (nType < 0 || nType > DataPilotOutputRangeType::RESULT)
1181 throw IllegalArgumentException();
1183 CellRangeAddress aRet;
1184 if (ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName))
1185 ScUnoConversion::FillApiRange( aRet, pDPObj->GetOutputRangeByType( nType ) );
1186 return aRet;
1189 // ============================================================================
1191 ScDataPilotDescriptor::ScDataPilotDescriptor(ScDocShell* pDocSh) :
1192 ScDataPilotDescriptorBase( pDocSh ),
1193 mpDPObject(new ScDPObject(pDocSh ? pDocSh->GetDocument() : NULL) )
1195 mpDPObject->SetAlive(sal_True);
1196 ScDPSaveData aSaveData;
1197 // set defaults like in ScPivotParam constructor
1198 aSaveData.SetColumnGrand( sal_True );
1199 aSaveData.SetRowGrand( sal_True );
1200 aSaveData.SetIgnoreEmptyRows( sal_False );
1201 aSaveData.SetRepeatIfEmpty( sal_False );
1202 mpDPObject->SetSaveData(aSaveData);
1203 ScSheetSourceDesc aSheetDesc;
1204 mpDPObject->SetSheetDesc(aSheetDesc);
1205 mpDPObject->GetSource();
1208 ScDataPilotDescriptor::~ScDataPilotDescriptor()
1210 delete mpDPObject;
1213 ScDPObject* ScDataPilotDescriptor::GetDPObject() const
1215 return mpDPObject;
1218 void ScDataPilotDescriptor::SetDPObject( ScDPObject* pDPObject )
1220 if (mpDPObject != pDPObject)
1222 delete mpDPObject;
1223 mpDPObject = pDPObject;
1224 DBG_ERROR("replace DPObject should not happen");
1228 // "rest of XDataPilotDescriptor"
1230 OUString SAL_CALL ScDataPilotDescriptor::getName() throw(RuntimeException)
1232 ScUnoGuard aGuard;
1233 return mpDPObject->GetName();
1236 void SAL_CALL ScDataPilotDescriptor::setName( const OUString& aNewName )
1237 throw(RuntimeException)
1239 ScUnoGuard aGuard;
1240 mpDPObject->SetName( aNewName );
1243 OUString SAL_CALL ScDataPilotDescriptor::getTag() throw(RuntimeException)
1245 ScUnoGuard aGuard;
1246 return mpDPObject->GetTag();
1249 void SAL_CALL ScDataPilotDescriptor::setTag( const OUString& aNewTag )
1250 throw(RuntimeException)
1252 ScUnoGuard aGuard;
1253 mpDPObject->SetTag( aNewTag );
1256 // ============================================================================
1258 ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent ) :
1259 mrParent( rParent )
1261 mrParent.acquire();
1264 ScDataPilotChildObjBase::ScDataPilotChildObjBase( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1265 mrParent( rParent ),
1266 maFieldId( rFieldId )
1268 mrParent.acquire();
1271 ScDataPilotChildObjBase::~ScDataPilotChildObjBase()
1273 mrParent.release();
1276 ScDPObject* ScDataPilotChildObjBase::GetDPObject() const
1278 return mrParent.GetDPObject();
1281 void ScDataPilotChildObjBase::SetDPObject( ScDPObject* pDPObject )
1283 mrParent.SetDPObject( pDPObject );
1286 ScDPSaveDimension* ScDataPilotChildObjBase::GetDPDimension( ScDPObject** ppDPObject ) const
1288 if( ScDPObject* pDPObj = GetDPObject() )
1290 if( ppDPObject ) *ppDPObject = pDPObj;
1291 if( ScDPSaveData* pSaveData = pDPObj->GetSaveData() )
1293 if( maFieldId.mbDataLayout )
1294 return pSaveData->GetDataLayoutDimension();
1296 if( maFieldId.mnFieldIdx == 0 )
1297 return pSaveData->GetDimensionByName( maFieldId.maFieldName );
1299 // find dimension with specified index (search in duplicated dimensions)
1300 String aFieldName = maFieldId.maFieldName; // needed for comparison
1301 const List& rDimensions = pSaveData->GetDimensions();
1302 ULONG nDimCount = rDimensions.Count();
1303 sal_Int32 nFoundIdx = 0;
1304 for( ULONG nDim = 0; nDim < nDimCount; ++nDim )
1306 ScDPSaveDimension* pDim = static_cast< ScDPSaveDimension* >( rDimensions.GetObject( nDim ) );
1307 if( !pDim->IsDataLayout() && (pDim->GetName() == aFieldName) )
1309 if( nFoundIdx == maFieldId.mnFieldIdx )
1310 return pDim;
1311 ++nFoundIdx;
1316 return 0;
1319 sal_Int32 ScDataPilotChildObjBase::GetMemberCount() const
1321 sal_Int32 nRet = 0;
1322 Reference<XNameAccess> xMembersNA = GetMembers();
1323 if (xMembersNA.is())
1325 Reference< XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
1326 nRet = xMembersIA->getCount();
1328 return nRet;
1331 Reference< XNameAccess > ScDataPilotChildObjBase::GetMembers() const
1333 Reference< XNameAccess > xMembersNA;
1334 if( ScDPObject* pDPObj = GetDPObject() )
1335 pDPObj->GetMembersNA( lcl_GetObjectIndex( pDPObj, maFieldId ), xMembersNA );
1336 return xMembersNA;
1339 // ============================================================================
1341 ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent ) :
1342 ScDataPilotChildObjBase( rParent )
1346 ScDataPilotFieldsObj::ScDataPilotFieldsObj( ScDataPilotDescriptorBase& rParent, DataPilotFieldOrientation eOrient ) :
1347 ScDataPilotChildObjBase( rParent ),
1348 maOrient( eOrient )
1352 ScDataPilotFieldsObj::~ScDataPilotFieldsObj()
1356 sal_Int32 lcl_GetFieldCount( const Reference<XDimensionsSupplier>& rSource, const Any& rOrient )
1358 sal_Int32 nRet = 0;
1360 Reference<XNameAccess> xDimsName(rSource->getDimensions());
1361 Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1362 sal_Int32 nIntCount = xIntDims->getCount();
1363 if (rOrient.hasValue())
1365 // all fields of the specified orientation, including duplicated
1366 Reference<XPropertySet> xDim;
1367 for (sal_Int32 i = 0; i < nIntCount; ++i)
1369 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1370 if (xDim.is() && (xDim->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ORIENTAT))) == rOrient))
1371 ++nRet;
1374 else
1376 // count all non-duplicated fields
1378 Reference<XPropertySet> xDim;
1379 for (sal_Int32 i = 0; i < nIntCount; ++i)
1381 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1382 if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1383 ++nRet;
1387 return nRet;
1390 BOOL lcl_GetFieldDataByIndex( const Reference<XDimensionsSupplier>& rSource,
1391 const Any& rOrient, SCSIZE nIndex, ScFieldIdentifier& rFieldId )
1393 BOOL bOk = FALSE;
1394 SCSIZE nPos = 0;
1395 sal_Int32 nDimIndex = 0;
1397 Reference<XNameAccess> xDimsName(rSource->getDimensions());
1398 Reference<XIndexAccess> xIntDims(new ScNameToIndexAccess( xDimsName ));
1399 sal_Int32 nIntCount = xIntDims->getCount();
1400 Reference<XPropertySet> xDim;
1401 if (rOrient.hasValue())
1403 sal_Int32 i = 0;
1404 while (i < nIntCount && !bOk)
1406 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1407 if (xDim.is() && (xDim->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ORIENTAT))) == rOrient))
1409 if (nPos == nIndex)
1411 bOk = sal_True;
1412 nDimIndex = i;
1414 else
1415 ++nPos;
1417 ++i;
1420 else
1422 sal_Int32 i = 0;
1423 while (i < nIntCount && !bOk)
1425 xDim.set(xIntDims->getByIndex(i), UNO_QUERY);
1426 if ( xDim.is() && !lcl_IsDuplicated( xDim ) )
1428 if (nPos == nIndex)
1430 bOk = sal_True;
1431 nDimIndex = i;
1433 else
1434 ++nPos;
1436 ++i;
1440 if ( bOk )
1442 xDim.set( xIntDims->getByIndex(nDimIndex), UNO_QUERY );
1443 Reference<XNamed> xDimName( xDim, UNO_QUERY );
1444 if ( xDimName.is() )
1446 OUString sOriginalName( lcl_GetOriginalName( xDimName ) );
1447 rFieldId.maFieldName = sOriginalName;
1448 rFieldId.mbDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDim,
1449 OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_ISDATALA)) );
1451 sal_Int32 nRepeat = 0;
1452 if ( rOrient.hasValue() && lcl_IsDuplicated( xDim ) )
1454 // find the repeat count
1455 // (this relies on the original dimension always being before the duplicates)
1457 Reference<XNamed> xPrevName;
1458 for (sal_Int32 i = 0; i < nDimIndex; ++i)
1460 xPrevName.set( xIntDims->getByIndex(i), UNO_QUERY );
1461 if ( xPrevName.is() && lcl_GetOriginalName( xPrevName ) == sOriginalName )
1462 ++nRepeat;
1465 rFieldId.mnFieldIdx = nRepeat;
1467 else
1468 bOk = sal_False;
1471 return bOk;
1474 BOOL lcl_GetFieldDataByName( ScDPObject* pDPObj, const OUString& rFieldName, ScFieldIdentifier& rFieldId )
1476 // "By name" is always the first match.
1477 // The name "Data" always refers to the data layout field.
1478 rFieldId.maFieldName = rFieldName;
1479 rFieldId.mnFieldIdx = 0;
1480 rFieldId.mbDataLayout = rFieldName.equalsAscii( SC_DATALAYOUT_NAME );
1482 pDPObj->GetSource(); // IsDimNameInUse doesn't update source data
1484 // check if the named field exists (not for data layout)
1485 return rFieldId.mbDataLayout || pDPObj->IsDimNameInUse( rFieldName );
1488 // XDataPilotFields
1490 ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
1492 // TODO
1493 if (ScDPObject* pObj = GetDPObject())
1495 ScFieldIdentifier aFieldId;
1496 if (lcl_GetFieldDataByIndex( pObj->GetSource(), maOrient, nIndex, aFieldId ))
1497 return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1499 return 0;
1502 ScDataPilotFieldObj* ScDataPilotFieldsObj::GetObjectByName_Impl(const OUString& aName) const
1504 if (ScDPObject* pDPObj = GetDPObject())
1506 ScFieldIdentifier aFieldId;
1507 if (lcl_GetFieldDataByName( pDPObj, aName, aFieldId ))
1508 return new ScDataPilotFieldObj( mrParent, aFieldId, maOrient );
1510 return 0;
1513 // XEnumerationAccess
1515 Reference<XEnumeration> SAL_CALL ScDataPilotFieldsObj::createEnumeration()
1516 throw(RuntimeException)
1518 ScUnoGuard aGuard;
1519 return new ScIndexEnumeration(this, OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DataPilotFieldsEnumeration")));
1522 // XIndexAccess
1524 sal_Int32 SAL_CALL ScDataPilotFieldsObj::getCount() throw(RuntimeException)
1526 ScUnoGuard aGuard;
1527 // TODO
1528 ScDPObject* pDPObj = GetDPObject();
1529 return pDPObj ? lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) : 0;
1532 Any SAL_CALL ScDataPilotFieldsObj::getByIndex( sal_Int32 nIndex )
1533 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
1535 ScUnoGuard aGuard;
1536 Reference< XPropertySet > xField( GetObjectByIndex_Impl( nIndex ) );
1537 if (!xField.is())
1538 throw IndexOutOfBoundsException();
1539 return Any( xField );
1542 uno::Type SAL_CALL ScDataPilotFieldsObj::getElementType() throw(RuntimeException)
1544 ScUnoGuard aGuard;
1545 return getCppuType((Reference<XPropertySet>*)0);
1548 sal_Bool SAL_CALL ScDataPilotFieldsObj::hasElements() throw(RuntimeException)
1550 ScUnoGuard aGuard;
1551 return ( getCount() != 0 );
1554 Any SAL_CALL ScDataPilotFieldsObj::getByName( const OUString& aName )
1555 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
1557 ScUnoGuard aGuard;
1558 Reference<XPropertySet> xField(GetObjectByName_Impl(aName));
1559 if (!xField.is())
1560 throw NoSuchElementException();
1561 return Any( xField );
1564 Sequence<OUString> SAL_CALL ScDataPilotFieldsObj::getElementNames()
1565 throw(RuntimeException)
1567 ScUnoGuard aGuard;
1568 // TODO
1569 if (ScDPObject* pDPObj = GetDPObject())
1571 Sequence< OUString > aSeq( lcl_GetFieldCount( pDPObj->GetSource(), maOrient ) );
1572 OUString* pAry = aSeq.getArray();
1573 const List& rDimensions = pDPObj->GetSaveData()->GetDimensions();
1574 sal_Int32 nDimCount = rDimensions.Count();
1575 for (sal_Int32 nDim = 0; nDim < nDimCount; nDim++)
1577 ScDPSaveDimension* pDim = (ScDPSaveDimension*)rDimensions.GetObject(nDim);
1578 if(maOrient.hasValue() && (pDim->GetOrientation() == maOrient.get< DataPilotFieldOrientation >()))
1580 *pAry = pDim->GetName();
1581 ++pAry;
1584 return aSeq;
1586 return Sequence<OUString>();
1589 sal_Bool SAL_CALL ScDataPilotFieldsObj::hasByName( const OUString& aName )
1590 throw(RuntimeException)
1592 ScUnoGuard aGuard;
1594 return GetObjectByName_Impl(aName) != NULL;
1597 //------------------------------------------------------------------------
1599 ScDataPilotFieldObj::ScDataPilotFieldObj(
1600 ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
1601 ScDataPilotChildObjBase( rParent, rFieldId ),
1602 maPropSet( lcl_GetDataPilotFieldMap() )
1606 ScDataPilotFieldObj::ScDataPilotFieldObj( ScDataPilotDescriptorBase& rParent,
1607 const ScFieldIdentifier& rFieldId, const Any& rOrient ) :
1608 ScDataPilotChildObjBase( rParent, rFieldId ),
1609 maPropSet( lcl_GetDataPilotFieldMap() ),
1610 maOrient( rOrient )
1614 ScDataPilotFieldObj::~ScDataPilotFieldObj()
1618 // XNamed
1620 OUString SAL_CALL ScDataPilotFieldObj::getName() throw(RuntimeException)
1622 ScUnoGuard aGuard;
1623 OUString aName;
1624 if( ScDPSaveDimension* pDim = GetDPDimension() )
1626 if( pDim->IsDataLayout() )
1627 aName = OUString( RTL_CONSTASCII_USTRINGPARAM( SC_DATALAYOUT_NAME ) );
1628 else
1630 const rtl::OUString* pLayoutName = pDim->GetLayoutName();
1631 if (pLayoutName)
1632 aName = *pLayoutName;
1633 else
1634 aName = pDim->GetName();
1636 return aName;
1639 void SAL_CALL ScDataPilotFieldObj::setName( const OUString& rName ) throw(RuntimeException)
1641 ScUnoGuard aGuard;
1642 ScDPObject* pDPObj = 0;
1643 ScDPSaveDimension* pDim = GetDPDimension( &pDPObj );
1644 if( pDim && !pDim->IsDataLayout() )
1646 String aName( rName );
1647 pDim->SetLayoutName(aName);
1648 SetDPObject( pDPObj );
1652 // XPropertySet
1654 Reference<XPropertySetInfo> SAL_CALL ScDataPilotFieldObj::getPropertySetInfo()
1655 throw(RuntimeException)
1657 ScUnoGuard aGuard;
1658 static Reference<XPropertySetInfo> aRef(
1659 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() ));
1660 return aRef;
1663 void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
1664 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
1666 ScUnoGuard aGuard;
1667 String aNameString(aPropertyName);
1668 if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) )
1670 GeneralFunction eFunction = GeneralFunction_NONE;
1671 if( aValue >>= eFunction )
1672 setFunction( eFunction );
1674 else if ( aNameString.EqualsAscii( SC_UNONAME_SUBTOTALS ) )
1676 Sequence< GeneralFunction > aSubtotals;
1677 if( aValue >>= aSubtotals )
1678 setSubtotals( aSubtotals );
1680 else if ( aNameString.EqualsAscii( SC_UNONAME_ORIENT ) )
1682 //! test for correct enum type?
1683 DataPilotFieldOrientation eOrient = (DataPilotFieldOrientation)
1684 ScUnoHelpFunctions::GetEnumFromAny( aValue );
1685 setOrientation( eOrient );
1687 else if ( aNameString.EqualsAscii( SC_UNONAME_SELPAGE ) )
1689 OUString sCurrentPage;
1690 if (aValue >>= sCurrentPage)
1691 setCurrentPage(sCurrentPage);
1693 else if ( aNameString.EqualsAscii( SC_UNONAME_USESELPAGE ) )
1695 setUseCurrentPage(cppu::any2bool(aValue));
1697 else if ( aNameString.EqualsAscii( SC_UNONAME_HASAUTOSHOW ) )
1699 if (!cppu::any2bool(aValue))
1700 setAutoShowInfo(NULL);
1702 else if ( aNameString.EqualsAscii( SC_UNONAME_AUTOSHOW ) )
1704 DataPilotFieldAutoShowInfo aInfo;
1705 if (aValue >>= aInfo)
1706 setAutoShowInfo(&aInfo);
1708 else if ( aNameString.EqualsAscii( SC_UNONAME_HASLAYOUTINFO ) )
1710 if (!cppu::any2bool(aValue))
1711 setLayoutInfo(NULL);
1713 else if ( aNameString.EqualsAscii( SC_UNONAME_LAYOUTINFO ) )
1715 DataPilotFieldLayoutInfo aInfo;
1716 if (aValue >>= aInfo)
1717 setLayoutInfo(&aInfo);
1719 else if ( aNameString.EqualsAscii( SC_UNONAME_HASREFERENCE ) )
1721 if (!cppu::any2bool(aValue))
1722 setReference(NULL);
1724 else if ( aNameString.EqualsAscii( SC_UNONAME_REFERENCE ) )
1726 DataPilotFieldReference aRef;
1727 if (aValue >>= aRef)
1728 setReference(&aRef);
1730 else if ( aNameString.EqualsAscii( SC_UNONAME_HASSORTINFO ) )
1732 if (!cppu::any2bool(aValue))
1733 setSortInfo(NULL);
1735 else if ( aNameString.EqualsAscii( SC_UNONAME_SORTINFO ) )
1737 DataPilotFieldSortInfo aInfo;
1738 if (aValue >>= aInfo)
1739 setSortInfo(&aInfo);
1741 else if ( aNameString.EqualsAscii( SC_UNONAME_ISGROUP ) )
1743 if (!cppu::any2bool(aValue))
1744 setGroupInfo(NULL);
1746 else if ( aNameString.EqualsAscii( SC_UNONAME_GROUPINFO ) )
1748 DataPilotFieldGroupInfo aInfo;
1749 if (aValue >>= aInfo)
1750 setGroupInfo(&aInfo);
1752 else if ( aNameString.EqualsAscii( SC_UNONAME_SHOWEMPTY ) )
1754 setShowEmpty(cppu::any2bool(aValue));
1758 Any SAL_CALL ScDataPilotFieldObj::getPropertyValue( const OUString& aPropertyName )
1759 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
1761 ScUnoGuard aGuard;
1762 String aNameString(aPropertyName);
1763 Any aRet;
1765 if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) )
1766 aRet <<= getFunction();
1767 else if ( aNameString.EqualsAscii( SC_UNONAME_SUBTOTALS ) )
1768 aRet <<= getSubtotals();
1769 else if ( aNameString.EqualsAscii( SC_UNONAME_ORIENT ) )
1770 aRet <<= getOrientation();
1771 else if ( aNameString.EqualsAscii( SC_UNONAME_SELPAGE ) )
1772 aRet <<= getCurrentPage();
1773 else if ( aNameString.EqualsAscii( SC_UNONAME_USESELPAGE ) )
1774 aRet <<= getUseCurrentPage();
1775 else if ( aNameString.EqualsAscii( SC_UNONAME_HASAUTOSHOW ) )
1776 aRet = ::cppu::bool2any(getAutoShowInfo() != NULL);
1777 else if ( aNameString.EqualsAscii( SC_UNONAME_AUTOSHOW ) )
1779 const DataPilotFieldAutoShowInfo* pInfo = getAutoShowInfo();
1780 if (pInfo)
1781 aRet <<= DataPilotFieldAutoShowInfo(*pInfo);
1783 else if ( aNameString.EqualsAscii( SC_UNONAME_HASLAYOUTINFO ) )
1784 aRet = ::cppu::bool2any(getLayoutInfo() != NULL);
1785 else if ( aNameString.EqualsAscii( SC_UNONAME_LAYOUTINFO ) )
1787 const DataPilotFieldLayoutInfo* pInfo = getLayoutInfo();
1788 if (pInfo)
1789 aRet <<= DataPilotFieldLayoutInfo(*pInfo);
1791 else if ( aNameString.EqualsAscii( SC_UNONAME_HASREFERENCE ) )
1792 aRet = ::cppu::bool2any(getReference() != NULL);
1793 else if ( aNameString.EqualsAscii( SC_UNONAME_REFERENCE ) )
1795 const DataPilotFieldReference* pRef = getReference();
1796 if (pRef)
1797 aRet <<= DataPilotFieldReference(*pRef);
1799 else if ( aNameString.EqualsAscii( SC_UNONAME_HASSORTINFO ) )
1800 aRet = ::cppu::bool2any(getSortInfo() != NULL);
1801 else if ( aNameString.EqualsAscii( SC_UNONAME_SORTINFO ) )
1803 const DataPilotFieldSortInfo* pInfo = getSortInfo();
1804 if (pInfo)
1805 aRet <<= DataPilotFieldSortInfo(*pInfo);
1807 else if ( aNameString.EqualsAscii( SC_UNONAME_ISGROUP ) )
1808 aRet = ::cppu::bool2any(hasGroupInfo());
1809 else if ( aNameString.EqualsAscii( SC_UNONAME_GROUPINFO ) )
1811 aRet <<= getGroupInfo();
1813 else if ( aNameString.EqualsAscii( SC_UNONAME_SHOWEMPTY ) )
1814 aRet <<= getShowEmpty();
1816 return aRet;
1819 // XDatePilotField
1821 Reference<XIndexAccess> SAL_CALL ScDataPilotFieldObj::getItems()
1822 throw (RuntimeException)
1824 ScUnoGuard aGuard;
1825 if (!mxItems.is())
1826 mxItems.set( new ScDataPilotItemsObj( mrParent, maFieldId ) );
1827 return mxItems;
1830 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDataPilotFieldObj )
1832 DataPilotFieldOrientation ScDataPilotFieldObj::getOrientation() const
1834 ScUnoGuard aGuard;
1835 ScDPSaveDimension* pDim = GetDPDimension();
1836 return pDim ? static_cast< DataPilotFieldOrientation >( pDim->GetOrientation() ) : DataPilotFieldOrientation_HIDDEN;
1839 void ScDataPilotFieldObj::setOrientation(DataPilotFieldOrientation eNew)
1841 ScUnoGuard aGuard;
1842 if (maOrient.hasValue() && (eNew == maOrient.get< DataPilotFieldOrientation >()))
1843 return;
1845 ScDPObject* pDPObj = 0;
1846 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
1848 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1850 /* If the field was taken from getDataPilotFields(), don't reset the
1851 orientation for an existing use, but create a duplicated field
1852 instead (for "Data" orientation only). */
1853 if ( !maOrient.hasValue() && !maFieldId.mbDataLayout &&
1854 (pDim->GetOrientation() != DataPilotFieldOrientation_HIDDEN) &&
1855 (eNew == DataPilotFieldOrientation_DATA) )
1858 ScDPSaveDimension* pNewDim = 0;
1860 // look for existing duplicate with orientation "hidden"
1862 String aNameStr( maFieldId.maFieldName );
1863 const List& rDimensions = pSaveData->GetDimensions();
1864 sal_Int32 nDimCount = rDimensions.Count();
1865 sal_Int32 nFound = 0;
1866 for ( sal_Int32 nDim = 0; nDim < nDimCount && !pNewDim; nDim++ )
1868 ScDPSaveDimension* pOneDim = static_cast<ScDPSaveDimension*>(rDimensions.GetObject(nDim));
1869 if ( !pOneDim->IsDataLayout() && (pOneDim->GetName() == aNameStr) )
1871 if ( pOneDim->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
1872 pNewDim = pOneDim; // use this one
1873 else
1874 ++nFound; // count existing non-hidden occurences
1878 if ( !pNewDim ) // if none found, create a new duplicated dimension
1879 pNewDim = &pSaveData->DuplicateDimension( *pDim );
1881 maFieldId.mnFieldIdx = nFound; // keep accessing the new one
1882 pDim = pNewDim;
1885 pDim->SetOrientation(sal::static_int_cast<USHORT>(eNew));
1887 // move changed field behind all other fields (make it the last field in dimension)
1888 pSaveData->SetPosition( pDim, pSaveData->GetDimensions().Count() );
1890 SetDPObject( pDPObj );
1892 maOrient <<= eNew; // modifying the same object's orientation again doesn't create another duplicate
1896 GeneralFunction ScDataPilotFieldObj::getFunction() const
1898 ScUnoGuard aGuard;
1899 GeneralFunction eRet = GeneralFunction_NONE;
1900 if( ScDPSaveDimension* pDim = GetDPDimension() )
1902 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
1904 // for non-data fields, property Function is the subtotals
1905 long nSubCount = pDim->GetSubTotalsCount();
1906 if ( nSubCount > 0 )
1907 eRet = (GeneralFunction)pDim->GetSubTotalFunc(0); // always use the first one
1908 // else keep NONE
1910 else
1911 eRet = (GeneralFunction)pDim->GetFunction();
1913 return eRet;
1916 void ScDataPilotFieldObj::setFunction(GeneralFunction eNewFunc)
1918 ScUnoGuard aGuard;
1919 ScDPObject* pDPObj = 0;
1920 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
1922 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
1924 // for non-data fields, property Function is the subtotals
1925 if ( eNewFunc == GeneralFunction_NONE )
1926 pDim->SetSubTotals( 0, NULL );
1927 else
1929 USHORT nFunc = sal::static_int_cast<USHORT>( eNewFunc );
1930 pDim->SetSubTotals( 1, &nFunc );
1933 else
1934 pDim->SetFunction( sal::static_int_cast<USHORT>( eNewFunc ) );
1935 SetDPObject( pDPObj );
1939 Sequence< GeneralFunction > ScDataPilotFieldObj::getSubtotals() const
1941 ScUnoGuard aGuard;
1942 Sequence< GeneralFunction > aRet;
1943 if( ScDPSaveDimension* pDim = GetDPDimension() )
1945 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
1947 // for non-data fields, property Functions is the sequence of subtotals
1948 sal_Int32 nCount = static_cast< sal_Int32 >( pDim->GetSubTotalsCount() );
1949 if ( nCount > 0 )
1951 aRet.realloc( nCount );
1952 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
1953 aRet[ nIdx ] = (GeneralFunction)pDim->GetSubTotalFunc( nIdx );
1957 return aRet;
1960 void ScDataPilotFieldObj::setSubtotals( const Sequence< GeneralFunction >& rSubtotals )
1962 ScUnoGuard aGuard;
1963 ScDPObject* pDPObj = 0;
1964 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
1966 if( pDim->GetOrientation() != DataPilotFieldOrientation_DATA )
1968 sal_Int32 nCount = rSubtotals.getLength();
1969 if( nCount == 1 )
1971 // count 1: all values are allowed (including NONE and AUTO)
1972 if( rSubtotals[ 0 ] == GeneralFunction_NONE )
1973 pDim->SetSubTotals( 0, NULL );
1974 else
1976 USHORT nFunc = sal::static_int_cast<USHORT>( rSubtotals[ 0 ] );
1977 pDim->SetSubTotals( 1, &nFunc );
1980 else if( nCount > 1 )
1982 // set multiple functions, ignore NONE and AUTO in this case
1983 ::std::vector< USHORT > aSubt;
1984 for( sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx )
1986 GeneralFunction eFunc = rSubtotals[ nIdx ];
1987 if( (eFunc != GeneralFunction_NONE) && (eFunc != GeneralFunction_AUTO) )
1989 // do not insert functions twice
1990 USHORT nFunc = static_cast< USHORT >( eFunc );
1991 if( ::std::find( aSubt.begin(), aSubt.end(), nFunc ) == aSubt.end() )
1992 aSubt.push_back( nFunc );
1995 // set values from vector to ScDPSaveDimension
1996 if ( aSubt.empty() )
1997 pDim->SetSubTotals( 0, NULL );
1998 else
1999 pDim->SetSubTotals( static_cast< long >( aSubt.size() ), &aSubt.front() );
2002 SetDPObject( pDPObj );
2006 OUString ScDataPilotFieldObj::getCurrentPage() const
2008 ScUnoGuard aGuard;
2009 ScDPSaveDimension* pDim = GetDPDimension();
2010 if( pDim && pDim->HasCurrentPage() )
2011 return pDim->GetCurrentPage();
2012 return OUString();
2015 void ScDataPilotFieldObj::setCurrentPage( const OUString& rPage )
2017 ScUnoGuard aGuard;
2018 ScDPObject* pDPObj = 0;
2019 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2021 String aPage( rPage );
2022 pDim->SetCurrentPage( &aPage );
2023 SetDPObject( pDPObj );
2027 sal_Bool ScDataPilotFieldObj::getUseCurrentPage() const
2029 ScUnoGuard aGuard;
2030 ScDPSaveDimension* pDim = GetDPDimension();
2031 return pDim && pDim->HasCurrentPage();
2034 void ScDataPilotFieldObj::setUseCurrentPage( sal_Bool bUse )
2036 ScUnoGuard aGuard;
2037 ScDPObject* pDPObj = 0;
2038 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2040 if( bUse )
2042 /* It is somehow useless to set the property "HasSelectedPage" to
2043 true, because it is still needed to set an explicit page name. */
2044 if( !pDim->HasCurrentPage() )
2046 String aPage;
2047 pDim->SetCurrentPage( &aPage );
2050 else
2051 pDim->SetCurrentPage( 0 );
2052 SetDPObject( pDPObj );
2056 const DataPilotFieldAutoShowInfo* ScDataPilotFieldObj::getAutoShowInfo()
2058 ScUnoGuard aGuard;
2059 ScDPSaveDimension* pDim = GetDPDimension();
2060 return pDim ? pDim->GetAutoShowInfo() : 0;
2063 void ScDataPilotFieldObj::setAutoShowInfo( const DataPilotFieldAutoShowInfo* pInfo )
2065 ScUnoGuard aGuard;
2066 ScDPObject* pDPObj = 0;
2067 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2069 pDim->SetAutoShowInfo( pInfo );
2070 SetDPObject( pDPObj );
2074 const DataPilotFieldLayoutInfo* ScDataPilotFieldObj::getLayoutInfo()
2076 ScUnoGuard aGuard;
2077 ScDPSaveDimension* pDim = GetDPDimension();
2078 return pDim ? pDim->GetLayoutInfo() : 0;
2081 void ScDataPilotFieldObj::setLayoutInfo( const DataPilotFieldLayoutInfo* pInfo )
2083 ScUnoGuard aGuard;
2084 ScDPObject* pDPObj = 0;
2085 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2087 pDim->SetLayoutInfo( pInfo );
2088 SetDPObject( pDPObj );
2092 const DataPilotFieldReference* ScDataPilotFieldObj::getReference()
2094 ScUnoGuard aGuard;
2095 ScDPSaveDimension* pDim = GetDPDimension();
2096 return pDim ? pDim->GetReferenceValue() : 0;
2099 void ScDataPilotFieldObj::setReference( const DataPilotFieldReference* pInfo )
2101 ScUnoGuard aGuard;
2102 ScDPObject* pDPObj = 0;
2103 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2105 pDim->SetReferenceValue( pInfo );
2106 SetDPObject( pDPObj );
2110 const DataPilotFieldSortInfo* ScDataPilotFieldObj::getSortInfo()
2112 ScUnoGuard aGuard;
2113 ScDPSaveDimension* pDim = GetDPDimension();
2114 return pDim ? pDim->GetSortInfo() : 0;
2117 void ScDataPilotFieldObj::setSortInfo( const DataPilotFieldSortInfo* pInfo )
2119 ScUnoGuard aGuard;
2120 ScDPObject* pDPObj = 0;
2121 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2123 pDim->SetSortInfo( pInfo );
2124 SetDPObject( pDPObj );
2128 sal_Bool ScDataPilotFieldObj::getShowEmpty() const
2130 ScUnoGuard aGuard;
2131 ScDPSaveDimension* pDim = GetDPDimension();
2132 return pDim && pDim->GetShowEmpty();
2135 void ScDataPilotFieldObj::setShowEmpty( sal_Bool bShow )
2137 ScUnoGuard aGuard;
2138 ScDPObject* pDPObj = 0;
2139 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2141 pDim->SetShowEmpty( bShow );
2142 SetDPObject( pDPObj );
2146 sal_Bool ScDataPilotFieldObj::hasGroupInfo()
2148 ScUnoGuard aGuard;
2149 ScDPObject* pDPObj = 0;
2150 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2151 if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2152 return pDimData->GetNamedGroupDim( pDim->GetName() ) || pDimData->GetNumGroupDim( pDim->GetName() );
2153 return sal_False;
2156 DataPilotFieldGroupInfo ScDataPilotFieldObj::getGroupInfo()
2158 ScUnoGuard aGuard;
2159 DataPilotFieldGroupInfo aInfo;
2160 ScDPObject* pDPObj = 0;
2161 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2163 if( const ScDPDimensionSaveData* pDimData = pDPObj->GetSaveData()->GetExistingDimensionData() )
2165 if( const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( pDim->GetName() ) )
2167 // grouped by ...
2168 aInfo.GroupBy = pGroupDim->GetDatePart();
2170 // find source field
2173 Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2174 aInfo.SourceField.set( xFields->getByName( pGroupDim->GetSourceDimName() ), UNO_QUERY );
2176 catch( Exception& )
2180 ScDataPilotConversion::FillGroupInfo( aInfo, pGroupDim->GetDateInfo() );
2181 if( pGroupDim->GetDatePart() == 0 )
2183 // fill vector of group and group member information
2184 ScFieldGroups aGroups;
2185 for( sal_Int32 nIdx = 0, nCount = pGroupDim->GetGroupCount(); nIdx < nCount; ++nIdx )
2187 if( const ScDPSaveGroupItem* pGroup = pGroupDim->GetGroupByIndex( nIdx ) )
2189 ScFieldGroup aGroup;
2190 aGroup.maName = pGroup->GetGroupName();
2191 for( sal_Int32 nMemIdx = 0, nMemCount = pGroup->GetElementCount(); nMemIdx < nMemCount; ++nMemIdx )
2192 if( const String* pMem = pGroup->GetElementByIndex( nMemIdx ) )
2193 aGroup.maMembers.push_back( *pMem );
2194 aGroups.push_back( aGroup );
2197 aInfo.Groups = new ScDataPilotFieldGroupsObj( aGroups );
2200 else if( const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( pDim->GetName() ) )
2202 if (pNumGroupDim->GetDatePart())
2204 ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetDateInfo() );
2205 aInfo.GroupBy = pNumGroupDim->GetDatePart();
2207 else
2209 ScDataPilotConversion::FillGroupInfo( aInfo, pNumGroupDim->GetInfo() );
2214 return aInfo;
2217 void ScDataPilotFieldObj::setGroupInfo( const DataPilotFieldGroupInfo* pInfo )
2219 ScUnoGuard aGuard;
2220 ScDPObject* pDPObj = 0;
2221 if( /*ScDPSaveDimension* pDim =*/ GetDPDimension( &pDPObj ) )
2223 ScDPSaveData* pSaveData = pDPObj->GetSaveData();
2224 if( pInfo && lclCheckMinMaxStep( *pInfo ) )
2226 ScDPNumGroupInfo aInfo;
2227 aInfo.Enable = sal_True;
2228 aInfo.DateValues = pInfo->HasDateValues;
2229 aInfo.AutoStart = pInfo->HasAutoStart;
2230 aInfo.AutoEnd = pInfo->HasAutoEnd;
2231 aInfo.Start = pInfo->Start;
2232 aInfo.End = pInfo->End;
2233 aInfo.Step = pInfo->Step;
2234 Reference< XNamed > xNamed( pInfo->SourceField, UNO_QUERY );
2235 if( xNamed.is() )
2237 ScDPSaveGroupDimension aGroupDim( xNamed->getName(), getName() );
2238 if( pInfo->GroupBy )
2239 aGroupDim.SetDateInfo(aInfo, pInfo->GroupBy);
2240 else
2242 Reference<XIndexAccess> xIndex(pInfo->Groups, UNO_QUERY);
2243 if (xIndex.is())
2245 sal_Int32 nCount(xIndex->getCount());
2246 for(sal_Int32 i = 0; i < nCount; i++)
2248 Reference<XNamed> xGroupNamed(xIndex->getByIndex(i), UNO_QUERY);
2249 if (xGroupNamed.is())
2251 ScDPSaveGroupItem aItem(xGroupNamed->getName());
2252 Reference<XIndexAccess> xGroupIndex(xGroupNamed, UNO_QUERY);
2253 if (xGroupIndex.is())
2255 sal_Int32 nItemCount(xGroupIndex->getCount());
2256 for (sal_Int32 j = 0; j < nItemCount; ++j)
2258 Reference<XNamed> xItemNamed(xGroupIndex->getByIndex(j), UNO_QUERY);
2259 if (xItemNamed.is())
2260 aItem.AddElement(xItemNamed->getName());
2263 aGroupDim.AddGroupItem(aItem);
2269 // get dimension savedata or create new if none
2270 ScDPDimensionSaveData& rDimSaveData = *pSaveData->GetDimensionData();
2271 rDimSaveData.ReplaceGroupDimension( aGroupDim );
2273 else // no source field in group info -> numeric group
2275 ScDPDimensionSaveData* pDimData = pSaveData->GetDimensionData(); // created if not there
2277 ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( getName() );
2278 if ( pExisting )
2280 if (pInfo->GroupBy)
2281 pExisting->SetDateInfo(aInfo, pInfo->GroupBy);
2282 // modify existing group dimension
2283 pExisting->SetGroupInfo( aInfo );
2285 else if (pInfo->GroupBy)
2287 // create new group dimension
2288 ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo, pInfo->GroupBy );
2289 pDimData->AddNumGroupDimension( aNumGroupDim );
2291 else
2293 // create new group dimension
2294 ScDPSaveNumGroupDimension aNumGroupDim( getName(), aInfo );
2295 pDimData->AddNumGroupDimension( aNumGroupDim );
2299 else // null passed as argument
2301 pSaveData->SetDimensionData( 0 );
2304 pDPObj->SetSaveData( *pSaveData );
2305 SetDPObject( pDPObj );
2309 sal_Bool ScDataPilotFieldObj::HasString(const Sequence< OUString >& rItems, const OUString& aString)
2311 sal_Bool bRet = sal_False;
2313 sal_Int32 nCount(rItems.getLength());
2314 sal_Int32 nItem(0);
2315 while (nItem < nCount && !bRet)
2317 bRet = rItems[nItem] == aString;
2318 ++nItem;
2321 return bRet;
2324 // XDataPilotFieldGrouping
2325 Reference< XDataPilotField > SAL_CALL ScDataPilotFieldObj::createNameGroup( const Sequence< OUString >& rItems )
2326 throw (RuntimeException, IllegalArgumentException)
2328 ScUnoGuard aGuard;
2330 Reference< XDataPilotField > xRet;
2331 OUString sNewDim;
2333 if( !rItems.hasElements() )
2334 throw IllegalArgumentException();
2336 ScDPObject* pDPObj = 0;
2337 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2339 String aDimName = pDim->GetName();
2341 ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2342 ScDPDimensionSaveData* pDimData = aSaveData.GetDimensionData(); // created if not there
2344 // find original base
2345 String aBaseDimName( aDimName );
2346 const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
2347 if ( pBaseGroupDim )
2349 // any entry's SourceDimName is the original base
2350 aBaseDimName = pBaseGroupDim->GetSourceDimName();
2353 // find existing group dimension
2354 // (using the selected dim, can be intermediate group dim)
2355 ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
2357 // remove the selected items from their groups
2358 // (empty groups are removed, too)
2359 sal_Int32 nEntryCount = rItems.getLength();
2360 sal_Int32 nEntry;
2361 if ( pGroupDimension )
2363 for (nEntry=0; nEntry<nEntryCount; nEntry++)
2365 String aEntryName(rItems[nEntry]);
2366 if ( pBaseGroupDim )
2368 // for each selected (intermediate) group, remove all its items
2369 // (same logic as for adding, below)
2370 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2371 if ( pBaseGroup )
2372 pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements
2373 else
2374 pGroupDimension->RemoveFromGroups( aEntryName );
2376 else
2377 pGroupDimension->RemoveFromGroups( aEntryName );
2381 ScDPSaveGroupDimension* pNewGroupDim = 0;
2382 if ( !pGroupDimension )
2384 // create a new group dimension
2385 String aGroupDimName = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
2386 pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, aGroupDimName );
2387 sNewDim = aGroupDimName;
2389 pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
2391 if ( pBaseGroupDim )
2393 // If it's a higher-order group dimension, pre-allocate groups for all
2394 // non-selected original groups, so the individual base members aren't
2395 // used for automatic groups (this would make the original groups hard
2396 // to find).
2397 //! Also do this when removing groups?
2398 //! Handle this case dynamically with automatic groups?
2400 long nGroupCount = pBaseGroupDim->GetGroupCount();
2401 for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
2403 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
2405 StrData aStrData( pBaseGroup->GetGroupName() );
2406 if ( !HasString(rItems, aStrData.GetString()) ) //! ignore case?
2408 // add an additional group for each item that is not in the selection
2409 ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
2410 aGroup.AddElementsFromGroup( *pBaseGroup );
2411 pGroupDimension->AddGroupItem( aGroup );
2416 String aGroupDimName = pGroupDimension->GetGroupDimName();
2418 //! localized prefix string
2419 String aGroupName = pGroupDimension->CreateGroupName( String( RTL_CONSTASCII_USTRINGPARAM( "Group" ) ) );
2420 ScDPSaveGroupItem aGroup( aGroupName );
2421 Reference< XNameAccess > xMembers = GetMembers();
2422 if (!xMembers.is())
2424 delete pNewGroupDim;
2425 throw RuntimeException();
2428 for (nEntry=0; nEntry<nEntryCount; nEntry++)
2430 String aEntryName(rItems[nEntry]);
2432 if (!xMembers->hasByName(aEntryName))
2434 delete pNewGroupDim;
2435 throw IllegalArgumentException();
2438 if ( pBaseGroupDim )
2440 // for each selected (intermediate) group, add all its items
2441 const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
2442 if ( pBaseGroup )
2443 aGroup.AddElementsFromGroup( *pBaseGroup );
2444 else
2445 aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself
2447 else
2448 aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
2451 pGroupDimension->AddGroupItem( aGroup );
2453 if ( pNewGroupDim )
2455 pDimData->AddGroupDimension( *pNewGroupDim );
2456 delete pNewGroupDim; // AddGroupDimension copies the object
2457 // don't access pGroupDimension after here
2459 pGroupDimension = pNewGroupDim = NULL;
2461 // set orientation
2462 ScDPSaveDimension* pSaveDimension = aSaveData.GetDimensionByName( aGroupDimName );
2463 if ( pSaveDimension->GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2465 ScDPSaveDimension* pOldDimension = aSaveData.GetDimensionByName( aDimName );
2466 pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
2467 long nPosition = 0; //! before (immediate) base
2468 aSaveData.SetPosition( pSaveDimension, nPosition );
2471 // apply changes
2472 pDPObj->SetSaveData( aSaveData );
2473 SetDPObject( pDPObj );
2476 // if new grouping field has been created (on first group), return it
2477 if( sNewDim.getLength() > 0 )
2479 Reference< XNameAccess > xFields(mrParent.getDataPilotFields(), UNO_QUERY);
2480 if (xFields.is())
2482 xRet.set(xFields->getByName(sNewDim), UNO_QUERY);
2483 DBG_ASSERT(xRet.is(), "there is a name, so there should be also a field");
2486 return xRet;
2489 Reference < XDataPilotField > SAL_CALL ScDataPilotFieldObj::createDateGroup( const DataPilotFieldGroupInfo& rInfo )
2490 throw (RuntimeException, IllegalArgumentException)
2492 ScUnoGuard aGuard;
2493 using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
2495 // check min/max/step, HasDateValues must be set always
2496 if( !rInfo.HasDateValues || !lclCheckMinMaxStep( rInfo ) )
2497 throw IllegalArgumentException();
2498 // only a single date flag is allowed
2499 if( (rInfo.GroupBy == 0) || (rInfo.GroupBy > YEARS) || ((rInfo.GroupBy & (rInfo.GroupBy - 1)) != 0) )
2500 throw IllegalArgumentException();
2501 // step must be zero, if something else than DAYS is specified
2502 if( rInfo.Step >= ((rInfo.GroupBy == DAYS) ? 32768.0 : 1.0) )
2503 throw IllegalArgumentException();
2505 String aGroupDimName;
2506 ScDPObject* pDPObj = 0;
2507 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
2509 ScDPNumGroupInfo aInfo;
2510 aInfo.Enable = sal_True;
2511 aInfo.DateValues = (rInfo.GroupBy == DAYS) && (rInfo.Step >= 1.0);
2512 aInfo.AutoStart = rInfo.HasAutoStart;
2513 aInfo.AutoEnd = rInfo.HasAutoEnd;
2514 aInfo.Start = rInfo.Start;
2515 aInfo.End = rInfo.End;
2516 aInfo.Step = static_cast< sal_Int32 >( rInfo.Step );
2518 // create a local copy of the entire save data (will be written back below)
2519 ScDPSaveData aSaveData = *pDPObj->GetSaveData();
2520 // get or create dimension save data
2521 ScDPDimensionSaveData& rDimData = *aSaveData.GetDimensionData();
2523 // find source dimension name
2524 const String& rDimName = pDim->GetName();
2525 const ScDPSaveGroupDimension* pGroupDim = rDimData.GetNamedGroupDim( rDimName );
2526 String aSrcDimName = pGroupDim ? pGroupDim->GetSourceDimName() : rDimName;
2528 // find a group dimension for the base field, or get numeric grouping
2529 pGroupDim = rDimData.GetFirstNamedGroupDim( aSrcDimName );
2530 const ScDPSaveNumGroupDimension* pNumGroupDim = rDimData.GetNumGroupDim( aSrcDimName );
2532 // do not group by dates, if named groups or numeric grouping is present
2533 bool bHasNamedGrouping = pGroupDim && !pGroupDim->GetDateInfo().Enable;
2534 bool bHasNumGrouping = pNumGroupDim && pNumGroupDim->GetInfo().Enable && !pNumGroupDim->GetInfo().DateValues && !pNumGroupDim->GetDateInfo().Enable;
2535 if( bHasNamedGrouping || bHasNumGrouping )
2536 throw IllegalArgumentException();
2538 if( aInfo.DateValues ) // create day ranges grouping
2540 // first remove all named group dimensions
2541 while( pGroupDim )
2543 String aGroupDimName2 = pGroupDim->GetGroupDimName();
2544 // find next group dimension before deleting this group
2545 pGroupDim = rDimData.GetNextNamedGroupDim( aGroupDimName2 );
2546 // remove from dimension save data
2547 rDimData.RemoveGroupDimension( aGroupDimName2 );
2548 // also remove save data settings for the dimension that no longer exists
2549 aSaveData.RemoveDimensionByName( aGroupDimName2 );
2551 // create or replace the number grouping dimension
2552 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo );
2553 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2555 else // create date grouping
2557 // collect all existing date flags
2558 sal_Int32 nDateParts = rDimData.CollectDateParts( aSrcDimName );
2559 if( nDateParts == 0 )
2561 // insert numeric group dimension, if no date groups exist yet (or replace day range grouping)
2562 ScDPSaveNumGroupDimension aNumGroupDim( aSrcDimName, aInfo, rInfo.GroupBy );
2563 rDimData.ReplaceNumGroupDimension( aNumGroupDim );
2565 else if( (nDateParts & rInfo.GroupBy) == 0 ) // do nothing if date field exists already
2567 // create new named group dimension for additional date groups
2568 aGroupDimName = rDimData.CreateDateGroupDimName( rInfo.GroupBy, *pDPObj, true, 0 );
2569 ScDPSaveGroupDimension aGroupDim( aSrcDimName, aGroupDimName, aInfo, rInfo.GroupBy );
2570 rDimData.AddGroupDimension( aGroupDim );
2572 // set orientation of new named group dimension
2573 ScDPSaveDimension& rSaveDim = *aSaveData.GetDimensionByName( aGroupDimName );
2574 if( rSaveDim.GetOrientation() == DataPilotFieldOrientation_HIDDEN )
2576 ScDPSaveDimension& rOldDim = *aSaveData.GetDimensionByName( aSrcDimName );
2577 rSaveDim.SetOrientation( rOldDim.GetOrientation() );
2578 aSaveData.SetPosition( &rSaveDim, 0 ); //! before (immediate) base
2583 // apply changes
2584 pDPObj->SetSaveData( aSaveData );
2585 SetDPObject( pDPObj );
2588 // return the UNO object of the new dimension, after writing back saved data
2589 Reference< XDataPilotField > xRet;
2590 if( aGroupDimName.Len() > 0 ) try
2592 Reference< XNameAccess > xFields( mrParent.getDataPilotFields(), UNO_QUERY_THROW );
2593 xRet.set( xFields->getByName( aGroupDimName ), UNO_QUERY );
2595 catch( Exception& )
2598 return xRet;
2601 // ============================================================================
2603 namespace {
2605 bool lclExtractGroupMembers( ScFieldGroupMembers& rMembers, const Any& rElement )
2607 // allow empty value to create a new group
2608 if( !rElement.hasValue() )
2609 return true;
2611 // try to extract a simple sequence of strings
2612 Sequence< OUString > aSeq;
2613 if( rElement >>= aSeq )
2615 if( aSeq.hasElements() )
2616 rMembers.insert( rMembers.end(), aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength() );
2617 return true;
2620 // try to use XIndexAccess providing objects that support XNamed
2621 Reference< XIndexAccess > xItemsIA( rElement, UNO_QUERY );
2622 if( xItemsIA.is() )
2624 for( sal_Int32 nIdx = 0, nCount = xItemsIA->getCount(); nIdx < nCount; ++nIdx )
2626 try // getByIndex() should not throw, but we cannot be sure
2628 Reference< XNamed > xItemName( xItemsIA->getByIndex( nIdx ), UNO_QUERY_THROW );
2629 rMembers.push_back( xItemName->getName() );
2631 catch( Exception& )
2633 // ignore exceptions, go ahead with next element in the array
2636 return true;
2639 // nothing valid inside the Any -> return false
2640 return false;
2643 } // namespace
2645 // ----------------------------------------------------------------------------
2647 ScDataPilotFieldGroupsObj::ScDataPilotFieldGroupsObj( const ScFieldGroups& rGroups ) :
2648 maGroups( rGroups )
2652 ScDataPilotFieldGroupsObj::~ScDataPilotFieldGroupsObj()
2656 // XNameAccess
2658 Any SAL_CALL ScDataPilotFieldGroupsObj::getByName( const OUString& rName )
2659 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2661 ScUnoGuard aGuard;
2662 if( implFindByName( rName ) == maGroups.end() )
2663 throw NoSuchElementException();
2664 return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, rName ) ) );
2667 Sequence< OUString > SAL_CALL ScDataPilotFieldGroupsObj::getElementNames() throw(RuntimeException)
2669 ScUnoGuard aGuard;
2670 Sequence< OUString > aSeq;
2671 if( !maGroups.empty() )
2673 aSeq.realloc( static_cast< sal_Int32 >( maGroups.size() ) );
2674 OUString* pName = aSeq.getArray();
2675 for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt, ++pName )
2676 *pName = aIt->maName;
2678 return aSeq;
2681 sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasByName( const OUString& rName ) throw(RuntimeException)
2683 ScUnoGuard aGuard;
2684 return implFindByName( rName ) != maGroups.end();
2687 // XNameReplace
2689 void SAL_CALL ScDataPilotFieldGroupsObj::replaceByName( const OUString& rName, const Any& rElement )
2690 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2692 ScUnoGuard aGuard;
2694 if( rName.getLength() == 0 )
2695 throw IllegalArgumentException();
2697 ScFieldGroups::iterator aIt = implFindByName( rName );
2698 if( aIt == maGroups.end() )
2699 throw NoSuchElementException();
2701 // read all item names provided by the passed object
2702 ScFieldGroupMembers aMembers;
2703 if( !lclExtractGroupMembers( aMembers, rElement ) )
2704 throw IllegalArgumentException();
2706 // copy and forget, faster than vector assignment
2707 aIt->maMembers.swap( aMembers );
2710 // XNameContainer
2712 void SAL_CALL ScDataPilotFieldGroupsObj::insertByName( const OUString& rName, const Any& rElement )
2713 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2715 ScUnoGuard aGuard;
2717 if( rName.getLength() == 0 )
2718 throw IllegalArgumentException();
2720 ScFieldGroups::iterator aIt = implFindByName( rName );
2721 if( aIt != maGroups.end() )
2722 throw ElementExistException();
2724 // read all item names provided by the passed object
2725 ScFieldGroupMembers aMembers;
2726 if( !lclExtractGroupMembers( aMembers, rElement ) )
2727 throw IllegalArgumentException();
2729 // create the new entry if no error has been occured
2730 maGroups.resize( maGroups.size() + 1 );
2731 ScFieldGroup& rGroup = maGroups.back();
2732 rGroup.maName = rName;
2733 rGroup.maMembers.swap( aMembers );
2736 void SAL_CALL ScDataPilotFieldGroupsObj::removeByName( const OUString& rName )
2737 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
2739 ScUnoGuard aGuard;
2741 if( rName.getLength() == 0 )
2742 throw IllegalArgumentException();
2744 ScFieldGroups::iterator aIt = implFindByName( rName );
2745 if( aIt == maGroups.end() )
2746 throw NoSuchElementException();
2748 maGroups.erase( aIt );
2751 // XIndexAccess
2753 sal_Int32 SAL_CALL ScDataPilotFieldGroupsObj::getCount() throw(RuntimeException)
2755 ScUnoGuard aGuard;
2756 return static_cast< sal_Int32 >( maGroups.size() );
2759 Any SAL_CALL ScDataPilotFieldGroupsObj::getByIndex( sal_Int32 nIndex )
2760 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
2762 ScUnoGuard aGuard;
2763 if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( maGroups.size() )))
2764 throw IndexOutOfBoundsException();
2765 return Any( Reference< XNameAccess >( new ScDataPilotFieldGroupObj( *this, maGroups[ nIndex ].maName ) ) );
2768 // XEnumerationAccess
2770 Reference<XEnumeration> SAL_CALL ScDataPilotFieldGroupsObj::createEnumeration() throw(RuntimeException)
2772 ScUnoGuard aGuard;
2773 return new ScIndexEnumeration( this, OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.DataPilotFieldGroupsEnumeration" ) ) );
2776 // XElementAccess
2778 uno::Type SAL_CALL ScDataPilotFieldGroupsObj::getElementType() throw(RuntimeException)
2780 ScUnoGuard aGuard;
2781 return getCppuType( (Reference< XNameAccess >*)0 );
2784 sal_Bool SAL_CALL ScDataPilotFieldGroupsObj::hasElements() throw(RuntimeException)
2786 ScUnoGuard aGuard;
2787 return !maGroups.empty();
2790 // implementation
2792 ScFieldGroup& ScDataPilotFieldGroupsObj::getFieldGroup( const OUString& rName ) throw(RuntimeException)
2794 ScUnoGuard aGuard;
2795 ScFieldGroups::iterator aIt = implFindByName( rName );
2796 if( aIt == maGroups.end() )
2797 throw RuntimeException();
2798 return *aIt;
2801 void ScDataPilotFieldGroupsObj::renameFieldGroup( const OUString& rOldName, const OUString& rNewName ) throw(RuntimeException)
2803 ScUnoGuard aGuard;
2804 ScFieldGroups::iterator aOldIt = implFindByName( rOldName );
2805 ScFieldGroups::iterator aNewIt = implFindByName( rNewName );
2806 // new name must not exist yet
2807 if( (aOldIt == maGroups.end()) || ((aNewIt != maGroups.end()) && (aNewIt != aOldIt)) )
2808 throw RuntimeException();
2809 aOldIt->maName = rNewName;
2812 // private
2814 ScFieldGroups::iterator ScDataPilotFieldGroupsObj::implFindByName( const OUString& rName )
2816 for( ScFieldGroups::iterator aIt = maGroups.begin(), aEnd = maGroups.end(); aIt != aEnd; ++aIt )
2817 if( aIt->maName == rName )
2818 return aIt;
2819 return maGroups.end();
2822 // ============================================================================
2824 namespace {
2826 OUString lclExtractMember( const Any& rElement )
2828 if( rElement.has< OUString >() )
2829 return rElement.get< OUString >();
2831 Reference< XNamed > xNamed( rElement, UNO_QUERY );
2832 if( xNamed.is() )
2833 return xNamed->getName();
2835 return OUString();
2838 } // namespace
2840 // ----------------------------------------------------------------------------
2842 ScDataPilotFieldGroupObj::ScDataPilotFieldGroupObj( ScDataPilotFieldGroupsObj& rParent, const OUString& rGroupName ) :
2843 mrParent( rParent ),
2844 maGroupName( rGroupName )
2846 mrParent.acquire();
2849 ScDataPilotFieldGroupObj::~ScDataPilotFieldGroupObj()
2851 mrParent.release();
2854 // XNameAccess
2856 Any SAL_CALL ScDataPilotFieldGroupObj::getByName( const OUString& rName )
2857 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
2859 ScUnoGuard aGuard;
2860 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
2861 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
2862 if( aIt == rMembers.end() )
2863 throw NoSuchElementException();
2864 return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, *aIt ) ) );
2867 Sequence< OUString > SAL_CALL ScDataPilotFieldGroupObj::getElementNames() throw(RuntimeException)
2869 ScUnoGuard aGuard;
2870 return ::comphelper::containerToSequence( mrParent.getFieldGroup( maGroupName ).maMembers );
2873 sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasByName( const OUString& rName ) throw(RuntimeException)
2875 ScUnoGuard aGuard;
2876 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
2877 return ::std::find( rMembers.begin(), rMembers.end(), rName ) != rMembers.end();
2880 // XNameReplace
2882 void SAL_CALL ScDataPilotFieldGroupObj::replaceByName( const OUString& rName, const Any& rElement )
2883 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
2885 ScUnoGuard aGuard;
2887 // it should be possible to quickly rename an item -> accept string or XNamed
2888 OUString aNewName = lclExtractMember( rElement );
2889 if( (rName.getLength() == 0) || (aNewName.getLength() == 0) )
2890 throw IllegalArgumentException();
2891 if( rName == aNewName )
2892 return;
2894 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
2895 ScFieldGroupMembers::iterator aOldIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
2896 ScFieldGroupMembers::iterator aNewIt = ::std::find( rMembers.begin(), rMembers.end(), aNewName );
2897 // throw if passed member name does not exist
2898 if( aOldIt == rMembers.end() )
2899 throw NoSuchElementException();
2900 // throw if new name already exists
2901 if( aNewIt != rMembers.end() )
2902 throw IllegalArgumentException();
2903 *aOldIt = aNewName;
2906 // XNameContainer
2908 void SAL_CALL ScDataPilotFieldGroupObj::insertByName( const OUString& rName, const Any& /*rElement*/ )
2909 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
2911 ScUnoGuard aGuard;
2913 // we will ignore the passed element and just try to insert the name
2914 if( rName.getLength() == 0 )
2915 throw IllegalArgumentException();
2917 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
2918 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
2919 // throw if passed name already exists
2920 if( aIt != rMembers.end() )
2921 throw IllegalArgumentException();
2922 rMembers.push_back( rName );
2925 void SAL_CALL ScDataPilotFieldGroupObj::removeByName( const OUString& rName )
2926 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
2928 ScUnoGuard aGuard;
2930 if( rName.getLength() == 0 )
2931 throw IllegalArgumentException();
2932 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
2933 ScFieldGroupMembers::iterator aIt = ::std::find( rMembers.begin(), rMembers.end(), rName );
2934 // throw if passed name does not exist
2935 if( aIt == rMembers.end() )
2936 throw NoSuchElementException();
2937 rMembers.erase( aIt );
2940 // XIndexAccess
2942 sal_Int32 SAL_CALL ScDataPilotFieldGroupObj::getCount() throw(RuntimeException)
2944 ScUnoGuard aGuard;
2945 return static_cast< sal_Int32 >( mrParent.getFieldGroup( maGroupName ).maMembers.size() );
2948 Any SAL_CALL ScDataPilotFieldGroupObj::getByIndex( sal_Int32 nIndex )
2949 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
2951 ScUnoGuard aGuard;
2952 ScFieldGroupMembers& rMembers = mrParent.getFieldGroup( maGroupName ).maMembers;
2953 if ((nIndex < 0) || (nIndex >= static_cast< sal_Int32 >( rMembers.size() )))
2954 throw IndexOutOfBoundsException();
2955 return Any( Reference< XNamed >( new ScDataPilotFieldGroupItemObj( *this, rMembers[ nIndex ] ) ) );
2958 // XEnumerationAccess
2960 Reference< XEnumeration > SAL_CALL ScDataPilotFieldGroupObj::createEnumeration() throw(RuntimeException)
2962 ScUnoGuard aGuard;
2963 return new ScIndexEnumeration( this, OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.DataPilotFieldGroupEnumeration" ) ) );
2966 // XElementAccess
2968 uno::Type SAL_CALL ScDataPilotFieldGroupObj::getElementType() throw(RuntimeException)
2970 ScUnoGuard aGuard;
2971 return getCppuType( (Reference< XNamed >*)0 );
2974 sal_Bool SAL_CALL ScDataPilotFieldGroupObj::hasElements() throw(RuntimeException)
2976 ScUnoGuard aGuard;
2977 return !mrParent.getFieldGroup( maGroupName ).maMembers.empty();
2980 // XNamed
2982 OUString SAL_CALL ScDataPilotFieldGroupObj::getName() throw(RuntimeException)
2984 ScUnoGuard aGuard;
2985 return maGroupName;
2988 void SAL_CALL ScDataPilotFieldGroupObj::setName( const OUString& rName ) throw(RuntimeException)
2990 ScUnoGuard aGuard;
2991 mrParent.renameFieldGroup( maGroupName, rName );
2992 // if call to renameFieldGroup() did not throw, remember the new name
2993 maGroupName = rName;
2996 // ============================================================================
2998 ScDataPilotFieldGroupItemObj::ScDataPilotFieldGroupItemObj( ScDataPilotFieldGroupObj& rParent, const OUString& rName ) :
2999 mrParent( rParent ),
3000 maName( rName )
3002 mrParent.acquire();
3005 ScDataPilotFieldGroupItemObj::~ScDataPilotFieldGroupItemObj()
3007 mrParent.release();
3010 // XNamed
3012 OUString SAL_CALL ScDataPilotFieldGroupItemObj::getName() throw(RuntimeException)
3014 ScUnoGuard aGuard;
3015 return maName;
3018 void SAL_CALL ScDataPilotFieldGroupItemObj::setName( const OUString& rName ) throw(RuntimeException)
3020 ScUnoGuard aGuard;
3021 mrParent.replaceByName( maName, Any( rName ) );
3022 // if call to replaceByName() did not throw, remember the new name
3023 maName = rName;
3026 // ============================================================================
3028 ScDataPilotItemsObj::ScDataPilotItemsObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId ) :
3029 ScDataPilotChildObjBase( rParent, rFieldId )
3033 ScDataPilotItemsObj::~ScDataPilotItemsObj()
3037 // XDataPilotItems
3039 ScDataPilotItemObj* ScDataPilotItemsObj::GetObjectByIndex_Impl( sal_Int32 nIndex ) const
3041 return ((0 <= nIndex) && (nIndex < GetMemberCount())) ?
3042 new ScDataPilotItemObj( mrParent, maFieldId, nIndex ) : 0;
3045 // XNameAccess
3047 Any SAL_CALL ScDataPilotItemsObj::getByName( const OUString& aName )
3048 throw(NoSuchElementException, WrappedTargetException, RuntimeException)
3050 ScUnoGuard aGuard;
3051 Reference<XNameAccess> xMembers = GetMembers();
3052 if (xMembers.is())
3054 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3055 sal_Int32 nCount = xMembersIndex->getCount();
3056 sal_Bool bFound(sal_False);
3057 sal_Int32 nItem = 0;
3058 while (nItem < nCount && !bFound )
3060 Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3061 if (xMember.is() && (aName == xMember->getName()))
3062 return Any( Reference< XPropertySet >( GetObjectByIndex_Impl( nItem ) ) );
3063 ++nItem;
3065 if (!bFound)
3066 throw NoSuchElementException();
3068 return Any();
3071 Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
3072 throw(RuntimeException)
3074 ScUnoGuard aGuard;
3075 Sequence< OUString > aSeq;
3076 if( ScDPObject* pDPObj = GetDPObject() )
3077 pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
3078 return aSeq;
3081 sal_Bool SAL_CALL ScDataPilotItemsObj::hasByName( const OUString& aName )
3082 throw(RuntimeException)
3084 ScUnoGuard aGuard;
3085 sal_Bool bFound = sal_False;
3086 Reference<XNameAccess> xMembers = GetMembers();
3087 if (xMembers.is())
3089 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3090 sal_Int32 nCount = xMembersIndex->getCount();
3091 sal_Int32 nItem = 0;
3092 while (nItem < nCount && !bFound )
3094 Reference<XNamed> xMember(xMembersIndex->getByIndex(nItem), UNO_QUERY);
3095 if (xMember.is() && aName == xMember->getName())
3096 bFound = sal_True;
3097 else
3098 nItem++;
3101 return bFound;
3104 // XEnumerationAccess
3106 Reference<XEnumeration> SAL_CALL ScDataPilotItemsObj::createEnumeration()
3107 throw(RuntimeException)
3109 ScUnoGuard aGuard;
3110 return new ScIndexEnumeration(this, OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.DataPilotItemsEnumeration")));
3113 // XIndexAccess
3115 sal_Int32 SAL_CALL ScDataPilotItemsObj::getCount() throw(RuntimeException)
3117 ScUnoGuard aGuard;
3118 return GetMemberCount();
3121 Any SAL_CALL ScDataPilotItemsObj::getByIndex( sal_Int32 nIndex )
3122 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
3124 ScUnoGuard aGuard;
3125 Reference< XPropertySet > xItem( GetObjectByIndex_Impl( nIndex ) );
3126 if (!xItem.is())
3127 throw IndexOutOfBoundsException();
3128 return Any( xItem );
3131 uno::Type SAL_CALL ScDataPilotItemsObj::getElementType() throw(RuntimeException)
3133 ScUnoGuard aGuard;
3134 return getCppuType((Reference<XPropertySet>*)0);
3137 sal_Bool SAL_CALL ScDataPilotItemsObj::hasElements() throw(RuntimeException)
3139 ScUnoGuard aGuard;
3140 return ( getCount() != 0 );
3143 //------------------------------------------------------------------------
3145 ScDataPilotItemObj::ScDataPilotItemObj( ScDataPilotDescriptorBase& rParent, const ScFieldIdentifier& rFieldId, sal_Int32 nIndex ) :
3146 ScDataPilotChildObjBase( rParent, rFieldId ),
3147 maPropSet( lcl_GetDataPilotItemMap() ),
3148 mnIndex( nIndex )
3152 ScDataPilotItemObj::~ScDataPilotItemObj()
3156 // XNamed
3157 OUString SAL_CALL ScDataPilotItemObj::getName() throw(RuntimeException)
3159 ScUnoGuard aGuard;
3160 OUString sRet;
3161 Reference<XNameAccess> xMembers = GetMembers();
3162 if (xMembers.is())
3164 Reference<XIndexAccess> xMembersIndex(new ScNameToIndexAccess( xMembers ));
3165 sal_Int32 nCount = xMembersIndex->getCount();
3166 if (mnIndex < nCount)
3168 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3169 sRet = xMember->getName();
3172 return sRet;
3175 void SAL_CALL ScDataPilotItemObj::setName( const OUString& /* aName */ )
3176 throw(RuntimeException)
3180 // XPropertySet
3181 Reference< XPropertySetInfo >
3182 SAL_CALL ScDataPilotItemObj::getPropertySetInfo( )
3183 throw(RuntimeException)
3185 ScUnoGuard aGuard;
3186 static Reference<XPropertySetInfo> aRef =
3187 new SfxItemPropertySetInfo( maPropSet.getPropertyMap() );
3188 return aRef;
3191 void SAL_CALL ScDataPilotItemObj::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
3192 throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
3194 ScUnoGuard aGuard;
3195 ScDPObject* pDPObj = 0;
3196 if( ScDPSaveDimension* pDim = GetDPDimension( &pDPObj ) )
3198 Reference<XNameAccess> xMembers = GetMembers();
3199 if( xMembers.is() )
3201 Reference<XIndexAccess> xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3202 sal_Int32 nCount = xMembersIndex->getCount();
3203 if( mnIndex < nCount )
3205 Reference<XNamed> xMember(xMembersIndex->getByIndex(mnIndex), UNO_QUERY);
3206 String sName(xMember->getName());
3207 ScDPSaveMember* pMember = pDim->GetMemberByName(sName);
3208 if (pMember)
3210 bool bGetNewIndex = false;
3211 if ( aPropertyName.equalsAscii( SC_UNONAME_SHOWDETAIL ) )
3212 pMember->SetShowDetails(cppu::any2bool(aValue));
3213 else if ( aPropertyName.equalsAscii( SC_UNONAME_ISHIDDEN ) )
3214 pMember->SetIsVisible(!cppu::any2bool(aValue));
3215 else if ( aPropertyName.equalsAscii( SC_UNONAME_POS ) )
3217 sal_Int32 nNewPos = 0;
3218 if ( ( aValue >>= nNewPos ) && nNewPos >= 0 && nNewPos < nCount )
3220 pDim->SetMemberPosition( sName, nNewPos );
3221 // get new effective index (depends on sorting mode, which isn't modified)
3222 bGetNewIndex = true;
3224 else
3225 throw IllegalArgumentException();
3227 SetDPObject( pDPObj );
3229 if ( bGetNewIndex ) // after SetDPObject, get the new index
3231 OUString aOUName( sName );
3232 Sequence< OUString > aItemNames = xMembers->getElementNames();
3233 sal_Int32 nItemCount = aItemNames.getLength();
3234 for (sal_Int32 nItem=0; nItem<nItemCount; ++nItem)
3235 if (aItemNames[nItem] == aOUName)
3236 mnIndex = nItem;
3244 Any SAL_CALL ScDataPilotItemObj::getPropertyValue( const OUString& aPropertyName )
3245 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3247 ScUnoGuard aGuard;
3248 Any aRet;
3249 if( ScDPSaveDimension* pDim = GetDPDimension() )
3251 Reference< XNameAccess > xMembers = GetMembers();
3252 if( xMembers.is() )
3254 Reference< XIndexAccess > xMembersIndex( new ScNameToIndexAccess( xMembers ) );
3255 sal_Int32 nCount = xMembersIndex->getCount();
3256 if( mnIndex < nCount )
3258 Reference< XNamed > xMember( xMembersIndex->getByIndex( mnIndex ), UNO_QUERY );
3259 String sName( xMember->getName() );
3260 ScDPSaveMember* pMember = pDim->GetExistingMemberByName( sName );
3261 if( aPropertyName.equalsAscii( SC_UNONAME_SHOWDETAIL ) )
3263 if (pMember && pMember->HasShowDetails())
3265 aRet <<= (bool)pMember->GetShowDetails();
3267 else
3269 Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3270 if( xMemberProps.is() )
3271 aRet = xMemberProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWDETA ) ) );
3272 else
3273 aRet <<= true;
3276 else if ( aPropertyName.equalsAscii( SC_UNONAME_ISHIDDEN ) )
3278 if (pMember && pMember->HasIsVisible())
3280 aRet <<= !pMember->GetIsVisible();
3282 else
3284 Reference< XPropertySet > xMemberProps( xMember, UNO_QUERY );
3285 if( xMemberProps.is() )
3286 aRet <<= !cppu::any2bool( xMemberProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ISVISIBL ) ) ) );
3287 else
3288 aRet <<= false;
3291 else if ( aPropertyName.equalsAscii( SC_UNONAME_POS ) )
3293 aRet <<= mnIndex;
3298 return aRet;
3301 void SAL_CALL ScDataPilotItemObj::addPropertyChangeListener(
3302 const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* xListener */ )
3303 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3307 void SAL_CALL ScDataPilotItemObj::removePropertyChangeListener(
3308 const OUString& /* aPropertyName */, const Reference< XPropertyChangeListener >& /* aListener */ )
3309 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3313 void SAL_CALL ScDataPilotItemObj::addVetoableChangeListener(
3314 const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3315 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3319 void SAL_CALL ScDataPilotItemObj::removeVetoableChangeListener(
3320 const OUString& /* PropertyName */, const Reference< XVetoableChangeListener >& /* aListener */ )
3321 throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
3325 //------------------------------------------------------------------------