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