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

Generated by: LCOV version 1.10