1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sdext.hxx" 26 27 #include "PresenterScreen.hxx" 28 #include "PresenterConfigurationAccess.hxx" 29 #include "PresenterController.hxx" 30 #include "PresenterFrameworkObserver.hxx" 31 #include "PresenterHelper.hxx" 32 #include "PresenterPaneContainer.hxx" 33 #include "PresenterPaneFactory.hxx" 34 #include "PresenterViewFactory.hxx" 35 #include "PresenterWindowManager.hxx" 36 #include <com/sun/star/frame/XController.hpp> 37 #include <com/sun/star/lang/XServiceInfo.hpp> 38 #include <com/sun/star/drawing/framework/Configuration.hpp> 39 #include <com/sun/star/drawing/framework/XControllerManager.hpp> 40 #include <com/sun/star/drawing/framework/ResourceId.hpp> 41 #include <com/sun/star/drawing/framework/ResourceActivationMode.hpp> 42 #include <com/sun/star/presentation/XSlideShow.hpp> 43 #include <com/sun/star/presentation/XPresentation2.hpp> 44 #include <com/sun/star/presentation/XPresentationSupplier.hpp> 45 #include <com/sun/star/document/XEventBroadcaster.hpp> 46 #include <boost/bind.hpp> 47 #include <tools/debug.hxx> 48 49 #include <com/sun/star/view/XSelectionSupplier.hpp> 50 51 using namespace ::com::sun::star; 52 using namespace ::com::sun::star::uno; 53 using namespace ::com::sun::star::lang; 54 using namespace ::com::sun::star::presentation; 55 using namespace ::com::sun::star::drawing::framework; 56 using ::rtl::OUString; 57 58 #define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))) 59 60 namespace sdext { namespace presenter { 61 62 namespace { 63 64 static sal_Bool lcl_IsPresenterEnabled( 65 const css::uno::Reference< css::uno::XComponentContext > &rxContext ) 66 { 67 sal_Bool bEnabled( sal_True ); 68 PresenterConfigurationAccess aConfig( 69 rxContext, 70 A2S( "/org.openoffice.Office.Impress" ), 71 PresenterConfigurationAccess::READ_ONLY ); 72 if ( aConfig.IsValid() ) 73 { 74 sal_Bool bVal( sal_False ); 75 if ( ( aConfig.GetConfigurationNode( 76 A2S( "Misc/Start/PresenterScreen" )) >>= bVal ) ) 77 bEnabled = bVal; 78 } 79 return bEnabled; 80 } 81 82 typedef ::cppu::WeakComponentImplHelper1 < 83 css::document::XEventListener 84 > PresenterScreenListenerInterfaceBase; 85 86 /** One instance of a PresenterScreenListener is registered per Impress 87 document and waits for the full screen slide show to start and to 88 end. 89 */ 90 class PresenterScreenListener 91 : private ::boost::noncopyable, 92 private ::cppu::BaseMutex, 93 public PresenterScreenListenerInterfaceBase 94 { 95 public: 96 PresenterScreenListener ( 97 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 98 const css::uno::Reference<css::frame::XModel2>& rxModel); 99 virtual ~PresenterScreenListener (void); 100 101 void Initialize (void); 102 virtual void SAL_CALL disposing (void); 103 104 // document::XEventListener 105 106 virtual void SAL_CALL notifyEvent( const css::document::EventObject& Event ) throw (css::uno::RuntimeException); 107 108 // XEventListener 109 110 virtual void SAL_CALL disposing ( const css::lang::EventObject& rEvent) throw (css::uno::RuntimeException); 111 112 private: 113 css::uno::Reference<css::frame::XModel2 > mxModel; 114 css::uno::Reference<css::uno::XComponentContext> mxComponentContext; 115 rtl::Reference<PresenterScreen> mpPresenterScreen; 116 117 void ThrowIfDisposed (void) const throw (::com::sun::star::lang::DisposedException); 118 }; 119 } 120 121 122 //----- Service --------------------------------------------------------------- 123 124 OUString PresenterScreenJob::getImplementationName_static (void) 125 { 126 return A2S("com.sun.star.comp.presentation.PresenterScreenJob"); 127 } 128 129 130 131 132 Sequence<OUString> PresenterScreenJob::getSupportedServiceNames_static (void) 133 { 134 static const ::rtl::OUString sServiceName( 135 A2S("com.sun.star.presentation.PresenterScreenJob")); 136 return Sequence<rtl::OUString>(&sServiceName, 1); 137 } 138 139 140 141 142 Reference<XInterface> PresenterScreenJob::Create (const Reference<uno::XComponentContext>& rxContext) 143 SAL_THROW((css::uno::Exception)) 144 { 145 return Reference<XInterface>(static_cast<XWeak*>(new PresenterScreenJob(rxContext))); 146 } 147 148 149 150 151 //===== PresenterScreenJob ==================================================== 152 153 PresenterScreenJob::PresenterScreenJob (const Reference<XComponentContext>& rxContext) 154 : PresenterScreenJobInterfaceBase(m_aMutex), 155 mxComponentContext(rxContext) 156 { 157 } 158 159 160 161 162 PresenterScreenJob::~PresenterScreenJob (void) 163 { 164 } 165 166 167 168 169 void SAL_CALL PresenterScreenJob::disposing (void) 170 { 171 mxComponentContext = NULL; 172 } 173 174 175 176 177 //----- XJob ----------------------------------------------------------- 178 179 Any SAL_CALL PresenterScreenJob::execute( 180 const Sequence< beans::NamedValue >& Arguments ) 181 throw (lang::IllegalArgumentException, Exception, RuntimeException) 182 { 183 Sequence< beans::NamedValue > lEnv; 184 185 sal_Int32 i = 0; 186 sal_Int32 c = Arguments.getLength(); 187 const beans::NamedValue* p = Arguments.getConstArray(); 188 for (i=0; i<c; ++i) 189 { 190 if (p[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Environment"))) 191 { 192 p[i].Value >>= lEnv; 193 break; 194 } 195 } 196 197 Reference<frame::XModel2> xModel; 198 c = lEnv.getLength(); 199 p = lEnv.getConstArray(); 200 for (i=0; i<c; ++i) 201 { 202 if (p[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Model"))) 203 { 204 p[i].Value >>= xModel; 205 break; 206 } 207 } 208 209 Reference< XServiceInfo > xInfo( xModel, UNO_QUERY ); 210 if( !xInfo.is() || !xInfo->supportsService( 211 A2S( "com.sun.star.presentation.PresentationDocument" ) ) ) 212 return Any(); 213 214 // Create a new listener that waits for the full screen presentation 215 // to start and to end. It takes care of its own lifetime. 216 ::rtl::Reference<PresenterScreenListener> pListener ( 217 new PresenterScreenListener(mxComponentContext, xModel)); 218 pListener->Initialize(); 219 220 return Any(); 221 } 222 223 224 225 226 //===== PresenterScreenListener =============================================== 227 228 namespace { 229 230 PresenterScreenListener::PresenterScreenListener ( 231 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 232 const css::uno::Reference<css::frame::XModel2>& rxModel) 233 : PresenterScreenListenerInterfaceBase(m_aMutex), 234 mxModel(rxModel), 235 mxComponentContext(rxContext), 236 mpPresenterScreen() 237 { 238 } 239 240 241 242 243 void PresenterScreenListener::Initialize (void) 244 { 245 Reference< document::XEventListener > xDocListener( 246 static_cast< document::XEventListener* >(this), UNO_QUERY); 247 Reference< document::XEventBroadcaster > xDocBroadcaster( mxModel, UNO_QUERY ); 248 if( xDocBroadcaster.is() ) 249 xDocBroadcaster->addEventListener(xDocListener); 250 } 251 252 253 254 255 PresenterScreenListener::~PresenterScreenListener (void) 256 { 257 } 258 259 260 261 262 void SAL_CALL PresenterScreenListener::disposing (void) 263 { 264 Reference< document::XEventBroadcaster > xDocBroadcaster( mxModel, UNO_QUERY ); 265 if( xDocBroadcaster.is() ) 266 xDocBroadcaster->removeEventListener( 267 Reference<document::XEventListener>( 268 static_cast<document::XEventListener*>(this), UNO_QUERY)); 269 270 if (mpPresenterScreen.is()) 271 { 272 mpPresenterScreen->RequestShutdownPresenterScreen(); 273 mpPresenterScreen = NULL; 274 } 275 } 276 277 278 279 280 // document::XEventListener 281 282 void SAL_CALL PresenterScreenListener::notifyEvent( const css::document::EventObject& Event ) throw (css::uno::RuntimeException) 283 { 284 ThrowIfDisposed(); 285 286 if( Event.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnStartPresentation" ) ) ) 287 { 288 mpPresenterScreen = new PresenterScreen(mxComponentContext, mxModel); 289 mpPresenterScreen->InitializePresenterScreen(); 290 } 291 else if( Event.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnEndPresentation" ) ) ) 292 { 293 if (mpPresenterScreen.is()) 294 { 295 mpPresenterScreen->RequestShutdownPresenterScreen(); 296 mpPresenterScreen = NULL; 297 } 298 } 299 } 300 301 302 303 304 // XEventListener 305 306 void SAL_CALL PresenterScreenListener::disposing (const css::lang::EventObject& rEvent) 307 throw (css::uno::RuntimeException) 308 { 309 (void)rEvent; 310 311 if (mpPresenterScreen.is()) 312 { 313 mpPresenterScreen->RequestShutdownPresenterScreen(); 314 mpPresenterScreen = NULL; 315 } 316 } 317 318 319 320 321 void PresenterScreenListener::ThrowIfDisposed (void) const throw ( 322 ::com::sun::star::lang::DisposedException) 323 { 324 if (rBHelper.bDisposed || rBHelper.bInDispose) 325 { 326 throw lang::DisposedException ( 327 A2S("PresenterScreenListener object has already been disposed"), 328 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); 329 } 330 } 331 332 } // end of anonymous namespace 333 334 335 336 337 //===== PresenterScreen ======================================================= 338 339 PresenterScreen::PresenterScreen ( 340 const Reference<XComponentContext>& rxContext, 341 const css::uno::Reference<css::frame::XModel2>& rxModel) 342 : PresenterScreenInterfaceBase(m_aMutex), 343 mxModel(rxModel), 344 mxController(), 345 mxConfigurationControllerWeak(), 346 mxContextWeak(rxContext), 347 mxSlideShowControllerWeak(), 348 mpPresenterController(), 349 mxSlideShowViewId(), 350 mxSavedConfiguration(), 351 mpPaneContainer(), 352 mnComponentIndex(0), 353 mxPaneFactory(), 354 mxViewFactory(), 355 maViewDescriptors() 356 { 357 } 358 359 360 361 362 PresenterScreen::~PresenterScreen (void) 363 { 364 } 365 366 367 368 369 void SAL_CALL PresenterScreen::disposing (void) 370 { 371 Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); 372 if (xCC.is() && mxSavedConfiguration.is()) 373 { 374 xCC->restoreConfiguration(mxSavedConfiguration); 375 } 376 mxConfigurationControllerWeak = Reference<XConfigurationController>(NULL); 377 378 Reference<lang::XComponent> xViewFactoryComponent (mxViewFactory, UNO_QUERY); 379 if (xViewFactoryComponent.is()) 380 xViewFactoryComponent->dispose(); 381 Reference<lang::XComponent> xPaneFactoryComponent (mxPaneFactory, UNO_QUERY); 382 if (xPaneFactoryComponent.is()) 383 xPaneFactoryComponent->dispose(); 384 385 mxModel = NULL; 386 } 387 388 389 390 391 //----- XEventListener -------------------------------------------------------- 392 393 void SAL_CALL PresenterScreen::disposing (const lang::EventObject& /*rEvent*/) 394 throw (RuntimeException) 395 { 396 mxSlideShowControllerWeak = WeakReference<presentation::XSlideShowController>(); 397 RequestShutdownPresenterScreen(); 398 } 399 400 401 402 403 //----------------------------------------------------------------------------- 404 405 void PresenterScreen::InitializePresenterScreen (void) 406 { 407 try 408 { 409 Reference<XComponentContext> xContext (mxContextWeak); 410 411 // Check if disabled by configuration 412 if (!lcl_IsPresenterEnabled(xContext) ) 413 return; 414 415 mpPaneContainer = 416 new PresenterPaneContainer(Reference<XComponentContext>(xContext)); 417 418 Reference<XPresentationSupplier> xPS ( mxModel, UNO_QUERY_THROW); 419 Reference<XPresentation2> xPresentation(xPS->getPresentation(), UNO_QUERY_THROW); 420 Reference<presentation::XSlideShowController> xSlideShowController( xPresentation->getController() ); 421 mxSlideShowControllerWeak = xSlideShowController; 422 423 if( !xSlideShowController.is() || !xSlideShowController->isFullScreen() ) 424 return; 425 426 // find first controller that is not the current controller (the one with the slideshow 427 mxController = mxModel->getCurrentController(); 428 Reference< container::XEnumeration > xEnum( mxModel->getControllers() ); 429 if( xEnum.is() ) 430 { 431 while( xEnum->hasMoreElements() ) 432 { 433 Reference< frame::XController > xC( xEnum->nextElement(), UNO_QUERY ); 434 if( xC.is() && (xC != mxController) ) 435 { 436 mxController = xC; 437 break; 438 } 439 } 440 } 441 // Get the XController from the first argument. 442 Reference<XControllerManager> xCM(mxController, UNO_QUERY_THROW); 443 444 Reference<XConfigurationController> xCC( xCM->getConfigurationController()); 445 mxConfigurationControllerWeak = xCC; 446 447 Reference<drawing::framework::XResourceId> xMainPaneId( 448 GetMainPaneId(xPresentation)); 449 // An empty reference means that the presenter screen can 450 // not or must not be displayed. 451 if ( ! xMainPaneId.is()) 452 return; 453 454 if (xCC.is() && xContext.is()) 455 { 456 // Store the current configuration so that we can restore it when 457 // the presenter view is deactivated. 458 mxSavedConfiguration = xCC->getRequestedConfiguration(); 459 xCC->lock(); 460 461 try 462 { 463 // At the moment the presenter controller is displayed in its 464 // own full screen window that is controlled by the same 465 // configuration controller as the Impress document from 466 // which the presentation was started. Therefore the main 467 // pane is actived additionally to the already existing 468 // panes and does not replace them. 469 xCC->requestResourceActivation( 470 xMainPaneId, 471 ResourceActivationMode_ADD); 472 SetupConfiguration(xContext, xMainPaneId); 473 474 mpPresenterController = new PresenterController( 475 xContext, 476 mxController, 477 xSlideShowController, 478 mpPaneContainer, 479 xMainPaneId); 480 481 // Create pane and view factories and integrate them into the 482 // drawing framework. 483 SetupPaneFactory(xContext); 484 SetupViewFactory(xContext); 485 486 mpPresenterController->GetWindowManager()->RestoreViewMode(); 487 } 488 catch (RuntimeException&) 489 { 490 xCC->restoreConfiguration(mxSavedConfiguration); 491 } 492 xCC->unlock(); 493 } 494 } 495 catch (Exception&) 496 { 497 } 498 } 499 500 501 502 503 sal_Int32 PresenterScreen::GetScreenNumber ( 504 const Reference<presentation::XPresentation2>& rxPresentation) const 505 { 506 // Determine the screen on which the full screen presentation is being 507 // displayed. 508 sal_Int32 nScreenNumber (0); 509 sal_Int32 nScreenCount (1); 510 try 511 { 512 Reference<beans::XPropertySet> xProperties (rxPresentation, UNO_QUERY); 513 if ( ! xProperties.is()) 514 return -1; 515 516 sal_Int32 nDisplayNumber (-1); 517 if ( ! (xProperties->getPropertyValue(A2S("Display")) >>= nDisplayNumber)) 518 return -1; 519 if (nDisplayNumber == -1) 520 { 521 // The special value -1 indicates that the slide show 522 // spans all available displays. That leaves no room for 523 // the presenter screen. 524 return -1; 525 } 526 527 Reference<XComponentContext> xContext (mxContextWeak); 528 if ( ! xContext.is()) 529 return -1; 530 Reference<lang::XMultiComponentFactory> xFactory ( 531 xContext->getServiceManager(), UNO_QUERY); 532 if ( ! xFactory.is()) 533 return -1; 534 Reference<beans::XPropertySet> xDisplayProperties ( 535 xFactory->createInstanceWithContext(A2S("com.sun.star.awt.DisplayAccess"),xContext), 536 UNO_QUERY); 537 if ( ! xDisplayProperties.is()) 538 return -1; 539 540 if (nDisplayNumber > 0) 541 { 542 nScreenNumber = nDisplayNumber - 1; 543 } 544 else if (nDisplayNumber == 0) 545 { 546 // A display number value of 0 indicates the primary screen. 547 // Instantiate the DisplayAccess service to find out which 548 // screen number that is. 549 if (nDisplayNumber <= 0 && xDisplayProperties.is()) 550 xDisplayProperties->getPropertyValue(A2S("DefaultDisplay")) >>= nScreenNumber; 551 } 552 553 // We still have to determine the number of screens to decide 554 // whether the presenter screen may be shown at all. 555 Reference<container::XIndexAccess> xIndexAccess (xDisplayProperties, UNO_QUERY); 556 if ( ! xIndexAccess.is()) 557 return -1; 558 nScreenCount = xIndexAccess->getCount(); 559 560 if (nScreenCount < 2 || nDisplayNumber > nScreenCount) 561 { 562 // There is either only one screen or the full screen 563 // presentation spans all available screens. The presenter 564 // screen is shown only when a special flag in the configuration 565 // is set. 566 PresenterConfigurationAccess aConfiguration ( 567 xContext, 568 A2S("/org.openoffice.Office.PresenterScreen/"), 569 PresenterConfigurationAccess::READ_ONLY); 570 bool bStartAlways (false); 571 if (aConfiguration.GetConfigurationNode( 572 A2S("Presenter/StartAlways")) >>= bStartAlways) 573 { 574 if (bStartAlways) 575 return nScreenNumber; 576 } 577 return -1; 578 } 579 } 580 catch (beans::UnknownPropertyException&) 581 { 582 OSL_ASSERT(false); 583 // For some reason we can not access the screen number. Use 584 // the default instead. 585 } 586 587 return nScreenNumber; 588 } 589 590 591 592 593 Reference<drawing::framework::XResourceId> PresenterScreen::GetMainPaneId ( 594 const Reference<presentation::XPresentation2>& rxPresentation) const 595 { 596 // A negative value means that the presentation spans all available 597 // displays. That leaves no room for the presenter. 598 const sal_Int32 nScreenNumber(GetScreenNumber(rxPresentation)); 599 if (nScreenNumber < 0) 600 return NULL; 601 602 // Setup the resource id of the full screen background pane so that 603 // it is displayed on another screen than the presentation. 604 sal_Int32 nPresenterScreenNumber (1); 605 switch (nScreenNumber) 606 { 607 case 0: 608 nPresenterScreenNumber = 1; 609 break; 610 611 case 1: 612 nPresenterScreenNumber = 0; 613 break; 614 615 default: 616 // When the full screen presentation is displayed on a screen 617 // other than 0 or 1 then place the presenter on the first 618 // available screen. 619 nPresenterScreenNumber = 0; 620 break; 621 } 622 623 return ResourceId::create( 624 Reference<XComponentContext>(mxContextWeak), 625 PresenterHelper::msFullScreenPaneURL 626 +A2S("?FullScreen=true&ScreenNumber=") 627 + OUString::valueOf(nPresenterScreenNumber)); 628 } 629 630 631 632 633 void PresenterScreen::RequestShutdownPresenterScreen (void) 634 { 635 // Restore the configuration that was active before the presenter screen 636 // has been activated. Now, that the presenter screen is displayed in 637 // its own top level window this probably not necessary, but one never knows. 638 Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); 639 if (xCC.is() && mxSavedConfiguration.is()) 640 { 641 xCC->restoreConfiguration(mxSavedConfiguration); 642 mxSavedConfiguration = NULL; 643 } 644 645 if (xCC.is()) 646 { 647 // The actual restoration of the configuration takes place 648 // asynchronously. The view and pane factories can only by disposed 649 // after that. Therefore, set up a listener and wait for the 650 // restoration. 651 rtl::Reference<PresenterScreen> pSelf (this); 652 PresenterFrameworkObserver::RunOnUpdateEnd( 653 xCC, 654 ::boost::bind(&PresenterScreen::ShutdownPresenterScreen, pSelf)); 655 xCC->update(); 656 } 657 } 658 659 660 661 662 void PresenterScreen::ShutdownPresenterScreen (void) 663 { 664 Reference<lang::XComponent> xViewFactoryComponent (mxViewFactory, UNO_QUERY); 665 if (xViewFactoryComponent.is()) 666 xViewFactoryComponent->dispose(); 667 mxViewFactory = NULL; 668 669 Reference<lang::XComponent> xPaneFactoryComponent (mxPaneFactory, UNO_QUERY); 670 if (xPaneFactoryComponent.is()) 671 xPaneFactoryComponent->dispose(); 672 mxPaneFactory = NULL; 673 674 if (mpPresenterController.get() != NULL) 675 { 676 mpPresenterController->dispose(); 677 mpPresenterController = rtl::Reference<PresenterController>(); 678 } 679 mpPaneContainer = new PresenterPaneContainer(Reference<XComponentContext>(mxContextWeak)); 680 } 681 682 683 684 685 void PresenterScreen::SetupPaneFactory (const Reference<XComponentContext>& rxContext) 686 { 687 try 688 { 689 if ( ! mxPaneFactory.is()) 690 mxPaneFactory = PresenterPaneFactory::Create( 691 rxContext, 692 mxController, 693 mpPresenterController); 694 } 695 catch (RuntimeException&) 696 { 697 OSL_ASSERT(false); 698 } 699 } 700 701 702 703 704 void PresenterScreen::SetupViewFactory (const Reference<XComponentContext>& rxContext) 705 { 706 try 707 { 708 if ( ! mxViewFactory.is()) 709 mxViewFactory = PresenterViewFactory::Create( 710 rxContext, 711 mxController, 712 mpPresenterController); 713 } 714 catch (RuntimeException&) 715 { 716 OSL_ASSERT(false); 717 } 718 } 719 720 721 722 723 void PresenterScreen::SetupConfiguration ( 724 const Reference<XComponentContext>& rxContext, 725 const Reference<XResourceId>& rxAnchorId) 726 { 727 try 728 { 729 PresenterConfigurationAccess aConfiguration ( 730 rxContext, 731 A2S("org.openoffice.Office.PresenterScreen"), 732 PresenterConfigurationAccess::READ_ONLY); 733 maViewDescriptors.clear(); 734 ProcessViewDescriptions(aConfiguration); 735 OUString sLayoutName (RTL_CONSTASCII_USTRINGPARAM("DefaultLayout")); 736 aConfiguration.GetConfigurationNode( 737 A2S("Presenter/CurrentLayout")) >>= sLayoutName; 738 ProcessLayout(aConfiguration, sLayoutName, rxContext, rxAnchorId); 739 } 740 catch (RuntimeException&) 741 { 742 } 743 } 744 745 746 747 748 void PresenterScreen::ProcessLayout ( 749 PresenterConfigurationAccess& rConfiguration, 750 const OUString& rsLayoutName, 751 const Reference<XComponentContext>& rxContext, 752 const Reference<XResourceId>& rxAnchorId) 753 { 754 try 755 { 756 Reference<container::XHierarchicalNameAccess> xLayoutNode ( 757 rConfiguration.GetConfigurationNode( 758 A2S("Presenter/Layouts/") + rsLayoutName), 759 UNO_QUERY_THROW); 760 761 // Read the parent layout first, if one is referenced. 762 OUString sParentLayout; 763 rConfiguration.GetConfigurationNode( 764 xLayoutNode, 765 A2S("ParentLayout")) >>= sParentLayout; 766 if (sParentLayout.getLength() > 0) 767 { 768 // Prevent infinite recursion. 769 if (rsLayoutName != sParentLayout) 770 ProcessLayout(rConfiguration, sParentLayout, rxContext, rxAnchorId); 771 } 772 773 // Process the actual layout list. 774 Reference<container::XNameAccess> xList ( 775 rConfiguration.GetConfigurationNode( 776 xLayoutNode, 777 A2S("Layout")), 778 UNO_QUERY_THROW); 779 780 ::std::vector<rtl::OUString> aProperties (6); 781 aProperties[0] = A2S("PaneURL"); 782 aProperties[1] = A2S("ViewURL"); 783 aProperties[2] = A2S("RelativeX"); 784 aProperties[3] = A2S("RelativeY"); 785 aProperties[4] = A2S("RelativeWidth"); 786 aProperties[5] = A2S("RelativeHeight"); 787 mnComponentIndex = 1; 788 PresenterConfigurationAccess::ForAll( 789 xList, 790 aProperties, 791 ::boost::bind(&PresenterScreen::ProcessComponent, this, 792 _1, 793 _2, 794 rxContext, 795 rxAnchorId)); 796 } 797 catch (RuntimeException&) 798 { 799 } 800 } 801 802 803 804 805 void PresenterScreen::ProcessViewDescriptions ( 806 PresenterConfigurationAccess& rConfiguration) 807 { 808 try 809 { 810 Reference<container::XNameAccess> xViewDescriptionsNode ( 811 rConfiguration.GetConfigurationNode(A2S("Presenter/Views")), 812 UNO_QUERY_THROW); 813 814 ::std::vector<rtl::OUString> aProperties (4); 815 aProperties[0] = A2S("ViewURL"); 816 aProperties[1] = A2S("Title"); 817 aProperties[2] = A2S("AccessibleTitle"); 818 aProperties[3] = A2S("IsOpaque"); 819 mnComponentIndex = 1; 820 PresenterConfigurationAccess::ForAll( 821 xViewDescriptionsNode, 822 aProperties, 823 ::boost::bind(&PresenterScreen::ProcessViewDescription, this, _1, _2)); 824 } 825 catch (RuntimeException&) 826 { 827 OSL_ASSERT(false); 828 } 829 } 830 831 832 833 834 void PresenterScreen::ProcessComponent ( 835 const OUString& rsKey, 836 const ::std::vector<Any>& rValues, 837 const Reference<XComponentContext>& rxContext, 838 const Reference<XResourceId>& rxAnchorId) 839 { 840 (void)rsKey; 841 842 if (rValues.size() != 6) 843 return; 844 845 try 846 { 847 OUString sPaneURL; 848 OUString sViewURL; 849 double nX = 0; 850 double nY = 0; 851 double nWidth = 0; 852 double nHeight = 0; 853 rValues[0] >>= sPaneURL; 854 rValues[1] >>= sViewURL; 855 rValues[2] >>= nX; 856 rValues[3] >>= nY; 857 rValues[4] >>= nWidth; 858 rValues[5] >>= nHeight; 859 860 if (nX>=0 && nY>=0 && nWidth>0 && nHeight>0) 861 { 862 SetupView( 863 rxContext, 864 rxAnchorId, 865 sPaneURL, 866 sViewURL, 867 PresenterPaneContainer::ViewInitializationFunction(), 868 nX, 869 nY, 870 nX+nWidth, 871 nY+nHeight); 872 } 873 } 874 catch (Exception& e) 875 { 876 (void)e; 877 OSL_ASSERT(false); 878 } 879 } 880 881 882 883 884 void PresenterScreen::ProcessViewDescription ( 885 const OUString& rsKey, 886 const ::std::vector<Any>& rValues) 887 { 888 (void)rsKey; 889 890 if (rValues.size() != 4) 891 return; 892 893 try 894 { 895 ViewDescriptor aViewDescriptor; 896 OUString sViewURL; 897 rValues[0] >>= sViewURL; 898 rValues[1] >>= aViewDescriptor.msTitle; 899 rValues[2] >>= aViewDescriptor.msAccessibleTitle; 900 rValues[3] >>= aViewDescriptor.mbIsOpaque; 901 if (aViewDescriptor.msAccessibleTitle.getLength()==0) 902 aViewDescriptor.msAccessibleTitle = aViewDescriptor.msTitle; 903 maViewDescriptors[sViewURL] = aViewDescriptor; 904 } 905 catch (Exception&) 906 { 907 OSL_ASSERT(false); 908 } 909 } 910 911 912 913 914 void PresenterScreen::SetupView( 915 const Reference<XComponentContext>& rxContext, 916 const Reference<XResourceId>& rxAnchorId, 917 const OUString& rsPaneURL, 918 const OUString& rsViewURL, 919 const PresenterPaneContainer::ViewInitializationFunction& rViewInitialization, 920 const double nLeft, 921 const double nTop, 922 const double nRight, 923 const double nBottom) 924 { 925 Reference<XConfigurationController> xCC (mxConfigurationControllerWeak); 926 if (xCC.is()) 927 { 928 Reference<XResourceId> xPaneId (ResourceId::createWithAnchor(rxContext,rsPaneURL,rxAnchorId)); 929 // Look up the view descriptor. 930 ViewDescriptor aViewDescriptor; 931 ViewDescriptorContainer::const_iterator iDescriptor (maViewDescriptors.find(rsViewURL)); 932 if (iDescriptor != maViewDescriptors.end()) 933 aViewDescriptor = iDescriptor->second; 934 935 // Prepare the pane. 936 OSL_ASSERT(mpPaneContainer.get() != NULL); 937 mpPaneContainer->PreparePane( 938 xPaneId, 939 rsViewURL, 940 aViewDescriptor.msTitle, 941 aViewDescriptor.msAccessibleTitle, 942 aViewDescriptor.mbIsOpaque, 943 rViewInitialization, 944 nLeft, 945 nTop, 946 nRight, 947 nBottom); 948 } 949 } 950 951 952 953 954 } } // end of namespace ::sdext::presenter 955