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