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 #include "precompiled_sd.hxx" 23 24 #include <osl/time.h> 25 26 #include "framework/FrameworkHelper.hxx" 27 28 #include "framework/ConfigurationController.hxx" 29 #include "framework/ResourceId.hxx" 30 #include "framework/ViewShellWrapper.hxx" 31 #include "ViewShellBase.hxx" 32 #include "FrameView.hxx" 33 #include "DrawViewShell.hxx" 34 #include "ViewShellHint.hxx" 35 #include "DrawController.hxx" 36 #include "app.hrc" 37 #include <com/sun/star/drawing/framework/XControllerManager.hpp> 38 #include <com/sun/star/drawing/framework/XPane.hpp> 39 #include <cppuhelper/compbase1.hxx> 40 #include <svl/lstner.hxx> 41 42 #include <comphelper/stl_types.hxx> 43 #include <sfx2/request.hxx> 44 #include <sfx2/dispatch.hxx> 45 46 #include "MutexOwner.hxx" 47 #include "vcl/svapp.hxx" 48 #include <osl/doublecheckedlocking.h> 49 #include <osl/getglobalmutex.hxx> 50 #include <tools/diagnose_ex.h> 51 52 using namespace ::com::sun::star; 53 using namespace ::com::sun::star::uno; 54 using namespace ::com::sun::star::drawing::framework; 55 56 using ::rtl::OUString; 57 58 namespace { 59 60 61 //----- CallbackCaller -------------------------------------------------------- 62 63 typedef ::cppu::WeakComponentImplHelper1 < 64 ::com::sun::star::drawing::framework::XConfigurationChangeListener 65 > CallbackCallerInterfaceBase; 66 67 /** A CallbackCaller registers as listener at an XConfigurationController 68 object and waits for the notification of one type of event. When that 69 event is received, or when the CallbackCaller detects at its 70 construction that the event will not be sent in the near future, the 71 actual callback object is called and the CallbackCaller destroys itself. 72 */ 73 class CallbackCaller 74 : public ::sd::MutexOwner, 75 public CallbackCallerInterfaceBase 76 { 77 public: 78 /** Create a new CallbackCaller object. This object controls its own 79 lifetime by acquiring a reference to itself in the constructor. 80 When it detects that the event will not be notified in the near 81 future (because the queue of pending configuration change operations 82 is empty and therefore no event will be sent int the near future, it 83 does not acquires a reference and thus initiates its destruction in 84 the constructor.) 85 @param rBase 86 This ViewShellBase object is used to determine the 87 XConfigurationController at which to register. 88 @param rsEventType 89 The event type which the callback is waiting for. 90 @param pCallback 91 The callback object which is to be notified. The caller will 92 typically release his reference to the caller so that when the 93 CallbackCaller dies (after having called the callback) the 94 callback is destroyed. 95 */ 96 CallbackCaller ( 97 ::sd::ViewShellBase& rBase, 98 const OUString& rsEventType, 99 const ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter& rFilter, 100 const ::sd::framework::FrameworkHelper::Callback& rCallback); 101 virtual ~CallbackCaller (void); 102 103 virtual void SAL_CALL disposing (void); 104 // XEventListener 105 virtual void SAL_CALL disposing (const lang::EventObject& rEvent) 106 throw (RuntimeException); 107 // XConfigurationChangeListener 108 virtual void SAL_CALL notifyConfigurationChange (const ConfigurationChangeEvent& rEvent) 109 throw (RuntimeException); 110 111 private: 112 OUString msEventType; 113 Reference<XConfigurationController> mxConfigurationController; 114 ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter maFilter; 115 ::sd::framework::FrameworkHelper::Callback maCallback; 116 }; 117 118 119 120 121 //----- LifetimeController ---------------------------------------------------- 122 123 typedef ::cppu::WeakComponentImplHelper1 < 124 ::com::sun::star::lang::XEventListener 125 > LifetimeControllerInterfaceBase; 126 127 /** This class helps controling the lifetime of the 128 FrameworkHelper. Register at a ViewShellBase object and an XController 129 object and call Dispose() at the associated FrameworkHelper object when 130 one of them and Release() when both of them are destroyed. 131 */ 132 class LifetimeController 133 : public ::sd::MutexOwner, 134 public LifetimeControllerInterfaceBase, 135 public SfxListener 136 { 137 public: 138 explicit LifetimeController (::sd::ViewShellBase& rBase); 139 virtual ~LifetimeController (void); 140 141 virtual void SAL_CALL disposing (void); 142 143 /** XEventListener. This method is called when the frame::XController 144 is being destroyed. 145 */ 146 virtual void SAL_CALL disposing (const lang::EventObject& rEvent) 147 throw (RuntimeException); 148 149 /** This method is called when the ViewShellBase is being destroyed. 150 */ 151 virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); 152 153 private: 154 ::sd::ViewShellBase& mrBase; 155 bool mbListeningToViewShellBase; 156 bool mbListeningToController; 157 158 /** When one or both of the mbListeningToViewShellBase and 159 mbListeningToController members were modified then call this method 160 to either dispose or release the associated FrameworkHelper. 161 */ 162 void Update (void); 163 }; 164 165 166 167 } // end of anonymous namespace 168 169 namespace sd { namespace framework { 170 171 // Pane URLS. 172 173 const OUString FrameworkHelper::msPaneURLPrefix( 174 OUString::createFromAscii("private:resource/pane/")); 175 const OUString FrameworkHelper::msCenterPaneURL( 176 msPaneURLPrefix + OUString::createFromAscii("CenterPane")); 177 const OUString FrameworkHelper::msFullScreenPaneURL( 178 msPaneURLPrefix + OUString::createFromAscii("FullScreenPane")); 179 const OUString FrameworkHelper::msLeftImpressPaneURL( 180 msPaneURLPrefix + OUString::createFromAscii("LeftImpressPane")); 181 const OUString FrameworkHelper::msLeftDrawPaneURL( 182 msPaneURLPrefix + OUString::createFromAscii("LeftDrawPane")); 183 const OUString FrameworkHelper::msSidebarPaneURL( 184 msPaneURLPrefix + OUString::createFromAscii("SidebarPane")); 185 186 187 // View URLs. 188 189 const OUString FrameworkHelper::msViewURLPrefix( 190 OUString::createFromAscii("private:resource/view/")); 191 const OUString FrameworkHelper::msImpressViewURL( 192 msViewURLPrefix + OUString::createFromAscii("ImpressView")); 193 const OUString FrameworkHelper::msDrawViewURL( 194 msViewURLPrefix + OUString::createFromAscii("GraphicView")); 195 const OUString FrameworkHelper::msOutlineViewURL( 196 msViewURLPrefix + OUString::createFromAscii("OutlineView")); 197 const OUString FrameworkHelper::msNotesViewURL( 198 msViewURLPrefix + OUString::createFromAscii("NotesView")); 199 const OUString FrameworkHelper::msHandoutViewURL( 200 msViewURLPrefix + OUString::createFromAscii("HandoutView")); 201 const OUString FrameworkHelper::msSlideSorterURL( 202 msViewURLPrefix + OUString::createFromAscii("SlideSorter")); 203 const OUString FrameworkHelper::msPresentationViewURL( 204 msViewURLPrefix + OUString::createFromAscii("PresentationView")); 205 const OUString FrameworkHelper::msSidebarViewURL( 206 msViewURLPrefix + OUString::createFromAscii("SidebarView")); 207 208 209 // Tool bar URLs. 210 211 const OUString FrameworkHelper::msToolBarURLPrefix( 212 OUString::createFromAscii("private:resource/toolbar/")); 213 const OUString FrameworkHelper::msViewTabBarURL( 214 msToolBarURLPrefix + OUString::createFromAscii("ViewTabBar")); 215 216 217 // Task panel URLs. 218 const ::rtl::OUString FrameworkHelper::msTaskPanelURLPrefix( 219 OUString::createFromAscii("private:resource/toolpanel/")); 220 const ::rtl::OUString FrameworkHelper::msAllMasterPagesTaskPanelURL( 221 msTaskPanelURLPrefix + OUString::createFromAscii("AllMasterPages")); 222 const ::rtl::OUString FrameworkHelper::msRecentMasterPagesTaskPanelURL( 223 msTaskPanelURLPrefix + OUString::createFromAscii("RecentMasterPages")); 224 const ::rtl::OUString FrameworkHelper::msUsedMasterPagesTaskPanelURL( 225 msTaskPanelURLPrefix + OUString::createFromAscii("UsedMasterPages")); 226 const ::rtl::OUString FrameworkHelper::msLayoutTaskPanelURL( 227 msTaskPanelURLPrefix + OUString::createFromAscii("Layouts")); 228 const ::rtl::OUString FrameworkHelper::msTableDesignPanelURL( 229 msTaskPanelURLPrefix + OUString::createFromAscii("TableDesign")); 230 const ::rtl::OUString FrameworkHelper::msCustomAnimationTaskPanelURL( 231 msTaskPanelURLPrefix + OUString::createFromAscii("CustomAnimations")); 232 const ::rtl::OUString FrameworkHelper::msSlideTransitionTaskPanelURL( 233 msTaskPanelURLPrefix + OUString::createFromAscii("SlideTransitions")); 234 235 236 // Event URLs. 237 const OUString FrameworkHelper::msResourceActivationRequestEvent( 238 OUString::createFromAscii("ResourceActivationRequested")); 239 const OUString FrameworkHelper::msResourceDeactivationRequestEvent( 240 OUString::createFromAscii("ResourceDeactivationRequest")); 241 const OUString FrameworkHelper::msResourceActivationEvent( 242 OUString::createFromAscii("ResourceActivation")); 243 const OUString FrameworkHelper::msResourceDeactivationEvent( 244 OUString::createFromAscii("ResourceDeactivation")); 245 const OUString FrameworkHelper::msResourceDeactivationEndEvent( 246 OUString::createFromAscii("ResourceDeactivationEnd")); 247 const OUString FrameworkHelper::msConfigurationUpdateStartEvent( 248 OUString::createFromAscii("ConfigurationUpdateStart")); 249 const OUString FrameworkHelper::msConfigurationUpdateEndEvent( 250 OUString::createFromAscii("ConfigurationUpdateEnd")); 251 252 253 // Service names of controllers. 254 const OUString FrameworkHelper::msModuleControllerService( 255 OUString::createFromAscii("com.sun.star.drawing.framework.ModuleController")); 256 const OUString FrameworkHelper::msConfigurationControllerService( 257 OUString::createFromAscii("com.sun.star.drawing.framework.ConfigurationController")); 258 259 //----- helper ---------------------------------------------------------------- 260 namespace 261 { 262 static ::boost::shared_ptr< ViewShell > lcl_getViewShell( const Reference< XResource >& i_rViewShellWrapper ) 263 { 264 ::boost::shared_ptr< ViewShell > pViewShell; 265 if ( !i_rViewShellWrapper.is() ) 266 return pViewShell; 267 268 try 269 { 270 Reference<lang::XUnoTunnel> xViewTunnel( i_rViewShellWrapper, UNO_QUERY_THROW ); 271 pViewShell = reinterpret_cast< ViewShellWrapper* >( 272 xViewTunnel->getSomething( ViewShellWrapper::getUnoTunnelId() ) )->GetViewShell(); 273 } 274 catch( const Exception& ) 275 { 276 DBG_UNHANDLED_EXCEPTION(); 277 } 278 return pViewShell; 279 } 280 Reference< XResource > lcl_getFirstViewInPane( const Reference< XConfigurationController >& i_rConfigController, 281 const Reference< XResourceId >& i_rPaneId ) 282 { 283 try 284 { 285 Reference< XConfiguration > xConfiguration( i_rConfigController->getRequestedConfiguration(), UNO_SET_THROW ); 286 Sequence< Reference< XResourceId > > aViewIds( xConfiguration->getResources( 287 i_rPaneId, FrameworkHelper::msViewURLPrefix, AnchorBindingMode_DIRECT ) ); 288 if ( aViewIds.getLength() > 0 ) 289 return i_rConfigController->getResource( aViewIds[0] ); 290 } 291 catch( const Exception& ) 292 { 293 DBG_UNHANDLED_EXCEPTION(); 294 } 295 return NULL; 296 } 297 } 298 299 300 //----- FrameworkHelper::ViewURLMap ------------------------------------------- 301 302 /** The ViewURLMap is used to translate between the view URLs used by the 303 drawing framework and the enums defined in the ViewShell class. 304 */ 305 class FrameworkHelper::ViewURLMap 306 : public ::std::hash_map< 307 rtl::OUString, 308 ViewShell::ShellType, 309 ::comphelper::UStringHash, 310 ::comphelper::UStringEqual> 311 { 312 public: 313 ViewURLMap (void) {} 314 }; 315 316 317 318 319 //----- Framework::DiposeListener --------------------------------------------- 320 321 namespace { 322 typedef ::cppu::WeakComponentImplHelper1 < 323 ::com::sun::star::lang::XEventListener 324 > FrameworkHelperDisposeListenerInterfaceBase; 325 } 326 327 class FrameworkHelper::DisposeListener 328 : public ::sd::MutexOwner, 329 public FrameworkHelperDisposeListenerInterfaceBase 330 { 331 public: 332 DisposeListener (const ::boost::shared_ptr<FrameworkHelper>& rpHelper); 333 ~DisposeListener (void); 334 335 virtual void SAL_CALL disposing (void); 336 337 virtual void SAL_CALL disposing (const lang::EventObject& rEventObject) 338 throw(RuntimeException); 339 340 private: 341 ::boost::shared_ptr<FrameworkHelper> mpHelper; 342 }; 343 344 345 346 347 //----- FrameworkHelper::Deleter ---------------------------------------------- 348 349 class FrameworkHelper::Deleter 350 { 351 public: 352 void operator()(FrameworkHelper* pObject) 353 { 354 delete pObject; 355 } 356 }; 357 358 359 360 361 //----- FrameworkHelper ------------------------------------------------------- 362 363 ::boost::scoped_ptr<FrameworkHelper::ViewURLMap> FrameworkHelper::mpViewURLMap(new ViewURLMap()); 364 365 366 FrameworkHelper::InstanceMap FrameworkHelper::maInstanceMap; 367 368 369 370 ::boost::shared_ptr<FrameworkHelper> FrameworkHelper::Instance ( 371 const Reference<frame::XController>& rxController) 372 { 373 // Tunnel through the controller to obtain a ViewShellBase. 374 Reference<lang::XUnoTunnel> xTunnel (rxController, UNO_QUERY); 375 if (xTunnel.is()) 376 { 377 ::sd::DrawController* pController = reinterpret_cast<sd::DrawController*>( 378 xTunnel->getSomething(sd::DrawController::getUnoTunnelId())); 379 if (pController != NULL) 380 { 381 ViewShellBase* pBase = pController->GetViewShellBase(); 382 if (pBase != NULL) 383 return Instance(*pBase); 384 } 385 } 386 387 return ::boost::shared_ptr<FrameworkHelper>(); 388 } 389 390 391 392 393 ::boost::shared_ptr<FrameworkHelper> FrameworkHelper::Instance (ViewShellBase& rBase) 394 { 395 396 ::boost::shared_ptr<FrameworkHelper> pHelper; 397 398 InstanceMap::const_iterator iHelper (maInstanceMap.find(&rBase)); 399 if (iHelper == maInstanceMap.end()) 400 { 401 ::osl::GetGlobalMutex aMutexFunctor; 402 ::osl::MutexGuard aGuard (aMutexFunctor()); 403 if (iHelper == maInstanceMap.end()) 404 { 405 pHelper = ::boost::shared_ptr<FrameworkHelper>( 406 new FrameworkHelper(rBase), 407 FrameworkHelper::Deleter()); 408 pHelper->Initialize(); 409 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 410 maInstanceMap[&rBase] = pHelper; 411 } 412 } 413 else 414 { 415 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 416 pHelper = iHelper->second; 417 } 418 419 return pHelper; 420 } 421 422 423 424 425 void FrameworkHelper::DisposeInstance (ViewShellBase& rBase) 426 { 427 InstanceMap::iterator iHelper (maInstanceMap.find(&rBase)); 428 if (iHelper != maInstanceMap.end()) 429 { 430 iHelper->second->Dispose(); 431 } 432 } 433 434 435 436 437 void FrameworkHelper::ReleaseInstance (ViewShellBase& rBase) 438 { 439 InstanceMap::iterator iHelper (maInstanceMap.find(&rBase)); 440 if (iHelper != maInstanceMap.end()) 441 maInstanceMap.erase(iHelper); 442 } 443 444 445 446 447 FrameworkHelper::FrameworkHelper (ViewShellBase& rBase) 448 : mrBase(rBase), 449 mxConfigurationController(), 450 mxDisposeListener() 451 452 { 453 Reference<XControllerManager> xControllerManager (rBase.GetController(), UNO_QUERY); 454 if (xControllerManager.is()) 455 { 456 mxConfigurationController = xControllerManager->getConfigurationController(); 457 } 458 459 new LifetimeController(mrBase); 460 } 461 462 463 464 465 void FrameworkHelper::Initialize (void) 466 { 467 mxDisposeListener = new DisposeListener(shared_from_this()); 468 } 469 470 471 472 473 FrameworkHelper::~FrameworkHelper (void) 474 { 475 } 476 477 478 479 480 void FrameworkHelper::Dispose (void) 481 { 482 if (mxDisposeListener.is()) 483 mxDisposeListener->dispose(); 484 mxConfigurationController = NULL; 485 } 486 487 488 489 490 bool FrameworkHelper::IsValid (void) 491 { 492 return mxConfigurationController.is(); 493 } 494 495 496 497 498 ::boost::shared_ptr<ViewShell> FrameworkHelper::GetViewShell (const OUString& rsPaneURL) 499 { 500 if ( !mxConfigurationController.is() ) 501 return ::boost::shared_ptr<ViewShell>(); 502 503 Reference<XResourceId> xPaneId( CreateResourceId( rsPaneURL ) ); 504 return lcl_getViewShell( lcl_getFirstViewInPane( mxConfigurationController, xPaneId ) ); 505 } 506 507 508 509 510 ::boost::shared_ptr<ViewShell> FrameworkHelper::GetViewShell (const Reference<XView>& rxView) 511 { 512 return lcl_getViewShell( rxView.get() ); 513 } 514 515 516 517 518 Reference<XView> FrameworkHelper::GetView (const Reference<XResourceId>& rxPaneOrViewId) 519 { 520 Reference<XView> xView; 521 522 if ( ! rxPaneOrViewId.is() || ! mxConfigurationController.is()) 523 return NULL; 524 525 try 526 { 527 if (rxPaneOrViewId->getResourceURL().match(msViewURLPrefix)) 528 { 529 xView.set( mxConfigurationController->getResource( rxPaneOrViewId ), UNO_QUERY ); 530 } 531 else 532 { 533 xView.set( lcl_getFirstViewInPane( mxConfigurationController, rxPaneOrViewId ), UNO_QUERY ); 534 } 535 } 536 catch (lang::DisposedException&) 537 { 538 Dispose(); 539 } 540 catch (RuntimeException&) 541 { 542 } 543 544 return xView; 545 } 546 547 548 549 550 Reference<awt::XWindow> FrameworkHelper::GetPaneWindow (const Reference<XResourceId>& rxPaneId) 551 { 552 Reference<awt::XWindow> xWindow; 553 554 if (rxPaneId.is() && mxConfigurationController.is()) 555 { 556 try 557 { 558 if (rxPaneId->getResourceURL().match(msPaneURLPrefix)) 559 { 560 Reference<XPane> xPane (mxConfigurationController->getResource(rxPaneId), UNO_QUERY); 561 if (xPane.is()) 562 xWindow = xPane->getWindow(); 563 } 564 } 565 catch (lang::DisposedException&) 566 { 567 Dispose(); 568 } 569 catch (RuntimeException&) 570 { 571 } 572 } 573 574 return xWindow; 575 } 576 577 578 579 580 Reference<XResource> FrameworkHelper::GetResource (const Reference<XResourceId>& rxResourceId) 581 { 582 Reference<XResource> xResource; 583 584 if (rxResourceId.is() && mxConfigurationController.is()) 585 { 586 try 587 { 588 return mxConfigurationController->getResource(rxResourceId); 589 } 590 catch (lang::DisposedException&) 591 { 592 Dispose(); 593 } 594 catch (RuntimeException&) 595 { 596 } 597 } 598 599 return NULL; 600 } 601 602 603 604 605 Reference<XResourceId> FrameworkHelper::RequestView ( 606 const OUString& rsResourceURL, 607 const OUString& rsAnchorURL) 608 { 609 Reference<XResourceId> xViewId; 610 611 try 612 { 613 if (mxConfigurationController.is()) 614 { 615 mxConfigurationController->requestResourceActivation( 616 CreateResourceId(rsAnchorURL), 617 ResourceActivationMode_ADD); 618 xViewId = CreateResourceId(rsResourceURL, rsAnchorURL); 619 mxConfigurationController->requestResourceActivation( 620 xViewId, 621 ResourceActivationMode_REPLACE); 622 } 623 } 624 catch (lang::DisposedException&) 625 { 626 Dispose(); 627 xViewId = NULL; 628 } 629 catch (RuntimeException&) 630 { 631 xViewId = NULL; 632 } 633 634 return xViewId; 635 } 636 637 638 639 640 Reference<XResourceId> FrameworkHelper::RequestSidebarPanel ( 641 const OUString& rsTaskPanelURL, 642 const bool bEnsureTaskPaneIsVisible) 643 { 644 try 645 { 646 if (mxConfigurationController.is()) 647 { 648 // Check the existence of the task pane. 649 if ( ! bEnsureTaskPaneIsVisible) 650 { 651 Reference<XConfiguration> xConfiguration ( 652 mxConfigurationController->getCurrentConfiguration()); 653 if (xConfiguration.is()) 654 if ( ! xConfiguration->hasResource( 655 CreateResourceId(msSidebarViewURL, msSidebarPaneURL))) 656 { 657 // Task pane is not active. Do not force it. 658 return NULL; 659 } 660 } 661 662 // Create the resource id from URLs for the sidebar pane 663 // and view and the requested panel. 664 mxConfigurationController->requestResourceActivation( 665 CreateResourceId(msSidebarPaneURL), 666 ResourceActivationMode_ADD); 667 mxConfigurationController->requestResourceActivation( 668 CreateResourceId(msSidebarViewURL, msSidebarPaneURL), 669 ResourceActivationMode_REPLACE); 670 Reference<XResourceId> xPanelId (CreateResourceId(rsTaskPanelURL, msSidebarViewURL, msSidebarPaneURL)); 671 mxConfigurationController->requestResourceActivation( 672 xPanelId, 673 ResourceActivationMode_REPLACE); 674 675 return xPanelId; 676 } 677 } 678 catch (lang::DisposedException&) 679 { 680 Dispose(); 681 } 682 catch (RuntimeException&) 683 {} 684 685 return NULL; 686 } 687 688 689 690 691 void FrameworkHelper::RequestResourceDeactivation (const cssu::Reference<cssdf::XResourceId>& rxResourceId) 692 { 693 try 694 { 695 if (mxConfigurationController.is() && rxResourceId.is()) 696 mxConfigurationController->requestResourceDeactivation(rxResourceId); 697 } 698 catch (lang::DisposedException&) 699 { 700 Dispose(); 701 } 702 catch (RuntimeException&) 703 {} 704 } 705 706 707 708 709 ViewShell::ShellType FrameworkHelper::GetViewId (const rtl::OUString& rsViewURL) 710 { 711 if (mpViewURLMap->empty()) 712 { 713 (*mpViewURLMap)[msImpressViewURL] = ViewShell::ST_IMPRESS; 714 (*mpViewURLMap)[msDrawViewURL] = ViewShell::ST_DRAW; 715 (*mpViewURLMap)[msOutlineViewURL] = ViewShell::ST_OUTLINE; 716 (*mpViewURLMap)[msNotesViewURL] = ViewShell::ST_NOTES; 717 (*mpViewURLMap)[msHandoutViewURL] = ViewShell::ST_HANDOUT; 718 (*mpViewURLMap)[msSlideSorterURL] = ViewShell::ST_SLIDE_SORTER; 719 (*mpViewURLMap)[msPresentationViewURL] = ViewShell::ST_PRESENTATION; 720 (*mpViewURLMap)[msSidebarViewURL] = ViewShell::ST_SIDEBAR; 721 } 722 ViewURLMap::const_iterator iView (mpViewURLMap->find(rsViewURL)); 723 if (iView != mpViewURLMap->end()) 724 return iView->second; 725 else 726 return ViewShell::ST_NONE; 727 } 728 729 730 731 732 ::rtl::OUString FrameworkHelper::GetViewURL (ViewShell::ShellType eType) 733 { 734 switch (eType) 735 { 736 case ViewShell::ST_IMPRESS : return msImpressViewURL; 737 case ViewShell::ST_DRAW : return msDrawViewURL; 738 case ViewShell::ST_OUTLINE : return msOutlineViewURL; 739 case ViewShell::ST_NOTES : return msNotesViewURL; 740 case ViewShell::ST_HANDOUT : return msHandoutViewURL; 741 case ViewShell::ST_SLIDE_SORTER : return msSlideSorterURL; 742 case ViewShell::ST_PRESENTATION : return msPresentationViewURL; 743 case ViewShell::ST_SIDEBAR : return msSidebarViewURL; 744 default: 745 return OUString(); 746 } 747 } 748 749 750 751 752 void FrameworkHelper::HandleModeChangeSlot ( 753 sal_uLong nSlotId, 754 SfxRequest& rRequest) 755 { 756 sal_Bool bIsActive = sal_True; 757 758 if ( ! mxConfigurationController.is()) 759 return; 760 761 switch (nSlotId) 762 { 763 case SID_DRAWINGMODE: 764 case SID_NOTESMODE: 765 case SID_HANDOUTMODE: 766 case SID_DIAMODE: 767 case SID_OUTLINEMODE: 768 { 769 const SfxItemSet* pRequestArguments = rRequest.GetArgs(); 770 if (pRequestArguments) 771 { 772 SFX_REQUEST_ARG (rRequest, 773 pIsActive, 774 SfxBoolItem, 775 (sal_uInt16)nSlotId, 776 sal_False); 777 bIsActive = pIsActive->GetValue (); 778 } 779 } 780 break; 781 } 782 783 try 784 { 785 if ( ! mxConfigurationController.is()) 786 throw RuntimeException(); 787 788 789 Reference<XResourceId> xPaneId ( 790 CreateResourceId(framework::FrameworkHelper::msCenterPaneURL)); 791 Reference<XView> xView (GetView(xPaneId)); 792 ::boost::shared_ptr<ViewShell> pCenterViewShell (GetViewShell(xView)); 793 794 ::rtl::OUString sRequestedView; 795 if (bIsActive) 796 { 797 switch (nSlotId) 798 { 799 case SID_NORMAL_MULTI_PANE_GUI: 800 case SID_DRAWINGMODE: 801 sRequestedView = FrameworkHelper::msImpressViewURL; 802 break; 803 804 case SID_NOTESMODE: 805 sRequestedView = FrameworkHelper::msNotesViewURL; 806 break; 807 808 case SID_HANDOUTMODE: 809 sRequestedView = FrameworkHelper::msHandoutViewURL; 810 break; 811 812 case SID_SLIDE_SORTER_MULTI_PANE_GUI: 813 case SID_DIAMODE: 814 sRequestedView = FrameworkHelper::msSlideSorterURL; 815 break; 816 817 case SID_OUTLINEMODE: 818 sRequestedView = FrameworkHelper::msOutlineViewURL; 819 break; 820 } 821 } 822 823 if (xView.is() 824 && xView->getResourceId()->getResourceURL().equals(sRequestedView)) 825 { 826 // We do not have to switch the view shell but maybe the edit mode 827 // has changed. 828 DrawViewShell* pDrawViewShell 829 = dynamic_cast<DrawViewShell*>(pCenterViewShell.get()); 830 if (pDrawViewShell != NULL) 831 { 832 pCenterViewShell->Broadcast ( 833 ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_START)); 834 835 pDrawViewShell->ChangeEditMode ( 836 EM_PAGE, pDrawViewShell->IsLayerModeActive()); 837 838 pCenterViewShell->Broadcast ( 839 ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_END)); 840 } 841 } 842 else 843 { 844 mxConfigurationController->requestResourceActivation( 845 CreateResourceId(sRequestedView, msCenterPaneURL), 846 ResourceActivationMode_REPLACE); 847 } 848 } 849 catch (RuntimeException&) 850 { 851 DBG_UNHANDLED_EXCEPTION(); 852 } 853 } 854 855 856 857 858 void FrameworkHelper::RunOnConfigurationEvent( 859 const ::rtl::OUString& rsEventType, 860 const Callback& rCallback) 861 { 862 RunOnEvent( 863 rsEventType, 864 FrameworkHelperAllPassFilter(), 865 rCallback); 866 } 867 868 869 870 871 void FrameworkHelper::RunOnResourceActivation( 872 const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId, 873 const Callback& rCallback) 874 { 875 if (mxConfigurationController.is() 876 && mxConfigurationController->getResource(rxResourceId).is()) 877 { 878 rCallback(false); 879 } 880 else 881 { 882 RunOnEvent( 883 msResourceActivationEvent, 884 FrameworkHelperResourceIdFilter(rxResourceId), 885 rCallback); 886 } 887 } 888 889 890 891 892 void FrameworkHelper::RunOnResourceDeactivation( 893 const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId, 894 const Callback& rCallback, 895 const bool bRunOnDeactivationEnd) 896 { 897 if (mxConfigurationController.is() 898 && ! mxConfigurationController->getResource(rxResourceId).is()) 899 { 900 rCallback(false); 901 } 902 else 903 { 904 RunOnEvent( 905 bRunOnDeactivationEnd 906 ? msResourceDeactivationEndEvent 907 : msResourceDeactivationEvent, 908 FrameworkHelperResourceIdFilter(rxResourceId), 909 rCallback); 910 } 911 } 912 913 914 915 916 /** A callback that sets a flag to a specified value when the callback is 917 called. 918 */ 919 class FlagUpdater 920 { 921 public: 922 FlagUpdater (bool& rFlag) : mrFlag(rFlag) {} 923 void operator() (bool) {mrFlag = true;} 924 private: 925 bool& mrFlag; 926 }; 927 928 929 930 931 void FrameworkHelper::RequestSynchronousUpdate (void) 932 { 933 rtl::Reference<ConfigurationController> pCC ( 934 dynamic_cast<ConfigurationController*>(mxConfigurationController.get())); 935 if (pCC.is()) 936 pCC->RequestSynchronousUpdate(); 937 } 938 939 940 941 942 void FrameworkHelper::WaitForEvent (const OUString& rsEventType) const 943 { 944 bool bConfigurationUpdateSeen (false); 945 946 RunOnEvent( 947 rsEventType, 948 FrameworkHelperAllPassFilter(), 949 FlagUpdater(bConfigurationUpdateSeen)); 950 951 sal_uInt32 nStartTime = osl_getGlobalTimer(); 952 while ( ! bConfigurationUpdateSeen) 953 { 954 Application::Reschedule(); 955 956 if( (osl_getGlobalTimer() - nStartTime) > 60000 ) 957 { 958 DBG_ERROR("FrameworkHelper::WaitForEvent(), no event for a minute? giving up!"); 959 break; 960 } 961 } 962 } 963 964 965 966 967 void FrameworkHelper::WaitForUpdate (void) const 968 { 969 WaitForEvent(msConfigurationUpdateEndEvent); 970 } 971 972 973 974 975 void FrameworkHelper::RunOnEvent( 976 const ::rtl::OUString& rsEventType, 977 const ConfigurationChangeEventFilter& rFilter, 978 const Callback& rCallback) const 979 { 980 new CallbackCaller(mrBase,rsEventType,rFilter,rCallback); 981 } 982 983 984 985 986 void FrameworkHelper::disposing (const lang::EventObject& rEventObject) 987 { 988 if (rEventObject.Source == mxConfigurationController) 989 mxConfigurationController = NULL; 990 } 991 992 993 994 995 void FrameworkHelper::UpdateConfiguration (void) 996 { 997 if (mxConfigurationController.is()) 998 { 999 try 1000 { 1001 if (mxConfigurationController.is()) 1002 mxConfigurationController->update(); 1003 } 1004 catch (lang::DisposedException&) 1005 { 1006 Dispose(); 1007 } 1008 catch (RuntimeException&) 1009 { 1010 DBG_UNHANDLED_EXCEPTION(); 1011 } 1012 } 1013 } 1014 1015 1016 1017 1018 OUString FrameworkHelper::ResourceIdToString (const Reference<XResourceId>& rxResourceId) 1019 { 1020 OUString sString; 1021 if (rxResourceId.is()) 1022 { 1023 sString += rxResourceId->getResourceURL(); 1024 if (rxResourceId->hasAnchor()) 1025 { 1026 Sequence<OUString> aAnchorURLs (rxResourceId->getAnchorURLs()); 1027 for (sal_Int32 nIndex=0; nIndex<aAnchorURLs.getLength(); ++nIndex) 1028 { 1029 sString += OUString::createFromAscii(" | "); 1030 sString += aAnchorURLs[nIndex]; 1031 } 1032 } 1033 } 1034 return sString; 1035 } 1036 1037 1038 1039 1040 Reference<XResourceId> FrameworkHelper::CreateResourceId (const ::rtl::OUString& rsResourceURL) 1041 { 1042 return new ::sd::framework::ResourceId(rsResourceURL); 1043 } 1044 1045 1046 1047 1048 Reference<XResourceId> FrameworkHelper::CreateResourceId ( 1049 const OUString& rsResourceURL, 1050 const OUString& rsAnchorURL) 1051 { 1052 return new ::sd::framework::ResourceId(rsResourceURL, rsAnchorURL); 1053 } 1054 1055 1056 1057 1058 Reference<XResourceId> FrameworkHelper::CreateResourceId ( 1059 const OUString& rsResourceURL, 1060 const OUString& rsFirstAnchorURL, 1061 const OUString& rsSecondAnchorURL) 1062 { 1063 ::std::vector<OUString> aAnchorURLs (2); 1064 aAnchorURLs[0] = rsFirstAnchorURL; 1065 aAnchorURLs[1] = rsSecondAnchorURL; 1066 return new ::sd::framework::ResourceId(rsResourceURL, aAnchorURLs); 1067 } 1068 1069 1070 1071 1072 Reference<XResourceId> FrameworkHelper::CreateResourceId ( 1073 const ::rtl::OUString& rsResourceURL, 1074 const Reference<XResourceId>& rxAnchorId) 1075 { 1076 if (rxAnchorId.is()) 1077 return new ::sd::framework::ResourceId( 1078 rsResourceURL, 1079 rxAnchorId->getResourceURL(), 1080 rxAnchorId->getAnchorURLs()); 1081 else 1082 return new ::sd::framework::ResourceId(rsResourceURL); 1083 } 1084 1085 1086 1087 1088 Reference<XConfigurationController> FrameworkHelper::GetConfigurationController (void) const 1089 { 1090 return mxConfigurationController; 1091 } 1092 1093 1094 1095 1096 //----- FrameworkHelper::DisposeListener -------------------------------------- 1097 1098 FrameworkHelper::DisposeListener::DisposeListener ( 1099 const ::boost::shared_ptr<FrameworkHelper>& rpHelper) 1100 : FrameworkHelperDisposeListenerInterfaceBase(maMutex), 1101 mpHelper(rpHelper) 1102 { 1103 Reference<XComponent> xComponent (mpHelper->mxConfigurationController, UNO_QUERY); 1104 if (xComponent.is()) 1105 xComponent->addEventListener(this); 1106 } 1107 1108 1109 1110 1111 FrameworkHelper::DisposeListener::~DisposeListener (void) 1112 { 1113 } 1114 1115 1116 1117 1118 void SAL_CALL FrameworkHelper::DisposeListener::disposing (void) 1119 { 1120 Reference<XComponent> xComponent (mpHelper->mxConfigurationController, UNO_QUERY); 1121 if (xComponent.is()) 1122 xComponent->removeEventListener(this); 1123 1124 mpHelper.reset(); 1125 } 1126 1127 1128 1129 1130 void SAL_CALL FrameworkHelper::DisposeListener::disposing (const lang::EventObject& rEventObject) 1131 throw(RuntimeException) 1132 { 1133 if (mpHelper.get() != NULL) 1134 mpHelper->disposing(rEventObject); 1135 } 1136 1137 1138 1139 1140 //===== FrameworkHelperResourceIdFilter ======================================= 1141 1142 FrameworkHelperResourceIdFilter::FrameworkHelperResourceIdFilter ( 1143 const Reference<XResourceId>& rxResourceId) 1144 : mxResourceId(rxResourceId) 1145 { 1146 } 1147 1148 1149 } } // end of namespace sd::framework 1150 1151 namespace { 1152 1153 //===== CallbackCaller ======================================================== 1154 1155 CallbackCaller::CallbackCaller ( 1156 ::sd::ViewShellBase& rBase, 1157 const OUString& rsEventType, 1158 const ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter& rFilter, 1159 const ::sd::framework::FrameworkHelper::Callback& rCallback) 1160 : CallbackCallerInterfaceBase(MutexOwner::maMutex), 1161 msEventType(rsEventType), 1162 mxConfigurationController(), 1163 maFilter(rFilter), 1164 maCallback(rCallback) 1165 { 1166 try 1167 { 1168 Reference<XControllerManager> xControllerManager (rBase.GetController(), UNO_QUERY_THROW); 1169 mxConfigurationController = xControllerManager->getConfigurationController(); 1170 if (mxConfigurationController.is()) 1171 { 1172 if (mxConfigurationController->hasPendingRequests()) 1173 mxConfigurationController->addConfigurationChangeListener(this,msEventType,Any()); 1174 else 1175 { 1176 // There are no requests waiting to be processed. Therefore 1177 // no event, especially not the one we are waiting for, will 1178 // be sent in the near future and the callback would never be 1179 // called. 1180 // Call the callback now and tell him that the event it is 1181 // waiting for was not sent. 1182 mxConfigurationController = NULL; 1183 maCallback(false); 1184 } 1185 } 1186 } 1187 catch (RuntimeException&) 1188 { 1189 DBG_UNHANDLED_EXCEPTION(); 1190 } 1191 } 1192 1193 1194 1195 1196 CallbackCaller::~CallbackCaller (void) 1197 { 1198 } 1199 1200 1201 1202 1203 void CallbackCaller::disposing (void) 1204 { 1205 try 1206 { 1207 if (mxConfigurationController.is()) 1208 { 1209 Reference<XConfigurationController> xCC (mxConfigurationController); 1210 mxConfigurationController = NULL; 1211 xCC->removeConfigurationChangeListener(this); 1212 } 1213 } 1214 catch (RuntimeException&) 1215 { 1216 DBG_UNHANDLED_EXCEPTION(); 1217 } 1218 } 1219 1220 1221 1222 1223 void SAL_CALL CallbackCaller::disposing (const lang::EventObject& rEvent) 1224 throw (RuntimeException) 1225 { 1226 if (rEvent.Source == mxConfigurationController) 1227 { 1228 mxConfigurationController = NULL; 1229 maCallback(false); 1230 } 1231 } 1232 1233 1234 1235 1236 void SAL_CALL CallbackCaller::notifyConfigurationChange ( 1237 const ConfigurationChangeEvent& rEvent) 1238 throw (RuntimeException) 1239 { 1240 if (rEvent.Type.equals(msEventType) && maFilter(rEvent)) 1241 { 1242 maCallback(true); 1243 if (mxConfigurationController.is()) 1244 { 1245 // Reset the reference to the configuration controller so that 1246 // dispose() will not try to remove the listener a second time. 1247 Reference<XConfigurationController> xCC (mxConfigurationController); 1248 mxConfigurationController = NULL; 1249 1250 // Removing this object from the controller may very likely lead 1251 // to its destruction, so no calls after that. 1252 xCC->removeConfigurationChangeListener(this); 1253 } 1254 } 1255 } 1256 1257 1258 1259 1260 //----- LifetimeController ------------------------------------------------- 1261 1262 LifetimeController::LifetimeController (::sd::ViewShellBase& rBase) 1263 : LifetimeControllerInterfaceBase(maMutex), 1264 mrBase(rBase), 1265 mbListeningToViewShellBase(false), 1266 mbListeningToController(false) 1267 { 1268 // Register as listener at the ViewShellBase. Because that is not done 1269 // via a reference we have to increase the reference count manually. 1270 // This is necessary even though listening to the XController did 1271 // increase the reference count because the controller may release its 1272 // reference to us before the ViewShellBase is destroyed. 1273 StartListening(mrBase); 1274 acquire(); 1275 mbListeningToViewShellBase = true; 1276 1277 Reference<XComponent> xComponent (rBase.GetController(), UNO_QUERY); 1278 if (xComponent.is()) 1279 { 1280 xComponent->addEventListener(this); 1281 mbListeningToController = true; 1282 } 1283 } 1284 1285 1286 1287 1288 LifetimeController::~LifetimeController (void) 1289 { 1290 OSL_ASSERT(!mbListeningToController && !mbListeningToViewShellBase); 1291 } 1292 1293 1294 1295 1296 void LifetimeController::disposing (void) 1297 { 1298 } 1299 1300 1301 1302 1303 void SAL_CALL LifetimeController::disposing (const lang::EventObject& rEvent) 1304 throw(RuntimeException) 1305 { 1306 (void)rEvent; 1307 mbListeningToController = false; 1308 Update(); 1309 } 1310 1311 1312 1313 1314 void LifetimeController::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint) 1315 { 1316 (void)rBroadcaster; 1317 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint); 1318 if (pSimpleHint != NULL && pSimpleHint->GetId() == SFX_HINT_DYING) 1319 { 1320 mbListeningToViewShellBase = false; 1321 Update(); 1322 release(); 1323 } 1324 } 1325 1326 1327 1328 1329 void LifetimeController::Update (void) 1330 { 1331 if (mbListeningToViewShellBase && mbListeningToController) 1332 { 1333 // Both the controller and the ViewShellBase are alive. Keep 1334 // waiting for their destruction. 1335 } 1336 else if (mbListeningToViewShellBase) 1337 { 1338 // The controller has been destroyed but the ViewShellBase is still 1339 // alive. Dispose the associated FrameworkHelper but keep it around 1340 // so that no new instance is created for the dying framework. 1341 ::sd::framework::FrameworkHelper::DisposeInstance(mrBase); 1342 } 1343 else 1344 { 1345 // Both the controller and the ViewShellBase have been destroyed. 1346 // Remove the FrameworkHelper so that the next call its Instance() 1347 // method can create a new instance. 1348 ::sd::framework::FrameworkHelper::ReleaseInstance(mrBase); 1349 } 1350 } 1351 1352 1353 1354 } // end of anonymous namespace. 1355