LCOV - code coverage report
Current view: top level - sd/source/ui/view - FormShellManager.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 90 115 78.3 %
Date: 2015-06-13 12:38:46 Functions: 18 20 90.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 "FormShellManager.hxx"
      21             : 
      22             : #include "EventMultiplexer.hxx"
      23             : #include "ViewShell.hxx"
      24             : #include "ViewShellBase.hxx"
      25             : #include "ViewShellManager.hxx"
      26             : #include "Window.hxx"
      27             : #include <svx/fmshell.hxx>
      28             : 
      29             : namespace sd {
      30             : 
      31             : namespace {
      32             : 
      33             : /** This factory is responsible for creating and deleting the FmFormShell.
      34             : */
      35         266 : class FormShellManagerFactory
      36             :     : public ::sd::ShellFactory<SfxShell>
      37             : {
      38             : public:
      39             :     FormShellManagerFactory (ViewShell& rViewShell, FormShellManager& rManager);
      40             :     virtual FmFormShell* CreateShell (ShellId nId, vcl::Window* pParentWindow, FrameView* pFrameView) SAL_OVERRIDE;
      41             :     virtual void ReleaseShell (SfxShell* pShell) SAL_OVERRIDE;
      42             : 
      43             : private:
      44             :     ::sd::ViewShell& mrViewShell;
      45             :     FormShellManager& mrFormShellManager;
      46             : };
      47             : 
      48             : } // end of anonymous namespace
      49             : 
      50         127 : FormShellManager::FormShellManager (ViewShellBase& rBase)
      51             :     : mrBase(rBase),
      52             :       mpFormShell(NULL),
      53             :       mbFormShellAboveViewShell(false),
      54             :       mpSubShellFactory(),
      55             :       mbIsMainViewChangePending(false),
      56         127 :       mpMainViewShellWindow(NULL)
      57             : {
      58             :     // Register at the EventMultiplexer to be informed about changes in the
      59             :     // center pane.
      60         127 :     Link<> aLink (LINK(this, FormShellManager, ConfigurationUpdateHandler));
      61             :     mrBase.GetEventMultiplexer()->AddEventListener(
      62             :         aLink,
      63             :         sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
      64             :         | sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
      65         127 :         | sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
      66             : 
      67         127 :     RegisterAtCenterPane();
      68         127 : }
      69             : 
      70         381 : FormShellManager::~FormShellManager()
      71             : {
      72         127 :     SetFormShell(NULL);
      73         127 :     UnregisterAtCenterPane();
      74             : 
      75             :     // Unregister from the EventMultiplexer.
      76         127 :     Link<> aLink (LINK(this, FormShellManager, ConfigurationUpdateHandler));
      77         127 :     mrBase.GetEventMultiplexer()->RemoveEventListener(aLink);
      78             : 
      79         127 :     if (mpSubShellFactory.get() != NULL)
      80             :     {
      81           0 :         ViewShell* pShell = mrBase.GetMainViewShell().get();
      82           0 :         if (pShell != NULL)
      83           0 :             mrBase.GetViewShellManager()->RemoveSubShellFactory(pShell,mpSubShellFactory);
      84             :     }
      85         254 : }
      86             : 
      87         653 : void FormShellManager::SetFormShell (FmFormShell* pFormShell)
      88             : {
      89         653 :     if (mpFormShell != pFormShell)
      90             :     {
      91             :         // Disconnect from the old form shell.
      92         266 :         if (mpFormShell != NULL)
      93             :         {
      94         133 :             mpFormShell->SetControlActivationHandler(Link<>());
      95         133 :             EndListening(*mpFormShell);
      96         133 :             mpFormShell->SetView(NULL);
      97             :         }
      98             : 
      99         266 :         mpFormShell = pFormShell;
     100             : 
     101             :         // Connect to the new form shell.
     102         266 :         if (mpFormShell != NULL)
     103             :         {
     104             :             mpFormShell->SetControlActivationHandler(
     105             :                 LINK(
     106             :                     this,
     107             :                     FormShellManager,
     108         133 :                     FormControlActivated));
     109         133 :             StartListening(*mpFormShell);
     110             : 
     111         133 :             ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
     112         133 :             if (pMainViewShell != NULL)
     113             :             {
     114             :                 // Prevent setting the view twice at the FmFormShell.
     115         133 :                 FmFormView* pFormView = static_cast<FmFormView*>(pMainViewShell->GetView());
     116         133 :                 if (mpFormShell->GetFormView() != pFormView)
     117           0 :                     mpFormShell->SetView(pFormView);
     118             :             }
     119             :         }
     120             : 
     121             :         // Tell the ViewShellManager where on the stack to place the form shell.
     122             :         mrBase.GetViewShellManager()->SetFormShell(
     123         532 :             mrBase.GetMainViewShell().get(),
     124             :             mpFormShell,
     125         532 :             mbFormShellAboveViewShell);
     126             :     }
     127         653 : }
     128             : 
     129         260 : void FormShellManager::RegisterAtCenterPane()
     130             : {
     131         260 :     ViewShell* pShell = mrBase.GetMainViewShell().get();
     132         260 :     if (pShell == NULL)
     133         127 :         return;
     134             : 
     135             :     // No form shell for the slide sorter.  Besides that it is not
     136             :     // necessary, using both together results in crashes.
     137         133 :     if (pShell->GetShellType() == ViewShell::ST_SLIDE_SORTER)
     138           0 :         return;
     139             : 
     140         133 :     mpMainViewShellWindow = pShell->GetActiveWindow();
     141         133 :     if (mpMainViewShellWindow == nullptr)
     142           0 :         return;
     143             : 
     144             :     // Register at the window to get informed when to move the form
     145             :     // shell to the bottom of the shell stack.
     146             :     mpMainViewShellWindow->AddEventListener(
     147             :         LINK(
     148             :             this,
     149             :             FormShellManager,
     150         133 :             WindowEventHandler));
     151             : 
     152             :     // Create a shell factory and with it activate the form shell.
     153             :     OSL_ASSERT(mpSubShellFactory.get()==NULL);
     154         133 :     mpSubShellFactory.reset(new FormShellManagerFactory(*pShell, *this));
     155         133 :     mrBase.GetViewShellManager()->AddSubShellFactory(pShell,mpSubShellFactory);
     156         133 :     mrBase.GetViewShellManager()->ActivateSubShell(*pShell, RID_FORMLAYER_TOOLBOX);
     157             : }
     158             : 
     159         260 : void FormShellManager::UnregisterAtCenterPane()
     160             : {
     161         260 :     if (mpMainViewShellWindow != nullptr)
     162             :     {
     163             :         // Unregister from the window.
     164             :         mpMainViewShellWindow->RemoveEventListener(
     165             :             LINK(
     166             :                 this,
     167             :                 FormShellManager,
     168         133 :                 WindowEventHandler));
     169         133 :         mpMainViewShellWindow = NULL;
     170             :     }
     171             : 
     172             :     // Unregister form at the form shell.
     173         260 :     SetFormShell(NULL);
     174             : 
     175             :     // Deactivate the form shell and destroy the shell factory.
     176         260 :     ViewShell* pShell = mrBase.GetMainViewShell().get();
     177         260 :     if (pShell != NULL)
     178             :     {
     179           0 :         mrBase.GetViewShellManager()->DeactivateSubShell(*pShell,  RID_FORMLAYER_TOOLBOX);
     180           0 :         mrBase.GetViewShellManager()->RemoveSubShellFactory(pShell, mpSubShellFactory);
     181             :     }
     182             : 
     183         260 :     mpSubShellFactory.reset();
     184         260 : }
     185             : 
     186           0 : IMPL_LINK_NOARG(FormShellManager, FormControlActivated)
     187             : {
     188             :     // The form shell has been activated.  To give it priority in reacting to
     189             :     // slot calls the form shell is moved to the top of the object bar shell
     190             :     // stack.
     191           0 :     ViewShell* pShell = mrBase.GetMainViewShell().get();
     192           0 :     if (pShell!=NULL && !mbFormShellAboveViewShell)
     193             :     {
     194           0 :         mbFormShellAboveViewShell = true;
     195             : 
     196           0 :         ViewShellManager::UpdateLock aLock (mrBase.GetViewShellManager());
     197           0 :         mrBase.GetViewShellManager()->SetFormShell(pShell,mpFormShell,mbFormShellAboveViewShell);
     198             :     }
     199             : 
     200           0 :     return 0;
     201             : }
     202             : 
     203       14500 : IMPL_LINK(FormShellManager, ConfigurationUpdateHandler, sd::tools::EventMultiplexerEvent*, pEvent)
     204             : {
     205        7250 :     switch (pEvent->meEventId)
     206             :     {
     207             :         case sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
     208         133 :             UnregisterAtCenterPane();
     209         133 :             break;
     210             : 
     211             :         case sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
     212         133 :             mbIsMainViewChangePending = true;
     213         133 :             break;
     214             : 
     215             :         case sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
     216         355 :             if (mbIsMainViewChangePending)
     217             :             {
     218         133 :                 mbIsMainViewChangePending = false;
     219         133 :                 RegisterAtCenterPane();
     220             :             }
     221         355 :             break;
     222             : 
     223             :         default:
     224        6629 :             break;
     225             :     }
     226             : 
     227        7250 :     return 0;
     228             : }
     229             : 
     230        1736 : IMPL_LINK(FormShellManager, WindowEventHandler, VclWindowEvent*, pEvent)
     231             : {
     232         868 :     if (pEvent != NULL)
     233             :     {
     234         868 :         switch (pEvent->GetId())
     235             :         {
     236             :             case VCLEVENT_WINDOW_GETFOCUS:
     237             :             {
     238             :                 // The window of the center pane got the focus.  Therefore
     239             :                 // the form shell is moved to the bottom of the object bar
     240             :                 // stack.
     241          83 :                 ViewShell* pShell = mrBase.GetMainViewShell().get();
     242          83 :                 if (pShell!=NULL && mbFormShellAboveViewShell)
     243             :                 {
     244           0 :                     mbFormShellAboveViewShell = false;
     245           0 :                     ViewShellManager::UpdateLock aLock (mrBase.GetViewShellManager());
     246             :                     mrBase.GetViewShellManager()->SetFormShell(
     247             :                         pShell,
     248             :                         mpFormShell,
     249           0 :                         mbFormShellAboveViewShell);
     250             :                 }
     251             :             }
     252          83 :             break;
     253             : 
     254             :             case VCLEVENT_WINDOW_LOSEFOCUS:
     255             :                 // We follow the sloppy focus policy.  Losing the focus is
     256             :                 // ignored.  We wait for the focus to be placed either in
     257             :                 // the window or the form shell.  The later, however, is
     258             :                 // notified over the FormControlActivated handler, not this
     259             :                 // one.
     260           0 :                 break;
     261             : 
     262             :             case VCLEVENT_OBJECT_DYING:
     263           0 :                 mpMainViewShellWindow = NULL;
     264           0 :                 break;
     265             :         }
     266             :     }
     267             : 
     268         868 :     return 0;
     269             : }
     270             : 
     271          16 : void FormShellManager::Notify(SfxBroadcaster&, const SfxHint& rHint)
     272             : {
     273          16 :     const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
     274          16 :     if (pSimpleHint!=NULL && pSimpleHint->GetId()==SFX_HINT_DYING)
     275             :     {
     276             :         // If all goes well this listener is called after the
     277             :         // FormShellManager was notified about the dying form shell by the
     278             :         // FormShellManagerFactory.
     279             :         OSL_ASSERT(mpFormShell==NULL);
     280           0 :         if (mpFormShell != NULL)
     281             :         {
     282           0 :             mpFormShell = NULL;
     283             :             mrBase.GetViewShellManager()->SetFormShell(
     284           0 :                 mrBase.GetMainViewShell().get(),
     285             :                 NULL,
     286           0 :                 false);
     287             :         }
     288             :     }
     289          16 : }
     290             : 
     291             : //===== FormShellManagerFactory ===============================================
     292             : 
     293             : namespace {
     294             : 
     295         133 : FormShellManagerFactory::FormShellManagerFactory (
     296             :     ::sd::ViewShell& rViewShell,
     297             :     FormShellManager& rManager)
     298             :     : mrViewShell(rViewShell),
     299         133 :       mrFormShellManager(rManager)
     300             : {
     301         133 : }
     302             : 
     303         136 : FmFormShell* FormShellManagerFactory::CreateShell (
     304             :     ::sd::ShellId nId,
     305             :     vcl::Window*,
     306             :     ::sd::FrameView*)
     307             : {
     308         136 :     FmFormShell* pShell = NULL;
     309             : 
     310         136 :     ::sd::View* pView = mrViewShell.GetView();
     311         136 :     if (nId == RID_FORMLAYER_TOOLBOX)
     312             :     {
     313         133 :         pShell = new FmFormShell(&mrViewShell.GetViewShellBase(), pView);
     314         133 :         mrFormShellManager.SetFormShell(pShell);
     315             :     }
     316             : 
     317         136 :     return pShell;
     318             : }
     319             : 
     320         133 : void FormShellManagerFactory::ReleaseShell (SfxShell* pShell)
     321             : {
     322         133 :     if (pShell != NULL)
     323             :     {
     324         133 :         mrFormShellManager.SetFormShell(NULL);
     325         133 :         delete pShell;
     326             :     }
     327         133 : }
     328             : 
     329             : } // end of anonymous namespace
     330             : 
     331          66 : } // end of namespace sd
     332             : 
     333             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11