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

Generated by: LCOV version 1.10