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_framework.hxx" 30 31 //_______________________________________________ 32 // includes 33 34 #include <framework/titlehelper.hxx> 35 #include <services.h> 36 #include <properties.h> 37 38 #include <com/sun/star/frame/UntitledNumbersConst.hpp> 39 #include <com/sun/star/frame/XStorable.hpp> 40 #include <com/sun/star/frame/XModuleManager.hpp> 41 #include <com/sun/star/container/XNameAccess.hpp> 42 #include <com/sun/star/document/XEventBroadcaster.hpp> 43 #include <com/sun/star/beans/XMaterialHolder.hpp> 44 45 #include <unotools/configmgr.hxx> 46 #include <unotools/bootstrap.hxx> 47 #include <comphelper/sequenceashashmap.hxx> 48 #include <rtl/ustrbuf.hxx> 49 #include <osl/mutex.hxx> 50 #include <tools/urlobj.hxx> 51 52 //_______________________________________________ 53 // namespace 54 55 namespace framework{ 56 57 namespace css = ::com::sun::star; 58 59 //_______________________________________________ 60 // definitions 61 62 static const ::rtl::OUString ERRMSG_INVALID_COMPONENT_PARAM = ::rtl::OUString::createFromAscii("NULL as component reference not allowed."); 63 static const ::rtl::OUString ERRMSG_INVALID_NUMBER_PARAM = ::rtl::OUString::createFromAscii("Special valkud INVALID_NUMBER not allowed as input parameter."); 64 65 //----------------------------------------------- 66 TitleHelper::TitleHelper(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) 67 : ::cppu::BaseMutex () 68 , m_xSMGR (xSMGR) 69 , m_xOwner () 70 , m_xUntitledNumbers() 71 , m_xSubTitle () 72 , m_bExternalTitle (sal_False) 73 , m_sTitle () 74 , m_nLeasedNumber (css::frame::UntitledNumbersConst::INVALID_NUMBER) 75 , m_aListener (m_aMutex) 76 { 77 } 78 79 //----------------------------------------------- 80 TitleHelper::~TitleHelper() 81 { 82 } 83 84 //----------------------------------------------- 85 void TitleHelper::setOwner(const css::uno::Reference< css::uno::XInterface >& xOwner) 86 { 87 // SYNCHRONIZED -> 88 ::osl::ResettableMutexGuard aLock(m_aMutex); 89 90 m_xOwner = xOwner; 91 92 aLock.clear (); 93 // <- SYNCHRONIZED 94 95 css::uno::Reference< css::frame::XModel > xModel(xOwner, css::uno::UNO_QUERY); 96 if (xModel.is ()) 97 { 98 impl_startListeningForModel (xModel); 99 return; 100 } 101 102 css::uno::Reference< css::frame::XController > xController(xOwner, css::uno::UNO_QUERY); 103 if (xController.is ()) 104 { 105 impl_startListeningForController (xController); 106 return; 107 } 108 109 css::uno::Reference< css::frame::XFrame > xFrame(xOwner, css::uno::UNO_QUERY); 110 if (xFrame.is ()) 111 { 112 impl_startListeningForFrame (xFrame); 113 return; 114 } 115 } 116 117 //----------------------------------------------- 118 ::rtl::OUString SAL_CALL TitleHelper::getTitle() 119 throw (css::uno::RuntimeException) 120 { 121 // SYNCHRONIZED -> 122 ::osl::ResettableMutexGuard aLock(m_aMutex); 123 124 // An external title will win always and disable all internal logic about 125 // creating/using a title value. 126 // Even an empty string will be accepted as valid title ! 127 if (m_bExternalTitle) 128 return m_sTitle; 129 130 // Title seams to be up-to-date. Return it directly. 131 if (m_sTitle.getLength() > 0) 132 return m_sTitle; 133 134 // Title seams to be unused till now ... do bootstraping 135 impl_updateTitle (); 136 137 return m_sTitle; 138 139 // <- SYNCHRONIZED 140 } 141 142 //----------------------------------------------- 143 void TitleHelper::connectWithUntitledNumbers (const css::uno::Reference< css::frame::XUntitledNumbers >& xNumbers) 144 { 145 // SYNCHRONIZED -> 146 ::osl::ResettableMutexGuard aLock(m_aMutex); 147 148 m_xUntitledNumbers = xNumbers; 149 150 // <- SYNCHRONIZED 151 } 152 153 //----------------------------------------------- 154 void SAL_CALL TitleHelper::setTitle(const ::rtl::OUString& sTitle) 155 throw (css::uno::RuntimeException) 156 { 157 // SYNCHRONIZED -> 158 ::osl::ResettableMutexGuard aLock(m_aMutex); 159 160 m_bExternalTitle = sal_True; 161 m_sTitle = sTitle; 162 163 aLock.clear (); 164 // <- SYNCHRONIZED 165 166 impl_sendTitleChangedEvent (); 167 } 168 169 //----------------------------------------------- 170 void SAL_CALL TitleHelper::addTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener) 171 throw (css::uno::RuntimeException) 172 { 173 // container is threadsafe by himself 174 m_aListener.addInterface( ::getCppuType( (const css::uno::Reference< css::frame::XTitleChangeListener >*)NULL ), xListener ); 175 } 176 177 //----------------------------------------------- 178 void SAL_CALL TitleHelper::removeTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener) 179 throw (css::uno::RuntimeException) 180 { 181 // container is threadsafe by himself 182 m_aListener.removeInterface( ::getCppuType( (const css::uno::Reference< css::frame::XTitleChangeListener >*)NULL ), xListener ); 183 } 184 185 //----------------------------------------------- 186 void SAL_CALL TitleHelper::titleChanged(const css::frame::TitleChangedEvent& aEvent) 187 throw (css::uno::RuntimeException) 188 { 189 // SYNCHRONIZED -> 190 ::osl::ResettableMutexGuard aLock(m_aMutex); 191 192 css::uno::Reference< css::frame::XTitle > xSubTitle(m_xSubTitle.get (), css::uno::UNO_QUERY); 193 194 aLock.clear (); 195 // <- SYNCHRONIZED 196 197 if (aEvent.Source != xSubTitle) 198 return; 199 200 impl_updateTitle (); 201 } 202 203 //----------------------------------------------- 204 void SAL_CALL TitleHelper::notifyEvent(const css::document::EventObject& aEvent) 205 throw (css::uno::RuntimeException) 206 { 207 if ( ! aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnSaveAsDone") 208 && ! aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnTitleChanged")) 209 return; 210 211 // SYNCHRONIZED -> 212 ::osl::ResettableMutexGuard aLock(m_aMutex); 213 214 css::uno::Reference< css::frame::XModel > xOwner(m_xOwner.get (), css::uno::UNO_QUERY); 215 216 aLock.clear (); 217 // <- SYNCHRONIZED 218 219 if ( 220 aEvent.Source != xOwner || 221 (aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnTitleChanged") && !xOwner.is()) 222 ) 223 { 224 return; 225 } 226 227 impl_updateTitle (); 228 } 229 230 //----------------------------------------------- 231 void SAL_CALL TitleHelper::frameAction(const css::frame::FrameActionEvent& aEvent) 232 throw(css::uno::RuntimeException) 233 { 234 // SYNCHRONIZED -> 235 ::osl::ResettableMutexGuard aLock(m_aMutex); 236 237 css::uno::Reference< css::frame::XFrame > xOwner(m_xOwner.get (), css::uno::UNO_QUERY); 238 239 aLock.clear (); 240 // <- SYNCHRONIZED 241 242 if (aEvent.Source != xOwner) 243 return; 244 245 // we are interested on events only, which must trigger a title bar update 246 // because component was changed. 247 if ( 248 (aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ) || 249 (aEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED) || 250 (aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) 251 ) 252 { 253 impl_updateListeningForFrame (xOwner); 254 impl_updateTitle (); 255 } 256 } 257 258 //----------------------------------------------- 259 void SAL_CALL TitleHelper::disposing(const css::lang::EventObject& aEvent) 260 throw (css::uno::RuntimeException) 261 { 262 // SYNCHRONIZED -> 263 ::osl::ResettableMutexGuard aLock(m_aMutex); 264 css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY); 265 css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY); 266 ::sal_Int32 nLeasedNumber = m_nLeasedNumber; 267 aLock.clear (); 268 // <- SYNCHRONIZED 269 270 if ( ! xOwner.is ()) 271 return; 272 273 if (xOwner != aEvent.Source) 274 return; 275 276 if ( 277 (xNumbers.is () ) && 278 (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER) 279 ) 280 xNumbers->releaseNumber (nLeasedNumber); 281 282 // SYNCHRONIZED -> 283 aLock.reset (); 284 285 m_sTitle = ::rtl::OUString (); 286 m_nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER; 287 288 aLock.clear (); 289 // <- SYNCHRONIZED 290 291 impl_sendTitleChangedEvent (); 292 } 293 294 //----------------------------------------------- 295 void TitleHelper::impl_sendTitleChangedEvent () 296 { 297 // SYNCHRONIZED -> 298 ::osl::ResettableMutexGuard aLock(m_aMutex); 299 300 css::frame::TitleChangedEvent aEvent(m_xOwner.get (), m_sTitle); 301 302 aLock.clear (); 303 // <- SYNCHRONIZED 304 305 ::cppu::OInterfaceContainerHelper* pContainer = m_aListener.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTitleChangeListener >*) NULL ) ); 306 if ( ! pContainer) 307 return; 308 309 ::cppu::OInterfaceIteratorHelper pIt( *pContainer ); 310 while ( pIt.hasMoreElements() ) 311 { 312 try 313 { 314 ((css::frame::XTitleChangeListener*)pIt.next())->titleChanged( aEvent ); 315 } 316 catch(const css::uno::Exception&) 317 { 318 pIt.remove(); 319 } 320 } 321 } 322 323 //----------------------------------------------- 324 void TitleHelper::impl_updateTitle () 325 { 326 // SYNCHRONIZED -> 327 ::osl::ResettableMutexGuard aLock(m_aMutex); 328 329 css::uno::Reference< css::frame::XModel > xModel (m_xOwner.get(), css::uno::UNO_QUERY); 330 css::uno::Reference< css::frame::XController > xController(m_xOwner.get(), css::uno::UNO_QUERY); 331 css::uno::Reference< css::frame::XFrame > xFrame (m_xOwner.get(), css::uno::UNO_QUERY); 332 333 aLock.clear (); 334 // <- SYNCHRONIZED 335 336 if (xModel.is ()) 337 { 338 impl_updateTitleForModel (xModel); 339 return; 340 } 341 342 if (xController.is ()) 343 { 344 impl_updateTitleForController (xController); 345 return; 346 } 347 348 if (xFrame.is ()) 349 { 350 impl_updateTitleForFrame (xFrame); 351 return; 352 } 353 } 354 355 //----------------------------------------------- 356 void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::frame::XModel >& xModel) 357 { 358 // SYNCHRONIZED -> 359 ::osl::ResettableMutexGuard aLock(m_aMutex); 360 361 // external title wont be updated internaly ! 362 // It has to be set from outside new. 363 if (m_bExternalTitle) 364 return; 365 366 css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY); 367 css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY); 368 ::sal_Int32 nLeasedNumber = m_nLeasedNumber; 369 370 aLock.clear (); 371 // <- SYNCHRONIZED 372 373 if ( 374 ( ! xOwner.is ()) || 375 ( ! xNumbers.is ()) || 376 ( ! xModel.is ()) 377 ) 378 return; 379 380 ::rtl::OUString sTitle; 381 ::rtl::OUString sURL ; 382 383 css::uno::Reference< css::frame::XStorable > xURLProvider(xModel , css::uno::UNO_QUERY); 384 if (xURLProvider.is()) 385 sURL = xURLProvider->getLocation (); 386 387 if (sURL.getLength () > 0) 388 { 389 sTitle = impl_convertURL2Title(sURL); 390 if (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER) 391 xNumbers->releaseNumber (nLeasedNumber); 392 nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER; 393 } 394 else 395 { 396 if (nLeasedNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) 397 nLeasedNumber = xNumbers->leaseNumber (xOwner); 398 399 ::rtl::OUStringBuffer sNewTitle(256); 400 sNewTitle.append (xNumbers->getUntitledPrefix ()); 401 if (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER) 402 sNewTitle.append ((::sal_Int32)nLeasedNumber); 403 else 404 sNewTitle.appendAscii ("?"); 405 406 sTitle = sNewTitle.makeStringAndClear (); 407 } 408 409 // SYNCHRONIZED -> 410 aLock.reset (); 411 412 // WORKAROUND: the notification is currently sent always, 413 // can be changed after shared mode is supported per UNO API 414 sal_Bool bChanged = sal_True; // (! m_sTitle.equals(sTitle)); 415 416 m_sTitle = sTitle; 417 m_nLeasedNumber = nLeasedNumber; 418 419 aLock.clear (); 420 // <- SYNCHRONIZED 421 422 if (bChanged) 423 impl_sendTitleChangedEvent (); 424 } 425 426 //----------------------------------------------- 427 void TitleHelper::impl_updateTitleForController (const css::uno::Reference< css::frame::XController >& xController) 428 { 429 // SYNCHRONIZED -> 430 ::osl::ResettableMutexGuard aLock(m_aMutex); 431 432 // external title wont be updated internaly ! 433 // It has to be set from outside new. 434 if (m_bExternalTitle) 435 return; 436 437 css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY); 438 css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY); 439 ::sal_Int32 nLeasedNumber = m_nLeasedNumber; 440 441 aLock.clear (); 442 // <- SYNCHRONIZED 443 444 if ( 445 ( ! xOwner.is ()) || 446 ( ! xNumbers.is ()) || 447 ( ! xController.is ()) 448 ) 449 return; 450 451 ::rtl::OUStringBuffer sTitle(256); 452 453 if (nLeasedNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) 454 nLeasedNumber = xNumbers->leaseNumber (xOwner); 455 456 css::uno::Reference< css::frame::XTitle > xModelTitle(xController->getModel (), css::uno::UNO_QUERY); 457 if (!xModelTitle.is ()) 458 xModelTitle.set(xController, css::uno::UNO_QUERY); 459 if (xModelTitle.is ()) 460 { 461 sTitle.append (xModelTitle->getTitle ()); 462 if ( nLeasedNumber > 1 ) 463 { 464 sTitle.appendAscii (" : "); 465 sTitle.append ((::sal_Int32)nLeasedNumber); 466 } 467 } 468 else 469 { 470 sTitle.append (xNumbers->getUntitledPrefix ()); 471 if ( nLeasedNumber > 1 ) 472 { 473 sTitle.append ((::sal_Int32)nLeasedNumber ); 474 } 475 } 476 477 // SYNCHRONIZED -> 478 aLock.reset (); 479 480 ::rtl::OUString sNewTitle = sTitle.makeStringAndClear (); 481 sal_Bool bChanged = (! m_sTitle.equals(sNewTitle)); 482 m_sTitle = sNewTitle; 483 m_nLeasedNumber = nLeasedNumber; 484 485 aLock.clear (); 486 // <- SYNCHRONIZED 487 488 if (bChanged) 489 impl_sendTitleChangedEvent (); 490 } 491 492 //----------------------------------------------- 493 void TitleHelper::impl_updateTitleForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame) 494 { 495 if ( ! xFrame.is ()) 496 return; 497 498 // SYNCHRONIZED -> 499 ::osl::ResettableMutexGuard aLock(m_aMutex); 500 501 // external title wont be updated internaly ! 502 // It has to be set from outside new. 503 if (m_bExternalTitle) 504 return; 505 506 aLock.clear (); 507 // <- SYNCHRONIZED 508 509 css::uno::Reference< css::uno::XInterface > xComponent; 510 xComponent = xFrame->getController (); 511 if ( ! xComponent.is ()) 512 xComponent = xFrame->getComponentWindow (); 513 514 ::rtl::OUStringBuffer sTitle (256); 515 516 impl_appendComponentTitle (sTitle, xComponent); 517 impl_appendProductName (sTitle); 518 impl_appendModuleName (sTitle); 519 impl_appendProductExtension (sTitle); 520 //impl_appendEvalVersion (sTitle); 521 impl_appendDebugVersion (sTitle); 522 523 // SYNCHRONIZED -> 524 aLock.reset (); 525 526 ::rtl::OUString sNewTitle = sTitle.makeStringAndClear (); 527 sal_Bool bChanged = (! m_sTitle.equals(sNewTitle)); 528 m_sTitle = sNewTitle; 529 530 aLock.clear (); 531 // <- SYNCHRONIZED 532 533 if (bChanged) 534 impl_sendTitleChangedEvent (); 535 } 536 537 //***************************************************************************************************************** 538 void TitleHelper::impl_appendComponentTitle ( ::rtl::OUStringBuffer& sTitle , 539 const css::uno::Reference< css::uno::XInterface >& xComponent) 540 { 541 css::uno::Reference< css::frame::XTitle > xTitle(xComponent, css::uno::UNO_QUERY); 542 543 // Note: Title has to be used (even if it's empty) if the right interface is supported. 544 if (xTitle.is ()) 545 sTitle.append (xTitle->getTitle ()); 546 } 547 548 //***************************************************************************************************************** 549 void TitleHelper::impl_appendProductName (::rtl::OUStringBuffer& sTitle) 550 { 551 ::rtl::OUString sProductName; 552 ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTNAME) >>= sProductName; 553 554 if (sProductName.getLength ()) 555 { 556 if (sTitle.getLength() > 0) 557 sTitle.appendAscii (" - "); 558 559 sTitle.append (sProductName); 560 } 561 } 562 563 //***************************************************************************************************************** 564 void TitleHelper::impl_appendProductExtension (::rtl::OUStringBuffer& sTitle) 565 { 566 ::rtl::OUString sProductExtension; 567 ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTEXTENSION) >>= sProductExtension; 568 569 if (sProductExtension.getLength ()) 570 { 571 sTitle.appendAscii (" "); 572 sTitle.append (sProductExtension); 573 } 574 } 575 576 //***************************************************************************************************************** 577 void TitleHelper::impl_appendModuleName (::rtl::OUStringBuffer& sTitle) 578 { 579 // SYNCHRONIZED -> 580 ::osl::ResettableMutexGuard aLock(m_aMutex); 581 582 css::uno::Reference< css::uno::XInterface > xOwner = m_xOwner.get(); 583 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; 584 585 aLock.clear (); 586 // <- SYNCHRONIZED 587 588 try 589 { 590 css::uno::Reference< css::frame::XModuleManager > xModuleManager( 591 xSMGR->createInstance(SERVICENAME_MODULEMANAGER), 592 css::uno::UNO_QUERY_THROW); 593 594 css::uno::Reference< css::container::XNameAccess > xConfig( 595 xModuleManager, 596 css::uno::UNO_QUERY_THROW); 597 598 const ::rtl::OUString sID = xModuleManager->identify(xOwner); 599 ::comphelper::SequenceAsHashMap lProps = xConfig->getByName (sID); 600 const ::rtl::OUString sUIName = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_UINAME, ::rtl::OUString()); 601 602 // An UIname property is an optional value ! 603 // So please add it to the title in case it does realy exists only. 604 if (sUIName.getLength() > 0) 605 { 606 sTitle.appendAscii (" " ); 607 sTitle.append (sUIName); 608 } 609 } 610 catch(const css::uno::Exception&) 611 {} 612 } 613 614 //***************************************************************************************************************** 615 #ifdef DBG_UTIL 616 void TitleHelper::impl_appendDebugVersion (::rtl::OUStringBuffer& sTitle) 617 { 618 ::rtl::OUString sDefault ; 619 ::rtl::OUString sVersion = ::utl::Bootstrap::getBuildIdData( sDefault ); 620 621 sTitle.appendAscii (" [" ); 622 sTitle.append (sVersion); 623 sTitle.appendAscii ("]" ); 624 } 625 #else 626 void TitleHelper::impl_appendDebugVersion (::rtl::OUStringBuffer&) 627 { 628 } 629 #endif 630 631 //***************************************************************************************************************** 632 void TitleHelper::impl_appendEvalVersion (::rtl::OUStringBuffer& /*sTitle*/) 633 { 634 // SYNCHRONIZED -> 635 // ::osl::ResettableMutexGuard aLock(m_aMutex); 636 // css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ; 637 //aLock.clear (); 638 //// <- SYNCHRONIZED 639 640 //css::uno::Reference< css::beans::XMaterialHolder > xHolder( 641 // xSMGR->createInstance(SERVICENAME_TABREG), 642 // css::uno::UNO_QUERY); 643 644 // if ( ! xHolder.is()) 645 // return; 646 647 // ::comphelper::SequenceAsHashMap aMaterial(xHolder->getMaterial()); 648 //const ::rtl::OUString sEvalTitle = aMaterial.getUnpackedValueOrDefault(TABREG_PROPNAME_TITLE, ::rtl::OUString()); 649 650 //if (sEvalTitle.getLength()) 651 //{ 652 // sTitle.appendAscii (" " ); 653 // sTitle.append (sEvalTitle); 654 //} 655 } 656 657 //----------------------------------------------- 658 void TitleHelper::impl_startListeningForModel (const css::uno::Reference< css::frame::XModel >& xModel) 659 { 660 css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xModel, css::uno::UNO_QUERY); 661 if ( ! xBroadcaster.is ()) 662 return; 663 664 xBroadcaster->addEventListener (static_cast< css::document::XEventListener* >(this)); 665 } 666 667 //----------------------------------------------- 668 void TitleHelper::impl_startListeningForController (const css::uno::Reference< css::frame::XController >& xController) 669 { 670 css::uno::Reference< css::frame::XTitle > xSubTitle(xController->getModel (), css::uno::UNO_QUERY); 671 impl_setSubTitle (xSubTitle); 672 } 673 674 //----------------------------------------------- 675 void TitleHelper::impl_startListeningForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame) 676 { 677 xFrame->addFrameActionListener(this ); 678 impl_updateListeningForFrame (xFrame); 679 } 680 681 //----------------------------------------------- 682 void TitleHelper::impl_updateListeningForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame) 683 { 684 css::uno::Reference< css::frame::XTitle > xSubTitle(xFrame->getController (), css::uno::UNO_QUERY); 685 impl_setSubTitle (xSubTitle); 686 } 687 688 //----------------------------------------------- 689 void TitleHelper::impl_setSubTitle (const css::uno::Reference< css::frame::XTitle >& xSubTitle) 690 { 691 // SYNCHRONIZED -> 692 ::osl::ResettableMutexGuard aLock(m_aMutex); 693 694 // ignore duplicate calls. Makes outside using of this helper more easy :-) 695 css::uno::Reference< css::frame::XTitle > xOldSubTitle(m_xSubTitle.get(), css::uno::UNO_QUERY); 696 if (xOldSubTitle == xSubTitle) 697 return; 698 699 m_xSubTitle = xSubTitle; 700 701 aLock.clear (); 702 // <- SYNCHRONIZED 703 704 css::uno::Reference< css::frame::XTitleChangeBroadcaster > xOldBroadcaster(xOldSubTitle , css::uno::UNO_QUERY ); 705 css::uno::Reference< css::frame::XTitleChangeBroadcaster > xNewBroadcaster(xSubTitle , css::uno::UNO_QUERY ); 706 css::uno::Reference< css::frame::XTitleChangeListener > xThis (static_cast< css::frame::XTitleChangeListener* >(this), css::uno::UNO_QUERY_THROW); 707 708 if (xOldBroadcaster.is()) 709 xOldBroadcaster->removeTitleChangeListener (xThis); 710 711 if (xNewBroadcaster.is()) 712 xNewBroadcaster->addTitleChangeListener (xThis); 713 } 714 715 //----------------------------------------------- 716 ::rtl::OUString TitleHelper::impl_getSubTitle () 717 { 718 // SYNCHRONIZED -> 719 ::osl::ResettableMutexGuard aLock(m_aMutex); 720 721 css::uno::Reference< css::frame::XTitle > xSubTitle(m_xSubTitle.get (), css::uno::UNO_QUERY); 722 723 aLock.clear (); 724 // <- SYNCHRONIZED 725 726 if (xSubTitle.is ()) 727 return xSubTitle->getTitle (); 728 729 return ::rtl::OUString (); 730 } 731 732 //----------------------------------------------- 733 ::rtl::OUString TitleHelper::impl_convertURL2Title(const ::rtl::OUString& sURL) 734 { 735 INetURLObject aURL (sURL); 736 ::rtl::OUString sTitle; 737 738 if (aURL.GetProtocol() == INET_PROT_FILE) 739 { 740 if (aURL.HasMark()) 741 aURL = INetURLObject(aURL.GetURLNoMark()); 742 743 sTitle = aURL.getName(INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::DECODE_WITH_CHARSET); 744 } 745 else 746 { 747 if (aURL.hasExtension(INetURLObject::LAST_SEGMENT)) 748 sTitle = aURL.getName(INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::DECODE_WITH_CHARSET); 749 750 if ( ! sTitle.getLength() ) 751 sTitle = aURL.GetHostPort(INetURLObject::DECODE_WITH_CHARSET); 752 753 if ( ! sTitle.getLength() ) 754 sTitle = aURL.GetURLNoPass(INetURLObject::DECODE_WITH_CHARSET); 755 } 756 757 return sTitle; 758 } 759 760 } // namespace framework 761