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