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

Generated by: LCOV version 1.10