/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include "PresenterPaneFactory.hxx" #include "PresenterController.hxx" #include "PresenterPane.hxx" #include "PresenterPaneBorderPainter.hxx" #include "PresenterPaneContainer.hxx" #include "PresenterSpritePane.hxx" #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::drawing::framework; namespace sdext::presenter { //===== PresenterPaneFactory ================================================== Reference PresenterPaneFactory::Create ( const Reference& rxContext, const rtl::Reference<::sd::DrawController>& rxController, const ::rtl::Reference& rpPresenterController) { rtl::Reference pFactory ( new PresenterPaneFactory(rxContext,rpPresenterController)); pFactory->Register(rxController); return Reference(pFactory); } PresenterPaneFactory::PresenterPaneFactory ( const Reference& rxContext, ::rtl::Reference xPresenterController) : PresenterPaneFactoryInterfaceBase(m_aMutex), mxComponentContextWeak(rxContext), mpPresenterController(std::move(xPresenterController)) { } void PresenterPaneFactory::Register (const rtl::Reference<::sd::DrawController>& rxController) { rtl::Reference<::sd::framework::ConfigurationController> xCC; try { // Get the configuration controller. xCC = rxController->getConfigurationControllerImpl(); mxConfigurationControllerWeak = xCC.get(); if ( ! xCC.is()) { throw RuntimeException(); } xCC->addResourceFactory( u"private:resource/pane/Presenter/*"_ustr, this); } catch (RuntimeException&) { OSL_ASSERT(false); if (xCC.is()) xCC->removeResourceFactoryForReference(this); mxConfigurationControllerWeak.clear(); throw; } } PresenterPaneFactory::~PresenterPaneFactory() { } void SAL_CALL PresenterPaneFactory::disposing() { rtl::Reference<::sd::framework::ConfigurationController> xCC (mxConfigurationControllerWeak); if (xCC.is()) xCC->removeResourceFactoryForReference(this); mxConfigurationControllerWeak.clear(); // Dispose the panes in the cache. if (mpResourceCache != nullptr) { for (const auto& rxPane : *mpResourceCache) { Reference xPaneComponent (rxPane.second, UNO_QUERY); if (xPaneComponent.is()) xPaneComponent->dispose(); } mpResourceCache.reset(); } } //----- XPaneFactory ---------------------------------------------------------- Reference SAL_CALL PresenterPaneFactory::createResource ( const Reference& rxPaneId) { ThrowIfDisposed(); if ( ! rxPaneId.is()) return nullptr; const OUString sPaneURL (rxPaneId->getResourceURL()); if (sPaneURL.isEmpty()) return nullptr; if (mpResourceCache != nullptr) { // Has the requested resource already been created? ResourceContainer::const_iterator iResource (mpResourceCache->find(sPaneURL)); if (iResource != mpResourceCache->end()) { // Yes. Mark it as active. rtl::Reference pPaneContainer( mpPresenterController->GetPaneContainer()); PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( pPaneContainer->FindPaneURL(sPaneURL)); if (pDescriptor) { pDescriptor->SetActivationState(true); if (pDescriptor->mxBorderWindow.is()) pDescriptor->mxBorderWindow->setVisible(true); pPaneContainer->StorePane(pDescriptor->mxPane); } return iResource->second; } } // No. Create a new one. Reference xResource = CreatePane(rxPaneId); return xResource; } void SAL_CALL PresenterPaneFactory::releaseResource (const Reference& rxResource) { ThrowIfDisposed(); if ( ! rxResource.is()) throw lang::IllegalArgumentException(); // Mark the pane as inactive. rtl::Reference pPaneContainer( mpPresenterController->GetPaneContainer()); const OUString sPaneURL (rxResource->getResourceId()->getResourceURL()); PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( pPaneContainer->FindPaneURL(sPaneURL)); if (!pDescriptor) return; pDescriptor->SetActivationState(false); if (pDescriptor->mxBorderWindow.is()) pDescriptor->mxBorderWindow->setVisible(false); if (mpResourceCache != nullptr) { // Store the pane in the cache. (*mpResourceCache)[sPaneURL] = rxResource; } else { // Dispose the pane. Reference xPaneComponent (rxResource, UNO_QUERY); if (xPaneComponent.is()) xPaneComponent->dispose(); } } Reference PresenterPaneFactory::CreatePane ( const Reference& rxPaneId) { if ( ! rxPaneId.is()) return nullptr; rtl::Reference<::sd::framework::ConfigurationController> xCC (mxConfigurationControllerWeak); if ( ! xCC.is()) return nullptr; Reference xContext (mxComponentContextWeak); if ( ! xContext.is()) return nullptr; Reference xParentPane (xCC->getResource(rxPaneId->getAnchor()), UNO_QUERY); if ( ! xParentPane.is()) return nullptr; try { return CreatePane( rxPaneId, xParentPane, rxPaneId->getFullResourceURL().Arguments == "Sprite=1"); } catch (Exception&) { OSL_ASSERT(false); } return nullptr; } Reference PresenterPaneFactory::CreatePane ( const Reference& rxPaneId, const Reference& rxParentPane, const bool bIsSpritePane) { Reference xContext (mxComponentContextWeak); Reference xFactory ( xContext->getServiceManager(), UNO_SET_THROW); // Create a border window and canvas and store it in the pane // container. // Create the pane. ::rtl::Reference xPane; if (bIsSpritePane) { xPane.set( new PresenterSpritePane(xContext, mpPresenterController)); } else { xPane.set( new PresenterPane(xContext, mpPresenterController)); } // Supply arguments. Sequence aArguments{ Any(rxPaneId), Any(rxParentPane->getWindow()), Any(rxParentPane->getCanvas()), Any(OUString()), Any(Reference( mpPresenterController->GetPaneBorderPainter())), Any(!bIsSpritePane) }; xPane->initialize(aArguments); // Store pane and canvases and windows in container. ::rtl::Reference pContainer ( mpPresenterController->GetPaneContainer()); PresenterPaneContainer::SharedPaneDescriptor pDescriptor( pContainer->StoreBorderWindow(rxPaneId, xPane->GetBorderWindow())); pContainer->StorePane(xPane); if (pDescriptor) { pDescriptor->mbIsSprite = bIsSpritePane; // Get the window of the frame and make that visible. Reference xWindow (pDescriptor->mxBorderWindow, UNO_SET_THROW); xWindow->setVisible(true); } return Reference(static_cast(xPane.get()), UNO_QUERY_THROW); } void PresenterPaneFactory::ThrowIfDisposed() const { if (rBHelper.bDisposed || rBHelper.bInDispose) { throw lang::DisposedException ( u"PresenterPaneFactory object has already been disposed"_ustr, const_cast(static_cast(this))); } } } // end of namespace sdext::presenter /* vim:set shiftwidth=4 softtabstop=4 expandtab: */