LCOV - code coverage report
Current view: top level - sd/source/ui/view - ViewShellManager.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 465 0.0 %
Date: 2014-04-14 Functions: 0 61 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "ViewShellManager.hxx"
      22             : #include "ViewShell.hxx"
      23             : #include "ViewShellBase.hxx"
      24             : #include "Window.hxx"
      25             : #include "DrawDocShell.hxx"
      26             : #include "FormShellManager.hxx"
      27             : 
      28             : #include <sfx2/dispatch.hxx>
      29             : #include <svx/svxids.hrc>
      30             : #include <svx/fmshell.hxx>
      31             : 
      32             : #include <boost/unordered_map.hpp>
      33             : #include <iterator>
      34             : 
      35             : namespace sd {
      36             : 
      37             : namespace {
      38             : 
      39             : /** The ShellDescriptor class is used to shells together with their ids and
      40             :     the factory that was used to create the shell.
      41             : 
      42             :     The shell pointer may be NULL.  In that case the shell is created on
      43             :     demand by a factory.
      44             : 
      45             :     The factory pointer may be NULL.  In that case the shell pointer is
      46             :     given to the ViewShellManager.
      47             : 
      48             :     Shell pointer and factory pointer can but should not be NULL at the same
      49             :     time.
      50             : */
      51           0 : class ShellDescriptor {
      52             : public:
      53             :     SfxShell* mpShell;
      54             :     ShellId mnId;
      55             :     ViewShellManager::SharedShellFactory mpFactory;
      56             :     bool mbIsListenerAddedToWindow;
      57             : 
      58             :     ShellDescriptor ();
      59             :     ShellDescriptor (SfxShell* pShell, ShellId nId);
      60             :     ShellDescriptor (const ShellDescriptor& rDescriptor);
      61             :     ShellDescriptor& operator= (const ShellDescriptor& rDescriptor);
      62             :     bool IsMainViewShell (void) const;
      63             :     ::Window* GetWindow (void) const;
      64             : };
      65             : 
      66             : 
      67             : 
      68             : 
      69             : /** This functor can be used to search for a shell in an STL container when the
      70             :     shell pointer is given.
      71             : */
      72             : class IsShell : public ::std::unary_function<ShellDescriptor,bool>
      73             : {
      74             : public:
      75           0 :     IsShell (const SfxShell* pShell) : mpShell(pShell) {}
      76           0 :     bool operator() (const ShellDescriptor& rDescriptor)
      77           0 :     { return rDescriptor.mpShell == mpShell; }
      78             : private:
      79             :     const SfxShell* mpShell;
      80             : };
      81             : 
      82             : 
      83             : 
      84             : 
      85             : /** This functor can be used to search for a shell in an STL container when the
      86             :     id of the shell is given.
      87             : */
      88             : class IsId : public ::std::unary_function<ShellDescriptor,bool>
      89             : {
      90             : public:
      91           0 :     IsId (ShellId nId) : mnId(nId) {}
      92           0 :     bool operator() (const ShellDescriptor& rDescriptor)
      93           0 :     { return rDescriptor.mnId == mnId; }
      94             : private:
      95             :     ShellId mnId;
      96             : };
      97             : 
      98             : } // end of anonymous namespace
      99             : 
     100             : 
     101             : 
     102             : 
     103             : class ViewShellManager::Implementation
     104             : {
     105             : public:
     106             :     Implementation (
     107             :         ViewShellManager& rManager,
     108             :         ViewShellBase& rBase);
     109             :     ~Implementation (void);
     110             : 
     111             :     void AddShellFactory (
     112             :         const SfxShell* pViewShell,
     113             :         const SharedShellFactory& rpFactory);
     114             :     void RemoveShellFactory (
     115             :         const SfxShell* pViewShell,
     116             :         const SharedShellFactory& rpFactory);
     117             :     void ActivateViewShell (
     118             :         ViewShell* pViewShell);
     119             :     void DeactivateViewShell (const ViewShell& rShell);
     120             :     void ActivateShell (SfxShell& rShell);
     121             :     void DeactivateShell (const SfxShell& rShell);
     122             :     void ActivateShell (const ShellDescriptor& rDescriptor);
     123             :     void SetFormShell (const ViewShell* pViewShell, FmFormShell* pFormShell, bool bAbove);
     124             :     void ActivateSubShell (const SfxShell& rParentShell, ShellId nId);
     125             :     void DeactivateSubShell (const SfxShell& rParentShell, ShellId nId);
     126             :     void MoveToTop (const SfxShell& rParentShell);
     127             :     SfxShell* GetShell (ShellId nId) const;
     128             :     SfxShell* GetTopShell (void) const;
     129             :     void Shutdown (void);
     130             :     void InvalidateAllSubShells (const SfxShell* pParentShell);
     131             : 
     132             :     /** Remove all shells from the SFX stack above and including the given
     133             :         shell.
     134             :     */
     135             :     void TakeShellsFromStack (const SfxShell* pShell);
     136             : 
     137             :     class UpdateLock
     138             :     {
     139             :     public:
     140           0 :         UpdateLock (Implementation& rImpl) : mrImpl(rImpl) {mrImpl.LockUpdate();}
     141           0 :         ~UpdateLock (void) {mrImpl.UnlockUpdate();};
     142             :     private:
     143             :         Implementation& mrImpl;
     144             :     };
     145             : 
     146             : 
     147             : 
     148             :     /** Prevent updates of the shell stack.  While the sub shell manager is
     149             :         locked it will update its internal data structures but not alter the
     150             :         shell stack.  Use this method when there are several modifications
     151             :         to the shell stack to prevent multiple rebuilds of the shell stack
     152             :         and resulting broadcasts.
     153             :     */
     154             :     void LockUpdate (void);
     155             : 
     156             :     /** Allow updates of the shell stack.  This method has to be called the
     157             :         same number of times as LockUpdate() to really allow a rebuild of
     158             :         the shell stack.
     159             :     */
     160             :     void UnlockUpdate (void);
     161             : 
     162             : private:
     163             :     ViewShellBase& mrBase;
     164             :     mutable ::osl::Mutex maMutex;
     165             : 
     166           0 :     class ShellHash{public: size_t operator()(const SfxShell* p) const { return (size_t)p;} };
     167             :     typedef ::boost::unordered_multimap<const SfxShell*,SharedShellFactory,ShellHash>
     168             :         FactoryList;
     169             :     FactoryList maShellFactories;
     170             : 
     171             :     /** List of the active view shells.  In order to create gather all shells
     172             :         to put on the shell stack each view shell in this list is asked for
     173             :         its sub-shells (typically toolbars).
     174             :     */
     175             :     typedef ::std::list<ShellDescriptor> ActiveShellList;
     176             :     ActiveShellList maActiveViewShells;
     177             : 
     178             :     typedef ::std::list<ShellDescriptor> SubShellSubList;
     179             :     typedef ::boost::unordered_map<const SfxShell*,SubShellSubList,ShellHash> SubShellList;
     180             :     SubShellList maActiveSubShells;
     181             : 
     182             :     /** In this member we remember what shells we have pushed on the shell
     183             :         stack.
     184             :     */
     185             :     typedef ::std::vector<SfxShell*> ShellStack;
     186             : 
     187             :     int mnUpdateLockCount;
     188             : 
     189             :     /** When this flag is set then the main view shell is always kept at the
     190             :         top of the shell stack.
     191             :     */
     192             :     bool mbKeepMainViewShellOnTop;
     193             : 
     194             :     /** The UpdateShellStack() method can be called recursively.  This flag
     195             :         is used to communicate between different levels of invocation: if
     196             :         the stack has been updated in an inner call the outer call can (has
     197             :         to) stop and return immediately.
     198             :     */
     199             :     bool mbShellStackIsUpToDate;
     200             : 
     201             :     SfxShell* mpFormShell;
     202             :     const ViewShell* mpFormShellParent;
     203             :     bool mbFormShellAboveParent;
     204             : 
     205             :     SfxShell* mpTopShell;
     206             : 
     207             :     void GatherActiveShells (ShellStack& rShellList);
     208             : 
     209             :     void UpdateShellStack (void);
     210             : 
     211             :     void CreateShells (void);
     212             : 
     213             :     /** This method rebuilds the stack of shells that are stacked upon the
     214             :         view shell base.
     215             :     */
     216             :     void CreateTargetStack (ShellStack& rStack) const;
     217             : 
     218             :     DECL_LINK(WindowEventHandler, VclWindowEvent*);
     219             : 
     220             : #if OSL_DEBUG_LEVEL >= 2
     221             :     void DumpShellStack (const ShellStack& rStack);
     222             :     void DumpSfxShellStack (void);
     223             : #endif
     224             : 
     225             :     /** To be called before a shell is taken fom the SFX shell stack.  This
     226             :         method deactivates an active text editing to avoid problems with
     227             :         undo managers.
     228             :         Afterwards the Deactivate() of the shell is called.
     229             :     */
     230             :     void Deactivate (SfxShell* pShell);
     231             : 
     232             :     ShellDescriptor CreateSubShell (
     233             :         SfxShell* pShell,
     234             :         ShellId nShellId,
     235             :         ::Window* pParentWindow,
     236             :         FrameView* pFrameView);
     237             :     void DestroyViewShell (ShellDescriptor& rDescriptor);
     238             :     void DestroySubShell (
     239             :         const SfxShell& rViewShell,
     240             :         const ShellDescriptor& rDescriptor);
     241             : };
     242             : 
     243             : 
     244             : 
     245             : 
     246             : //===== ViewShellManager ======================================================
     247             : 
     248           0 : ViewShellManager::ViewShellManager (ViewShellBase& rBase)
     249           0 :     : mpImpl(new Implementation(*this,rBase)),
     250           0 :       mbValid(true)
     251             : {
     252           0 : }
     253             : 
     254             : 
     255             : 
     256             : 
     257           0 : ViewShellManager::~ViewShellManager (void)
     258             : {
     259           0 : }
     260             : 
     261             : 
     262             : 
     263             : 
     264           0 : void ViewShellManager::AddSubShellFactory (
     265             :     ViewShell* pViewShell,
     266             :     const SharedShellFactory& rpFactory)
     267             : {
     268           0 :     if (mbValid)
     269           0 :         mpImpl->AddShellFactory(pViewShell, rpFactory);
     270           0 : }
     271             : 
     272             : 
     273             : 
     274             : 
     275           0 : void ViewShellManager::RemoveSubShellFactory (
     276             :     ViewShell* pViewShell,
     277             :     const SharedShellFactory& rpFactory)
     278             : {
     279           0 :     if (mbValid)
     280           0 :         mpImpl->RemoveShellFactory(pViewShell, rpFactory);
     281           0 : }
     282             : 
     283             : 
     284             : 
     285             : 
     286           0 : void ViewShellManager::ActivateViewShell (ViewShell* pViewShell)
     287             : {
     288           0 :     if (mbValid)
     289           0 :         return mpImpl->ActivateViewShell(pViewShell);
     290             : }
     291             : 
     292             : 
     293             : 
     294             : 
     295           0 : void ViewShellManager::DeactivateViewShell (const ViewShell* pShell)
     296             : {
     297           0 :     if (mbValid && pShell!=NULL)
     298           0 :         mpImpl->DeactivateViewShell(*pShell);
     299           0 : }
     300             : 
     301             : 
     302             : 
     303             : 
     304           0 : void ViewShellManager::SetFormShell (
     305             :     const ViewShell* pParentShell,
     306             :     FmFormShell* pFormShell,
     307             :     bool bAbove)
     308             : {
     309           0 :     if (mbValid)
     310           0 :         mpImpl->SetFormShell(pParentShell,pFormShell,bAbove);
     311           0 : }
     312             : 
     313             : 
     314             : 
     315             : 
     316           0 : void ViewShellManager::ActivateSubShell (const ViewShell& rViewShell, ShellId nId)
     317             : {
     318           0 :     if (mbValid)
     319           0 :         mpImpl->ActivateSubShell(rViewShell,nId);
     320           0 : }
     321             : 
     322             : 
     323             : 
     324             : 
     325           0 : void ViewShellManager::DeactivateSubShell (const ViewShell& rViewShell, ShellId nId)
     326             : {
     327           0 :     if (mbValid)
     328           0 :         mpImpl->DeactivateSubShell(rViewShell,nId);
     329           0 : }
     330             : 
     331             : 
     332             : 
     333             : 
     334           0 : void ViewShellManager::InvalidateAllSubShells (ViewShell* pViewShell)
     335             : {
     336           0 :     if (mbValid)
     337           0 :         mpImpl->InvalidateAllSubShells(pViewShell);
     338           0 : }
     339             : 
     340             : 
     341             : 
     342             : 
     343           0 : void ViewShellManager::ActivateShell (SfxShell* pShell)
     344             : {
     345           0 :     if (mbValid && pShell!=NULL)
     346           0 :         mpImpl->ActivateShell(*pShell);
     347           0 : }
     348             : 
     349             : 
     350             : 
     351             : 
     352           0 : void ViewShellManager::DeactivateShell (const SfxShell* pShell)
     353             : {
     354           0 :     if (mbValid && pShell!=NULL)
     355           0 :         mpImpl->DeactivateShell(*pShell);
     356           0 : }
     357             : 
     358             : 
     359             : 
     360             : 
     361           0 : void ViewShellManager::MoveToTop (const ViewShell& rParentShell)
     362             : {
     363           0 :     if (mbValid)
     364           0 :         mpImpl->MoveToTop(rParentShell);
     365           0 : }
     366             : 
     367             : 
     368             : 
     369             : 
     370           0 : SfxShell* ViewShellManager::GetShell (ShellId nId) const
     371             : {
     372           0 :     if (mbValid)
     373           0 :         return mpImpl->GetShell(nId);
     374             :     else
     375           0 :         return NULL;
     376             : }
     377             : 
     378             : 
     379             : 
     380             : 
     381           0 : SfxShell* ViewShellManager::GetTopShell (void) const
     382             : {
     383           0 :     if (mbValid)
     384           0 :         return mpImpl->GetTopShell();
     385             :     else
     386           0 :         return NULL;
     387             : }
     388             : 
     389             : 
     390             : 
     391             : 
     392           0 : void ViewShellManager::Shutdown (void)
     393             : {
     394           0 :     if (mbValid)
     395             :     {
     396           0 :         mpImpl->Shutdown();
     397           0 :         mbValid = false;
     398             :     }
     399           0 : }
     400             : 
     401             : 
     402             : 
     403           0 : void ViewShellManager::LockUpdate (void)
     404             : {
     405           0 :     mpImpl->LockUpdate();
     406           0 : }
     407             : 
     408             : 
     409             : 
     410             : 
     411           0 : void ViewShellManager::UnlockUpdate (void)
     412             : {
     413           0 :     mpImpl->UnlockUpdate();
     414           0 : }
     415             : 
     416             : 
     417             : 
     418             : 
     419             : //===== ViewShellManager::Implementation ======================================
     420             : 
     421           0 : ViewShellManager::Implementation::Implementation (
     422             :     ViewShellManager& rManager,
     423             :     ViewShellBase& rBase)
     424             :     : mrBase(rBase),
     425             :       maMutex(),
     426             :       maShellFactories(),
     427             :       maActiveViewShells(),
     428             :       mnUpdateLockCount(0),
     429             :       mbKeepMainViewShellOnTop(false),
     430             :       mbShellStackIsUpToDate(true),
     431             :       mpFormShell(NULL),
     432             :       mpFormShellParent(NULL),
     433             :       mbFormShellAboveParent(true),
     434           0 :       mpTopShell(NULL)
     435             : {
     436             :     (void)rManager;
     437           0 : }
     438             : 
     439             : 
     440             : 
     441             : 
     442           0 : ViewShellManager::Implementation::~Implementation (void)
     443             : {
     444           0 :     Shutdown();
     445           0 : }
     446             : 
     447             : 
     448             : 
     449             : 
     450           0 : void ViewShellManager::Implementation::AddShellFactory (
     451             :     const SfxShell* pViewShell,
     452             :     const SharedShellFactory& rpFactory)
     453             : {
     454           0 :     bool bAlreadyAdded (false);
     455             : 
     456             :     // Check that the given factory has not already been added.
     457             :     ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
     458           0 :         maShellFactories.equal_range(pViewShell));
     459           0 :     for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
     460           0 :         if (iFactory->second == rpFactory)
     461             :         {
     462           0 :             bAlreadyAdded = true;
     463           0 :             break;
     464             :         }
     465             : 
     466             :     // Add the factory if it is not already present.
     467           0 :     if ( ! bAlreadyAdded)
     468           0 :         maShellFactories.insert(FactoryList::value_type(pViewShell, rpFactory));
     469           0 : }
     470             : 
     471             : 
     472             : 
     473             : 
     474           0 : void ViewShellManager::Implementation::RemoveShellFactory (
     475             :     const SfxShell* pViewShell,
     476             :     const SharedShellFactory& rpFactory)
     477             : {
     478             :     ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
     479           0 :         maShellFactories.equal_range(pViewShell));
     480           0 :     for (FactoryList::iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
     481           0 :         if (iFactory->second == rpFactory)
     482             :         {
     483           0 :             maShellFactories.erase(iFactory);
     484           0 :             break;
     485             :         }
     486           0 : }
     487             : 
     488             : 
     489             : 
     490             : 
     491           0 : void ViewShellManager::Implementation::ActivateViewShell (ViewShell* pViewShell)
     492             : {
     493           0 :     ::osl::MutexGuard aGuard (maMutex);
     494             : 
     495           0 :     ShellDescriptor aResult;
     496           0 :     aResult.mpShell = pViewShell;
     497             : 
     498             :     // Register as window listener so that the shells of the current
     499             :     // window can be moved to the top of the shell stack.
     500           0 :     if (aResult.mpShell != NULL)
     501             :     {
     502           0 :         ::Window* pWindow = aResult.GetWindow();
     503           0 :         if (pWindow != NULL)
     504             :         {
     505             :             pWindow->AddEventListener(
     506           0 :                 LINK(this, ViewShellManager::Implementation, WindowEventHandler));
     507           0 :             aResult.mbIsListenerAddedToWindow = true;
     508             :         }
     509             :         else
     510             :         {
     511             :             DBG_ASSERT(false,
     512             :                 "ViewShellManager::ActivateViewShell: "
     513             :                 "new view shell has no active window");
     514             :         }
     515             :     }
     516             : 
     517           0 :     ActivateShell(aResult);
     518           0 : }
     519             : 
     520             : 
     521             : 
     522             : 
     523           0 : void ViewShellManager::Implementation::DeactivateViewShell (const ViewShell& rShell)
     524             : {
     525           0 :     ::osl::MutexGuard aGuard (maMutex);
     526             : 
     527             :     ActiveShellList::iterator iShell (::std::find_if (
     528             :         maActiveViewShells.begin(),
     529             :         maActiveViewShells.end(),
     530           0 :         IsShell(&rShell)));
     531           0 :     if (iShell != maActiveViewShells.end())
     532             :     {
     533           0 :         UpdateLock aLocker (*this);
     534             : 
     535           0 :         ShellDescriptor aDescriptor(*iShell);
     536           0 :         mrBase.GetDocShell()->Disconnect(dynamic_cast<ViewShell*>(aDescriptor.mpShell));
     537           0 :         maActiveViewShells.erase(iShell);
     538           0 :         TakeShellsFromStack(aDescriptor.mpShell);
     539             : 
     540             :         // Deactivate sub shells.
     541           0 :         SubShellList::iterator iList (maActiveSubShells.find(&rShell));
     542           0 :         if (iList != maActiveSubShells.end())
     543             :         {
     544           0 :             SubShellSubList& rList (iList->second);
     545           0 :             while ( ! rList.empty())
     546           0 :                 DeactivateSubShell(rShell, rList.front().mnId);
     547             :         }
     548             : 
     549           0 :         DestroyViewShell(aDescriptor);
     550           0 :     }
     551           0 : }
     552             : 
     553             : 
     554             : 
     555             : 
     556           0 : void ViewShellManager::Implementation::ActivateShell (SfxShell& rShell)
     557             : {
     558           0 :     ::osl::MutexGuard aGuard (maMutex);
     559             : 
     560             :     // Create a new shell or recycle on in the cache.
     561           0 :     ShellDescriptor aDescriptor;
     562           0 :     aDescriptor.mpShell = &rShell;
     563             : 
     564           0 :     ActivateShell(aDescriptor);
     565           0 : }
     566             : 
     567             : 
     568             : 
     569             : 
     570           0 : void ViewShellManager::Implementation::ActivateShell (const ShellDescriptor& rDescriptor)
     571             : {
     572             :     // Put shell on top of the active view shells.
     573           0 :     if (rDescriptor.mpShell != NULL)
     574             :     {
     575             :         // Determine where to put the view shell on the stack.  By default
     576             :         // it is put on top of the stack.  When the view shell of the center
     577             :         // pane is to be kept top most and the new view shell is not
     578             :         // displayed in the center pane then it is inserted at the position
     579             :         // one below the top.
     580           0 :         ActiveShellList::iterator iInsertPosition (maActiveViewShells.begin());
     581           0 :         if (iInsertPosition != maActiveViewShells.end()
     582           0 :             && mbKeepMainViewShellOnTop
     583           0 :             && ! rDescriptor.IsMainViewShell()
     584           0 :             && iInsertPosition->IsMainViewShell())
     585             :         {
     586           0 :             ++iInsertPosition;
     587             :         }
     588             :         maActiveViewShells.insert(
     589             :             iInsertPosition,
     590           0 :             rDescriptor);
     591             :     }
     592           0 : }
     593             : 
     594             : 
     595             : 
     596             : 
     597           0 : void ViewShellManager::Implementation::DeactivateShell (const SfxShell& rShell)
     598             : {
     599           0 :     ::osl::MutexGuard aGuard (maMutex);
     600             : 
     601             :     ActiveShellList::iterator iShell (::std::find_if (
     602             :         maActiveViewShells.begin(),
     603             :         maActiveViewShells.end(),
     604           0 :         IsShell(&rShell)));
     605           0 :     if (iShell != maActiveViewShells.end())
     606             :     {
     607           0 :         UpdateLock aLocker (*this);
     608             : 
     609           0 :         ShellDescriptor aDescriptor(*iShell);
     610           0 :         mrBase.GetDocShell()->Disconnect(dynamic_cast<ViewShell*>(aDescriptor.mpShell));
     611           0 :         maActiveViewShells.erase(iShell);
     612           0 :         TakeShellsFromStack(aDescriptor.mpShell);
     613             : 
     614             :         // Deactivate sub shells.
     615           0 :         SubShellList::iterator iList (maActiveSubShells.find(&rShell));
     616           0 :         if (iList != maActiveSubShells.end())
     617             :         {
     618           0 :             SubShellSubList& rList (iList->second);
     619           0 :             while ( ! rList.empty())
     620           0 :                 DeactivateSubShell(rShell, rList.front().mnId);
     621             :         }
     622             : 
     623           0 :         DestroyViewShell(aDescriptor);
     624           0 :     }
     625           0 : }
     626             : 
     627             : 
     628             : 
     629             : 
     630           0 : void ViewShellManager::Implementation::ActivateSubShell (
     631             :     const SfxShell& rParentShell,
     632             :     ShellId nId)
     633             : {
     634           0 :     ::osl::MutexGuard aGuard (maMutex);
     635             : 
     636             :     // Check that the given view shell is active.
     637             :     ActiveShellList::iterator iShell (::std::find_if (
     638             :         maActiveViewShells.begin(),
     639             :         maActiveViewShells.end(),
     640           0 :         IsShell(&rParentShell)));
     641           0 :     if (iShell == maActiveViewShells.end())
     642           0 :         return;
     643             : 
     644             :     // Create the sub shell list if it does not yet exist.
     645           0 :     SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
     646           0 :     if (iList == maActiveSubShells.end())
     647             :         iList = maActiveSubShells.insert(
     648           0 :             SubShellList::value_type(&rParentShell,SubShellSubList())).first;
     649             : 
     650             :     // Do not activate an object bar that is already active.  Requesting
     651             :     // this is not exactly an error but may be an indication of one.
     652           0 :     SubShellSubList& rList (iList->second);
     653           0 :     if (::std::find_if(rList.begin(),rList.end(), IsId(nId)) != rList.end())
     654           0 :         return;
     655             : 
     656             :     // Add just the id of the sub shell. The actual shell is created
     657             :     // later in CreateShells().
     658           0 :     UpdateLock aLock (*this);
     659           0 :     rList.push_back(ShellDescriptor(NULL, nId));
     660             : }
     661             : 
     662             : 
     663             : 
     664             : 
     665           0 : void ViewShellManager::Implementation::DeactivateSubShell (
     666             :     const SfxShell& rParentShell,
     667             :     ShellId nId)
     668             : {
     669           0 :     ::osl::MutexGuard aGuard (maMutex);
     670             : 
     671             :     // Check that the given view shell is active.
     672           0 :     SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
     673           0 :     if (iList == maActiveSubShells.end())
     674           0 :         return;
     675             : 
     676             :     // Look up the sub shell.
     677           0 :     SubShellSubList& rList (iList->second);
     678             :     SubShellSubList::iterator iShell (
     679           0 :         ::std::find_if(rList.begin(),rList.end(), IsId(nId)));
     680           0 :     if (iShell == rList.end())
     681           0 :         return;
     682           0 :     SfxShell* pShell = iShell->mpShell;
     683           0 :     if (pShell == NULL)
     684           0 :         return;
     685             : 
     686           0 :     UpdateLock aLock (*this);
     687             : 
     688           0 :     ShellDescriptor aDescriptor(*iShell);
     689             :     // Remove the sub shell from both the internal structure as well as the
     690             :     // SFX shell stack above and including the sub shell.
     691           0 :     rList.erase(iShell);
     692           0 :     TakeShellsFromStack(pShell);
     693             : 
     694           0 :     DestroySubShell(rParentShell, aDescriptor);
     695             : }
     696             : 
     697             : 
     698             : 
     699             : 
     700           0 : void ViewShellManager::Implementation::MoveToTop (const SfxShell& rShell)
     701             : {
     702           0 :     ::osl::MutexGuard aGuard (maMutex);
     703             : 
     704             :     // Check that we have access to a dispatcher.  If not, then we are
     705             :     // (probably) called while the view shell is still being created or
     706             :     // initialized.  Without dispatcher we can not rebuild the shell stack
     707             :     // to move the requested shell to the top.  So return right away instead
     708             :     // of making a mess without being able to clean up afterwards.
     709           0 :     if (mrBase.GetDispatcher() == NULL)
     710           0 :         return;
     711             : 
     712             :     ActiveShellList::iterator iShell (::std::find_if (
     713             :         maActiveViewShells.begin(),
     714             :         maActiveViewShells.end(),
     715           0 :         IsShell(&rShell)));
     716           0 :     bool bMove = true;
     717           0 :     if (iShell != maActiveViewShells.end())
     718             :     {
     719             :         // Is the shell already at the top of the stack?  We have to keep
     720             :         // the case in mind that mbKeepMainViewShellOnTop is true.  Shells
     721             :         // that are not the main view shell are placed on the second-to-top
     722             :         // position in this case.
     723           0 :             if (iShell == maActiveViewShells.begin()
     724           0 :             && (iShell->IsMainViewShell() || ! mbKeepMainViewShellOnTop))
     725             :         {
     726             :             // The shell is at the top position and is either a) the main
     727             :             // view shell or b) another shell but the main view shell is not
     728             :             // kept at the top position.  We do not have to move the shell.
     729           0 :             bMove = false;
     730             :         }
     731           0 :         else if (iShell == ++maActiveViewShells.begin()
     732           0 :             && ! iShell->IsMainViewShell()
     733           0 :             && mbKeepMainViewShellOnTop)
     734             :         {
     735             :             // The shell is a the second-to-top position, not the main view
     736             :             // shell and the main view shell is kept at the top position.
     737             :             // Therefore we do not have to move the shell.
     738           0 :             bMove = false;
     739             :         }
     740             :     }
     741             :     else
     742             :     {
     743             :         // The shell is not on the stack.  Therefore it can not be moved.
     744             :         // We could insert it but we don't.  Use ActivateViewShell() for
     745             :         // that.
     746           0 :         bMove = false;
     747             :     }
     748             : 
     749             :     // When the shell is not at the right position it is removed from the
     750             :     // internal list of shells and inserted at the correct position.
     751           0 :     if (bMove)
     752             :     {
     753           0 :         UpdateLock aLock (*this);
     754             : 
     755           0 :         ShellDescriptor aDescriptor(*iShell);
     756             : 
     757           0 :         TakeShellsFromStack(&rShell);
     758           0 :         maActiveViewShells.erase(iShell);
     759             : 
     760             :         // Find out whether to insert at the top or one below.
     761           0 :         ActiveShellList::iterator aInsertPosition (maActiveViewShells.begin());
     762           0 :         if (mbKeepMainViewShellOnTop && ! aDescriptor.IsMainViewShell())
     763             :         {
     764           0 :             if (maActiveViewShells.back().IsMainViewShell())
     765           0 :                 ++aInsertPosition;
     766             :         }
     767             : 
     768           0 :         maActiveViewShells.insert(aInsertPosition, aDescriptor);
     769           0 :     }
     770             : }
     771             : 
     772             : 
     773             : 
     774             : 
     775           0 : SfxShell* ViewShellManager::Implementation::GetShell (ShellId nId) const
     776             : {
     777           0 :     ::osl::MutexGuard aGuard (maMutex);
     778             : 
     779           0 :     SfxShell* pShell = NULL;
     780             : 
     781             :     // First search the active view shells.
     782             :     ActiveShellList::const_iterator iShell (
     783             :         ::std::find_if (
     784             :         maActiveViewShells.begin(),
     785             :         maActiveViewShells.end(),
     786           0 :         IsId(nId)));
     787           0 :     if (iShell != maActiveViewShells.end())
     788           0 :         pShell = iShell->mpShell;
     789             :     else
     790             :     {
     791             :         // Now search the active sub shells of every active view shell.
     792           0 :         SubShellList::const_iterator iList;
     793           0 :         for (iList=maActiveSubShells.begin(); iList!=maActiveSubShells.end(); ++iList)
     794             :         {
     795           0 :             const SubShellSubList& rList (iList->second);
     796             :             SubShellSubList::const_iterator iSubShell(
     797           0 :                 ::std::find_if(rList.begin(),rList.end(), IsId(nId)));
     798           0 :             if (iSubShell != rList.end())
     799             :             {
     800           0 :                 pShell = iSubShell->mpShell;
     801           0 :                 break;
     802             :             }
     803             :         }
     804             :     }
     805             : 
     806           0 :     return pShell;
     807             : }
     808             : 
     809             : 
     810             : 
     811             : 
     812           0 : SfxShell* ViewShellManager::Implementation::GetTopShell (void) const
     813             : {
     814             :     OSL_ASSERT(mpTopShell == mrBase.GetSubShell(0));
     815           0 :     return mpTopShell;
     816             : }
     817             : 
     818             : 
     819             : 
     820             : 
     821           0 : void ViewShellManager::Implementation::LockUpdate (void)
     822             : {
     823           0 :     mnUpdateLockCount++;
     824           0 : }
     825             : 
     826             : 
     827             : 
     828             : 
     829           0 : void ViewShellManager::Implementation::UnlockUpdate (void)
     830             : {
     831           0 :     ::osl::MutexGuard aGuard (maMutex);
     832             : 
     833           0 :     mnUpdateLockCount--;
     834           0 :     if (mnUpdateLockCount < 0)
     835             :     {
     836             :         // This should not happen.
     837             :         OSL_ASSERT (mnUpdateLockCount>=0);
     838           0 :         mnUpdateLockCount = 0;
     839             :     }
     840           0 :     if (mnUpdateLockCount == 0)
     841           0 :         UpdateShellStack();
     842           0 : }
     843             : 
     844             : 
     845             : 
     846             : 
     847             : /** Update the SFX shell stack (the portion that is visible to us) so that
     848             :     it matches the internal shell stack.  This is done in six steps:
     849             :     1. Create the missing view shells and sub shells.
     850             :     2. Set up the internal shell stack.
     851             :     3. Get the SFX shell stack.
     852             :     4. Find the lowest shell in which the two stacks differ.
     853             :     5. Remove all shells above and including that shell from the SFX stack.
     854             :     6. Push all shells of the internal stack on the SFX shell stack that are
     855             :     not already present on the later.
     856             : */
     857           0 : void ViewShellManager::Implementation::UpdateShellStack (void)
     858             : {
     859           0 :     ::osl::MutexGuard aGuard (maMutex);
     860             : 
     861             :     // Remember the undo manager from the top-most shell on the stack.
     862           0 :     SfxShell* pTopMostShell = mrBase.GetSubShell(0);
     863             :     ::svl::IUndoManager* pUndoManager = (pTopMostShell!=NULL)
     864           0 :         ? pTopMostShell->GetUndoManager()
     865           0 :         : NULL;
     866             : 
     867             :     // 1. Create the missing shells.
     868           0 :     CreateShells();
     869             : 
     870             : 
     871             :     // 2. Create the internal target stack.
     872           0 :     ShellStack aTargetStack;
     873           0 :     CreateTargetStack(aTargetStack);
     874             : 
     875             : 
     876             :     // 3. Get SFX shell stack.
     877           0 :     ShellStack aSfxShellStack;
     878           0 :     sal_uInt16 nIndex (0);
     879           0 :     while (mrBase.GetSubShell(nIndex)!=NULL)
     880           0 :         ++nIndex;
     881           0 :     aSfxShellStack.reserve(nIndex);
     882           0 :     while (nIndex-- > 0)
     883           0 :         aSfxShellStack.push_back(mrBase.GetSubShell(nIndex));
     884             : 
     885             : 
     886             : #if OSL_DEBUG_LEVEL >= 2
     887             :     SAL_INFO("sd.view", OSL_THIS_FUNC << ": Current SFX Stack");
     888             :     DumpShellStack(aSfxShellStack);
     889             :     SAL_INFO("sd.view", OSL_THIS_FUNC << ": Target Stack");
     890             :     DumpShellStack(aTargetStack);
     891             : #endif
     892             : 
     893             : 
     894             :     // 4. Find the lowest shell in which the two stacks differ.
     895           0 :     ShellStack::iterator iSfxShell (aSfxShellStack.begin());
     896           0 :     ShellStack::iterator iTargetShell (aTargetStack.begin());
     897           0 :     while (iSfxShell != aSfxShellStack.end()
     898           0 :         && iTargetShell!=aTargetStack.end()
     899           0 :         && (*iSfxShell)==(*iTargetShell))
     900             :     {
     901           0 :         ++iSfxShell;
     902           0 :         ++iTargetShell;
     903             :     }
     904             : 
     905             : 
     906             :     // 5. Remove all shells above and including the differing shell from the
     907             :     // SFX stack starting with the shell on top of the stack.
     908           0 :     for (std::reverse_iterator<ShellStack::const_iterator> i(aSfxShellStack.end()), iLast(iSfxShell);
     909             :             i != iLast; ++i)
     910             :     {
     911           0 :         SfxShell* const pShell = *i;
     912             :         SAL_INFO("sd.view", OSL_THIS_FUNC << ": removing shell " << pShell << " from stack");
     913           0 :         mrBase.RemoveSubShell(pShell);
     914             :     }
     915           0 :     aSfxShellStack.erase(iSfxShell, aSfxShellStack.end());
     916             : 
     917             : 
     918             :     // 6. Push shells from the given stack onto the SFX stack.
     919           0 :     mbShellStackIsUpToDate = false;
     920           0 :     while (iTargetShell != aTargetStack.end())
     921             :     {
     922             :         SAL_INFO("sd.view", OSL_THIS_FUNC << ": pushing shell " << *iTargetShell << " on stack");
     923           0 :         mrBase.AddSubShell(**iTargetShell);
     924           0 :         ++iTargetShell;
     925             : 
     926             :         // The pushing of the shell on to the shell stack may have lead to
     927             :         // another invocation of this method.  In this case we have to abort
     928             :         // pushing shells on the stack and return immediately.
     929           0 :         if (mbShellStackIsUpToDate)
     930           0 :             break;
     931             :     }
     932           0 :     if (mrBase.GetDispatcher() != NULL)
     933           0 :         mrBase.GetDispatcher()->Flush();
     934             : 
     935             :     // Update the pointer to the top-most shell and set its undo manager
     936             :     // to the one of the previous top-most shell.
     937           0 :     mpTopShell = mrBase.GetSubShell(0);
     938           0 :     if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL)
     939           0 :         mpTopShell->SetUndoManager(pUndoManager);
     940             : 
     941             :     // Finally tell an invocation of this method on a higher level that it can (has
     942             :     // to) abort and return immediately.
     943           0 :     mbShellStackIsUpToDate = true;
     944             : 
     945             : #if OSL_DEBUG_LEVEL >= 2
     946             :     SAL_INFO("sd.view", OSL_THIS_FUNC << ": New current stack");
     947             :     DumpSfxShellStack();
     948             : #endif
     949           0 : }
     950             : 
     951             : 
     952             : 
     953             : 
     954           0 : void ViewShellManager::Implementation::TakeShellsFromStack (const SfxShell* pShell)
     955             : {
     956           0 :     ::osl::MutexGuard aGuard (maMutex);
     957             : 
     958             :     // Remember the undo manager from the top-most shell on the stack.
     959           0 :     SfxShell* pTopMostShell = mrBase.GetSubShell(0);
     960             :     ::svl::IUndoManager* pUndoManager = (pTopMostShell!=NULL)
     961           0 :         ? pTopMostShell->GetUndoManager()
     962           0 :         : NULL;
     963             : 
     964             : #if OSL_DEBUG_LEVEL >= 2
     965             :     SAL_INFO("sd.view", OSL_THIS_FUNC << "TakeShellsFromStack( " << pShell << ")");
     966             :     DumpSfxShellStack();
     967             : #endif
     968             : 
     969             :     // 0.Make sure that the given shell is on the stack.  This is a
     970             :     // preparation for the following assertion.
     971           0 :     for (sal_uInt16 nIndex=0; true; nIndex++)
     972             :     {
     973           0 :         SfxShell* pShellOnStack = mrBase.GetSubShell(nIndex);
     974           0 :         if (pShellOnStack == NULL)
     975             :         {
     976             :             // Set pShell to NULL to indicate the following code that the
     977             :             // shell is not on the stack.
     978           0 :             pShell = NULL;
     979           0 :             break;
     980             :         }
     981           0 :         else if (pShellOnStack == pShell)
     982           0 :             break;
     983           0 :     }
     984             : 
     985           0 :     if (pShell != NULL)
     986             :     {
     987             :         // 1. Deactivate our shells on the stack before they are removed so
     988             :         // that during the Deactivation() calls the stack is still intact.
     989           0 :         for (sal_uInt16 nIndex=0; true; nIndex++)
     990             :         {
     991           0 :             SfxShell* pShellOnStack = mrBase.GetSubShell(nIndex);
     992           0 :             Deactivate(pShellOnStack);
     993           0 :             if (pShellOnStack == pShell)
     994           0 :                 break;
     995           0 :         }
     996             : 
     997             :         // 2. Remove the shells from the stack.
     998             :         while (true)
     999             :         {
    1000           0 :             SfxShell* pShellOnStack = mrBase.GetSubShell(0);
    1001             :             SAL_INFO("sd.view", OSL_THIS_FUNC << "removing shell " << pShellOnStack << " from stack");
    1002           0 :             mrBase.RemoveSubShell(pShellOnStack);
    1003           0 :             if (pShellOnStack == pShell)
    1004           0 :                 break;
    1005             :         }
    1006             : 
    1007             :         // 3. Update the stack.
    1008           0 :         if (mrBase.GetDispatcher() != NULL)
    1009           0 :             mrBase.GetDispatcher()->Flush();
    1010             : 
    1011             :         // Update the pointer to the top-most shell and set its undo manager
    1012             :         // to the one of the previous top-most shell.
    1013           0 :         mpTopShell = mrBase.GetSubShell(0);
    1014           0 :         if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL)
    1015           0 :             mpTopShell->SetUndoManager(pUndoManager);
    1016           0 :     }
    1017             : 
    1018             : 
    1019             : #if OSL_DEBUG_LEVEL >= 2
    1020             :     SAL_INFO("sd.view", OSL_THIS_FUNC << "Sfx shell stack is:");
    1021             :     DumpSfxShellStack();
    1022             : #endif
    1023           0 : }
    1024             : 
    1025             : 
    1026             : 
    1027             : 
    1028           0 : void ViewShellManager::Implementation::CreateShells (void)
    1029             : {
    1030           0 :     ::osl::MutexGuard aGuard (maMutex);
    1031             : 
    1032             :     // Iterate over all view shells.
    1033           0 :     ActiveShellList::reverse_iterator iShell;
    1034           0 :     for (iShell=maActiveViewShells.rbegin(); iShell!=maActiveViewShells.rend(); ++iShell)
    1035             :     {
    1036             :         // Get the list of associated sub shells.
    1037           0 :         SubShellList::iterator iList (maActiveSubShells.find(iShell->mpShell));
    1038           0 :         if (iList != maActiveSubShells.end())
    1039             :         {
    1040           0 :             SubShellSubList& rList (iList->second);
    1041             : 
    1042             :             // Iterate over all sub shells of the current view shell.
    1043           0 :             SubShellSubList::iterator iSubShell;
    1044           0 :             for (iSubShell=rList.begin(); iSubShell!=rList.end(); ++iSubShell)
    1045             :             {
    1046           0 :                 if (iSubShell->mpShell == NULL)
    1047             :                 {
    1048           0 :                     *iSubShell = CreateSubShell(iShell->mpShell,iSubShell->mnId,NULL,NULL);
    1049             :                 }
    1050             :             }
    1051             :         }
    1052           0 :    }
    1053           0 : }
    1054             : 
    1055             : 
    1056             : 
    1057             : 
    1058           0 : void ViewShellManager::Implementation::CreateTargetStack (ShellStack& rStack) const
    1059             : {
    1060             :     // Create a local stack of the shells that are to push on the shell
    1061             :     // stack.  We can thus safly create the required shells wile still
    1062             :     // having a valid shell stack.
    1063           0 :     for (ActiveShellList::const_reverse_iterator iViewShell (maActiveViewShells.rbegin());
    1064           0 :          iViewShell != maActiveViewShells.rend();
    1065             :          ++iViewShell)
    1066             :     {
    1067             :         // Possibly place the form shell below the current view shell.
    1068           0 :         if ( ! mbFormShellAboveParent
    1069           0 :             && mpFormShell!=NULL
    1070           0 :             && iViewShell->mpShell==mpFormShellParent)
    1071             :         {
    1072           0 :             rStack.push_back(mpFormShell);
    1073             :         }
    1074             : 
    1075             :         // Put the view shell itself on the local stack.
    1076           0 :         rStack.push_back (iViewShell->mpShell);
    1077             : 
    1078             :         // Possibly place the form shell above the current view shell.
    1079           0 :         if (mbFormShellAboveParent
    1080           0 :             && mpFormShell!=NULL
    1081           0 :             && iViewShell->mpShell==mpFormShellParent)
    1082             :         {
    1083           0 :             rStack.push_back(mpFormShell);
    1084             :         }
    1085             : 
    1086             :         // Add all other sub shells.
    1087           0 :         SubShellList::const_iterator iList (maActiveSubShells.find(iViewShell->mpShell));
    1088           0 :         if (iList != maActiveSubShells.end())
    1089             :         {
    1090           0 :             const SubShellSubList& rList (iList->second);
    1091           0 :             SubShellSubList::const_reverse_iterator iSubShell;
    1092           0 :             for (iSubShell=rList.rbegin(); iSubShell!=rList.rend(); ++iSubShell)
    1093           0 :                 if (iSubShell->mpShell != mpFormShell)
    1094           0 :                     rStack.push_back(iSubShell->mpShell);
    1095             :         }
    1096             :     }
    1097           0 : }
    1098             : 
    1099             : 
    1100             : 
    1101             : 
    1102           0 : IMPL_LINK(ViewShellManager::Implementation, WindowEventHandler, VclWindowEvent*, pEvent)
    1103             : {
    1104           0 :     if (pEvent != NULL)
    1105             :     {
    1106             :         ::Window* pEventWindow
    1107           0 :             = static_cast<VclWindowEvent*>(pEvent)->GetWindow();
    1108             : 
    1109           0 :         switch (pEvent->GetId())
    1110             :         {
    1111             :             case VCLEVENT_WINDOW_GETFOCUS:
    1112             :             {
    1113           0 :                 for (ActiveShellList::iterator aI(maActiveViewShells.begin());
    1114           0 :                      aI!=maActiveViewShells.end();
    1115             :                      aI++)
    1116             :                 {
    1117           0 :                     if (pEventWindow == static_cast< ::Window*>(aI->GetWindow()))
    1118             :                     {
    1119           0 :                         MoveToTop(*aI->mpShell);
    1120           0 :                         break;
    1121             :                     }
    1122             :                 }
    1123             :             }
    1124           0 :             break;
    1125             : 
    1126             :             case VCLEVENT_WINDOW_LOSEFOCUS:
    1127           0 :                 break;
    1128             : 
    1129             :             case VCLEVENT_OBJECT_DYING:
    1130             :                 // Remember that we do not have to remove the window
    1131             :                 // listener for this window.
    1132           0 :                 for (ActiveShellList::iterator
    1133           0 :                          iShell(maActiveViewShells.begin()),
    1134           0 :                          iEnd(maActiveViewShells.end());
    1135             :                      iShell!=iEnd;
    1136             :                      ++iShell)
    1137             :                 {
    1138           0 :                     if (iShell->GetWindow() == pEventWindow)
    1139             :                     {
    1140           0 :                         iShell->mbIsListenerAddedToWindow = false;
    1141           0 :                         break;
    1142             :                     }
    1143             :                 }
    1144           0 :                 break;
    1145             :         }
    1146             :     }
    1147           0 :     return sal_True;
    1148             : }
    1149             : 
    1150             : 
    1151             : 
    1152             : 
    1153           0 : ShellDescriptor ViewShellManager::Implementation::CreateSubShell (
    1154             :     SfxShell* pParentShell,
    1155             :     ShellId nShellId,
    1156             :     ::Window* pParentWindow,
    1157             :     FrameView* pFrameView)
    1158             : {
    1159           0 :     ::osl::MutexGuard aGuard (maMutex);
    1160           0 :     ShellDescriptor aResult;
    1161             : 
    1162             :     // Look up the factories for the parent shell.
    1163             :     ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
    1164           0 :         maShellFactories.equal_range(pParentShell));
    1165             : 
    1166             :     // Try all factories to create the shell.
    1167           0 :     for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
    1168             :     {
    1169           0 :         SharedShellFactory pFactory = iFactory->second;
    1170           0 :         if (pFactory != 0)
    1171           0 :             aResult.mpShell = pFactory->CreateShell(nShellId, pParentWindow, pFrameView);
    1172             : 
    1173             :         // Exit the loop when the shell has been successfully created.
    1174           0 :         if (aResult.mpShell != NULL)
    1175             :         {
    1176           0 :             aResult.mpFactory = pFactory;
    1177           0 :             aResult.mnId = nShellId;
    1178           0 :             break;
    1179             :         }
    1180           0 :     }
    1181             : 
    1182           0 :     return aResult;
    1183             : }
    1184             : 
    1185             : 
    1186             : 
    1187             : 
    1188           0 : void ViewShellManager::Implementation::DestroyViewShell (
    1189             :     ShellDescriptor& rDescriptor)
    1190             : {
    1191             :     OSL_ASSERT(rDescriptor.mpShell != NULL);
    1192             : 
    1193           0 :     if (rDescriptor.mbIsListenerAddedToWindow)
    1194             :     {
    1195           0 :         rDescriptor.mbIsListenerAddedToWindow = false;
    1196           0 :         ::Window* pWindow = rDescriptor.GetWindow();
    1197           0 :         if (pWindow != NULL)
    1198             :         {
    1199             :             pWindow->RemoveEventListener(
    1200           0 :                 LINK(this, ViewShellManager::Implementation, WindowEventHandler));
    1201             :         }
    1202             :     }
    1203             : 
    1204             :     // Destroy the sub shell factories.
    1205             :     ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
    1206           0 :         maShellFactories.equal_range(rDescriptor.mpShell));
    1207           0 :     if (aRange.first != maShellFactories.end())
    1208           0 :         maShellFactories.erase(aRange.first, aRange.second);
    1209             : 
    1210             :     // Release the shell.
    1211           0 :     if (rDescriptor.mpFactory.get() != NULL)
    1212           0 :         rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell);
    1213           0 : }
    1214             : 
    1215             : 
    1216             : 
    1217             : 
    1218           0 : void ViewShellManager::Implementation::DestroySubShell (
    1219             :     const SfxShell& rParentShell,
    1220             :     const ShellDescriptor& rDescriptor)
    1221             : {
    1222             :     (void)rParentShell;
    1223             :     OSL_ASSERT(rDescriptor.mpFactory.get() != NULL);
    1224           0 :     rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell);
    1225           0 : }
    1226             : 
    1227             : 
    1228             : 
    1229             : 
    1230           0 : void ViewShellManager::Implementation::InvalidateAllSubShells (const SfxShell* pParentShell)
    1231             : {
    1232           0 :     ::osl::MutexGuard aGuard (maMutex);
    1233             : 
    1234           0 :     SubShellList::iterator iList (maActiveSubShells.find(pParentShell));
    1235           0 :     if (iList != maActiveSubShells.end())
    1236             :     {
    1237           0 :         SubShellSubList& rList (iList->second);
    1238           0 :         SubShellSubList::iterator iShell;
    1239           0 :         for (iShell=rList.begin(); iShell!=rList.end(); ++iShell)
    1240           0 :             if (iShell->mpShell != NULL)
    1241           0 :                 iShell->mpShell->Invalidate();
    1242           0 :     }
    1243           0 : }
    1244             : 
    1245             : 
    1246             : 
    1247             : 
    1248           0 : void ViewShellManager::Implementation::Shutdown (void)
    1249             : {
    1250           0 :     ::osl::MutexGuard aGuard (maMutex);
    1251             : 
    1252             :     // Take stacked shells from stack.
    1253           0 :     if ( ! maActiveViewShells.empty())
    1254             :     {
    1255           0 :         UpdateLock aLock (*this);
    1256             : 
    1257             : 
    1258           0 :         while ( ! maActiveViewShells.empty())
    1259             :         {
    1260           0 :             SfxShell* pShell = maActiveViewShells.front().mpShell;
    1261           0 :             if (pShell != NULL)
    1262             :             {
    1263           0 :                 ViewShell* pViewShell = dynamic_cast<ViewShell*>(pShell);
    1264           0 :                 if (pViewShell != NULL)
    1265           0 :                     DeactivateViewShell(*pViewShell);
    1266             :                 else
    1267           0 :                     DeactivateShell(*pShell);
    1268             :             }
    1269             :             else
    1270             :             {
    1271             :                 DBG_ASSERT(false,
    1272             :                     "ViewShellManager::Implementation::Shutdown(): empty active shell descriptor");
    1273           0 :                 maActiveViewShells.pop_front();
    1274             :             }
    1275           0 :         }
    1276             :     }
    1277           0 :     mrBase.RemoveSubShell (NULL);
    1278             : 
    1279           0 :     maShellFactories.clear();
    1280           0 : }
    1281             : 
    1282             : 
    1283             : 
    1284             : 
    1285             : #if OSL_DEBUG_LEVEL >= 2
    1286             : void ViewShellManager::Implementation::DumpShellStack (const ShellStack& rStack)
    1287             : {
    1288             :     ShellStack::const_reverse_iterator iEntry;
    1289             :     for (iEntry=rStack.rbegin(); iEntry!=rStack.rend(); ++iEntry)
    1290             :         if (*iEntry != NULL)
    1291             :             SAL_INFO("sd.view", OSL_THIS_FUNC << ":    " <<
    1292             :                 *iEntry << " : " <<
    1293             :                 OUStringToOString((*iEntry)->GetName(),RTL_TEXTENCODING_UTF8).getStr());
    1294             :         else
    1295             :             SAL_INFO("sd.view", OSL_THIS_FUNC << "     null");
    1296             : }
    1297             : 
    1298             : 
    1299             : 
    1300             : 
    1301             : void ViewShellManager::Implementation::DumpSfxShellStack (void)
    1302             : {
    1303             :     ShellStack aSfxShellStack;
    1304             :     sal_uInt16 nIndex (0);
    1305             :     while (mrBase.GetSubShell(nIndex)!=NULL)
    1306             :         ++nIndex;
    1307             :     aSfxShellStack.reserve(nIndex);
    1308             :     while (nIndex-- > 0)
    1309             :         aSfxShellStack.push_back(mrBase.GetSubShell(nIndex));
    1310             :     DumpShellStack(aSfxShellStack);
    1311             : }
    1312             : #endif
    1313             : 
    1314             : 
    1315             : 
    1316           0 : void ViewShellManager::Implementation::Deactivate (SfxShell* pShell)
    1317             : {
    1318             :     OSL_ASSERT(pShell!=NULL);
    1319             : 
    1320             :     // We have to end a text edit for view shells that are to be taken from
    1321             :     // the shell stack.
    1322           0 :     ViewShell* pViewShell = dynamic_cast<ViewShell*>(pShell);
    1323           0 :     if (pViewShell != NULL)
    1324             :     {
    1325           0 :         sd::View* pView = pViewShell->GetView();
    1326           0 :         if (pView!=NULL && pView->IsTextEdit())
    1327             :         {
    1328           0 :             pView->SdrEndTextEdit();
    1329           0 :             pView->UnmarkAll();
    1330             :             pViewShell->GetViewFrame()->GetDispatcher()->Execute(
    1331             :                 SID_OBJECT_SELECT,
    1332           0 :                 SFX_CALLMODE_ASYNCHRON);
    1333             :         }
    1334             :     }
    1335             : 
    1336             :     // Now we can deactivate the shell.
    1337           0 :     pShell->Deactivate(true);
    1338           0 : }
    1339             : 
    1340             : 
    1341             : 
    1342             : 
    1343           0 : void ViewShellManager::Implementation::SetFormShell (
    1344             :     const ViewShell* pFormShellParent,
    1345             :     FmFormShell* pFormShell,
    1346             :     bool bFormShellAboveParent)
    1347             : {
    1348           0 :     ::osl::MutexGuard aGuard (maMutex);
    1349             : 
    1350           0 :     mpFormShellParent = pFormShellParent;
    1351           0 :     mpFormShell = pFormShell;
    1352           0 :     mbFormShellAboveParent = bFormShellAboveParent;
    1353           0 : }
    1354             : 
    1355             : 
    1356             : 
    1357             : 
    1358             : namespace {
    1359             : 
    1360           0 : ShellDescriptor::ShellDescriptor (void)
    1361             :     : mpShell(NULL),
    1362             :       mnId(0),
    1363             :       mpFactory(),
    1364           0 :       mbIsListenerAddedToWindow(false)
    1365             : {
    1366           0 : }
    1367             : 
    1368             : 
    1369             : 
    1370             : 
    1371           0 : ShellDescriptor::ShellDescriptor (
    1372             :     SfxShell* pShell,
    1373             :     ShellId nId)
    1374             :     : mpShell(pShell),
    1375             :       mnId(nId),
    1376             :       mpFactory(),
    1377           0 :       mbIsListenerAddedToWindow(false)
    1378             : {
    1379           0 : }
    1380             : 
    1381             : 
    1382             : 
    1383             : 
    1384           0 : ShellDescriptor::ShellDescriptor (const ShellDescriptor& rDescriptor)
    1385             :     : mpShell(rDescriptor.mpShell),
    1386             :       mnId(rDescriptor.mnId),
    1387             :       mpFactory(rDescriptor.mpFactory),
    1388           0 :       mbIsListenerAddedToWindow(rDescriptor.mbIsListenerAddedToWindow)
    1389             : {
    1390           0 : }
    1391             : 
    1392             : 
    1393             : 
    1394             : 
    1395           0 : ShellDescriptor& ShellDescriptor::operator= (const ShellDescriptor& rDescriptor)
    1396             : {
    1397           0 :     if (this != &rDescriptor)
    1398             :     {
    1399           0 :         mpShell = rDescriptor.mpShell;
    1400           0 :         mnId = rDescriptor.mnId;
    1401           0 :         mpFactory = rDescriptor.mpFactory;
    1402           0 :         mbIsListenerAddedToWindow = rDescriptor.mbIsListenerAddedToWindow;
    1403             :     }
    1404           0 :     return *this;
    1405             : }
    1406             : 
    1407             : 
    1408             : 
    1409             : 
    1410           0 : bool ShellDescriptor::IsMainViewShell (void) const
    1411             : {
    1412           0 :     ViewShell* pViewShell = dynamic_cast<ViewShell*>(mpShell);
    1413           0 :     if (pViewShell != NULL)
    1414           0 :         return pViewShell->IsMainViewShell();
    1415             :     else
    1416           0 :         return false;
    1417             : }
    1418             : 
    1419             : 
    1420             : 
    1421             : 
    1422           0 : ::Window* ShellDescriptor::GetWindow (void) const
    1423             : {
    1424           0 :     ViewShell* pViewShell = dynamic_cast<ViewShell*>(mpShell);
    1425           0 :     if (pViewShell != NULL)
    1426           0 :         return pViewShell->GetActiveWindow();
    1427             :     else
    1428           0 :         return NULL;
    1429             : }
    1430             : 
    1431             : 
    1432             : 
    1433             : } // end of anonymous namespace
    1434             : 
    1435             : } // end of namespace sd
    1436             : 
    1437             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10