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 28 29 #include <svl/smplhint.hxx> 30 31 #include <com/sun/star/sheet/NamedRangeFlag.hpp> 32 #include <com/sun/star/awt/XBitmap.hpp> 33 #include <com/sun/star/beans/PropertyAttribute.hpp> 34 35 using namespace ::com::sun::star; 36 37 38 #include "nameuno.hxx" 39 #include "miscuno.hxx" 40 #include "cellsuno.hxx" 41 #include "convuno.hxx" 42 #include "targuno.hxx" 43 #include "tokenuno.hxx" 44 #include "tokenarray.hxx" 45 #include "docsh.hxx" 46 #include "docfunc.hxx" 47 #include "rangenam.hxx" 48 //CHINA001 #include "namecrea.hxx" // NAME_TOP etc. 49 #include "unoguard.hxx" 50 #include "unonames.hxx" 51 52 #include "scui_def.hxx" //CHINA001 53 54 //------------------------------------------------------------------------ 55 56 const SfxItemPropertyMapEntry* lcl_GetNamedRangeMap() 57 { 58 static SfxItemPropertyMapEntry aNamedRangeMap_Impl[] = 59 { 60 {MAP_CHAR_LEN(SC_UNO_LINKDISPBIT), 0, &getCppuType((uno::Reference<awt::XBitmap>*)0), beans::PropertyAttribute::READONLY, 0 }, 61 {MAP_CHAR_LEN(SC_UNO_LINKDISPNAME), 0, &getCppuType((rtl::OUString*)0), beans::PropertyAttribute::READONLY, 0 }, 62 {MAP_CHAR_LEN(SC_UNONAME_TOKENINDEX), 0, &getCppuType((sal_Int32*)0), beans::PropertyAttribute::READONLY, 0 }, 63 {MAP_CHAR_LEN(SC_UNONAME_ISSHAREDFMLA), 0, &getBooleanCppuType(), 0, 0 }, 64 {0,0,0,0,0,0} 65 }; 66 return aNamedRangeMap_Impl; 67 } 68 69 //------------------------------------------------------------------------ 70 71 #define SCNAMEDRANGEOBJ_SERVICE "com.sun.star.sheet.NamedRange" 72 73 SC_SIMPLE_SERVICE_INFO( ScLabelRangeObj, "ScLabelRangeObj", "com.sun.star.sheet.LabelRange" ) 74 SC_SIMPLE_SERVICE_INFO( ScLabelRangesObj, "ScLabelRangesObj", "com.sun.star.sheet.LabelRanges" ) 75 SC_SIMPLE_SERVICE_INFO( ScNamedRangesObj, "ScNamedRangesObj", "com.sun.star.sheet.NamedRanges" ) 76 77 //------------------------------------------------------------------------ 78 79 sal_Bool lcl_UserVisibleName( const ScRangeData* pData ) 80 { 81 //! als Methode an ScRangeData 82 83 return ( pData && !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) ); 84 } 85 86 //------------------------------------------------------------------------ 87 88 ScNamedRangeObj::ScNamedRangeObj(ScDocShell* pDocSh, const String& rNm) : 89 pDocShell( pDocSh ), 90 aName( rNm ) 91 { 92 pDocShell->GetDocument()->AddUnoObject(*this); 93 } 94 95 ScNamedRangeObj::~ScNamedRangeObj() 96 { 97 if (pDocShell) 98 pDocShell->GetDocument()->RemoveUnoObject(*this); 99 } 100 101 void ScNamedRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 102 { 103 // Ref-Update interessiert nicht 104 105 if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 106 pDocShell = NULL; // ungueltig geworden 107 } 108 109 // Hilfsfuntionen 110 111 ScRangeData* ScNamedRangeObj::GetRangeData_Impl() 112 { 113 ScRangeData* pRet = NULL; 114 if (pDocShell) 115 { 116 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); 117 if (pNames) 118 { 119 sal_uInt16 nPos = 0; 120 if (pNames->SearchName( aName, nPos )) 121 { 122 pRet = (*pNames)[nPos]; 123 pRet->ValidateTabRefs(); // adjust relative tab refs to valid tables 124 } 125 } 126 } 127 return pRet; 128 } 129 130 // sheet::XNamedRange 131 132 void ScNamedRangeObj::Modify_Impl( const String* pNewName, const ScTokenArray* pNewTokens, const String* pNewContent, 133 const ScAddress* pNewPos, const sal_uInt16* pNewType, 134 const formula::FormulaGrammar::Grammar eGrammar ) 135 { 136 if (pDocShell) 137 { 138 ScDocument* pDoc = pDocShell->GetDocument(); 139 ScRangeName* pNames = pDoc->GetRangeName(); 140 if (pNames) 141 { 142 sal_uInt16 nPos = 0; 143 if (pNames->SearchName( aName, nPos )) 144 { 145 ScRangeName* pNewRanges = new ScRangeName( *pNames ); 146 ScRangeData* pOld = (*pNames)[nPos]; 147 148 String aInsName(pOld->GetName()); 149 if (pNewName) 150 aInsName = *pNewName; 151 String aContent; // Content string based => 152 pOld->GetSymbol( aContent, eGrammar); // no problems with changed positions and such. 153 if (pNewContent) 154 aContent = *pNewContent; 155 ScAddress aPos(pOld->GetPos()); 156 if (pNewPos) 157 aPos = *pNewPos; 158 sal_uInt16 nType = pOld->GetType(); 159 if (pNewType) 160 nType = *pNewType; 161 162 ScRangeData* pNew = NULL; 163 if ( pNewTokens ) 164 pNew = new ScRangeData( pDoc, aInsName, *pNewTokens, aPos, nType ); 165 else 166 pNew = new ScRangeData( pDoc, aInsName, aContent, aPos, nType, eGrammar ); 167 pNew->SetIndex( pOld->GetIndex() ); 168 169 pNewRanges->AtFree( nPos ); 170 if ( pNewRanges->Insert(pNew) ) 171 { 172 ScDocFunc aFunc(*pDocShell); 173 aFunc.SetNewRangeNames( pNewRanges, sal_True ); 174 175 aName = aInsName; //! broadcast? 176 } 177 else 178 { 179 delete pNew; //! uno::Exception/Fehler oder so 180 delete pNewRanges; 181 } 182 } 183 } 184 } 185 } 186 187 188 rtl::OUString SAL_CALL ScNamedRangeObj::getName() throw(uno::RuntimeException) 189 { 190 ScUnoGuard aGuard; 191 return aName; 192 } 193 194 void SAL_CALL ScNamedRangeObj::setName( const rtl::OUString& aNewName ) 195 throw(uno::RuntimeException) 196 { 197 ScUnoGuard aGuard; 198 //! Formeln anpassen ????? 199 200 String aNewStr(aNewName); 201 // GRAM_PODF_A1 for API compatibility. 202 Modify_Impl( &aNewStr, NULL, NULL, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 ); 203 204 if ( aName != aNewStr ) // some error occured... 205 throw uno::RuntimeException(); // no other exceptions specified 206 } 207 208 rtl::OUString SAL_CALL ScNamedRangeObj::getContent() throw(uno::RuntimeException) 209 { 210 ScUnoGuard aGuard; 211 String aContent; 212 ScRangeData* pData = GetRangeData_Impl(); 213 if (pData) 214 // GRAM_PODF_A1 for API compatibility. 215 pData->GetSymbol( aContent,formula::FormulaGrammar::GRAM_PODF_A1); 216 return aContent; 217 } 218 219 void SAL_CALL ScNamedRangeObj::setContent( const rtl::OUString& aContent ) 220 throw(uno::RuntimeException) 221 { 222 ScUnoGuard aGuard; 223 String aContStr(aContent); 224 // GRAM_PODF_A1 for API compatibility. 225 Modify_Impl( NULL, NULL, &aContStr, NULL, NULL,formula::FormulaGrammar::GRAM_PODF_A1 ); 226 } 227 228 void ScNamedRangeObj::SetContentWithGrammar( const ::rtl::OUString& aContent, 229 const formula::FormulaGrammar::Grammar eGrammar ) 230 throw(::com::sun::star::uno::RuntimeException) 231 { 232 String aContStr(aContent); 233 Modify_Impl( NULL, NULL, &aContStr, NULL, NULL, eGrammar ); 234 } 235 236 table::CellAddress SAL_CALL ScNamedRangeObj::getReferencePosition() 237 throw(uno::RuntimeException) 238 { 239 ScUnoGuard aGuard; 240 ScAddress aPos; 241 ScRangeData* pData = GetRangeData_Impl(); 242 if (pData) 243 aPos = pData->GetPos(); 244 table::CellAddress aAddress; 245 aAddress.Column = aPos.Col(); 246 aAddress.Row = aPos.Row(); 247 aAddress.Sheet = aPos.Tab(); 248 if (pDocShell) 249 { 250 SCTAB nDocTabs = pDocShell->GetDocument()->GetTableCount(); 251 if ( aAddress.Sheet >= nDocTabs && nDocTabs > 0 ) 252 { 253 // Even after ValidateTabRefs, the position can be invalid if 254 // the content points to preceding tables. The resulting string 255 // is invalid in any case, so the position is just shifted. 256 aAddress.Sheet = nDocTabs - 1; 257 } 258 } 259 return aAddress; 260 } 261 262 void SAL_CALL ScNamedRangeObj::setReferencePosition( const table::CellAddress& aReferencePosition ) 263 throw(uno::RuntimeException) 264 { 265 ScUnoGuard aGuard; 266 ScAddress aPos( (SCCOL)aReferencePosition.Column, (SCROW)aReferencePosition.Row, aReferencePosition.Sheet ); 267 // GRAM_PODF_A1 for API compatibility. 268 Modify_Impl( NULL, NULL, NULL, &aPos, NULL,formula::FormulaGrammar::GRAM_PODF_A1 ); 269 } 270 271 sal_Int32 SAL_CALL ScNamedRangeObj::getType() throw(uno::RuntimeException) 272 { 273 ScUnoGuard aGuard; 274 sal_Int32 nType=0; 275 ScRangeData* pData = GetRangeData_Impl(); 276 if (pData) 277 { 278 // do not return internal RT_* flags 279 // see property 'IsSharedFormula' for RT_SHARED 280 if ( pData->HasType(RT_CRITERIA) ) nType |= sheet::NamedRangeFlag::FILTER_CRITERIA; 281 if ( pData->HasType(RT_PRINTAREA) ) nType |= sheet::NamedRangeFlag::PRINT_AREA; 282 if ( pData->HasType(RT_COLHEADER) ) nType |= sheet::NamedRangeFlag::COLUMN_HEADER; 283 if ( pData->HasType(RT_ROWHEADER) ) nType |= sheet::NamedRangeFlag::ROW_HEADER; 284 } 285 return nType; 286 } 287 288 void SAL_CALL ScNamedRangeObj::setType( sal_Int32 nUnoType ) throw(uno::RuntimeException) 289 { 290 // see property 'IsSharedFormula' for RT_SHARED 291 ScUnoGuard aGuard; 292 sal_uInt16 nNewType = RT_NAME; 293 if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA; 294 if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA; 295 if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER; 296 if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER; 297 298 // GRAM_PODF_A1 for API compatibility. 299 Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 ); 300 } 301 302 // XFormulaTokens 303 304 uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens() throw(uno::RuntimeException) 305 { 306 ScUnoGuard aGuard; 307 uno::Sequence<sheet::FormulaToken> aSequence; 308 ScRangeData* pData = GetRangeData_Impl(); 309 if (pData && pDocShell) 310 { 311 ScTokenArray* pTokenArray = pData->GetCode(); 312 if ( pTokenArray ) 313 (void)ScTokenConversion::ConvertToTokenSequence( *pDocShell->GetDocument(), aSequence, *pTokenArray ); 314 } 315 return aSequence; 316 } 317 318 void SAL_CALL ScNamedRangeObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException) 319 { 320 ScUnoGuard aGuard; 321 if( pDocShell ) 322 { 323 ScTokenArray aTokenArray; 324 (void)ScTokenConversion::ConvertToTokenArray( *pDocShell->GetDocument(), aTokenArray, rTokens ); 325 // GRAM_PODF_A1 for API compatibility. 326 Modify_Impl( NULL, &aTokenArray, NULL, NULL, NULL, formula::FormulaGrammar::GRAM_PODF_A1 ); 327 } 328 } 329 330 331 // XCellRangeSource 332 333 uno::Reference<table::XCellRange> SAL_CALL ScNamedRangeObj::getReferredCells() 334 throw(uno::RuntimeException) 335 { 336 ScUnoGuard aGuard; 337 ScRange aRange; 338 ScRangeData* pData = GetRangeData_Impl(); 339 if ( pData && pData->IsValidReference( aRange ) ) 340 { 341 //! static Funktion um ScCellObj/ScCellRangeObj zu erzeugen am ScCellRangeObj ??? 342 343 if ( aRange.aStart == aRange.aEnd ) 344 return new ScCellObj( pDocShell, aRange.aStart ); 345 else 346 return new ScCellRangeObj( pDocShell, aRange ); 347 } 348 return NULL; 349 } 350 351 // beans::XPropertySet 352 353 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScNamedRangeObj::getPropertySetInfo() 354 throw(uno::RuntimeException) 355 { 356 ScUnoGuard aGuard; 357 static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetNamedRangeMap() )); 358 return aRef; 359 } 360 361 void SAL_CALL ScNamedRangeObj::setPropertyValue( 362 const rtl::OUString& rPropertyName, const uno::Any& aValue ) 363 throw(beans::UnknownPropertyException, beans::PropertyVetoException, 364 lang::IllegalArgumentException, lang::WrappedTargetException, 365 uno::RuntimeException) 366 { 367 ScUnoGuard aGuard; 368 if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) ) 369 { 370 bool bIsShared = false; 371 if( aValue >>= bIsShared ) 372 { 373 sal_uInt16 nNewType = bIsShared ? RT_SHARED : RT_NAME; 374 Modify_Impl( NULL, NULL, NULL, NULL, &nNewType,formula::FormulaGrammar::GRAM_PODF_A1 ); 375 } 376 } 377 } 378 379 uno::Any SAL_CALL ScNamedRangeObj::getPropertyValue( const rtl::OUString& rPropertyName ) 380 throw(beans::UnknownPropertyException, lang::WrappedTargetException, 381 uno::RuntimeException) 382 { 383 ScUnoGuard aGuard; 384 uno::Any aRet; 385 if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPBIT ) ) 386 { 387 // no target bitmaps for individual entries (would be all equal) 388 // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_RANGENAME ); 389 } 390 else if ( rPropertyName.equalsAscii( SC_UNO_LINKDISPNAME ) ) 391 aRet <<= rtl::OUString( aName ); 392 else if ( rPropertyName.equalsAscii( SC_UNONAME_TOKENINDEX ) ) 393 { 394 // get index for use in formula tokens (read-only) 395 ScRangeData* pData = GetRangeData_Impl(); 396 if (pData) 397 aRet <<= static_cast<sal_Int32>(pData->GetIndex()); 398 } 399 else if ( rPropertyName.equalsAscii( SC_UNONAME_ISSHAREDFMLA ) ) 400 { 401 if( ScRangeData* pData = GetRangeData_Impl() ) 402 aRet <<= static_cast< bool >( pData->HasType( RT_SHARED ) ); 403 } 404 return aRet; 405 } 406 407 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScNamedRangeObj ) 408 409 // lang::XServiceInfo 410 411 rtl::OUString SAL_CALL ScNamedRangeObj::getImplementationName() throw(uno::RuntimeException) 412 { 413 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScNamedRangeObj" ) ); 414 } 415 416 sal_Bool SAL_CALL ScNamedRangeObj::supportsService( const rtl::OUString& rServiceName ) 417 throw(uno::RuntimeException) 418 { 419 return rServiceName.equalsAscii( SCNAMEDRANGEOBJ_SERVICE ) || 420 rServiceName.equalsAscii( SCLINKTARGET_SERVICE ); 421 } 422 423 uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangeObj::getSupportedServiceNames() 424 throw(uno::RuntimeException) 425 { 426 uno::Sequence<rtl::OUString> aRet(2); 427 aRet[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCNAMEDRANGEOBJ_SERVICE ) ); 428 aRet[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SCLINKTARGET_SERVICE ) ); 429 return aRet; 430 } 431 432 433 // XUnoTunnel 434 435 sal_Int64 SAL_CALL ScNamedRangeObj::getSomething( 436 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException) 437 { 438 if ( rId.getLength() == 16 && 439 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 440 rId.getConstArray(), 16 ) ) 441 { 442 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); 443 } 444 return 0; 445 } 446 447 // static 448 const uno::Sequence<sal_Int8>& ScNamedRangeObj::getUnoTunnelId() 449 { 450 static uno::Sequence<sal_Int8> * pSeq = 0; 451 if( !pSeq ) 452 { 453 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 454 if( !pSeq ) 455 { 456 static uno::Sequence< sal_Int8 > aSeq( 16 ); 457 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 458 pSeq = &aSeq; 459 } 460 } 461 return *pSeq; 462 } 463 464 // static 465 ScNamedRangeObj* ScNamedRangeObj::getImplementation( const uno::Reference<uno::XInterface> xObj ) 466 { 467 ScNamedRangeObj* pRet = NULL; 468 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY ); 469 if (xUT.is()) 470 pRet = reinterpret_cast<ScNamedRangeObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId()))); 471 return pRet; 472 } 473 474 //------------------------------------------------------------------------ 475 476 ScNamedRangesObj::ScNamedRangesObj(ScDocShell* pDocSh) : 477 pDocShell( pDocSh ) 478 { 479 pDocShell->GetDocument()->AddUnoObject(*this); 480 } 481 482 ScNamedRangesObj::~ScNamedRangesObj() 483 { 484 if (pDocShell) 485 pDocShell->GetDocument()->RemoveUnoObject(*this); 486 } 487 488 void ScNamedRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 489 { 490 // Referenz-Update interessiert hier nicht 491 492 if ( rHint.ISA( SfxSimpleHint ) && 493 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 494 { 495 pDocShell = NULL; // ungueltig geworden 496 } 497 } 498 499 // sheet::XNamedRanges 500 501 ScNamedRangeObj* ScNamedRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex) 502 { 503 if (pDocShell) 504 { 505 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); 506 if (pNames) 507 { 508 sal_uInt16 nCount = pNames->GetCount(); 509 sal_uInt16 nPos = 0; 510 for (sal_uInt16 i=0; i<nCount; i++) 511 { 512 ScRangeData* pData = (*pNames)[i]; 513 if (lcl_UserVisibleName(pData)) // interne weglassen 514 { 515 if ( nPos == nIndex ) 516 return new ScNamedRangeObj( pDocShell, pData->GetName() ); 517 ++nPos; 518 } 519 } 520 } 521 } 522 return NULL; 523 } 524 525 ScNamedRangeObj* ScNamedRangesObj::GetObjectByName_Impl(const rtl::OUString& aName) 526 { 527 if ( pDocShell && hasByName(aName) ) 528 return new ScNamedRangeObj( pDocShell, String(aName) ); 529 return NULL; 530 } 531 532 void SAL_CALL ScNamedRangesObj::addNewByName( const rtl::OUString& aName, 533 const rtl::OUString& aContent, const table::CellAddress& aPosition, 534 sal_Int32 nUnoType ) throw(uno::RuntimeException) 535 { 536 ScUnoGuard aGuard; 537 String aNameStr(aName); 538 String aContStr(aContent); 539 ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, aPosition.Sheet ); 540 541 sal_uInt16 nNewType = RT_NAME; 542 if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= RT_CRITERIA; 543 if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= RT_PRINTAREA; 544 if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= RT_COLHEADER; 545 if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= RT_ROWHEADER; 546 547 sal_Bool bDone = sal_False; 548 if (pDocShell) 549 { 550 ScDocument* pDoc = pDocShell->GetDocument(); 551 ScRangeName* pNames = pDoc->GetRangeName(); 552 sal_uInt16 nIndex = 0; 553 if (pNames && !pNames->SearchName(aNameStr, nIndex)) 554 { 555 ScRangeName* pNewRanges = new ScRangeName( *pNames ); 556 // GRAM_PODF_A1 for API compatibility. 557 ScRangeData* pNew = new ScRangeData( pDoc, aNameStr, aContStr, 558 aPos, nNewType,formula::FormulaGrammar::GRAM_PODF_A1 ); 559 if ( pNewRanges->Insert(pNew) ) 560 { 561 ScDocFunc aFunc(*pDocShell); 562 aFunc.SetNewRangeNames( pNewRanges, sal_True ); 563 bDone = sal_True; 564 } 565 else 566 { 567 delete pNew; 568 delete pNewRanges; 569 } 570 } 571 } 572 573 if (!bDone) 574 throw uno::RuntimeException(); // no other exceptions specified 575 } 576 577 void SAL_CALL ScNamedRangesObj::addNewFromTitles( const table::CellRangeAddress& aSource, 578 sheet::Border aBorder ) throw(uno::RuntimeException) 579 { 580 ScUnoGuard aGuard; 581 //! das darf kein enum sein, weil mehrere Bits gesetzt sein koennen !!! 582 583 sal_Bool bTop = ( aBorder == sheet::Border_TOP ); 584 sal_Bool bLeft = ( aBorder == sheet::Border_LEFT ); 585 sal_Bool bBottom = ( aBorder == sheet::Border_BOTTOM ); 586 sal_Bool bRight = ( aBorder == sheet::Border_RIGHT ); 587 588 ScRange aRange; 589 ScUnoConversion::FillScRange( aRange, aSource ); 590 591 sal_uInt16 nFlags = 0; 592 if (bTop) nFlags |= NAME_TOP; 593 if (bLeft) nFlags |= NAME_LEFT; 594 if (bBottom) nFlags |= NAME_BOTTOM; 595 if (bRight) nFlags |= NAME_RIGHT; 596 597 if (nFlags) 598 { 599 ScDocFunc aFunc(*pDocShell); 600 aFunc.CreateNames( aRange, nFlags, sal_True ); 601 } 602 } 603 604 void SAL_CALL ScNamedRangesObj::removeByName( const rtl::OUString& aName ) 605 throw(uno::RuntimeException) 606 { 607 ScUnoGuard aGuard; 608 sal_Bool bDone = sal_False; 609 if (pDocShell) 610 { 611 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); 612 if (pNames) 613 { 614 String aString(aName); 615 sal_uInt16 nPos = 0; 616 if (pNames->SearchName( aString, nPos )) 617 if ( lcl_UserVisibleName((*pNames)[nPos]) ) 618 { 619 ScRangeName* pNewRanges = new ScRangeName(*pNames); 620 pNewRanges->AtFree(nPos); 621 ScDocFunc aFunc(*pDocShell); 622 aFunc.SetNewRangeNames( pNewRanges, sal_True ); 623 bDone = sal_True; 624 } 625 } 626 } 627 628 if (!bDone) 629 throw uno::RuntimeException(); // no other exceptions specified 630 } 631 632 void SAL_CALL ScNamedRangesObj::outputList( const table::CellAddress& aOutputPosition ) 633 throw(uno::RuntimeException) 634 { 635 ScUnoGuard aGuard; 636 ScAddress aPos( (SCCOL)aOutputPosition.Column, (SCROW)aOutputPosition.Row, aOutputPosition.Sheet ); 637 if (pDocShell) 638 { 639 ScDocFunc aFunc(*pDocShell); 640 aFunc.InsertNameList( aPos, sal_True ); 641 } 642 } 643 644 // container::XEnumerationAccess 645 646 uno::Reference<container::XEnumeration> SAL_CALL ScNamedRangesObj::createEnumeration() 647 throw(uno::RuntimeException) 648 { 649 ScUnoGuard aGuard; 650 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.NamedRangesEnumeration"))); 651 } 652 653 // container::XIndexAccess 654 655 sal_Int32 SAL_CALL ScNamedRangesObj::getCount() throw(uno::RuntimeException) 656 { 657 ScUnoGuard aGuard; 658 long nRet = 0; 659 if (pDocShell) 660 { 661 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); 662 if (pNames) 663 { 664 sal_uInt16 nCount = pNames->GetCount(); 665 for (sal_uInt16 i=0; i<nCount; i++) 666 if (lcl_UserVisibleName( (*pNames)[i] )) // interne weglassen 667 ++nRet; 668 } 669 } 670 return nRet; 671 } 672 673 uno::Any SAL_CALL ScNamedRangesObj::getByIndex( sal_Int32 nIndex ) 674 throw(lang::IndexOutOfBoundsException, 675 lang::WrappedTargetException, uno::RuntimeException) 676 { 677 ScUnoGuard aGuard; 678 uno::Reference< sheet::XNamedRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex)); 679 if ( xRange.is() ) 680 return uno::makeAny(xRange); 681 else 682 throw lang::IndexOutOfBoundsException(); 683 // return uno::Any(); 684 } 685 686 uno::Type SAL_CALL ScNamedRangesObj::getElementType() throw(uno::RuntimeException) 687 { 688 ScUnoGuard aGuard; 689 return ::getCppuType((const uno::Reference< sheet::XNamedRange >*)0); // muss zu getByIndex passen 690 } 691 692 sal_Bool SAL_CALL ScNamedRangesObj::hasElements() throw(uno::RuntimeException) 693 { 694 ScUnoGuard aGuard; 695 return ( getCount() != 0 ); 696 } 697 698 uno::Any SAL_CALL ScNamedRangesObj::getByName( const rtl::OUString& aName ) 699 throw(container::NoSuchElementException, 700 lang::WrappedTargetException, uno::RuntimeException) 701 { 702 ScUnoGuard aGuard; 703 uno::Reference< sheet::XNamedRange > xRange(GetObjectByName_Impl(aName)); 704 if ( xRange.is() ) 705 return uno::makeAny(xRange); 706 else 707 throw container::NoSuchElementException(); 708 // return uno::Any(); 709 } 710 711 uno::Sequence<rtl::OUString> SAL_CALL ScNamedRangesObj::getElementNames() 712 throw(uno::RuntimeException) 713 { 714 ScUnoGuard aGuard; 715 if (pDocShell) 716 { 717 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); 718 if (pNames) 719 { 720 long nVisCount = getCount(); // Namen mit lcl_UserVisibleName 721 uno::Sequence<rtl::OUString> aSeq(nVisCount); 722 rtl::OUString* pAry = aSeq.getArray(); 723 724 sal_uInt16 nCount = pNames->GetCount(); 725 sal_uInt16 nVisPos = 0; 726 for (sal_uInt16 i=0; i<nCount; i++) 727 { 728 ScRangeData* pData = (*pNames)[i]; 729 if ( lcl_UserVisibleName(pData) ) 730 pAry[nVisPos++] = pData->GetName(); 731 } 732 // DBG_ASSERT(nVisPos == nVisCount, "huch, verzaehlt?"); 733 return aSeq; 734 } 735 } 736 return uno::Sequence<rtl::OUString>(0); 737 } 738 739 sal_Bool SAL_CALL ScNamedRangesObj::hasByName( const rtl::OUString& aName ) 740 throw(uno::RuntimeException) 741 { 742 ScUnoGuard aGuard; 743 if (pDocShell) 744 { 745 ScRangeName* pNames = pDocShell->GetDocument()->GetRangeName(); 746 if (pNames) 747 { 748 sal_uInt16 nPos = 0; 749 if (pNames->SearchName( String(aName), nPos )) 750 if ( lcl_UserVisibleName((*pNames)[nPos]) ) 751 return sal_True; 752 } 753 } 754 return sal_False; 755 } 756 757 /** called from the XActionLockable interface methods on initial locking */ 758 void ScNamedRangesObj::lock() 759 { 760 pDocShell->GetDocument()->CompileNameFormula( sal_True ); // CreateFormulaString 761 } 762 763 /** called from the XActionLockable interface methods on final unlock */ 764 void ScNamedRangesObj::unlock() 765 { 766 pDocShell->GetDocument()->CompileNameFormula( sal_False ); // CompileFormulaString 767 } 768 769 // document::XActionLockable 770 771 sal_Bool ScNamedRangesObj::isActionLocked() throw(uno::RuntimeException) 772 { 773 ScUnoGuard aGuard; 774 return pDocShell->GetDocument()->GetNamedRangesLockCount() != 0; 775 } 776 777 void ScNamedRangesObj::addActionLock() throw(uno::RuntimeException) 778 { 779 ScUnoGuard aGuard; 780 ScDocument* pDoc = pDocShell->GetDocument(); 781 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount(); 782 ++nLockCount; 783 if ( nLockCount == 1 ) 784 { 785 lock(); 786 } 787 pDoc->SetNamedRangesLockCount( nLockCount ); 788 } 789 790 void ScNamedRangesObj::removeActionLock() throw(uno::RuntimeException) 791 { 792 ScUnoGuard aGuard; 793 ScDocument* pDoc = pDocShell->GetDocument(); 794 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount(); 795 if ( nLockCount > 0 ) 796 { 797 --nLockCount; 798 if ( nLockCount == 0 ) 799 { 800 unlock(); 801 } 802 pDoc->SetNamedRangesLockCount( nLockCount ); 803 } 804 } 805 806 void ScNamedRangesObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException) 807 { 808 ScUnoGuard aGuard; 809 if ( nLock >= 0 ) 810 { 811 ScDocument* pDoc = pDocShell->GetDocument(); 812 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount(); 813 if ( nLock == 0 && nLockCount > 0 ) 814 { 815 unlock(); 816 } 817 if ( nLock > 0 && nLockCount == 0 ) 818 { 819 lock(); 820 } 821 pDoc->SetNamedRangesLockCount( nLock ); 822 } 823 } 824 825 sal_Int16 ScNamedRangesObj::resetActionLocks() throw(uno::RuntimeException) 826 { 827 ScUnoGuard aGuard; 828 ScDocument* pDoc = pDocShell->GetDocument(); 829 sal_Int16 nLockCount = pDoc->GetNamedRangesLockCount(); 830 if ( nLockCount > 0 ) 831 { 832 unlock(); 833 } 834 pDoc->SetNamedRangesLockCount( 0 ); 835 return nLockCount; 836 } 837 838 //------------------------------------------------------------------------ 839 840 ScLabelRangeObj::ScLabelRangeObj(ScDocShell* pDocSh, sal_Bool bCol, const ScRange& rR) : 841 pDocShell( pDocSh ), 842 bColumn( bCol ), 843 aRange( rR ) 844 { 845 pDocShell->GetDocument()->AddUnoObject(*this); 846 } 847 848 ScLabelRangeObj::~ScLabelRangeObj() 849 { 850 if (pDocShell) 851 pDocShell->GetDocument()->RemoveUnoObject(*this); 852 } 853 854 void ScLabelRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 855 { 856 //! Ref-Update !!! 857 858 if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 859 pDocShell = NULL; // ungueltig geworden 860 } 861 862 // Hilfsfuntionen 863 864 ScRangePair* ScLabelRangeObj::GetData_Impl() 865 { 866 ScRangePair* pRet = NULL; 867 if (pDocShell) 868 { 869 ScDocument* pDoc = pDocShell->GetDocument(); 870 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); 871 if (pList) 872 pRet = pList->Find( aRange ); 873 } 874 return pRet; 875 } 876 877 void ScLabelRangeObj::Modify_Impl( const ScRange* pLabel, const ScRange* pData ) 878 { 879 if (pDocShell) 880 { 881 ScDocument* pDoc = pDocShell->GetDocument(); 882 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); 883 if (pOldList) 884 { 885 ScRangePairListRef xNewList(pOldList->Clone()); 886 ScRangePair* pEntry = xNewList->Find( aRange ); 887 if (pEntry) 888 { 889 xNewList->Remove( pEntry ); // nur aus der Liste entfernt, nicht geloescht 890 891 if ( pLabel ) 892 pEntry->GetRange(0) = *pLabel; 893 if ( pData ) 894 pEntry->GetRange(1) = *pData; 895 896 xNewList->Join( *pEntry ); 897 delete pEntry; 898 899 if (bColumn) 900 pDoc->GetColNameRangesRef() = xNewList; 901 else 902 pDoc->GetRowNameRangesRef() = xNewList; 903 904 pDoc->CompileColRowNameFormula(); 905 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID ); 906 pDocShell->SetDocumentModified(); 907 908 //! Undo ?!?! (hier und aus Dialog) 909 910 if ( pLabel ) 911 aRange = *pLabel; // Objekt anpassen, um Range wiederzufinden 912 } 913 } 914 } 915 } 916 917 // sheet::XLabelRange 918 919 table::CellRangeAddress SAL_CALL ScLabelRangeObj::getLabelArea() 920 throw(uno::RuntimeException) 921 { 922 ScUnoGuard aGuard; 923 table::CellRangeAddress aRet; 924 ScRangePair* pData = GetData_Impl(); 925 if (pData) 926 ScUnoConversion::FillApiRange( aRet, pData->GetRange(0) ); 927 return aRet; 928 } 929 930 void SAL_CALL ScLabelRangeObj::setLabelArea( const table::CellRangeAddress& aLabelArea ) 931 throw(uno::RuntimeException) 932 { 933 ScUnoGuard aGuard; 934 ScRange aLabelRange; 935 ScUnoConversion::FillScRange( aLabelRange, aLabelArea ); 936 Modify_Impl( &aLabelRange, NULL ); 937 } 938 939 table::CellRangeAddress SAL_CALL ScLabelRangeObj::getDataArea() 940 throw(uno::RuntimeException) 941 { 942 ScUnoGuard aGuard; 943 table::CellRangeAddress aRet; 944 ScRangePair* pData = GetData_Impl(); 945 if (pData) 946 ScUnoConversion::FillApiRange( aRet, pData->GetRange(1) ); 947 return aRet; 948 } 949 950 void SAL_CALL ScLabelRangeObj::setDataArea( const table::CellRangeAddress& aDataArea ) 951 throw(uno::RuntimeException) 952 { 953 ScUnoGuard aGuard; 954 ScRange aDataRange; 955 ScUnoConversion::FillScRange( aDataRange, aDataArea ); 956 Modify_Impl( NULL, &aDataRange ); 957 } 958 959 //------------------------------------------------------------------------ 960 961 ScLabelRangesObj::ScLabelRangesObj(ScDocShell* pDocSh, sal_Bool bCol) : 962 pDocShell( pDocSh ), 963 bColumn( bCol ) 964 { 965 pDocShell->GetDocument()->AddUnoObject(*this); 966 } 967 968 ScLabelRangesObj::~ScLabelRangesObj() 969 { 970 if (pDocShell) 971 pDocShell->GetDocument()->RemoveUnoObject(*this); 972 } 973 974 void ScLabelRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 975 { 976 // Referenz-Update interessiert hier nicht 977 978 if ( rHint.ISA( SfxSimpleHint ) && 979 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) 980 { 981 pDocShell = NULL; // ungueltig geworden 982 } 983 } 984 985 // sheet::XLabelRanges 986 987 ScLabelRangeObj* ScLabelRangesObj::GetObjectByIndex_Impl(sal_uInt16 nIndex) 988 { 989 if (pDocShell) 990 { 991 ScDocument* pDoc = pDocShell->GetDocument(); 992 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); 993 if ( pList && nIndex < pList->Count() ) 994 { 995 ScRangePair* pData = pList->GetObject(nIndex); 996 if (pData) 997 return new ScLabelRangeObj( pDocShell, bColumn, pData->GetRange(0) ); 998 } 999 } 1000 return NULL; 1001 } 1002 1003 void SAL_CALL ScLabelRangesObj::addNew( const table::CellRangeAddress& aLabelArea, 1004 const table::CellRangeAddress& aDataArea ) 1005 throw(uno::RuntimeException) 1006 { 1007 ScUnoGuard aGuard; 1008 if (pDocShell) 1009 { 1010 ScDocument* pDoc = pDocShell->GetDocument(); 1011 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); 1012 if (pOldList) 1013 { 1014 ScRangePairListRef xNewList(pOldList->Clone()); 1015 1016 ScRange aLabelRange; 1017 ScRange aDataRange; 1018 ScUnoConversion::FillScRange( aLabelRange, aLabelArea ); 1019 ScUnoConversion::FillScRange( aDataRange, aDataArea ); 1020 xNewList->Join( ScRangePair( aLabelRange, aDataRange ) ); 1021 1022 if (bColumn) 1023 pDoc->GetColNameRangesRef() = xNewList; 1024 else 1025 pDoc->GetRowNameRangesRef() = xNewList; 1026 1027 pDoc->CompileColRowNameFormula(); 1028 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID ); 1029 pDocShell->SetDocumentModified(); 1030 1031 //! Undo ?!?! (hier und aus Dialog) 1032 } 1033 } 1034 } 1035 1036 void SAL_CALL ScLabelRangesObj::removeByIndex( sal_Int32 nIndex ) 1037 throw(uno::RuntimeException) 1038 { 1039 ScUnoGuard aGuard; 1040 sal_Bool bDone = sal_False; 1041 if (pDocShell) 1042 { 1043 ScDocument* pDoc = pDocShell->GetDocument(); 1044 ScRangePairList* pOldList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); 1045 1046 if ( pOldList && nIndex >= 0 && nIndex < (sal_Int32)pOldList->Count() ) 1047 { 1048 ScRangePairListRef xNewList(pOldList->Clone()); 1049 1050 ScRangePair* pEntry = xNewList->GetObject( nIndex ); 1051 if (pEntry) 1052 { 1053 xNewList->Remove( pEntry ); 1054 delete pEntry; 1055 1056 if (bColumn) 1057 pDoc->GetColNameRangesRef() = xNewList; 1058 else 1059 pDoc->GetRowNameRangesRef() = xNewList; 1060 1061 pDoc->CompileColRowNameFormula(); 1062 pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID ); 1063 pDocShell->SetDocumentModified(); 1064 bDone = sal_True; 1065 1066 //! Undo ?!?! (hier und aus Dialog) 1067 } 1068 } 1069 } 1070 if (!bDone) 1071 throw uno::RuntimeException(); // no other exceptions specified 1072 } 1073 1074 // container::XEnumerationAccess 1075 1076 uno::Reference<container::XEnumeration> SAL_CALL ScLabelRangesObj::createEnumeration() 1077 throw(uno::RuntimeException) 1078 { 1079 ScUnoGuard aGuard; 1080 return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.LabelRangesEnumeration"))); 1081 } 1082 1083 // container::XIndexAccess 1084 1085 sal_Int32 SAL_CALL ScLabelRangesObj::getCount() throw(uno::RuntimeException) 1086 { 1087 ScUnoGuard aGuard; 1088 if (pDocShell) 1089 { 1090 ScDocument* pDoc = pDocShell->GetDocument(); 1091 ScRangePairList* pList = bColumn ? pDoc->GetColNameRanges() : pDoc->GetRowNameRanges(); 1092 if (pList) 1093 return pList->Count(); 1094 } 1095 return 0; 1096 } 1097 1098 uno::Any SAL_CALL ScLabelRangesObj::getByIndex( sal_Int32 nIndex ) 1099 throw(lang::IndexOutOfBoundsException, 1100 lang::WrappedTargetException, uno::RuntimeException) 1101 { 1102 ScUnoGuard aGuard; 1103 uno::Reference< sheet::XLabelRange > xRange(GetObjectByIndex_Impl((sal_uInt16)nIndex)); 1104 if ( xRange.is() ) 1105 return uno::makeAny(xRange); 1106 else 1107 throw lang::IndexOutOfBoundsException(); 1108 // return uno::Any(); 1109 } 1110 1111 uno::Type SAL_CALL ScLabelRangesObj::getElementType() throw(uno::RuntimeException) 1112 { 1113 ScUnoGuard aGuard; 1114 return ::getCppuType((const uno::Reference< sheet::XLabelRange >*)0); // muss zu getByIndex passen 1115 1116 } 1117 1118 sal_Bool SAL_CALL ScLabelRangesObj::hasElements() throw(uno::RuntimeException) 1119 { 1120 ScUnoGuard aGuard; 1121 return ( getCount() != 0 ); 1122 } 1123 1124 //------------------------------------------------------------------------ 1125 1126 1127 1128