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