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 "PresenterViewFactory.hxx" 32 #include "PresenterPaneContainer.hxx" 33 #include "PresenterHelper.hxx" 34 #include "PresenterHelpView.hxx" 35 #include "PresenterNotesView.hxx" 36 #include "PresenterSlideShowView.hxx" 37 #include "PresenterSlidePreview.hxx" 38 #include "PresenterSlideSorter.hxx" 39 #include "PresenterToolBar.hxx" 40 #include <com/sun/star/beans/XPropertySet.hpp> 41 #include <com/sun/star/drawing/framework/ResourceId.hpp> 42 #include <com/sun/star/drawing/framework/XControllerManager.hpp> 43 #include <com/sun/star/drawing/framework/XConfigurationController.hpp> 44 #include <com/sun/star/drawing/XDrawPages.hpp> 45 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> 46 #include <com/sun/star/drawing/XSlideSorterBase.hpp> 47 #include <com/sun/star/presentation/XSlideShow.hpp> 48 #include <com/sun/star/presentation/XSlideShowView.hpp> 49 #include <cppuhelper/compbase1.hxx> 50 #include <boost/bind.hpp> 51 52 using namespace ::com::sun::star; 53 using namespace ::com::sun::star::uno; 54 using namespace ::com::sun::star::drawing::framework; 55 using ::rtl::OUString; 56 57 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) 58 59 namespace sdext { namespace presenter { 60 61 const ::rtl::OUString PresenterViewFactory::msCurrentSlidePreviewViewURL( 62 A2S("private:resource/view/Presenter/CurrentSlidePreview")); 63 const ::rtl::OUString PresenterViewFactory::msNextSlidePreviewViewURL( 64 A2S("private:resource/view/Presenter/NextSlidePreview")); 65 const ::rtl::OUString PresenterViewFactory::msNotesViewURL( 66 A2S("private:resource/view/Presenter/Notes")); 67 const ::rtl::OUString PresenterViewFactory::msToolBarViewURL( 68 A2S("private:resource/view/Presenter/ToolBar")); 69 const ::rtl::OUString PresenterViewFactory::msSlideSorterURL( 70 A2S("private:resource/view/Presenter/SlideSorter")); 71 const ::rtl::OUString PresenterViewFactory::msHelpViewURL( 72 A2S("private:resource/view/Presenter/Help")); 73 74 75 76 //===== SimpleView ============================================================ 77 78 namespace { 79 80 typedef ::cppu::WeakComponentImplHelper1 <XView> SimpleViewInterfaceBase; 81 82 class SimpleView 83 : private ::cppu::BaseMutex, 84 public SimpleViewInterfaceBase 85 { 86 public: 87 SimpleView (const Reference<XResourceId>& rxViewId) 88 : SimpleViewInterfaceBase(m_aMutex),mxResourceId(rxViewId) {}; 89 virtual ~SimpleView (void) {}; 90 91 // XView 92 93 virtual Reference<XResourceId> SAL_CALL getResourceId (void) throw (RuntimeException) 94 { return mxResourceId; }; 95 96 private: 97 Reference<XResourceId> mxResourceId; 98 }; 99 100 101 102 /** By default the PresenterSlidePreview shows the preview of the current 103 slide. This adapter class makes it display the preview of the next 104 slide. 105 */ 106 class NextSlidePreview : public PresenterSlidePreview 107 { 108 public: 109 NextSlidePreview ( 110 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 111 const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, 112 const css::uno::Reference<css::drawing::framework::XPane>& rxAnchorPane, 113 const ::rtl::Reference<PresenterController>& rpPresenterController) 114 : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController) 115 { 116 } 117 virtual ~NextSlidePreview (void) {} 118 virtual void SAL_CALL setCurrentPage ( 119 const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) 120 throw (css::uno::RuntimeException) 121 { 122 Reference<presentation::XSlideShowController> xSlideShowController ( 123 mpPresenterController->GetSlideShowController()); 124 Reference<drawing::XDrawPage> xSlide; 125 if (xSlideShowController.is()) 126 { 127 const sal_Int32 nCount (xSlideShowController->getSlideCount()); 128 sal_Int32 nNextSlideIndex (-1); 129 if (xSlideShowController->getCurrentSlide() == rxSlide) 130 { 131 nNextSlideIndex = xSlideShowController->getNextSlideIndex(); 132 } 133 else 134 { 135 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) 136 { 137 if (rxSlide == Reference<drawing::XDrawPage>( 138 xSlideShowController->getSlideByIndex(nIndex), UNO_QUERY)) 139 { 140 nNextSlideIndex = nIndex + 1; 141 } 142 } 143 } 144 if (nNextSlideIndex >= 0) 145 { 146 if (nNextSlideIndex < nCount) 147 { 148 xSlide = Reference<drawing::XDrawPage>( 149 xSlideShowController->getSlideByIndex(nNextSlideIndex), 150 UNO_QUERY); 151 } 152 } 153 } 154 PresenterSlidePreview::setCurrentPage(xSlide); 155 } 156 }; 157 158 } // end of anonymous namespace 159 160 161 162 163 //===== PresenterViewFactory ============================================== 164 165 PresenterViewFactory::PresenterViewFactory ( 166 const Reference<uno::XComponentContext>& rxContext, 167 const Reference<frame::XController>& rxController, 168 const ::rtl::Reference<PresenterController>& rpPresenterController) 169 : PresenterViewFactoryInterfaceBase(m_aMutex), 170 mxComponentContext(rxContext), 171 mxConfigurationController(), 172 mxControllerWeak(rxController), 173 mpPresenterController(rpPresenterController), 174 mpResourceCache() 175 { 176 } 177 178 179 180 181 Reference<drawing::framework::XResourceFactory> PresenterViewFactory::Create ( 182 const Reference<uno::XComponentContext>& rxContext, 183 const Reference<frame::XController>& rxController, 184 const ::rtl::Reference<PresenterController>& rpPresenterController) 185 { 186 rtl::Reference<PresenterViewFactory> pFactory ( 187 new PresenterViewFactory(rxContext,rxController,rpPresenterController)); 188 pFactory->Register(rxController); 189 return Reference<drawing::framework::XResourceFactory>( 190 static_cast<XWeak*>(pFactory.get()), UNO_QUERY); 191 } 192 193 194 195 196 void PresenterViewFactory::Register (const Reference<frame::XController>& rxController) 197 { 198 try 199 { 200 // Get the configuration controller. 201 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW); 202 mxConfigurationController = xCM->getConfigurationController(); 203 if ( ! mxConfigurationController.is()) 204 { 205 throw RuntimeException(); 206 } 207 else 208 { 209 mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this); 210 mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this); 211 mxConfigurationController->addResourceFactory(msNotesViewURL, this); 212 mxConfigurationController->addResourceFactory(msToolBarViewURL, this); 213 mxConfigurationController->addResourceFactory(msSlideSorterURL, this); 214 mxConfigurationController->addResourceFactory(msHelpViewURL, this); 215 } 216 } 217 catch (RuntimeException&) 218 { 219 OSL_ASSERT(false); 220 if (mxConfigurationController.is()) 221 mxConfigurationController->removeResourceFactoryForReference(this); 222 mxConfigurationController = NULL; 223 224 throw; 225 } 226 } 227 228 229 230 231 PresenterViewFactory::~PresenterViewFactory (void) 232 { 233 } 234 235 236 237 238 void SAL_CALL PresenterViewFactory::disposing (void) 239 throw (RuntimeException) 240 { 241 if (mxConfigurationController.is()) 242 mxConfigurationController->removeResourceFactoryForReference(this); 243 mxConfigurationController = NULL; 244 245 if (mpResourceCache.get() != NULL) 246 { 247 // Dispose all views in the cache. 248 ResourceContainer::const_iterator iView (mpResourceCache->begin()); 249 ResourceContainer::const_iterator iEnd (mpResourceCache->end()); 250 for ( ; iView!=iEnd; ++iView) 251 { 252 try 253 { 254 Reference<lang::XComponent> xComponent (iView->second.first, UNO_QUERY); 255 if (xComponent.is()) 256 xComponent->dispose(); 257 } 258 catch (lang::DisposedException&) 259 { 260 } 261 } 262 mpResourceCache.reset(); 263 } 264 } 265 266 267 268 269 //----- XViewFactory ---------------------------------------------------------- 270 271 Reference<XResource> SAL_CALL PresenterViewFactory::createResource ( 272 const Reference<XResourceId>& rxViewId) 273 throw (RuntimeException) 274 { 275 ThrowIfDisposed(); 276 277 Reference<XResource> xView; 278 279 if (rxViewId.is()) 280 { 281 Reference<XPane> xAnchorPane ( 282 mxConfigurationController->getResource(rxViewId->getAnchor()), 283 UNO_QUERY_THROW); 284 xView = GetViewFromCache(rxViewId, xAnchorPane); 285 if (xView == NULL) 286 xView = CreateView(rxViewId, xAnchorPane); 287 288 // Activate the view. 289 PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( 290 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor())); 291 if (pDescriptor.get() != NULL) 292 pDescriptor->SetActivationState(true); 293 } 294 295 return xView; 296 } 297 298 299 300 301 void SAL_CALL PresenterViewFactory::releaseResource (const Reference<XResource>& rxView) 302 throw (RuntimeException) 303 { 304 ThrowIfDisposed(); 305 306 if ( ! rxView.is()) 307 return; 308 309 // Deactivate the view. 310 PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( 311 mpPresenterController->GetPaneContainer()->FindPaneId( 312 rxView->getResourceId()->getAnchor())); 313 if (pDescriptor.get() != NULL) 314 pDescriptor->SetActivationState(false); 315 316 // Dispose only views that we can not put into the cache. 317 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(rxView.get()); 318 if (pView == NULL || mpResourceCache.get()==NULL) 319 { 320 try 321 { 322 if (pView != NULL) 323 pView->ReleaseView(); 324 Reference<lang::XComponent> xComponent (rxView, UNO_QUERY); 325 if (xComponent.is()) 326 xComponent->dispose(); 327 } 328 catch (lang::DisposedException&) 329 { 330 // Do not let disposed exceptions get out. It might be interpreted 331 // as coming from the factory, which would then be removed from the 332 // drawing framework. 333 } 334 } 335 else 336 { 337 // Put cachable views in the cache. 338 Reference<XResourceId> xViewId (rxView->getResourceId()); 339 if (xViewId.is()) 340 { 341 Reference<XPane> xAnchorPane ( 342 mxConfigurationController->getResource(xViewId->getAnchor()), 343 UNO_QUERY_THROW); 344 (*mpResourceCache)[xViewId->getResourceURL()] 345 = ViewResourceDescriptor(Reference<XView>(rxView, UNO_QUERY), xAnchorPane); 346 pView->DeactivatePresenterView(); 347 } 348 } 349 } 350 351 352 353 354 //----------------------------------------------------------------------------- 355 356 Reference<XResource> PresenterViewFactory::GetViewFromCache( 357 const Reference<XResourceId>& rxViewId, 358 const Reference<XPane>& rxAnchorPane) const 359 { 360 if (mpResourceCache.get() == NULL) 361 return NULL; 362 363 try 364 { 365 const OUString sResourceURL (rxViewId->getResourceURL()); 366 367 // Can we use a view from the cache? 368 ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL)); 369 if (iView != mpResourceCache->end()) 370 { 371 // The view is in the container but it can only be used if 372 // the anchor pane is the same now as it was at creation of 373 // the view. 374 if (iView->second.second == rxAnchorPane) 375 { 376 CachablePresenterView* pView 377 = dynamic_cast<CachablePresenterView*>(iView->second.first.get()); 378 if (pView != NULL) 379 pView->ActivatePresenterView(); 380 return Reference<XResource>(iView->second.first, UNO_QUERY); 381 } 382 383 // Right view, wrong pane. Create a new view. 384 } 385 } 386 catch (RuntimeException&) 387 { 388 } 389 return NULL; 390 } 391 392 393 394 395 Reference<XResource> PresenterViewFactory::CreateView( 396 const Reference<XResourceId>& rxViewId, 397 const Reference<XPane>& rxAnchorPane) 398 { 399 Reference<XView> xView; 400 401 try 402 { 403 const OUString sResourceURL (rxViewId->getResourceURL()); 404 405 if (sResourceURL.equals(msCurrentSlidePreviewViewURL)) 406 { 407 xView = CreateSlideShowView(rxViewId); 408 } 409 else if (sResourceURL.equals(msNotesViewURL)) 410 { 411 xView = CreateNotesView(rxViewId, rxAnchorPane); 412 } 413 else if (sResourceURL.equals(msNextSlidePreviewViewURL)) 414 { 415 xView = CreateSlidePreviewView(rxViewId, rxAnchorPane); 416 } 417 else if (sResourceURL.equals(msToolBarViewURL)) 418 { 419 xView = CreateToolBarView(rxViewId); 420 } 421 else if (sResourceURL.equals(msSlideSorterURL)) 422 { 423 xView = CreateSlideSorterView(rxViewId); 424 } 425 else if (sResourceURL.equals(msHelpViewURL)) 426 { 427 xView = CreateHelpView(rxViewId); 428 } 429 430 // Activate it. 431 CachablePresenterView* pView = dynamic_cast<CachablePresenterView*>(xView.get()); 432 if (pView != NULL) 433 pView->ActivatePresenterView(); 434 } 435 catch (RuntimeException&) 436 { 437 xView = NULL; 438 } 439 440 return Reference<XResource>(xView, UNO_QUERY); 441 } 442 443 444 445 446 Reference<XView> PresenterViewFactory::CreateSlideShowView( 447 const Reference<XResourceId>& rxViewId) const 448 { 449 Reference<XView> xView; 450 451 if ( ! mxConfigurationController.is()) 452 return xView; 453 if ( ! mxComponentContext.is()) 454 return xView; 455 456 try 457 { 458 rtl::Reference<PresenterSlideShowView> pShowView ( 459 new PresenterSlideShowView( 460 mxComponentContext, 461 rxViewId, 462 Reference<frame::XController>(mxControllerWeak), 463 mpPresenterController)); 464 pShowView->LateInit(); 465 xView = Reference<XView>(pShowView.get()); 466 } 467 catch (RuntimeException&) 468 { 469 xView = NULL; 470 } 471 472 return xView; 473 } 474 475 476 477 478 Reference<XView> PresenterViewFactory::CreateSlidePreviewView( 479 const Reference<XResourceId>& rxViewId, 480 const Reference<XPane>& rxAnchorPane) const 481 { 482 Reference<XView> xView; 483 484 if ( ! mxConfigurationController.is()) 485 return xView; 486 if ( ! mxComponentContext.is()) 487 return xView; 488 489 try 490 { 491 xView = Reference<XView>( 492 static_cast<XWeak*>(new NextSlidePreview( 493 mxComponentContext, 494 rxViewId, 495 rxAnchorPane, 496 mpPresenterController)), 497 UNO_QUERY_THROW); 498 } 499 catch (RuntimeException&) 500 { 501 xView = NULL; 502 } 503 504 return xView; 505 } 506 507 508 509 510 Reference<XView> PresenterViewFactory::CreateToolBarView( 511 const Reference<XResourceId>& rxViewId) const 512 { 513 return new PresenterToolBarView( 514 mxComponentContext, 515 rxViewId, 516 Reference<frame::XController>(mxControllerWeak), 517 mpPresenterController); 518 } 519 520 521 522 523 Reference<XView> PresenterViewFactory::CreateNotesView( 524 const Reference<XResourceId>& rxViewId, 525 const Reference<XPane>& rxAnchorPane) const 526 { 527 (void)rxAnchorPane; 528 Reference<XView> xView; 529 530 if ( ! mxConfigurationController.is()) 531 return xView; 532 if ( ! mxComponentContext.is()) 533 return xView; 534 535 try 536 { 537 xView = Reference<XView>(static_cast<XWeak*>( 538 new PresenterNotesView( 539 mxComponentContext, 540 rxViewId, 541 Reference<frame::XController>(mxControllerWeak), 542 mpPresenterController)), 543 UNO_QUERY_THROW); 544 } 545 catch (RuntimeException&) 546 { 547 xView = NULL; 548 } 549 550 return xView; 551 } 552 553 554 555 556 Reference<XView> PresenterViewFactory::CreateSlideSorterView( 557 const Reference<XResourceId>& rxViewId) const 558 { 559 Reference<XView> xView; 560 561 if ( ! mxConfigurationController.is()) 562 return xView; 563 if ( ! mxComponentContext.is()) 564 return xView; 565 566 try 567 { 568 rtl::Reference<PresenterSlideSorter> pView ( 569 new PresenterSlideSorter( 570 mxComponentContext, 571 rxViewId, 572 Reference<frame::XController>(mxControllerWeak), 573 mpPresenterController)); 574 PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( 575 mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor())); 576 if (pDescriptor.get() != NULL) 577 pDescriptor->maActivator = ::boost::bind( 578 &PresenterSlideSorter::SetActiveState, pView.get(), _1); 579 xView = pView.get(); 580 } 581 catch (RuntimeException&) 582 { 583 xView = NULL; 584 } 585 586 return xView; 587 } 588 589 590 591 592 Reference<XView> PresenterViewFactory::CreateHelpView( 593 const Reference<XResourceId>& rxViewId) const 594 { 595 return Reference<XView>(new PresenterHelpView( 596 mxComponentContext, 597 rxViewId, 598 Reference<frame::XController>(mxControllerWeak), 599 mpPresenterController)); 600 } 601 602 603 604 605 606 void PresenterViewFactory::ThrowIfDisposed (void) const 607 throw (::com::sun::star::lang::DisposedException) 608 { 609 if (rBHelper.bDisposed || rBHelper.bInDispose) 610 { 611 throw lang::DisposedException ( 612 OUString(RTL_CONSTASCII_USTRINGPARAM( 613 "PresenterViewFactory object has already been disposed")), 614 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); 615 } 616 } 617 618 619 620 621 //===== CachablePresenterView ================================================= 622 623 CachablePresenterView::CachablePresenterView (void) 624 : mbIsPresenterViewActive(true) 625 { 626 } 627 628 629 630 631 void CachablePresenterView::ActivatePresenterView (void) 632 { 633 mbIsPresenterViewActive = true; 634 } 635 636 637 638 639 void CachablePresenterView::DeactivatePresenterView (void) 640 { 641 mbIsPresenterViewActive = false; 642 } 643 644 645 646 647 void CachablePresenterView::ReleaseView (void) 648 { 649 } 650 651 652 653 } } 654