/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: PresenterViewFactory.cxx,v $ * * $Revision: 1.6 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sdext.hxx" #include "PresenterViewFactory.hxx" #include "PresenterPaneContainer.hxx" #include "PresenterHelper.hxx" #include "PresenterHelpView.hxx" #include "PresenterNotesView.hxx" #include "PresenterSlideShowView.hxx" #include "PresenterSlidePreview.hxx" #include "PresenterSlideSorter.hxx" #include "PresenterToolBar.hxx" #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; using ::rtl::OUString; #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) namespace sdext { namespace presenter { const ::rtl::OUString PresenterViewFactory::msCurrentSlidePreviewViewURL( A2S("private:resource/view/Presenter/CurrentSlidePreview")); const ::rtl::OUString PresenterViewFactory::msNextSlidePreviewViewURL( A2S("private:resource/view/Presenter/NextSlidePreview")); const ::rtl::OUString PresenterViewFactory::msNotesViewURL( A2S("private:resource/view/Presenter/Notes")); const ::rtl::OUString PresenterViewFactory::msToolBarViewURL( A2S("private:resource/view/Presenter/ToolBar")); const ::rtl::OUString PresenterViewFactory::msSlideSorterURL( A2S("private:resource/view/Presenter/SlideSorter")); const ::rtl::OUString PresenterViewFactory::msHelpViewURL( A2S("private:resource/view/Presenter/Help")); //===== SimpleView ============================================================ namespace { typedef ::cppu::WeakComponentImplHelper1 SimpleViewInterfaceBase; class SimpleView : private ::cppu::BaseMutex, public SimpleViewInterfaceBase { public: SimpleView (const Reference& rxViewId) : SimpleViewInterfaceBase(m_aMutex),mxResourceId(rxViewId) {}; virtual ~SimpleView (void) {}; // XView virtual Reference SAL_CALL getResourceId (void) throw (RuntimeException) { return mxResourceId; }; private: Reference mxResourceId; }; /** By default the PresenterSlidePreview shows the preview of the current slide. This adapter class makes it display the preview of the next slide. */ class NextSlidePreview : public PresenterSlidePreview { public: NextSlidePreview ( const css::uno::Reference& rxContext, const css::uno::Reference& rxViewId, const css::uno::Reference& rxAnchorPane, const ::rtl::Reference& rpPresenterController) : PresenterSlidePreview(rxContext, rxViewId, rxAnchorPane, rpPresenterController) { } virtual ~NextSlidePreview (void) {} virtual void SAL_CALL setCurrentPage ( const css::uno::Reference& rxSlide) throw (css::uno::RuntimeException) { Reference xSlideShowController ( mpPresenterController->GetSlideShowController()); Reference xSlide; if (xSlideShowController.is()) { const sal_Int32 nCount (xSlideShowController->getSlideCount()); sal_Int32 nNextSlideIndex (-1); if (xSlideShowController->getCurrentSlide() == rxSlide) { nNextSlideIndex = xSlideShowController->getNextSlideIndex(); } else { for (sal_Int32 nIndex=0; nIndex( xSlideShowController->getSlideByIndex(nIndex), UNO_QUERY)) { nNextSlideIndex = nIndex + 1; } } } if (nNextSlideIndex >= 0) { if (nNextSlideIndex < nCount) { xSlide = Reference( xSlideShowController->getSlideByIndex(nNextSlideIndex), UNO_QUERY); } } } PresenterSlidePreview::setCurrentPage(xSlide); } }; } // end of anonymous namespace //===== PresenterViewFactory ============================================== PresenterViewFactory::PresenterViewFactory ( const Reference& rxContext, const Reference& rxController, const ::rtl::Reference& rpPresenterController) : PresenterViewFactoryInterfaceBase(m_aMutex), mxComponentContext(rxContext), mxConfigurationController(), mxControllerWeak(rxController), mpPresenterController(rpPresenterController), mpResourceCache() { } Reference PresenterViewFactory::Create ( const Reference& rxContext, const Reference& rxController, const ::rtl::Reference& rpPresenterController) { rtl::Reference pFactory ( new PresenterViewFactory(rxContext,rxController,rpPresenterController)); pFactory->Register(rxController); return Reference( static_cast(pFactory.get()), UNO_QUERY); } void PresenterViewFactory::Register (const Reference& rxController) { try { // Get the configuration controller. Reference xCM (rxController, UNO_QUERY_THROW); mxConfigurationController = xCM->getConfigurationController(); if ( ! mxConfigurationController.is()) { throw RuntimeException(); } else { mxConfigurationController->addResourceFactory(msCurrentSlidePreviewViewURL, this); mxConfigurationController->addResourceFactory(msNextSlidePreviewViewURL, this); mxConfigurationController->addResourceFactory(msNotesViewURL, this); mxConfigurationController->addResourceFactory(msToolBarViewURL, this); mxConfigurationController->addResourceFactory(msSlideSorterURL, this); mxConfigurationController->addResourceFactory(msHelpViewURL, this); } } catch (RuntimeException&) { OSL_ASSERT(false); if (mxConfigurationController.is()) mxConfigurationController->removeResourceFactoryForReference(this); mxConfigurationController = NULL; throw; } } PresenterViewFactory::~PresenterViewFactory (void) { } void SAL_CALL PresenterViewFactory::disposing (void) throw (RuntimeException) { if (mxConfigurationController.is()) mxConfigurationController->removeResourceFactoryForReference(this); mxConfigurationController = NULL; if (mpResourceCache.get() != NULL) { // Dispose all views in the cache. ResourceContainer::const_iterator iView (mpResourceCache->begin()); ResourceContainer::const_iterator iEnd (mpResourceCache->end()); for ( ; iView!=iEnd; ++iView) { try { Reference xComponent (iView->second.first, UNO_QUERY); if (xComponent.is()) xComponent->dispose(); } catch (lang::DisposedException&) { } } mpResourceCache.reset(); } } //----- XViewFactory ---------------------------------------------------------- Reference SAL_CALL PresenterViewFactory::createResource ( const Reference& rxViewId) throw (RuntimeException) { ThrowIfDisposed(); Reference xView; if (rxViewId.is()) { Reference xAnchorPane ( mxConfigurationController->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW); xView = GetViewFromCache(rxViewId, xAnchorPane); if (xView == NULL) xView = CreateView(rxViewId, xAnchorPane); // Activate the view. PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor())); if (pDescriptor.get() != NULL) pDescriptor->SetActivationState(true); } return xView; } void SAL_CALL PresenterViewFactory::releaseResource (const Reference& rxView) throw (RuntimeException) { ThrowIfDisposed(); if ( ! rxView.is()) return; // Deactivate the view. PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( mpPresenterController->GetPaneContainer()->FindPaneId( rxView->getResourceId()->getAnchor())); if (pDescriptor.get() != NULL) pDescriptor->SetActivationState(false); // Dispose only views that we can not put into the cache. CachablePresenterView* pView = dynamic_cast(rxView.get()); if (pView == NULL || mpResourceCache.get()==NULL) { try { if (pView != NULL) pView->ReleaseView(); Reference xComponent (rxView, UNO_QUERY); if (xComponent.is()) xComponent->dispose(); } catch (lang::DisposedException&) { // Do not let disposed exceptions get out. It might be interpreted // as coming from the factory, which would then be removed from the // drawing framework. } } else { // Put cachable views in the cache. Reference xViewId (rxView->getResourceId()); if (xViewId.is()) { Reference xAnchorPane ( mxConfigurationController->getResource(xViewId->getAnchor()), UNO_QUERY_THROW); (*mpResourceCache)[xViewId->getResourceURL()] = ViewResourceDescriptor(Reference(rxView, UNO_QUERY), xAnchorPane); pView->DeactivatePresenterView(); } } } //----------------------------------------------------------------------------- Reference PresenterViewFactory::GetViewFromCache( const Reference& rxViewId, const Reference& rxAnchorPane) const { if (mpResourceCache.get() == NULL) return NULL; try { const OUString sResourceURL (rxViewId->getResourceURL()); // Can we use a view from the cache? ResourceContainer::const_iterator iView (mpResourceCache->find(sResourceURL)); if (iView != mpResourceCache->end()) { // The view is in the container but it can only be used if // the anchor pane is the same now as it was at creation of // the view. if (iView->second.second == rxAnchorPane) { CachablePresenterView* pView = dynamic_cast(iView->second.first.get()); if (pView != NULL) pView->ActivatePresenterView(); return Reference(iView->second.first, UNO_QUERY); } // Right view, wrong pane. Create a new view. } } catch (RuntimeException&) { } return NULL; } Reference PresenterViewFactory::CreateView( const Reference& rxViewId, const Reference& rxAnchorPane) { Reference xView; try { const OUString sResourceURL (rxViewId->getResourceURL()); if (sResourceURL.equals(msCurrentSlidePreviewViewURL)) { xView = CreateSlideShowView(rxViewId); } else if (sResourceURL.equals(msNotesViewURL)) { xView = CreateNotesView(rxViewId, rxAnchorPane); } else if (sResourceURL.equals(msNextSlidePreviewViewURL)) { xView = CreateSlidePreviewView(rxViewId, rxAnchorPane); } else if (sResourceURL.equals(msToolBarViewURL)) { xView = CreateToolBarView(rxViewId); } else if (sResourceURL.equals(msSlideSorterURL)) { xView = CreateSlideSorterView(rxViewId); } else if (sResourceURL.equals(msHelpViewURL)) { xView = CreateHelpView(rxViewId); } // Activate it. CachablePresenterView* pView = dynamic_cast(xView.get()); if (pView != NULL) pView->ActivatePresenterView(); } catch (RuntimeException&) { xView = NULL; } return Reference(xView, UNO_QUERY); } Reference PresenterViewFactory::CreateSlideShowView( const Reference& rxViewId) const { Reference xView; if ( ! mxConfigurationController.is()) return xView; if ( ! mxComponentContext.is()) return xView; try { rtl::Reference pShowView ( new PresenterSlideShowView( mxComponentContext, rxViewId, Reference(mxControllerWeak), mpPresenterController)); pShowView->LateInit(); xView = Reference(pShowView.get()); } catch (RuntimeException&) { xView = NULL; } return xView; } Reference PresenterViewFactory::CreateSlidePreviewView( const Reference& rxViewId, const Reference& rxAnchorPane) const { Reference xView; if ( ! mxConfigurationController.is()) return xView; if ( ! mxComponentContext.is()) return xView; try { xView = Reference( static_cast(new NextSlidePreview( mxComponentContext, rxViewId, rxAnchorPane, mpPresenterController)), UNO_QUERY_THROW); } catch (RuntimeException&) { xView = NULL; } return xView; } Reference PresenterViewFactory::CreateToolBarView( const Reference& rxViewId) const { return new PresenterToolBarView( mxComponentContext, rxViewId, Reference(mxControllerWeak), mpPresenterController); } Reference PresenterViewFactory::CreateNotesView( const Reference& rxViewId, const Reference& rxAnchorPane) const { (void)rxAnchorPane; Reference xView; if ( ! mxConfigurationController.is()) return xView; if ( ! mxComponentContext.is()) return xView; try { xView = Reference(static_cast( new PresenterNotesView( mxComponentContext, rxViewId, Reference(mxControllerWeak), mpPresenterController)), UNO_QUERY_THROW); } catch (RuntimeException&) { xView = NULL; } return xView; } Reference PresenterViewFactory::CreateSlideSorterView( const Reference& rxViewId) const { Reference xView; if ( ! mxConfigurationController.is()) return xView; if ( ! mxComponentContext.is()) return xView; try { rtl::Reference pView ( new PresenterSlideSorter( mxComponentContext, rxViewId, Reference(mxControllerWeak), mpPresenterController)); PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( mpPresenterController->GetPaneContainer()->FindPaneId(rxViewId->getAnchor())); if (pDescriptor.get() != NULL) pDescriptor->maActivator = ::boost::bind( &PresenterSlideSorter::SetActiveState, pView.get(), _1); xView = pView.get(); } catch (RuntimeException&) { xView = NULL; } return xView; } Reference PresenterViewFactory::CreateHelpView( const Reference& rxViewId) const { return Reference(new PresenterHelpView( mxComponentContext, rxViewId, Reference(mxControllerWeak), mpPresenterController)); } void PresenterViewFactory::ThrowIfDisposed (void) const throw (::com::sun::star::lang::DisposedException) { if (rBHelper.bDisposed || rBHelper.bInDispose) { throw lang::DisposedException ( OUString(RTL_CONSTASCII_USTRINGPARAM( "PresenterViewFactory object has already been disposed")), const_cast(static_cast(this))); } } //===== CachablePresenterView ================================================= CachablePresenterView::CachablePresenterView (void) : mbIsPresenterViewActive(true) { } void CachablePresenterView::ActivatePresenterView (void) { mbIsPresenterViewActive = true; } void CachablePresenterView::DeactivatePresenterView (void) { mbIsPresenterViewActive = false; } void CachablePresenterView::ReleaseView (void) { } } }