LCOV - code coverage report
Current view: top level - sd/source/ui/framework/factories - BasicPaneFactory.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 122 162 75.3 %
Date: 2014-04-11 Functions: 20 25 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "BasicPaneFactory.hxx"
      22             : 
      23             : #include "ChildWindowPane.hxx"
      24             : #include "FrameWindowPane.hxx"
      25             : #include "FullScreenPane.hxx"
      26             : 
      27             : #include "framework/FrameworkHelper.hxx"
      28             : #include "ViewShellBase.hxx"
      29             : #include "PaneChildWindows.hxx"
      30             : #include "DrawController.hxx"
      31             : #include "DrawDocShell.hxx"
      32             : #include <com/sun/star/drawing/framework/XControllerManager.hpp>
      33             : #include <boost/bind.hpp>
      34             : 
      35             : 
      36             : using namespace ::com::sun::star;
      37             : using namespace ::com::sun::star::uno;
      38             : using namespace ::com::sun::star::lang;
      39             : using namespace ::com::sun::star::drawing::framework;
      40             : 
      41             : using ::sd::framework::FrameworkHelper;
      42             : 
      43             : namespace {
      44             :     enum PaneId {
      45             :         CenterPaneId,
      46             :         FullScreenPaneId,
      47             :         LeftImpressPaneId,
      48             :         LeftDrawPaneId
      49             :     };
      50             : 
      51             :     static const sal_Int32 gnConfigurationUpdateStartEvent(0);
      52             :     static const sal_Int32 gnConfigurationUpdateEndEvent(1);
      53             : }
      54             : 
      55             : namespace sd { namespace framework {
      56             : 
      57             : 
      58             : /** Store URL, XPane reference and (local) PaneId for every pane factory
      59             :     that is registered at the PaneController.
      60             : */
      61         876 : class BasicPaneFactory::PaneDescriptor
      62             : {
      63             : public:
      64             :     OUString msPaneURL;
      65             :     Reference<XResource> mxPane;
      66             :     PaneId mePaneId;
      67             :     /** The mbReleased flag is set when the pane has been released.  Some
      68             :         panes are just hidden and destroyed.  When the pane is reused this
      69             :         flag is reset.
      70             :     */
      71             :     bool mbIsReleased;
      72             :     bool mbIsChildWindow;
      73             : 
      74         584 :     bool CompareURL (const OUString& rsPaneURL) { return msPaneURL.equals(rsPaneURL); }
      75         584 :     bool ComparePane (const Reference<XResource>& rxPane) { return mxPane==rxPane; }
      76             : };
      77             : 
      78             : 
      79           0 : class BasicPaneFactory::PaneContainer
      80             :     : public ::std::vector<PaneDescriptor>
      81             : {
      82             : public:
      83          73 :     PaneContainer (void) {}
      84             : };
      85             : 
      86             : 
      87             : 
      88          73 : Reference<XInterface> SAL_CALL BasicPaneFactory_createInstance (
      89             :     const Reference<XComponentContext>& rxContext)
      90             : {
      91          73 :     return Reference<XInterface>(static_cast<XWeak*>(new BasicPaneFactory(rxContext)));
      92             : }
      93             : 
      94             : 
      95             : 
      96             : 
      97          26 : OUString BasicPaneFactory_getImplementationName (void) throw(RuntimeException)
      98             : {
      99          26 :     return OUString("com.sun.star.comp.Draw.framework.BasicPaneFactory");
     100             : }
     101             : 
     102             : 
     103             : 
     104             : 
     105          11 : Sequence<OUString> SAL_CALL BasicPaneFactory_getSupportedServiceNames (void)
     106             :     throw (RuntimeException)
     107             : {
     108          11 :     static const OUString sServiceName("com.sun.star.drawing.framework.BasicPaneFactory");
     109          11 :     return Sequence<OUString>(&sServiceName, 1);
     110             : }
     111             : 
     112             : 
     113             : 
     114             : 
     115             : //===== PaneFactory ===========================================================
     116             : 
     117          73 : BasicPaneFactory::BasicPaneFactory (
     118             :     const Reference<XComponentContext>& rxContext)
     119             :     : BasicPaneFactoryInterfaceBase(m_aMutex),
     120             :       mxComponentContext(rxContext),
     121             :       mxConfigurationControllerWeak(),
     122             :       mpViewShellBase(NULL),
     123          73 :       mpPaneContainer(new PaneContainer)
     124             : {
     125          73 : }
     126             : 
     127             : 
     128             : 
     129             : 
     130             : 
     131           0 : BasicPaneFactory::~BasicPaneFactory (void)
     132             : {
     133           0 : }
     134             : 
     135             : 
     136             : 
     137             : 
     138           0 : void SAL_CALL BasicPaneFactory::disposing (void)
     139             : {
     140           0 :     Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
     141           0 :     if (xCC.is())
     142             :     {
     143           0 :         xCC->removeResourceFactoryForReference(this);
     144           0 :         xCC->removeConfigurationChangeListener(this);
     145           0 :         mxConfigurationControllerWeak.clear();
     146             :     }
     147             : 
     148           0 :     for (PaneContainer::const_iterator iDescriptor = mpPaneContainer->begin();
     149           0 :          iDescriptor != mpPaneContainer->end();
     150             :          ++iDescriptor)
     151             :     {
     152           0 :         if (iDescriptor->mbIsReleased)
     153             :         {
     154           0 :             Reference<XComponent> xComponent (iDescriptor->mxPane, UNO_QUERY);
     155           0 :             if (xComponent.is())
     156             :             {
     157           0 :                 xComponent->removeEventListener(this);
     158           0 :                 xComponent->dispose();
     159           0 :             }
     160             :         }
     161           0 :     }
     162           0 : }
     163             : 
     164             : 
     165             : 
     166             : 
     167          73 : void SAL_CALL BasicPaneFactory::initialize (const Sequence<Any>& aArguments)
     168             :     throw (Exception, RuntimeException, std::exception)
     169             : {
     170          73 :     if (aArguments.getLength() > 0)
     171             :     {
     172             :         try
     173             :         {
     174             :             // Get the XController from the first argument.
     175          73 :             Reference<frame::XController> xController (aArguments[0], UNO_QUERY_THROW);
     176          73 :             mxControllerWeak = xController;
     177             : 
     178             :             // Tunnel through the controller to obtain access to the ViewShellBase.
     179             :             try
     180             :             {
     181          73 :                 Reference<lang::XUnoTunnel> xTunnel (xController, UNO_QUERY_THROW);
     182             :                 DrawController* pController
     183             :                     = reinterpret_cast<DrawController*>(
     184             :                         (sal::static_int_cast<sal_uIntPtr>(
     185          73 :                             xTunnel->getSomething(DrawController::getUnoTunnelId()))));
     186          73 :                 mpViewShellBase = pController->GetViewShellBase();
     187             :             }
     188           0 :             catch(RuntimeException&)
     189             :             {}
     190             : 
     191         146 :             Reference<XControllerManager> xCM (xController, UNO_QUERY_THROW);
     192         146 :             Reference<XConfigurationController> xCC (xCM->getConfigurationController());
     193          73 :             mxConfigurationControllerWeak = xCC;
     194             : 
     195             :             // Add pane factories for the two left panes (one for Impress and one for
     196             :             // Draw) and the center pane.
     197          73 :             if (xController.is() && xCC.is())
     198             :             {
     199          73 :                 PaneDescriptor aDescriptor;
     200          73 :                 aDescriptor.msPaneURL = FrameworkHelper::msCenterPaneURL;
     201          73 :                 aDescriptor.mePaneId = CenterPaneId;
     202          73 :                 aDescriptor.mbIsReleased = false;
     203          73 :                 aDescriptor.mbIsChildWindow = false;
     204          73 :                 mpPaneContainer->push_back(aDescriptor);
     205          73 :                 xCC->addResourceFactory(aDescriptor.msPaneURL, this);
     206             : 
     207          73 :                 aDescriptor.msPaneURL = FrameworkHelper::msFullScreenPaneURL;
     208          73 :                 aDescriptor.mePaneId = FullScreenPaneId;
     209          73 :                 mpPaneContainer->push_back(aDescriptor);
     210          73 :                 xCC->addResourceFactory(aDescriptor.msPaneURL, this);
     211             : 
     212          73 :                 aDescriptor.msPaneURL = FrameworkHelper::msLeftImpressPaneURL;
     213          73 :                 aDescriptor.mePaneId = LeftImpressPaneId;
     214          73 :                 aDescriptor.mbIsChildWindow = true;
     215          73 :                 mpPaneContainer->push_back(aDescriptor);
     216          73 :                 xCC->addResourceFactory(aDescriptor.msPaneURL, this);
     217             : 
     218          73 :                 aDescriptor.msPaneURL = FrameworkHelper::msLeftDrawPaneURL;
     219          73 :                 aDescriptor.mePaneId = LeftDrawPaneId;
     220          73 :                 mpPaneContainer->push_back(aDescriptor);
     221          73 :                 xCC->addResourceFactory(aDescriptor.msPaneURL, this);
     222             :             }
     223             : 
     224             :             // Register as configuration change listener.
     225          73 :             if (xCC.is())
     226             :             {
     227          73 :                 xCC->addConfigurationChangeListener(
     228             :                     this,
     229             :                     FrameworkHelper::msConfigurationUpdateStartEvent,
     230          73 :                     makeAny(gnConfigurationUpdateStartEvent));
     231          73 :                 xCC->addConfigurationChangeListener(
     232             :                     this,
     233             :                     FrameworkHelper::msConfigurationUpdateEndEvent,
     234          73 :                     makeAny(gnConfigurationUpdateEndEvent));
     235          73 :             }
     236             :         }
     237           0 :         catch (RuntimeException&)
     238             :         {
     239           0 :             Reference<XConfigurationController> xCC (mxConfigurationControllerWeak);
     240           0 :             if (xCC.is())
     241           0 :                 xCC->removeResourceFactoryForReference(this);
     242             :         }
     243             :     }
     244          73 : }
     245             : 
     246             : 
     247             : 
     248             : 
     249             : //===== XPaneFactory ==========================================================
     250             : 
     251         209 : Reference<XResource> SAL_CALL BasicPaneFactory::createResource (
     252             :     const Reference<XResourceId>& rxPaneId)
     253             :     throw (RuntimeException, IllegalArgumentException, WrappedTargetException, std::exception)
     254             : {
     255         209 :     ThrowIfDisposed();
     256             : 
     257         209 :     Reference<XResource> xPane;
     258             : 
     259             :     // Based on the ResourceURL of the given ResourceId look up the
     260             :     // corresponding factory descriptor.
     261             :     PaneContainer::iterator iDescriptor (
     262             :         ::std::find_if (
     263         209 :             mpPaneContainer->begin(),
     264         209 :             mpPaneContainer->end(),
     265         627 :             ::boost::bind(&PaneDescriptor::CompareURL, _1, rxPaneId->getResourceURL())));
     266             : 
     267         209 :     if (iDescriptor != mpPaneContainer->end())
     268             :     {
     269         209 :         if (iDescriptor->mxPane.is())
     270             :         {
     271             :             // The pane has already been created and is still active (has
     272             :             // not yet been released).  This should not happen.
     273          63 :             xPane = iDescriptor->mxPane;
     274             :         }
     275             :         else
     276             :         {
     277             :             // Create a new pane.
     278         146 :             switch (iDescriptor->mePaneId)
     279             :             {
     280             :                 case CenterPaneId:
     281          73 :                     xPane = CreateFrameWindowPane(rxPaneId);
     282          73 :                     break;
     283             : 
     284             :                 case FullScreenPaneId:
     285           0 :                     xPane = CreateFullScreenPane(mxComponentContext, rxPaneId);
     286           0 :                     break;
     287             : 
     288             :                 case LeftImpressPaneId:
     289             :                 case LeftDrawPaneId:
     290         146 :                     xPane = CreateChildWindowPane(
     291             :                         rxPaneId,
     292         146 :                         *iDescriptor);
     293          73 :                     break;
     294             :             }
     295         146 :             iDescriptor->mxPane = xPane;
     296             : 
     297             :             // Listen for the pane being disposed.
     298         146 :             Reference<lang::XComponent> xComponent (xPane, UNO_QUERY);
     299         146 :             if (xComponent.is())
     300         146 :                 xComponent->addEventListener(this);
     301             :         }
     302         209 :         iDescriptor->mbIsReleased = false;
     303             :     }
     304             :     else
     305             :     {
     306             :         // The requested pane can not be created by any of the factories
     307             :         // managed by the called BasicPaneFactory object.
     308             :         throw lang::IllegalArgumentException("BasicPaneFactory::createPane() called for unknown resource id",
     309             :             NULL,
     310           0 :             0);
     311             :     }
     312             : 
     313         209 :     return xPane;
     314             : }
     315             : 
     316             : 
     317             : 
     318             : 
     319             : 
     320         209 : void SAL_CALL BasicPaneFactory::releaseResource (
     321             :     const Reference<XResource>& rxPane)
     322             :     throw (RuntimeException, std::exception)
     323             : {
     324         209 :     ThrowIfDisposed();
     325             : 
     326             :     // Based on the given XPane reference look up the corresponding factory
     327             :     // descriptor.
     328             :     PaneContainer::iterator iDescriptor (
     329             :         ::std::find_if(
     330         209 :             mpPaneContainer->begin(),
     331         209 :             mpPaneContainer->end(),
     332         627 :             ::boost::bind(&PaneDescriptor::ComparePane, _1, rxPane)));
     333             : 
     334         209 :     if (iDescriptor != mpPaneContainer->end())
     335             :     {
     336             :         // The given pane was created by one of the factories.  Child
     337             :         // windows are just hidden and will be reused when requested later.
     338             :         // Other windows are disposed and their reference is reset so that
     339             :         // on the next createPane() call for the same pane type the pane is
     340             :         // created anew.
     341         209 :         ChildWindowPane* pChildWindowPane = dynamic_cast<ChildWindowPane*>(rxPane.get());
     342         209 :         if (pChildWindowPane != NULL)
     343             :         {
     344         136 :             iDescriptor->mbIsReleased = true;
     345         136 :             pChildWindowPane->Hide();
     346             :         }
     347             :         else
     348             :         {
     349          73 :             iDescriptor->mxPane = NULL;
     350          73 :             Reference<XComponent> xComponent (rxPane, UNO_QUERY);
     351          73 :             if (xComponent.is())
     352             :             {
     353             :                 // We are disposing the pane and do not have to be informed of
     354             :                 // that.
     355          73 :                 xComponent->removeEventListener(this);
     356          73 :                 xComponent->dispose();
     357          73 :             }
     358             :         }
     359             :     }
     360             :     else
     361             :     {
     362             :         // The given XPane reference is either empty or the pane was not
     363             :         // created by any of the factories managed by the called
     364             :         // BasicPaneFactory object.
     365             :         throw lang::IllegalArgumentException("BasicPaneFactory::releasePane() called for pane that that was not created by same factory.",
     366             :             NULL,
     367           0 :             0);
     368             :     }
     369         209 : }
     370             : 
     371             : 
     372             : 
     373             : 
     374             : //===== XConfigurationChangeListener ==========================================
     375             : 
     376         431 : void SAL_CALL BasicPaneFactory::notifyConfigurationChange (
     377             :     const ConfigurationChangeEvent& /* rEvent */ )
     378             :     throw (RuntimeException, std::exception)
     379             : {
     380             :         // FIXME: nothing to do
     381         431 : }
     382             : 
     383             : 
     384             : 
     385             : 
     386             : //===== lang::XEventListener ==================================================
     387             : 
     388          73 : void SAL_CALL BasicPaneFactory::disposing (
     389             :     const lang::EventObject& rEventObject)
     390             :     throw (RuntimeException, std::exception)
     391             : {
     392          73 :     if (mxConfigurationControllerWeak == rEventObject.Source)
     393             :     {
     394          73 :         mxConfigurationControllerWeak.clear();
     395             :     }
     396             :     else
     397             :     {
     398             :         // Has one of the panes been disposed?  If so, then release the
     399             :         // reference to that pane, but not the pane descriptor.
     400           0 :         Reference<XResource> xPane (rEventObject.Source, UNO_QUERY);
     401             :         PaneContainer::iterator iDescriptor (
     402             :             ::std::find_if (
     403           0 :                 mpPaneContainer->begin(),
     404           0 :                 mpPaneContainer->end(),
     405           0 :                 ::boost::bind(&PaneDescriptor::ComparePane, _1, xPane)));
     406           0 :         if (iDescriptor != mpPaneContainer->end())
     407             :         {
     408           0 :             iDescriptor->mxPane = NULL;
     409           0 :         }
     410             :     }
     411          73 : }
     412             : 
     413             : 
     414             : 
     415             : 
     416             : 
     417             : 
     418          73 : Reference<XResource> BasicPaneFactory::CreateFrameWindowPane (
     419             :     const Reference<XResourceId>& rxPaneId)
     420             : {
     421          73 :     Reference<XResource> xPane;
     422             : 
     423          73 :     if (mpViewShellBase != NULL)
     424             :     {
     425          73 :         xPane = new FrameWindowPane(rxPaneId, mpViewShellBase->GetViewWindow());
     426             :     }
     427             : 
     428          73 :     return xPane;
     429             : }
     430             : 
     431             : 
     432             : 
     433             : 
     434           0 : Reference<XResource> BasicPaneFactory::CreateFullScreenPane (
     435             :     const Reference<XComponentContext>& rxComponentContext,
     436             :     const Reference<XResourceId>& rxPaneId)
     437             : {
     438             :     Reference<XResource> xPane (
     439             :         new FullScreenPane(
     440             :             rxComponentContext,
     441             :             rxPaneId,
     442           0 :             mpViewShellBase->GetViewWindow()));
     443             : 
     444           0 :     return xPane;
     445             : }
     446             : 
     447             : 
     448             : 
     449             : 
     450          73 : Reference<XResource> BasicPaneFactory::CreateChildWindowPane (
     451             :     const Reference<XResourceId>& rxPaneId,
     452             :     const PaneDescriptor& rDescriptor)
     453             : {
     454          73 :     Reference<XResource> xPane;
     455             : 
     456          73 :     if (mpViewShellBase != NULL)
     457             :     {
     458             :         // Create the corresponding shell and determine the id of the child window.
     459          73 :         sal_uInt16 nChildWindowId = 0;
     460             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     461          73 :         ::std::auto_ptr<SfxShell> pShell;
     462             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     463          73 :         switch (rDescriptor.mePaneId)
     464             :         {
     465             :             case LeftImpressPaneId:
     466          21 :                 pShell.reset(new LeftImpressPaneShell());
     467          21 :                 nChildWindowId = ::sd::LeftPaneImpressChildWindow::GetChildWindowId();
     468          21 :                 break;
     469             : 
     470             :             case LeftDrawPaneId:
     471          52 :                 pShell.reset(new LeftDrawPaneShell());
     472          52 :                 nChildWindowId = ::sd::LeftPaneDrawChildWindow::GetChildWindowId();
     473          52 :                 break;
     474             : 
     475             :             default:
     476           0 :                 break;
     477             :         }
     478             : 
     479             :         // With shell and child window id create the ChildWindowPane
     480             :         // wrapper.
     481          73 :         if (pShell.get() != NULL)
     482             :         {
     483         219 :             xPane = new ChildWindowPane(
     484             :                 rxPaneId,
     485             :                 nChildWindowId,
     486             :                 *mpViewShellBase,
     487         146 :                 pShell);
     488          73 :         }
     489             :     }
     490             : 
     491          73 :     return xPane;
     492             : }
     493             : 
     494         418 : void BasicPaneFactory::ThrowIfDisposed (void) const
     495             :     throw (lang::DisposedException)
     496             : {
     497         418 :     if (rBHelper.bDisposed || rBHelper.bInDispose)
     498             :     {
     499             :         throw lang::DisposedException ("BasicPaneFactory object has already been disposed",
     500           0 :             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
     501             :     }
     502         418 : }
     503             : 
     504             : 
     505          48 : } } // end of namespace sd::framework
     506             : 
     507             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10