LCOV - code coverage report
Current view: top level - sd/source/ui/framework/tools - FrameworkHelper.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 199 364 54.7 %
Date: 2014-11-03 Functions: 37 61 60.7 %
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 <osl/time.h>
      21             : 
      22             : #include "framework/FrameworkHelper.hxx"
      23             : 
      24             : #include "framework/ConfigurationController.hxx"
      25             : #include "framework/ResourceId.hxx"
      26             : #include "framework/ViewShellWrapper.hxx"
      27             : #include "ViewShellBase.hxx"
      28             : #include "FrameView.hxx"
      29             : #include "DrawViewShell.hxx"
      30             : #include "ViewShellHint.hxx"
      31             : #include "DrawController.hxx"
      32             : #include "app.hrc"
      33             : #include <com/sun/star/drawing/framework/XControllerManager.hpp>
      34             : #include <com/sun/star/drawing/framework/XPane.hpp>
      35             : #include <cppuhelper/compbase1.hxx>
      36             : #include <svl/lstner.hxx>
      37             : 
      38             : #include <sfx2/request.hxx>
      39             : #include <sfx2/dispatch.hxx>
      40             : 
      41             : #include "MutexOwner.hxx"
      42             : #include "vcl/svapp.hxx"
      43             : #include <osl/doublecheckedlocking.h>
      44             : #include <osl/getglobalmutex.hxx>
      45             : #include <tools/diagnose_ex.h>
      46             : #include <boost/unordered_map.hpp>
      47             : 
      48             : using namespace ::com::sun::star;
      49             : using namespace ::com::sun::star::uno;
      50             : using namespace ::com::sun::star::drawing::framework;
      51             : 
      52             : namespace {
      53             : 
      54             : //----- CallbackCaller --------------------------------------------------------
      55             : 
      56             : typedef ::cppu::WeakComponentImplHelper1 <
      57             :     ::com::sun::star::drawing::framework::XConfigurationChangeListener
      58             :     > CallbackCallerInterfaceBase;
      59             : 
      60             : /** A CallbackCaller registers as listener at an XConfigurationController
      61             :     object and waits for the notification of one type of event.  When that
      62             :     event is received, or when the CallbackCaller detects at its
      63             :     construction that the event will not be sent in the near future, the
      64             :     actual callback object is called and the CallbackCaller destroys itself.
      65             : */
      66             : class CallbackCaller
      67             :     : public ::sd::MutexOwner,
      68             :       public CallbackCallerInterfaceBase
      69             : {
      70             : public:
      71             :     /** Create a new CallbackCaller object.  This object controls its own
      72             :         lifetime by acquiring a reference to itself in the constructor.
      73             :         When it detects that the event will not be notified in the near
      74             :         future (because the queue of pending configuration change operations
      75             :         is empty and therefore no event will be sent int the near future, it
      76             :         does not acquires a reference and thus initiates its destruction in
      77             :         the constructor.)
      78             :         @param rBase
      79             :             This ViewShellBase object is used to determine the
      80             :             XConfigurationController at which to register.
      81             :         @param rsEventType
      82             :             The event type which the callback is waiting for.
      83             :         @param pCallback
      84             :             The callback object which is to be notified.  The caller will
      85             :             typically release his reference to the caller so that when the
      86             :             CallbackCaller dies (after having called the callback) the
      87             :             callback is destroyed.
      88             :     */
      89             :     CallbackCaller (
      90             :         ::sd::ViewShellBase& rBase,
      91             :         const OUString& rsEventType,
      92             :         const ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter& rFilter,
      93             :         const ::sd::framework::FrameworkHelper::Callback& rCallback);
      94             :     virtual ~CallbackCaller (void);
      95             : 
      96             :     virtual void SAL_CALL disposing (void) SAL_OVERRIDE;
      97             :     // XEventListener
      98             :     virtual void SAL_CALL disposing (const lang::EventObject& rEvent)
      99             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     100             :     // XConfigurationChangeListener
     101             :     virtual void SAL_CALL notifyConfigurationChange (const ConfigurationChangeEvent& rEvent)
     102             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     103             : 
     104             : private:
     105             :     OUString msEventType;
     106             :     Reference<XConfigurationController> mxConfigurationController;
     107             :     ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter maFilter;
     108             :     ::sd::framework::FrameworkHelper::Callback maCallback;
     109             : };
     110             : 
     111             : //----- LifetimeController ----------------------------------------------------
     112             : 
     113             : typedef ::cppu::WeakComponentImplHelper1 <
     114             :     ::com::sun::star::lang::XEventListener
     115             :     > LifetimeControllerInterfaceBase;
     116             : 
     117             : /** This class helps controlling the lifetime of the
     118             :     FrameworkHelper. Register at a ViewShellBase object and an XController
     119             :     object and call Dispose() at the associated FrameworkHelper object when
     120             :     one of them and Release() when both of them are destroyed.
     121             : */
     122             : class LifetimeController
     123             :     : public ::sd::MutexOwner,
     124             :       public LifetimeControllerInterfaceBase,
     125             :       public SfxListener
     126             : {
     127             : public:
     128             :     explicit LifetimeController (::sd::ViewShellBase& rBase);
     129             :     virtual ~LifetimeController (void);
     130             : 
     131             :     virtual void SAL_CALL disposing (void) SAL_OVERRIDE;
     132             : 
     133             :     /** XEventListener.  This method is called when the frame::XController
     134             :         is being destroyed.
     135             :     */
     136             :     virtual void SAL_CALL disposing (const lang::EventObject& rEvent)
     137             :         throw (RuntimeException, std::exception) SAL_OVERRIDE;
     138             : 
     139             :     /** This method is called when the ViewShellBase is being destroyed.
     140             :     */
     141             :     virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint) SAL_OVERRIDE;
     142             : 
     143             : private:
     144             :     ::sd::ViewShellBase& mrBase;
     145             :     bool mbListeningToViewShellBase;
     146             :     bool mbListeningToController;
     147             : 
     148             :     /** When one or both of the mbListeningToViewShellBase and
     149             :         mbListeningToController members were modified then call this method
     150             :         to either dispose or release the associated FrameworkHelper.
     151             :     */
     152             :     void Update (void);
     153             : };
     154             : 
     155             : } // end of anonymous namespace
     156             : 
     157             : namespace sd { namespace framework {
     158             : 
     159             : namespace {
     160             : 
     161             :     class FrameworkHelperAllPassFilter
     162             :     {
     163             :     public:
     164           0 :         bool operator() (const css::drawing::framework::ConfigurationChangeEvent&) { return true; }
     165             :     };
     166             : 
     167           0 :     class FrameworkHelperResourceIdFilter
     168             :     {
     169             :     public:
     170             :         FrameworkHelperResourceIdFilter (
     171             :             const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId);
     172           0 :         bool operator() (const css::drawing::framework::ConfigurationChangeEvent& rEvent)
     173           0 :         { return mxResourceId.is() && rEvent.ResourceId.is()
     174           0 :                 && mxResourceId->compareTo(rEvent.ResourceId) == 0; }
     175             :     private:
     176             :         css::uno::Reference<css::drawing::framework::XResourceId> mxResourceId;
     177             :     };
     178             : 
     179             : } // end of anonymous namespace
     180             : 
     181             : // Pane URLS.
     182             : 
     183          38 : const OUString FrameworkHelper::msPaneURLPrefix("private:resource/pane/");
     184          38 : const OUString FrameworkHelper::msCenterPaneURL( msPaneURLPrefix + "CenterPane");
     185          38 : const OUString FrameworkHelper::msFullScreenPaneURL( msPaneURLPrefix + "FullScreenPane");
     186          38 : const OUString FrameworkHelper::msLeftImpressPaneURL( msPaneURLPrefix + "LeftImpressPane");
     187          38 : const OUString FrameworkHelper::msLeftDrawPaneURL( msPaneURLPrefix + "LeftDrawPane");
     188          38 : const OUString FrameworkHelper::msSidebarPaneURL( msPaneURLPrefix + "SidebarPane");
     189             : 
     190             : // View URLs.
     191             : 
     192          38 : const OUString FrameworkHelper::msViewURLPrefix("private:resource/view/");
     193          38 : const OUString FrameworkHelper::msImpressViewURL( msViewURLPrefix + "ImpressView");
     194          38 : const OUString FrameworkHelper::msDrawViewURL( msViewURLPrefix + "GraphicView");
     195          38 : const OUString FrameworkHelper::msOutlineViewURL( msViewURLPrefix + "OutlineView");
     196          38 : const OUString FrameworkHelper::msNotesViewURL( msViewURLPrefix + "NotesView");
     197          38 : const OUString FrameworkHelper::msHandoutViewURL( msViewURLPrefix + "HandoutView");
     198          38 : const OUString FrameworkHelper::msSlideSorterURL( msViewURLPrefix + "SlideSorter");
     199          38 : const OUString FrameworkHelper::msPresentationViewURL( msViewURLPrefix + "PresentationView");
     200          38 : const OUString FrameworkHelper::msSidebarViewURL( msViewURLPrefix + "SidebarView");
     201             : 
     202             : // Tool bar URLs.
     203             : 
     204          38 : const OUString FrameworkHelper::msToolBarURLPrefix("private:resource/toolbar/");
     205          38 : const OUString FrameworkHelper::msViewTabBarURL( msToolBarURLPrefix + "ViewTabBar");
     206             : 
     207             : // Task panel URLs.
     208          38 : const OUString FrameworkHelper::msTaskPanelURLPrefix( "private:resource/toolpanel/" );
     209          38 : const OUString FrameworkHelper::msAllMasterPagesTaskPanelURL( msTaskPanelURLPrefix + "AllMasterPages" );
     210          38 : const OUString FrameworkHelper::msRecentMasterPagesTaskPanelURL( msTaskPanelURLPrefix + "RecentMasterPages" );
     211          38 : const OUString FrameworkHelper::msUsedMasterPagesTaskPanelURL( msTaskPanelURLPrefix + "UsedMasterPages" );
     212          38 : const OUString FrameworkHelper::msLayoutTaskPanelURL( msTaskPanelURLPrefix + "Layouts" );
     213          38 : const OUString FrameworkHelper::msTableDesignPanelURL( msTaskPanelURLPrefix + "TableDesign" );
     214          38 : const OUString FrameworkHelper::msCustomAnimationTaskPanelURL( msTaskPanelURLPrefix + "CustomAnimations" );
     215          38 : const OUString FrameworkHelper::msSlideTransitionTaskPanelURL( msTaskPanelURLPrefix + "SlideTransitions" );
     216             : 
     217             : // Event URLs.
     218          38 : const OUString FrameworkHelper::msResourceActivationRequestEvent( "ResourceActivationRequested" );
     219          38 : const OUString FrameworkHelper::msResourceDeactivationRequestEvent( "ResourceDeactivationRequest" );
     220          38 : const OUString FrameworkHelper::msResourceActivationEvent( "ResourceActivation" );
     221          38 : const OUString FrameworkHelper::msResourceDeactivationEvent( "ResourceDeactivation" );
     222          38 : const OUString FrameworkHelper::msResourceDeactivationEndEvent( "ResourceDeactivationEnd" );
     223          38 : const OUString FrameworkHelper::msConfigurationUpdateStartEvent( "ConfigurationUpdateStart" );
     224          38 : const OUString FrameworkHelper::msConfigurationUpdateEndEvent( "ConfigurationUpdateEnd" );
     225             : 
     226             : // Service names of controllers.
     227          38 : const OUString FrameworkHelper::msModuleControllerService("com.sun.star.drawing.framework.ModuleController");
     228          38 : const OUString FrameworkHelper::msConfigurationControllerService("com.sun.star.drawing.framework.ConfigurationController");
     229             : 
     230             : //----- helper ----------------------------------------------------------------
     231             : namespace
     232             : {
     233       10052 :     static ::boost::shared_ptr< ViewShell > lcl_getViewShell( const Reference< XResource >& i_rViewShellWrapper )
     234             :     {
     235       10052 :         ::boost::shared_ptr< ViewShell > pViewShell;
     236       10052 :         if ( !i_rViewShellWrapper.is() )
     237        1272 :             return pViewShell;
     238             : 
     239             :         try
     240             :         {
     241        8780 :             Reference<lang::XUnoTunnel> xViewTunnel( i_rViewShellWrapper, UNO_QUERY_THROW );
     242       17560 :             pViewShell = reinterpret_cast< ViewShellWrapper* >(
     243       26340 :                 xViewTunnel->getSomething( ViewShellWrapper::getUnoTunnelId() ) )->GetViewShell();
     244             :         }
     245           0 :         catch( const Exception& )
     246             :         {
     247             :             DBG_UNHANDLED_EXCEPTION();
     248             :         }
     249        8780 :         return pViewShell;
     250             :     }
     251       10234 :     Reference< XResource > lcl_getFirstViewInPane( const Reference< XConfigurationController >& i_rConfigController,
     252             :         const Reference< XResourceId >& i_rPaneId )
     253             :     {
     254             :         try
     255             :         {
     256       10234 :             Reference< XConfiguration > xConfiguration( i_rConfigController->getRequestedConfiguration(), UNO_SET_THROW );
     257       10234 :             Sequence< Reference< XResourceId > > aViewIds( xConfiguration->getResources(
     258       11082 :                 i_rPaneId, FrameworkHelper::msViewURLPrefix, AnchorBindingMode_DIRECT ) );
     259       10234 :             if ( aViewIds.getLength() > 0 )
     260       10234 :                 return i_rConfigController->getResource( aViewIds[0] );
     261             :         }
     262           0 :         catch( const Exception& )
     263             :         {
     264             :             DBG_UNHANDLED_EXCEPTION();
     265             :         }
     266         848 :         return NULL;
     267             :     }
     268             : }
     269             : 
     270             : //----- FrameworkHelper::ViewURLMap -------------------------------------------
     271             : 
     272             : /** The ViewURLMap is used to translate between the view URLs used by the
     273             :     drawing framework and the enums defined in the ViewShell class.
     274             : */
     275          38 : class FrameworkHelper::ViewURLMap
     276             :     : public ::boost::unordered_map<
     277             :           OUString,
     278             :           ViewShell::ShellType,
     279             :           OUStringHash>
     280             : {
     281             : public:
     282          38 :     ViewURLMap (void) {}
     283             : };
     284             : 
     285             : //----- Framework::DiposeListener ---------------------------------------------
     286             : 
     287             : namespace {
     288             :     typedef ::cppu::WeakComponentImplHelper1 <
     289             :         ::com::sun::star::lang::XEventListener
     290             :         > FrameworkHelperDisposeListenerInterfaceBase;
     291             : }
     292             : 
     293             : class FrameworkHelper::DisposeListener
     294             :     : public ::sd::MutexOwner,
     295             :       public FrameworkHelperDisposeListenerInterfaceBase
     296             : {
     297             : public:
     298             :     DisposeListener (const ::boost::shared_ptr<FrameworkHelper>& rpHelper);
     299             :     virtual ~DisposeListener (void);
     300             : 
     301             :     virtual void SAL_CALL disposing (void) SAL_OVERRIDE;
     302             : 
     303             :     virtual void SAL_CALL disposing (const lang::EventObject& rEventObject)
     304             :         throw(RuntimeException, std::exception) SAL_OVERRIDE;
     305             : 
     306             : private:
     307             :     ::boost::shared_ptr<FrameworkHelper> mpHelper;
     308             : };
     309             : 
     310             : //----- FrameworkHelper::Deleter ----------------------------------------------
     311             : 
     312             : class FrameworkHelper::Deleter
     313             : {
     314             : public:
     315         212 :     void operator()(FrameworkHelper* pObject)
     316             :     {
     317         212 :         delete pObject;
     318         212 :     }
     319             : };
     320             : 
     321             : //----- FrameworkHelper -------------------------------------------------------
     322             : 
     323          38 : ::boost::scoped_ptr<FrameworkHelper::ViewURLMap> FrameworkHelper::mpViewURLMap(new ViewURLMap());
     324             : 
     325          38 : FrameworkHelper::InstanceMap FrameworkHelper::maInstanceMap;
     326             : 
     327           0 : ::boost::shared_ptr<FrameworkHelper> FrameworkHelper::Instance (
     328             :     const Reference<frame::XController>& rxController)
     329             : {
     330             :     // Tunnel through the controller to obtain a ViewShellBase.
     331           0 :     Reference<lang::XUnoTunnel> xTunnel (rxController, UNO_QUERY);
     332           0 :     if (xTunnel.is())
     333             :     {
     334             :         ::sd::DrawController* pController = reinterpret_cast<sd::DrawController*>(
     335           0 :             xTunnel->getSomething(sd::DrawController::getUnoTunnelId()));
     336           0 :         if (pController != NULL)
     337             :         {
     338           0 :             ViewShellBase* pBase = pController->GetViewShellBase();
     339           0 :             if (pBase != NULL)
     340           0 :                 return Instance(*pBase);
     341             :         }
     342             :     }
     343             : 
     344           0 :     return ::boost::shared_ptr<FrameworkHelper>();
     345             : }
     346             : 
     347       13688 : ::boost::shared_ptr<FrameworkHelper> FrameworkHelper::Instance (ViewShellBase& rBase)
     348             : {
     349             : 
     350       13688 :     ::boost::shared_ptr<FrameworkHelper> pHelper;
     351             : 
     352       13688 :     InstanceMap::const_iterator iHelper (maInstanceMap.find(&rBase));
     353       13688 :     if (iHelper == maInstanceMap.end())
     354             :     {
     355             :         ::osl::GetGlobalMutex aMutexFunctor;
     356         212 :         ::osl::MutexGuard aGuard (aMutexFunctor());
     357         212 :         if (iHelper == maInstanceMap.end())
     358             :         {
     359         636 :             pHelper = ::boost::shared_ptr<FrameworkHelper>(
     360         212 :                 new FrameworkHelper(rBase),
     361         212 :                 FrameworkHelper::Deleter());
     362         212 :             pHelper->Initialize();
     363             :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     364         212 :             maInstanceMap[&rBase] = pHelper;
     365         212 :         }
     366             :     }
     367             :     else
     368             :     {
     369             :         OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     370       13476 :         pHelper = iHelper->second;
     371             :     }
     372             : 
     373       13688 :     return pHelper;
     374             : }
     375             : 
     376         212 : void FrameworkHelper::DisposeInstance (ViewShellBase& rBase)
     377             : {
     378         212 :     InstanceMap::iterator iHelper (maInstanceMap.find(&rBase));
     379         212 :     if (iHelper != maInstanceMap.end())
     380             :     {
     381         212 :         iHelper->second->Dispose();
     382             :     }
     383         212 : }
     384             : 
     385         212 : void FrameworkHelper::ReleaseInstance (ViewShellBase& rBase)
     386             : {
     387         212 :     InstanceMap::iterator iHelper (maInstanceMap.find(&rBase));
     388         212 :     if (iHelper != maInstanceMap.end())
     389         212 :         maInstanceMap.erase(iHelper);
     390         212 : }
     391             : 
     392         212 : FrameworkHelper::FrameworkHelper (ViewShellBase& rBase)
     393             :     : mrBase(rBase),
     394             :       mxConfigurationController(),
     395         212 :       mxDisposeListener()
     396             : 
     397             : {
     398         212 :     Reference<XControllerManager> xControllerManager (rBase.GetController(), UNO_QUERY);
     399         212 :     if (xControllerManager.is())
     400             :     {
     401         212 :         mxConfigurationController = xControllerManager->getConfigurationController();
     402             :     }
     403             : 
     404         212 :     new LifetimeController(mrBase);
     405         212 : }
     406             : 
     407         212 : void FrameworkHelper::Initialize (void)
     408             : {
     409         212 :     mxDisposeListener = new DisposeListener(shared_from_this());
     410         212 : }
     411             : 
     412         424 : FrameworkHelper::~FrameworkHelper (void)
     413             : {
     414         424 : }
     415             : 
     416         212 : void FrameworkHelper::Dispose (void)
     417             : {
     418         212 :     if (mxDisposeListener.is())
     419         212 :         mxDisposeListener->dispose();
     420         212 :     mxConfigurationController = NULL;
     421         212 : }
     422             : 
     423           0 : bool FrameworkHelper::IsValid (void)
     424             : {
     425           0 :     return mxConfigurationController.is();
     426             : }
     427             : 
     428       12464 : ::boost::shared_ptr<ViewShell> FrameworkHelper::GetViewShell (const OUString& rsPaneURL)
     429             : {
     430       12464 :     if ( !mxConfigurationController.is() )
     431        2664 :         return ::boost::shared_ptr<ViewShell>();
     432             : 
     433        9800 :     Reference<XResourceId> xPaneId( CreateResourceId( rsPaneURL ) );
     434        9800 :     return lcl_getViewShell( lcl_getFirstViewInPane( mxConfigurationController, xPaneId ) );
     435             : }
     436             : 
     437         252 : ::boost::shared_ptr<ViewShell> FrameworkHelper::GetViewShell (const Reference<XView>& rxView)
     438             : {
     439         252 :     return lcl_getViewShell( rxView.get() );
     440             : }
     441             : 
     442         434 : Reference<XView> FrameworkHelper::GetView (const Reference<XResourceId>& rxPaneOrViewId)
     443             : {
     444         434 :     Reference<XView> xView;
     445             : 
     446         434 :     if ( ! rxPaneOrViewId.is() || ! mxConfigurationController.is())
     447           0 :         return NULL;
     448             : 
     449             :     try
     450             :     {
     451         434 :         if (rxPaneOrViewId->getResourceURL().match(msViewURLPrefix))
     452             :         {
     453           0 :             xView.set( mxConfigurationController->getResource( rxPaneOrViewId ), UNO_QUERY );
     454             :         }
     455             :         else
     456             :         {
     457         434 :             xView.set( lcl_getFirstViewInPane( mxConfigurationController, rxPaneOrViewId ), UNO_QUERY );
     458             :         }
     459             :     }
     460           0 :     catch (lang::DisposedException&)
     461             :     {
     462           0 :         Dispose();
     463             :     }
     464           0 :     catch (RuntimeException&)
     465             :     {
     466             :     }
     467             : 
     468         434 :     return xView;
     469             : }
     470             : 
     471          52 : Reference<XResourceId> FrameworkHelper::RequestView (
     472             :     const OUString& rsResourceURL,
     473             :     const OUString& rsAnchorURL)
     474             : {
     475          52 :     Reference<XResourceId> xViewId;
     476             : 
     477             :     try
     478             :     {
     479          52 :         if (mxConfigurationController.is())
     480             :         {
     481          52 :             mxConfigurationController->requestResourceActivation(
     482             :                 CreateResourceId(rsAnchorURL),
     483          52 :                 ResourceActivationMode_ADD);
     484          52 :             xViewId = CreateResourceId(rsResourceURL, rsAnchorURL);
     485          52 :             mxConfigurationController->requestResourceActivation(
     486             :                 xViewId,
     487          52 :                 ResourceActivationMode_REPLACE);
     488             :         }
     489             :     }
     490           0 :     catch (lang::DisposedException&)
     491             :     {
     492           0 :         Dispose();
     493           0 :         xViewId = NULL;
     494             :     }
     495           0 :     catch (RuntimeException&)
     496             :     {
     497           0 :         xViewId = NULL;
     498             :     }
     499             : 
     500          52 :     return xViewId;
     501             : }
     502             : 
     503         126 : ViewShell::ShellType FrameworkHelper::GetViewId (const OUString& rsViewURL)
     504             : {
     505         126 :     if (mpViewURLMap->empty())
     506             :     {
     507          16 :         (*mpViewURLMap)[msImpressViewURL] = ViewShell::ST_IMPRESS;
     508          16 :         (*mpViewURLMap)[msDrawViewURL] = ViewShell::ST_DRAW;
     509          16 :         (*mpViewURLMap)[msOutlineViewURL] = ViewShell::ST_OUTLINE;
     510          16 :         (*mpViewURLMap)[msNotesViewURL] = ViewShell::ST_NOTES;
     511          16 :         (*mpViewURLMap)[msHandoutViewURL] = ViewShell::ST_HANDOUT;
     512          16 :         (*mpViewURLMap)[msSlideSorterURL] = ViewShell::ST_SLIDE_SORTER;
     513          16 :         (*mpViewURLMap)[msPresentationViewURL] = ViewShell::ST_PRESENTATION;
     514          16 :         (*mpViewURLMap)[msSidebarViewURL] = ViewShell::ST_SIDEBAR;
     515             :     }
     516         126 :     ViewURLMap::const_iterator iView (mpViewURLMap->find(rsViewURL));
     517         126 :     if (iView != mpViewURLMap->end())
     518         126 :         return iView->second;
     519             :     else
     520           0 :         return ViewShell::ST_NONE;
     521             : }
     522             : 
     523           0 : OUString FrameworkHelper::GetViewURL (ViewShell::ShellType eType)
     524             : {
     525           0 :     switch (eType)
     526             :     {
     527           0 :         case ViewShell::ST_IMPRESS : return msImpressViewURL;
     528           0 :         case ViewShell::ST_DRAW : return msDrawViewURL;
     529           0 :         case ViewShell::ST_OUTLINE : return msOutlineViewURL;
     530           0 :         case ViewShell::ST_NOTES : return msNotesViewURL;
     531           0 :         case ViewShell::ST_HANDOUT : return msHandoutViewURL;
     532           0 :         case ViewShell::ST_SLIDE_SORTER : return msSlideSorterURL;
     533           0 :         case ViewShell::ST_PRESENTATION : return msPresentationViewURL;
     534           0 :         case ViewShell::ST_SIDEBAR : return msSidebarViewURL;
     535             :         default:
     536           0 :             return OUString();
     537             :     }
     538             : }
     539             : 
     540           0 : void FrameworkHelper::HandleModeChangeSlot (
     541             :     sal_uLong nSlotId,
     542             :     SfxRequest& rRequest)
     543             : {
     544           0 :     bool bIsActive = true;
     545             : 
     546           0 :     if ( ! mxConfigurationController.is())
     547           0 :         return;
     548             : 
     549           0 :     switch (nSlotId)
     550             :     {
     551             :         case SID_DRAWINGMODE:
     552             :         case SID_NOTESMODE:
     553             :         case SID_HANDOUTMODE:
     554             :         case SID_DIAMODE:
     555             :         case SID_OUTLINEMODE:
     556             :         {
     557           0 :             const SfxItemSet* pRequestArguments = rRequest.GetArgs();
     558           0 :             if (pRequestArguments)
     559             :             {
     560           0 :                 SFX_REQUEST_ARG (rRequest,
     561             :                     pIsActive,
     562             :                     SfxBoolItem,
     563             :                     (sal_uInt16)nSlotId,
     564             :                     false);
     565           0 :                 bIsActive = pIsActive->GetValue ();
     566             :             }
     567             :         }
     568           0 :         break;
     569             :     }
     570             : 
     571             :     try
     572             :     {
     573           0 :         if ( ! mxConfigurationController.is())
     574           0 :             throw RuntimeException();
     575             : 
     576             :         Reference<XResourceId> xPaneId (
     577           0 :             CreateResourceId(framework::FrameworkHelper::msCenterPaneURL));
     578           0 :         Reference<XView> xView (GetView(xPaneId));
     579           0 :         ::boost::shared_ptr<ViewShell> pCenterViewShell (GetViewShell(xView));
     580             : 
     581           0 :         OUString sRequestedView;
     582           0 :         if (bIsActive)
     583             :         {
     584           0 :             switch (nSlotId)
     585             :             {
     586             :                 case SID_NORMAL_MULTI_PANE_GUI:
     587             :                 case SID_DRAWINGMODE:
     588           0 :                     sRequestedView = FrameworkHelper::msImpressViewURL;
     589           0 :                     break;
     590             : 
     591             :                 case SID_NOTESMODE:
     592           0 :                     sRequestedView = FrameworkHelper::msNotesViewURL;
     593           0 :                 break;
     594             : 
     595             :                 case SID_HANDOUTMODE:
     596           0 :                     sRequestedView = FrameworkHelper::msHandoutViewURL;
     597           0 :                     break;
     598             : 
     599             :                 case SID_SLIDE_SORTER_MULTI_PANE_GUI:
     600             :                 case SID_DIAMODE:
     601           0 :                     sRequestedView = FrameworkHelper::msSlideSorterURL;
     602           0 :                     break;
     603             : 
     604             :                 case SID_OUTLINEMODE:
     605           0 :                     sRequestedView = FrameworkHelper::msOutlineViewURL;
     606           0 :                     break;
     607             :             }
     608             :         }
     609             : 
     610           0 :         if (xView.is()
     611           0 :             && xView->getResourceId()->getResourceURL().equals(sRequestedView))
     612             :         {
     613             :             // We do not have to switch the view shell but maybe the edit mode
     614             :             // has changed.
     615             :             DrawViewShell* pDrawViewShell
     616           0 :                 = dynamic_cast<DrawViewShell*>(pCenterViewShell.get());
     617           0 :             if (pDrawViewShell != NULL)
     618             :             {
     619           0 :                 pCenterViewShell->Broadcast (
     620           0 :                     ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_START));
     621             : 
     622             :                 pDrawViewShell->ChangeEditMode (
     623           0 :                     EM_PAGE, pDrawViewShell->IsLayerModeActive());
     624             : 
     625           0 :                 pCenterViewShell->Broadcast (
     626           0 :                     ViewShellHint(ViewShellHint::HINT_CHANGE_EDIT_MODE_END));
     627             :             }
     628             :         }
     629             :         else
     630             :         {
     631           0 :             mxConfigurationController->requestResourceActivation(
     632             :                 CreateResourceId(sRequestedView, msCenterPaneURL),
     633           0 :                 ResourceActivationMode_REPLACE);
     634           0 :         }
     635             :     }
     636           0 :     catch (RuntimeException&)
     637             :     {
     638             :         DBG_UNHANDLED_EXCEPTION();
     639             :     }
     640             : }
     641             : 
     642           0 : void FrameworkHelper::RunOnConfigurationEvent(
     643             :     const OUString& rsEventType,
     644             :     const Callback& rCallback)
     645             : {
     646             :     RunOnEvent(
     647             :         rsEventType,
     648             :         FrameworkHelperAllPassFilter(),
     649           0 :         rCallback);
     650           0 : }
     651             : 
     652           0 : void FrameworkHelper::RunOnResourceActivation(
     653             :     const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId,
     654             :     const Callback& rCallback)
     655             : {
     656           0 :     if (mxConfigurationController.is()
     657           0 :         && mxConfigurationController->getResource(rxResourceId).is())
     658             :     {
     659           0 :         rCallback(false);
     660             :     }
     661             :     else
     662             :     {
     663             :         RunOnEvent(
     664             :             msResourceActivationEvent,
     665             :             FrameworkHelperResourceIdFilter(rxResourceId),
     666           0 :             rCallback);
     667             :     }
     668           0 : }
     669             : 
     670             : /** A callback that sets a flag to a specified value when the callback is
     671             :     called.
     672             : */
     673             : class FlagUpdater
     674             : {
     675             : public:
     676           0 :     FlagUpdater (bool& rFlag) : mrFlag(rFlag) {}
     677           0 :     void operator() (bool) const {mrFlag = true;}
     678             : private:
     679             :     bool& mrFlag;
     680             : };
     681             : 
     682           0 : void FrameworkHelper::RequestSynchronousUpdate (void)
     683             : {
     684             :     rtl::Reference<ConfigurationController> pCC (
     685           0 :         dynamic_cast<ConfigurationController*>(mxConfigurationController.get()));
     686           0 :     if (pCC.is())
     687           0 :         pCC->RequestSynchronousUpdate();
     688           0 : }
     689             : 
     690           0 : void FrameworkHelper::WaitForEvent (const OUString& rsEventType) const
     691             : {
     692           0 :     bool bConfigurationUpdateSeen (false);
     693             : 
     694             :     RunOnEvent(
     695             :         rsEventType,
     696             :         FrameworkHelperAllPassFilter(),
     697           0 :         FlagUpdater(bConfigurationUpdateSeen));
     698             : 
     699           0 :     sal_uInt32 nStartTime = osl_getGlobalTimer();
     700           0 :     while ( ! bConfigurationUpdateSeen)
     701             :     {
     702           0 :         Application::Reschedule();
     703             : 
     704           0 :         if( (osl_getGlobalTimer() - nStartTime) > 60000  )
     705             :         {
     706             :             OSL_FAIL("FrameworkHelper::WaitForEvent(), no event for a minute? giving up!");
     707           0 :             break;
     708             :         }
     709             :     }
     710           0 : }
     711             : 
     712           0 : void FrameworkHelper::WaitForUpdate (void) const
     713             : {
     714           0 :     WaitForEvent(msConfigurationUpdateEndEvent);
     715           0 : }
     716             : 
     717           0 : void FrameworkHelper::RunOnEvent(
     718             :     const OUString& rsEventType,
     719             :     const ConfigurationChangeEventFilter& rFilter,
     720             :     const Callback& rCallback) const
     721             : {
     722           0 :     new CallbackCaller(mrBase,rsEventType,rFilter,rCallback);
     723           0 : }
     724             : 
     725         212 : void FrameworkHelper::disposing (const lang::EventObject& rEventObject)
     726             : {
     727         212 :     if (rEventObject.Source == mxConfigurationController)
     728         212 :         mxConfigurationController = NULL;
     729         212 : }
     730             : 
     731         504 : void FrameworkHelper::UpdateConfiguration (void)
     732             : {
     733         504 :     if (mxConfigurationController.is())
     734             :     {
     735             :         try
     736             :         {
     737         252 :             if (mxConfigurationController.is())
     738         252 :                 mxConfigurationController->update();
     739             :         }
     740           0 :         catch (lang::DisposedException&)
     741             :         {
     742           0 :             Dispose();
     743             :         }
     744           0 :         catch (RuntimeException&)
     745             :         {
     746             :             DBG_UNHANDLED_EXCEPTION();
     747             :         }
     748             :     }
     749         504 : }
     750             : 
     751           0 : OUString FrameworkHelper::ResourceIdToString (const Reference<XResourceId>& rxResourceId)
     752             : {
     753           0 :     OUString sString;
     754           0 :     if (rxResourceId.is())
     755             :     {
     756           0 :         sString += rxResourceId->getResourceURL();
     757           0 :         if (rxResourceId->hasAnchor())
     758             :         {
     759           0 :             Sequence<OUString> aAnchorURLs (rxResourceId->getAnchorURLs());
     760           0 :             for (sal_Int32 nIndex=0; nIndex < aAnchorURLs.getLength(); ++nIndex)
     761             :             {
     762           0 :                 sString += " | ";
     763           0 :                 sString += aAnchorURLs[nIndex];
     764           0 :             }
     765             :         }
     766             :     }
     767           0 :     return sString;
     768             : }
     769             : 
     770       11532 : Reference<XResourceId> FrameworkHelper::CreateResourceId (const OUString& rsResourceURL)
     771             : {
     772       11532 :     return new ::sd::framework::ResourceId(rsResourceURL);
     773             : }
     774             : 
     775         728 : Reference<XResourceId> FrameworkHelper::CreateResourceId (
     776             :     const OUString& rsResourceURL,
     777             :     const OUString& rsAnchorURL)
     778             : {
     779         728 :     return new ::sd::framework::ResourceId(rsResourceURL, rsAnchorURL);
     780             : }
     781             : 
     782         420 : Reference<XResourceId> FrameworkHelper::CreateResourceId (
     783             :     const OUString& rsResourceURL,
     784             :     const Reference<XResourceId>& rxAnchorId)
     785             : {
     786         420 :     if (rxAnchorId.is())
     787             :         return new ::sd::framework::ResourceId(
     788             :             rsResourceURL,
     789         420 :             rxAnchorId->getResourceURL(),
     790         420 :             rxAnchorId->getAnchorURLs());
     791             :     else
     792           0 :         return new ::sd::framework::ResourceId(rsResourceURL);
     793             : }
     794             : 
     795             : //----- FrameworkHelper::DisposeListener --------------------------------------
     796             : 
     797         212 : FrameworkHelper::DisposeListener::DisposeListener (
     798             :     const ::boost::shared_ptr<FrameworkHelper>& rpHelper)
     799             :     : FrameworkHelperDisposeListenerInterfaceBase(maMutex),
     800         212 :       mpHelper(rpHelper)
     801             : {
     802         212 :     Reference<XComponent> xComponent (mpHelper->mxConfigurationController, UNO_QUERY);
     803         212 :     if (xComponent.is())
     804         212 :         xComponent->addEventListener(this);
     805         212 : }
     806             : 
     807         424 : FrameworkHelper::DisposeListener::~DisposeListener (void)
     808             : {
     809         424 : }
     810             : 
     811         212 : void SAL_CALL FrameworkHelper::DisposeListener::disposing (void)
     812             : {
     813         212 :     Reference<XComponent> xComponent (mpHelper->mxConfigurationController, UNO_QUERY);
     814         212 :     if (xComponent.is())
     815           0 :         xComponent->removeEventListener(this);
     816             : 
     817         212 :     mpHelper.reset();
     818         212 : }
     819             : 
     820         212 : void SAL_CALL FrameworkHelper::DisposeListener::disposing (const lang::EventObject& rEventObject)
     821             :     throw(RuntimeException, std::exception)
     822             : {
     823         212 :     if (mpHelper.get() != NULL)
     824         212 :         mpHelper->disposing(rEventObject);
     825         212 : }
     826             : 
     827             : //===== FrameworkHelperResourceIdFilter =======================================
     828             : 
     829           0 : FrameworkHelperResourceIdFilter::FrameworkHelperResourceIdFilter (
     830             :     const Reference<XResourceId>& rxResourceId)
     831           0 :     : mxResourceId(rxResourceId)
     832             : {
     833           0 : }
     834             : 
     835             : } } // end of namespace sd::framework
     836             : 
     837             : namespace {
     838             : 
     839             : //===== CallbackCaller ========================================================
     840             : 
     841           0 : CallbackCaller::CallbackCaller (
     842             :     ::sd::ViewShellBase& rBase,
     843             :     const OUString& rsEventType,
     844             :     const ::sd::framework::FrameworkHelper::ConfigurationChangeEventFilter& rFilter,
     845             :     const ::sd::framework::FrameworkHelper::Callback& rCallback)
     846             :     : CallbackCallerInterfaceBase(MutexOwner::maMutex),
     847             :       msEventType(rsEventType),
     848             :       mxConfigurationController(),
     849             :       maFilter(rFilter),
     850           0 :       maCallback(rCallback)
     851             : {
     852             :     try
     853             :     {
     854           0 :         Reference<XControllerManager> xControllerManager (rBase.GetController(), UNO_QUERY_THROW);
     855           0 :         mxConfigurationController = xControllerManager->getConfigurationController();
     856           0 :         if (mxConfigurationController.is())
     857             :         {
     858           0 :             if (mxConfigurationController->hasPendingRequests())
     859           0 :                 mxConfigurationController->addConfigurationChangeListener(this,msEventType,Any());
     860             :             else
     861             :             {
     862             :                 // There are no requests waiting to be processed.  Therefore
     863             :                 // no event, especially not the one we are waiting for, will
     864             :                 // be sent in the near future and the callback would never be
     865             :                 // called.
     866             :                 // Call the callback now and tell him that the event it is
     867             :                 // waiting for was not sent.
     868           0 :                 mxConfigurationController = NULL;
     869           0 :                 maCallback(false);
     870             :             }
     871           0 :         }
     872             :     }
     873           0 :     catch (RuntimeException&)
     874             :     {
     875             :         DBG_UNHANDLED_EXCEPTION();
     876             :     }
     877           0 : }
     878             : 
     879           0 : CallbackCaller::~CallbackCaller (void)
     880             : {
     881           0 : }
     882             : 
     883           0 : void CallbackCaller::disposing (void)
     884             : {
     885             :     try
     886             :     {
     887           0 :         if (mxConfigurationController.is())
     888             :         {
     889           0 :             Reference<XConfigurationController> xCC (mxConfigurationController);
     890           0 :             mxConfigurationController = NULL;
     891           0 :             xCC->removeConfigurationChangeListener(this);
     892             :         }
     893             :     }
     894           0 :     catch (RuntimeException&)
     895             :     {
     896             :         DBG_UNHANDLED_EXCEPTION();
     897             :     }
     898           0 : }
     899             : 
     900           0 : void SAL_CALL CallbackCaller::disposing (const lang::EventObject& rEvent)
     901             :     throw (RuntimeException, std::exception)
     902             : {
     903           0 :     if (rEvent.Source == mxConfigurationController)
     904             :     {
     905           0 :         mxConfigurationController = NULL;
     906           0 :         maCallback(false);
     907             :     }
     908           0 : }
     909             : 
     910           0 : void SAL_CALL CallbackCaller::notifyConfigurationChange (
     911             :     const ConfigurationChangeEvent& rEvent)
     912             :     throw (RuntimeException, std::exception)
     913             : {
     914           0 :     if (rEvent.Type.equals(msEventType) && maFilter(rEvent))
     915             :     {
     916           0 :         maCallback(true);
     917           0 :         if (mxConfigurationController.is())
     918             :         {
     919             :             // Reset the reference to the configuration controller so that
     920             :             // dispose() will not try to remove the listener a second time.
     921           0 :             Reference<XConfigurationController> xCC (mxConfigurationController);
     922           0 :             mxConfigurationController = NULL;
     923             : 
     924             :             // Removing this object from the controller may very likely lead
     925             :             // to its destruction, so no calls after that.
     926           0 :             xCC->removeConfigurationChangeListener(this);
     927             :         }
     928             :     }
     929           0 : }
     930             : 
     931             : //----- LifetimeController -------------------------------------------------
     932             : 
     933         212 : LifetimeController::LifetimeController (::sd::ViewShellBase& rBase)
     934             :     : LifetimeControllerInterfaceBase(maMutex),
     935             :       mrBase(rBase),
     936             :       mbListeningToViewShellBase(false),
     937         212 :       mbListeningToController(false)
     938             : {
     939             :     // Register as listener at the ViewShellBase.  Because that is not done
     940             :     // via a reference we have to increase the reference count manually.
     941             :     // This is necessary even though listening to the XController did
     942             :     // increase the reference count because the controller may release its
     943             :     // reference to us before the ViewShellBase is destroyed.
     944         212 :     StartListening(mrBase);
     945         212 :     acquire();
     946         212 :     mbListeningToViewShellBase = true;
     947             : 
     948         212 :     Reference<XComponent> xComponent (rBase.GetController(), UNO_QUERY);
     949         212 :     if (xComponent.is())
     950             :     {
     951         212 :         xComponent->addEventListener(this);
     952         212 :         mbListeningToController = true;
     953         212 :     }
     954         212 : }
     955             : 
     956         424 : LifetimeController::~LifetimeController (void)
     957             : {
     958             :     OSL_ASSERT(!mbListeningToController && !mbListeningToViewShellBase);
     959         424 : }
     960             : 
     961         212 : void LifetimeController::disposing (void)
     962             : {
     963         212 : }
     964             : 
     965         212 : void SAL_CALL LifetimeController::disposing (const lang::EventObject& rEvent)
     966             :     throw(RuntimeException, std::exception)
     967             : {
     968             :     (void)rEvent;
     969         212 :     mbListeningToController = false;
     970         212 :     Update();
     971         212 : }
     972             : 
     973         212 : void LifetimeController::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
     974             : {
     975             :     (void)rBroadcaster;
     976         212 :     const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
     977         212 :     if (pSimpleHint != NULL && pSimpleHint->GetId() == SFX_HINT_DYING)
     978             :     {
     979         212 :         mbListeningToViewShellBase = false;
     980         212 :         Update();
     981         212 :         release();
     982             :     }
     983         212 : }
     984             : 
     985         424 : void LifetimeController::Update (void)
     986             : {
     987         424 :     if (mbListeningToViewShellBase && mbListeningToController)
     988             :     {
     989             :         // Both the controller and the ViewShellBase are alive.  Keep
     990             :         // waiting for their destruction.
     991             :     }
     992         424 :     else if (mbListeningToViewShellBase)
     993             :     {
     994             :         // The controller has been destroyed but the ViewShellBase is still
     995             :         // alive.  Dispose the associated FrameworkHelper but keep it around
     996             :         // so that no new instance is created for the dying framework.
     997         212 :         ::sd::framework::FrameworkHelper::DisposeInstance(mrBase);
     998             :     }
     999             :     else
    1000             :     {
    1001             :         // Both the controller and the ViewShellBase have been destroyed.
    1002             :         // Remove the FrameworkHelper so that the next call its Instance()
    1003             :         // method can create a new instance.
    1004         212 :         ::sd::framework::FrameworkHelper::ReleaseInstance(mrBase);
    1005             :     }
    1006         424 : }
    1007             : 
    1008         114 : } // end of anonymous namespace.
    1009             : 
    1010             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10