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