diff options
author | Oliver Bolte <obo@openoffice.org> | 2006-03-21 16:41:15 +0000 |
---|---|---|
committer | Oliver Bolte <obo@openoffice.org> | 2006-03-21 16:41:15 +0000 |
commit | 5f47590d3911eb49ec86c671019fd32469fba4ae (patch) | |
tree | cbccfe240486f99cad1564fffda410e7146615df | |
parent | 24bf8adb1a4896fbb2a9b43749826473cb39e580 (diff) |
INTEGRATION: CWS viewswitch (1.14.72); FILE MERGED
2006/03/16 14:37:19 af 1.14.72.7: #132893# Fixed compiler issues.
2006/03/16 10:31:30 af 1.14.72.6: #132893# Shell factories can now be added and removed. More than one factory per view shell is possible. Form shell handling changed.
2006/03/03 15:32:14 af 1.14.72.5: #132596# Made a normal pointer out of mpFormShell.
2006/03/01 15:13:38 af 1.14.72.4: #i57551# Tell FormShellManager about created or destroyed form shell.
2006/01/20 14:35:34 af 1.14.72.3: #i57551# Fixed resync problems.
2005/11/29 15:55:40 af 1.14.72.2: #i57552# Improved the SfxUndoManager handling.
2005/11/17 14:41:25 af 1.14.72.1: #i57551# Added support for sub shells .
-rwxr-xr-x | sd/source/ui/view/ViewShellManager.cxx | 1072 |
1 files changed, 786 insertions, 286 deletions
diff --git a/sd/source/ui/view/ViewShellManager.cxx b/sd/source/ui/view/ViewShellManager.cxx index 27676b1362c7..22341bc8e9c6 100755 --- a/sd/source/ui/view/ViewShellManager.cxx +++ b/sd/source/ui/view/ViewShellManager.cxx @@ -4,9 +4,9 @@ * * $RCSfile: ViewShellManager.cxx,v $ * - * $Revision: 1.14 $ + * $Revision: 1.15 $ * - * last change: $Author: rt $ $Date: 2005-09-09 07:04:24 $ + * last change: $Author: obo $ $Date: 2006-03-21 17:41:15 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -35,23 +35,21 @@ #include "ViewShellManager.hxx" -#ifndef SD_OBJECT_BAR_MANAGER_HXX -#include "ObjectBarManager.hxx" -#endif #ifndef SD_VIEW_SHELL_HXX #include "ViewShell.hxx" #endif #ifndef SD_VIEW_SHELL_BASE_HXX #include "ViewShellBase.hxx" #endif -#include "ViewShellCache.hxx" #include "Window.hxx" #ifndef SD_DRAW_DOC_SHELL_HXX #include "DrawDocShell.hxx" #endif +#include "FormShellManager.hxx" #include <sfx2/dispatch.hxx> #include <svx/svxids.hrc> +#include <svx/fmshell.hxx> #include <hash_map> @@ -61,29 +59,55 @@ namespace sd { namespace { -class ActiveShellDescriptor { +/** The ShellDescriptor template class is used to store view shells or sub + shells together with their ids and the factory that was used to create + the shell. The shell pointer may be NULL. In that case the shell is + created on demand. +*/ +template<class Shell> +class ShellDescriptor { public: - ActiveShellDescriptor (ViewShell* pViewShell, ShellId nId) - : mpViewShell(pViewShell), mnId(nId) {} - ViewShell* mpViewShell; + Shell* mpShell; ShellId mnId; + ViewShellManager::SharedShellFactory mpFactory; + ShellDescriptor () : mpShell(NULL), mnId(0), mpFactory() {} + ShellDescriptor (Shell* pShell, ShellId nId) : mpShell(pShell), mnId(nId), mpFactory() {} + ShellDescriptor (const ShellDescriptor& rDescriptor) + : mpShell(rDescriptor.mpShell), mnId(rDescriptor.mnId), mpFactory(rDescriptor.mpFactory) {} + ShellDescriptor& operator= (const ShellDescriptor& rDescriptor) + { mpShell = rDescriptor.mpShell; mnId = rDescriptor.mnId; mpFactory = rDescriptor.mpFactory; + return *this; } }; -class IsShell : public ::std::unary_function<ActiveShellDescriptor,bool> + + + +/** This functor can be used to search for a shell in an STL container when the + shell pointer is given. +*/ +template<class Shell> +class IsShell : public ::std::unary_function<ShellDescriptor<Shell>,bool> { public: - IsShell (const ::sd::ViewShell* pShell) : mpShell(pShell) {} - bool operator() (const ActiveShellDescriptor& rDescriptor) - { return rDescriptor.mpViewShell == mpShell; } + IsShell (const Shell* pShell) : mpShell(pShell) {} + bool operator() (const ShellDescriptor<Shell>& rDescriptor) + { return rDescriptor.mpShell == mpShell; } private: - const ViewShell* mpShell; + const Shell* mpShell; }; -class IsId : public ::std::unary_function<ActiveShellDescriptor,bool> + + + +/** This functor can be used to search for a shell in an STL container when the + id of the shell is given. +*/ +template<class Shell> +class IsId : public ::std::unary_function<ShellDescriptor<Shell>,bool> { public: IsId (ShellId nId) : mnId(nId) {} - bool operator() (const ActiveShellDescriptor& rDescriptor) + bool operator() (const ShellDescriptor<Shell>& rDescriptor) { return rDescriptor.mnId == mnId; } private: ShellId mnId; @@ -102,30 +126,46 @@ public: ViewShellBase& rBase); ~Implementation (void); - void RegisterDefaultFactory (::std::auto_ptr<ViewShellFactory> pFactory); - void RegisterFactory ( - ShellId nId, - ::std::auto_ptr<ViewShellFactory> pFactory); + void AddShellFactory ( + ViewShell* pViewShell, + const SharedShellFactory& rpFactory); + void RemoveShellFactory ( + ViewShell* pViewShell, + const SharedShellFactory& rpFactory); ViewShell* ActivateViewShell ( ShellId nId, ::Window* pParentWindow, FrameView* pFrameView); - void DeactivateViewShell (const ViewShell* pShell); - void MoveToTop (const ViewShell* pShell); - ViewShell* GetShell (ShellId nId); - ShellId GetShellId (const ViewShell* pShell); - ViewShellBase& GetViewShellBase (void) const; + void DeactivateViewShell (const ViewShell& rShell); + void SetFormShell (const ViewShell* pViewShell, FmFormShell* pFormShell, bool bAbove); + void ActivateSubShell (const ViewShell& rParentShell, ShellId nId); + void DeactivateSubShell (const ViewShell& rParentShell, ShellId nId); + void DeactivateAllSubShells (const ViewShell& rViewShell); + void MoveSubShellToTop (const ViewShell& rParentShell, ShellId nId); + void MoveToTop (const ViewShell& rParentShell); + SfxShell* GetShell (ShellId nId) const; + SfxShell* GetTopShell (void) const; + ShellId GetShellId (const SfxShell* pShell) const; + void ReplaceUndoManager (SfxUndoManager* pManager, SfxUndoManager* pReplacement); void Shutdown (void); - ViewShell* CreateViewShell ( - ShellId nShellId, - ::Window* pParentWindow, - FrameView* pFrameView); + void InvalidateAllSubShells (const ViewShell* pParentShell); /** Remove all shells from the SFX stack above and including the given shell. */ void TakeShellsFromStack (const SfxShell* pShell); + class UpdateLock + { + public: + UpdateLock (Implementation& rImpl) : mrImpl(rImpl) {mrImpl.LockUpdate();} + ~UpdateLock (void) {mrImpl.UnlockUpdate();}; + private: + Implementation& mrImpl; + }; + + + /** Prevent updates of the shell stack. While the sub shell manager is locked it will update its internal data structures but not alter the shell stack. Use this method when there are several modifications @@ -137,31 +177,34 @@ public: /** Allow updates of the shell stack. This method has to be called the same number of times as LockUpdate() to really allow a rebuild of the shell stack. - */ + */ void UnlockUpdate (void); private: ViewShellBase& mrBase; + mutable ::osl::Mutex maMutex; - ::std::auto_ptr<ViewShellFactory> mpDefaultFactory; - - typedef ::std::hash_map<ShellId,ViewShellFactory*> SpecializedFactoryList; - SpecializedFactoryList maSpecializedFactories; + class ViewShellHash{public: size_t operator()(const ViewShell* p) const { return (size_t)p;} }; + typedef ::std::hash_multimap<const ViewShell*,SharedShellFactory,ViewShellHash> + FactoryList; + FactoryList maShellFactories; /** List of the active view shells. In order to create gather all shells to put on the shell stack each view shell in this list is asked for its sub-shells (typically toolbars). */ - typedef ::std::list<ActiveShellDescriptor> ActiveShellList; + typedef ::std::list<ShellDescriptor<ViewShell> > ActiveShellList; ActiveShellList maActiveViewShells; + typedef ::std::list<ShellDescriptor<SfxShell> > SubShellSubList; + typedef ::std::hash_map<const ViewShell*,SubShellSubList,ViewShellHash> SubShellList; + SubShellList maActiveSubShells; + /** In this member we remember what shells we have pushed on the shell stack. */ typedef ::std::vector<SfxShell*> ShellStack; - ViewShellCache maCache; - int mnUpdateLockCount; /** When this flag is set then the main view shell is always kept at the @@ -169,19 +212,29 @@ private: */ bool mbKeepMainViewShellOnTop; - /** The PushShellsOnStack() method can be called recursively. This flag + /** The UpdateShellStack() method can be called recursively. This flag is used to communicate between different levels of invocation: if the stack has been updated in an inner call the outer call can (has to) stop and return immediately. */ bool mbShellStackIsUpToDate; + SfxShell* mpFormShell; + const ViewShell* mpFormShellParent; + bool mbFormShellAboveParent; + + SfxShell* mpTopShell; + void GatherActiveShells (ShellStack& rShellList); + void UpdateShellStack (void); + + void CreateShells (void); + /** This method rebuilds the stack of shells that are stacked upon the view shell base. */ - void PushShellsOnStack (void); + void CreateTargetStack (ShellStack& rStack) const; DECL_LINK(WindowEventHandler, VclWindowEvent*); @@ -189,14 +242,26 @@ private: void DumpShellStack (const ShellStack& rStack); void DumpSfxShellStack (void); - void UpdateShellStack (ShellStack& rRequestedStack); - /** To be called before a shell is taken fom the SFX shell stack. This method deactivates an active text editing to avoid problems with undo managers. Afterwards the Deactivate() of the shell is called. */ void Deactivate (SfxShell* pShell); + + ShellDescriptor<ViewShell> CreateViewShell ( + ShellId nShellId, + ::Window* pParentWindow, + FrameView* pFrameView); + ShellDescriptor<SfxShell> CreateSubShell ( + ViewShell* pViewShell, + ShellId nShellId, + ::Window* pParentWindow, + FrameView* pFrameView); + void DestroyViewShell (const ShellDescriptor<ViewShell>& rDescriptor); + void DestroySubShell ( + const ViewShell& rViewShell, + const ShellDescriptor<SfxShell>& rDescriptor); }; @@ -220,22 +285,32 @@ ViewShellManager::~ViewShellManager (void) -void ViewShellManager::RegisterDefaultFactory ( - ::std::auto_ptr<ViewShellFactory> pFactory) +void ViewShellManager::SetViewShellFactory (const SharedShellFactory& rpFactory) { if (mbValid) - mpImpl->RegisterDefaultFactory(pFactory); + mpImpl->AddShellFactory(NULL, rpFactory); } -void ViewShellManager::RegisterFactory ( - ShellId nId, - ::std::auto_ptr<ViewShellFactory> pFactory) +void ViewShellManager::AddSubShellFactory ( + ViewShell* pViewShell, + const SharedShellFactory& rpFactory) { if (mbValid) - mpImpl->RegisterFactory(nId,pFactory); + mpImpl->AddShellFactory(pViewShell, rpFactory); +} + + + + +void ViewShellManager::RemoveSubShellFactory ( + ViewShell* pViewShell, + const SharedShellFactory& rpFactory) +{ + if (mbValid) + mpImpl->RemoveShellFactory(pViewShell, rpFactory); } @@ -257,8 +332,67 @@ ViewShell* ViewShellManager::ActivateViewShell ( void ViewShellManager::DeactivateViewShell (const ViewShell* pShell) { + if (mbValid && pShell!=NULL) + mpImpl->DeactivateViewShell(*pShell); +} + + + + +void ViewShellManager::MoveSubShellToTop ( + const ViewShell& rParentShell, + ShellId nId) +{ + if (mbValid) + mpImpl->MoveSubShellToTop(rParentShell, nId); +} + + + + +void ViewShellManager::SetFormShell ( + const ViewShell* pParentShell, + FmFormShell* pFormShell, + bool bAbove) +{ + if (mbValid) + mpImpl->SetFormShell(pParentShell,pFormShell,bAbove); +} + + + + +void ViewShellManager::ActivateSubShell (const ViewShell& rViewShell, ShellId nId) +{ if (mbValid) - mpImpl->DeactivateViewShell(pShell); + mpImpl->ActivateSubShell(rViewShell,nId); +} + + + + +void ViewShellManager::DeactivateSubShell (const ViewShell& rViewShell, ShellId nId) +{ + if (mbValid) + mpImpl->DeactivateSubShell(rViewShell,nId); +} + + + + +void ViewShellManager::DeactivateAllSubShells (const ViewShell& rViewShell) +{ + if (mbValid) + mpImpl->DeactivateAllSubShells(rViewShell); +} + + + + +void ViewShellManager::InvalidateAllSubShells (ViewShell* pViewShell) +{ + if (mbValid) + mpImpl->InvalidateAllSubShells(pViewShell); } @@ -273,16 +407,16 @@ void ViewShellManager::InvalidateShellStack (const SfxShell* pShell) -void ViewShellManager::MoveToTop (const ViewShell* pShell) +void ViewShellManager::MoveToTop (const ViewShell& rParentShell) { if (mbValid) - mpImpl->MoveToTop(pShell); + mpImpl->MoveToTop(rParentShell); } -ViewShell* ViewShellManager::GetShell (ShellId nId) +SfxShell* ViewShellManager::GetShell (ShellId nId) const { if (mbValid) return mpImpl->GetShell(nId); @@ -293,7 +427,18 @@ ViewShell* ViewShellManager::GetShell (ShellId nId) -ShellId ViewShellManager::GetShellId (const ViewShell* pShell) +SfxShell* ViewShellManager::GetTopShell (void) const +{ + if (mbValid) + return mpImpl->GetTopShell(); + else + return NULL; +} + + + + +ShellId ViewShellManager::GetShellId (const SfxShell* pShell) const { if (mbValid) return mpImpl->GetShellId(pShell); @@ -304,9 +449,10 @@ ShellId ViewShellManager::GetShellId (const ViewShell* pShell) -ViewShellBase& ViewShellManager::GetViewShellBase (void) const +void ViewShellManager::ReplaceUndoManager (SfxUndoManager* pManager, SfxUndoManager* pReplacement) { - return mpImpl->GetViewShellBase(); + if (mbValid) + mpImpl->ReplaceUndoManager(pManager,pReplacement); } @@ -323,16 +469,17 @@ void ViewShellManager::Shutdown (void) +void ViewShellManager::LockUpdate (void) +{ + mpImpl->LockUpdate(); +} -ViewShell* ViewShellManager::CreateViewShell ( - ShellId nShellId, - ::Window* pParentWindow, - FrameView* pFrameView) + + + +void ViewShellManager::UnlockUpdate (void) { - if (mbValid) - return mpImpl->CreateViewShell(nShellId,pParentWindow,pFrameView); - else - return NULL; + mpImpl->UnlockUpdate(); } @@ -344,13 +491,16 @@ ViewShellManager::Implementation::Implementation ( ViewShellManager& rManager, ViewShellBase& rBase) : mrBase(rBase), - mpDefaultFactory (NULL), - maSpecializedFactories (), + maMutex(), + maShellFactories(), maActiveViewShells(), - maCache (rManager), mnUpdateLockCount(0), mbKeepMainViewShellOnTop(false), - mbShellStackIsUpToDate(true) + mbShellStackIsUpToDate(true), + mpFormShell(NULL), + mpFormShellParent(NULL), + mbFormShellAboveParent(true), + mpTopShell(NULL) { } @@ -363,21 +513,44 @@ ViewShellManager::Implementation::~Implementation (void) } -void ViewShellManager::Implementation::RegisterDefaultFactory ( - ::std::auto_ptr<ViewShellFactory> pFactory) + + +void ViewShellManager::Implementation::AddShellFactory ( + ViewShell* pViewShell, + const SharedShellFactory& rpFactory) { - mpDefaultFactory = pFactory; + bool bAlreadyAdded (false); + + // Check that the given factory has not already been added. + ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange( + maShellFactories.equal_range(pViewShell)); + for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory) + if (iFactory->second == rpFactory) + { + bAlreadyAdded = true; + break; + } + + // Add the factory if it is not already present. + if ( ! bAlreadyAdded) + maShellFactories.insert(FactoryList::value_type(pViewShell, rpFactory)); } -void ViewShellManager::Implementation::RegisterFactory ( - ShellId nId, - ::std::auto_ptr<ViewShellFactory> pFactory) +void ViewShellManager::Implementation::RemoveShellFactory ( + ViewShell* pViewShell, + const SharedShellFactory& rpFactory) { - maSpecializedFactories[nId] = pFactory.get(); - pFactory.release(); + ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange( + maShellFactories.equal_range(pViewShell)); + for (FactoryList::iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory) + if (iFactory->second == rpFactory) + { + maShellFactories.erase(iFactory); + break; + } } @@ -388,103 +561,202 @@ ViewShell* ViewShellManager::Implementation::ActivateViewShell ( ::Window* pParentWindow, FrameView* pFrameView) { + ::osl::MutexGuard aGuard (maMutex); + // Create a new shell or recycle on in the cache. - ViewShell* pViewShell = maCache.GetViewShell ( - nShellId, - pParentWindow, - pFrameView); + ShellDescriptor<ViewShell> aDescriptor (CreateViewShell(nShellId, pParentWindow, pFrameView)); // Put shell on top of the active view shells. - if (pViewShell != NULL) + if (aDescriptor.mpShell != NULL) { - ::Window* pWindow = pViewShell->GetActiveWindow(); - if (pWindow != NULL) - pWindow->AddEventListener( - LINK( - this, - ViewShellManager::Implementation, - WindowEventHandler)); - else - { - DBG_ASSERT (pViewShell->GetActiveWindow()!=NULL, - "ViewShellManager::ActivateViewShell: " - "new view shell has no active window"); - } // Determine where to put the view shell on the stack. By default // it is put on top of the stack. When the view shell of the center // pane is to be kept top most and the new view shell is not // displayed in the center pane then it is inserted at the position // one below the top. - ActiveShellList::iterator iInsertPosition ( - maActiveViewShells.begin()); + ActiveShellList::iterator iInsertPosition (maActiveViewShells.begin()); if (iInsertPosition != maActiveViewShells.end() && mbKeepMainViewShellOnTop - && ! pViewShell->IsMainViewShell() - && iInsertPosition->mpViewShell->IsMainViewShell()) + && ! aDescriptor.mpShell->IsMainViewShell() + && iInsertPosition->mpShell->IsMainViewShell()) { ++iInsertPosition; } maActiveViewShells.insert( iInsertPosition, - ActiveShellDescriptor(pViewShell, nShellId)); + aDescriptor); } - return pViewShell; + return aDescriptor.mpShell; } -void ViewShellManager::Implementation::DeactivateViewShell (const ViewShell* pShell) +void ViewShellManager::Implementation::DeactivateViewShell (const ViewShell& rShell) { - ActiveShellList::iterator aI (::std::find_if ( + ::osl::MutexGuard aGuard (maMutex); + + ActiveShellList::iterator iShell (::std::find_if ( maActiveViewShells.begin(), maActiveViewShells.end(), - IsShell(pShell))); - if (aI != maActiveViewShells.end()) + IsShell<ViewShell>(&rShell))); + if (iShell != maActiveViewShells.end()) { UpdateLock aLocker (*this); - ViewShell* pViewShell = aI->mpViewShell; - mrBase.GetDocShell()->Disconnect(pViewShell); - pViewShell->GetObjectBarManager().Clear(); - maActiveViewShells.erase (aI); - pViewShell->GetActiveWindow()->RemoveEventListener( - LINK( - this, - ViewShellManager::Implementation, - WindowEventHandler)); - TakeShellsFromStack(pViewShell); - maCache.ReleaseViewShell (pViewShell); + ShellDescriptor<ViewShell> aDescriptor(*iShell); + mrBase.GetDocShell()->Disconnect(aDescriptor.mpShell); + maActiveViewShells.erase(iShell); + TakeShellsFromStack(aDescriptor.mpShell); + + // Deactivate sub shells. + SubShellList::iterator iList (maActiveSubShells.find(&rShell)); + if (iList != maActiveSubShells.end()) + { + SubShellSubList& rList (iList->second); + while ( ! rList.empty()) + DeactivateSubShell(rShell, rList.front().mnId); + } + + DestroyViewShell(aDescriptor); } } -void ViewShellManager::Implementation::MoveToTop (const ViewShell* pShell) +void ViewShellManager::Implementation::ActivateSubShell ( + const ViewShell& rParentShell, + ShellId nId) { - ActiveShellList::iterator aI (::std::find_if ( + ::osl::MutexGuard aGuard (maMutex); + + do + { + // Check that the given view shell is active. + ActiveShellList::iterator iShell (::std::find_if ( + maActiveViewShells.begin(), + maActiveViewShells.end(), + IsShell<ViewShell>(&rParentShell))); + if (iShell == maActiveViewShells.end()) + break; + + // Create the sub shell list if it does not yet exist. + SubShellList::iterator iList (maActiveSubShells.find(&rParentShell)); + if (iList == maActiveSubShells.end()) + iList = maActiveSubShells.insert( + SubShellList::value_type(&rParentShell,SubShellSubList())).first; + + // Do not activate an object bar that is already active. Requesting + // this is not exactly an error but may be an indication of one. + SubShellSubList& rList (iList->second); + if (::std::find_if(rList.begin(),rList.end(), IsId<SfxShell>(nId)) != rList.end()) + break; + + // Add just the id of the sub shell. The actual shell is created + // later in CreateShells(). + UpdateLock aLock (*this); + rList.push_back(ShellDescriptor<SfxShell>(NULL, nId)); + } + while (false); +} + + + + +void ViewShellManager::Implementation::DeactivateSubShell ( + const ViewShell& rParentShell, + ShellId nId) +{ + ::osl::MutexGuard aGuard (maMutex); + + do + { + // Check that the given view shell is active. + SubShellList::iterator iList (maActiveSubShells.find(&rParentShell)); + if (iList == maActiveSubShells.end()) + break; + + // Look up the sub shell. + SubShellSubList& rList (iList->second); + SubShellSubList::iterator iShell ( + ::std::find_if(rList.begin(),rList.end(), IsId<SfxShell>(nId))); + if (iShell == rList.end()) + break; + SfxShell* pShell = iShell->mpShell; + if (pShell == NULL) + break; + + UpdateLock aLock (*this); + + ShellDescriptor<SfxShell> aDescriptor(*iShell); + // Remove the sub shell from both the internal structure as well as the + // SFX shell stack above and including the sub shell. + rList.erase(iShell); + TakeShellsFromStack(pShell); + + DestroySubShell(rParentShell, aDescriptor); + } + while (false); +} + + + + +void ViewShellManager::Implementation::MoveSubShellToTop ( + const ViewShell& rParentShell, + ShellId nId) +{ + SubShellList::iterator iList (maActiveSubShells.find(&rParentShell)); + if (iList != maActiveSubShells.end()) + { + // Look up the sub shell. + SubShellSubList& rList (iList->second); + SubShellSubList::iterator iShell ( + ::std::find_if(rList.begin(),rList.end(), IsId<SfxShell>(nId))); + if (iShell!=rList.end() && iShell!=rList.begin()) + { + SubShellSubList::value_type aEntry (*iShell); + rList.erase(iShell); + rList.push_front(aEntry); + } + } + else + { + // Ignore this call when there are no sub shells for the given + // parent shell. We could remember the sub shell to move to the top + // but we do not. Do call this method at a later time instead. + } +} + + + +void ViewShellManager::Implementation::MoveToTop (const ViewShell& rShell) +{ + ::osl::MutexGuard aGuard (maMutex); + + ActiveShellList::iterator iShell (::std::find_if ( maActiveViewShells.begin(), maActiveViewShells.end(), - IsShell(pShell))); + IsShell<ViewShell>(&rShell))); bool bMove = true; - if (aI != maActiveViewShells.end()) + if (iShell != maActiveViewShells.end()) { // Is the shell already at the top of the stack? We have to keep // the case in mind that mbKeepMainViewShellOnTop is true. Shells // that are not the main view shell are placed on the second-to-top // position in this case. - if (aI == maActiveViewShells.begin() - && (aI->mpViewShell->IsMainViewShell() || ! mbKeepMainViewShellOnTop)) + if (iShell == maActiveViewShells.begin() + && (iShell->mpShell->IsMainViewShell() || ! mbKeepMainViewShellOnTop)) { // The shell is at the top position and is either a) the main // view shell or b) another shell but the main view shell is not // kept at the top position. We do not have to move the shell. bMove = false; } - else if (aI == ++maActiveViewShells.begin() - && ! aI->mpViewShell->IsMainViewShell() + else if (iShell == ++maActiveViewShells.begin() + && ! iShell->mpShell->IsMainViewShell() && mbKeepMainViewShellOnTop) { // The shell is a the second-to-top position, not the main view @@ -494,70 +766,145 @@ void ViewShellManager::Implementation::MoveToTop (const ViewShell* pShell) } } else + { // The shell is not on the stack. Therefore it can not be moved. // We could insert it but we don't. Use ActivateViewShell() for // that. bMove = false; + } // When the shell is not at the right position it is removed from the // internal list of shells and inserted at the correct position. if (bMove) { UpdateLock aLock (*this); - TakeShellsFromStack(pShell); - ViewShell* pNonConstViewShell = aI->mpViewShell; - ShellId nId = aI->mnId; - maActiveViewShells.erase(aI); + ShellDescriptor<ViewShell> aDescriptor(*iShell); + + TakeShellsFromStack(&rShell); + maActiveViewShells.erase(iShell); // Find out whether to insert at the top or one below. - ActiveShellList::iterator aInsertPosition ( - maActiveViewShells.begin()); - if (mbKeepMainViewShellOnTop && ! aI->mpViewShell->IsMainViewShell()) + ActiveShellList::iterator aInsertPosition (maActiveViewShells.begin()); + if (mbKeepMainViewShellOnTop && ! aDescriptor.mpShell->IsMainViewShell()) { - if (maActiveViewShells.back().mpViewShell->IsMainViewShell()) + if (maActiveViewShells.back().mpShell->IsMainViewShell()) aInsertPosition++; } - maActiveViewShells.insert ( - aInsertPosition, - ActiveShellDescriptor(pNonConstViewShell,nId)); + maActiveViewShells.insert(aInsertPosition, aDescriptor); } } -ViewShell* ViewShellManager::Implementation::GetShell (ShellId nId) +SfxShell* ViewShellManager::Implementation::GetShell (ShellId nId) const { - ActiveShellList::iterator aI (::std::find_if ( + ::osl::MutexGuard aGuard (maMutex); + + SfxShell* pShell = NULL; + + // First search the active view shells. + ActiveShellList::const_iterator iShell ( + ::std::find_if ( maActiveViewShells.begin(), maActiveViewShells.end(), - IsId(nId))); - if (aI != maActiveViewShells.end()) - return aI->mpViewShell; + IsId<ViewShell>(nId))); + if (iShell != maActiveViewShells.end()) + pShell = iShell->mpShell; else - return NULL; + { + // Now search the active sub shells of every active view shell. + SubShellList::const_iterator iList; + for (iList=maActiveSubShells.begin(); iList!=maActiveSubShells.end(); ++iList) + { + const SubShellSubList& rList (iList->second); + SubShellSubList::const_iterator iSubShell( + ::std::find_if(rList.begin(),rList.end(), IsId<SfxShell>(nId))); + if (iSubShell != rList.end()) + { + pShell = iSubShell->mpShell; + break; + } + } + } + + return pShell; } -ShellId ViewShellManager::Implementation::GetShellId (const ViewShell* pShell) +SfxShell* ViewShellManager::Implementation::GetTopShell (void) const { - ActiveShellList::iterator aI (::std::find_if ( - maActiveViewShells.begin(), - maActiveViewShells.end(), - IsShell(pShell))); - if (aI != maActiveViewShells.end()) - return aI->mnId; - else - return snInvalidShellId; + OSL_ASSERT(mpTopShell == mrBase.GetSubShell(0)); + return mpTopShell; +} + + + + +ShellId ViewShellManager::Implementation::GetShellId (const SfxShell* pShell) const +{ + ::osl::MutexGuard aGuard (maMutex); + + ShellId nId = snInvalidShellId; + + // First search the active view shells. + const ViewShell* pViewShell = dynamic_cast<const ViewShell*>(pShell); + if (pShell != NULL) + { + ActiveShellList::const_iterator iShell ( + ::std::find_if ( + maActiveViewShells.begin(), + maActiveViewShells.end(), + IsShell<ViewShell>(pViewShell))); + if (iShell != maActiveViewShells.end()) + nId = iShell->mnId; + } + if (nId == snInvalidShellId) + { + // Now search the active sub shells of every active view shell. + SubShellList::const_iterator iList; + for (iList=maActiveSubShells.begin(); iList!=maActiveSubShells.end(); ++iList) + { + const SubShellSubList& rList (iList->second); + SubShellSubList::const_iterator iSubShell( + ::std::find_if(rList.begin(),rList.end(), IsShell<SfxShell>(pShell))); + if (iSubShell != rList.end()) + { + nId = iSubShell->mnId; + break; + } + } + } + + return nId; +} + + + + +void ViewShellManager::Implementation::ReplaceUndoManager ( + SfxUndoManager* pManager, + SfxUndoManager* pReplacement) +{ + for (int i=0; ;++i) + { + SfxShell* pShell = mrBase.GetSubShell(i); + if (pShell == NULL) + break; + if (pShell->GetUndoManager() == pManager) + pShell->SetUndoManager(pReplacement); + } } + + void ViewShellManager::Implementation::LockUpdate (void) { mnUpdateLockCount++; @@ -568,6 +915,8 @@ void ViewShellManager::Implementation::LockUpdate (void) void ViewShellManager::Implementation::UnlockUpdate (void) { + ::osl::MutexGuard aGuard (maMutex); + mnUpdateLockCount--; if (mnUpdateLockCount < 0) { @@ -576,91 +925,72 @@ void ViewShellManager::Implementation::UnlockUpdate (void) mnUpdateLockCount = 0; } if (mnUpdateLockCount == 0) - PushShellsOnStack(); + UpdateShellStack(); } -void ViewShellManager::Implementation::PushShellsOnStack (void) +/** Update the SFX shell stack (the portion that is visible to us) so that + it matches the internal shell stack. This is done in six steps: + 1. Create the missing view shells and sub shells. + 2. Set up the internal shell stack. + 3. Get the SFX shell stack. + 4. Find the lowest shell in which the two stacks differ. + 5. Remove all shells above and including that shell from the SFX stack. + 6. Push all shells of the internal stack on the SFX shell stack that are + not already present on the later. +*/ +void ViewShellManager::Implementation::UpdateShellStack (void) { - // Create a local stack of the shells that are to push on the shell - // stack. We can thus safly create the required shells wile still - // having a valid shell stack. - ShellStack aShellStack; - for (ActiveShellList::reverse_iterator aI (maActiveViewShells.rbegin()); - aI!=maActiveViewShells.rend(); - ++aI) - { - // Get all its sub shells that are placed below the shell. - aI->mpViewShell->GetLowerShellList (aShellStack); + ::osl::MutexGuard aGuard (maMutex); - // Put the shell itself on the local stack. - aShellStack.push_back (aI->mpViewShell); + // Remember the undo manager from the top-most shell on the stack. + SfxShell* pTopMostShell = mrBase.GetSubShell(0); + SfxUndoManager* pUndoManager = (pTopMostShell!=NULL) + ? pTopMostShell->GetUndoManager() + : NULL; - // Get all its sub shells that are placed above the shell. - aI->mpViewShell->GetUpperShellList (aShellStack); - } - - // Now update the SFX stack to look like the local stack. - UpdateShellStack (aShellStack); -} + // 1. Create the missing shells. + CreateShells(); + // 2. Create the internal target stack. + ShellStack aTargetStack; + CreateTargetStack(aTargetStack); -/** Update the SFX shell stack (the portion that is visible to us) so that - it matches the internal shell stack. Since we can not look at the - shells on the SFX stack directly we use the copy that we created the - last time when we rebuilt the SFX stack. This is done in three steps: - 1. Find the lowest shell in which the two stack differ. - 2. Remove all shells above and including that shell from the SFX stack. - This should not be necessary because deactivated shells should have been - removed already. - 3. Push all shells of the internal stack on the SFX shell stack that are - not already present on the later. -*/ -void ViewShellManager::Implementation::UpdateShellStack (ShellStack& rRequestedStack) -{ + // 3. Get SFX shell stack. ShellStack aSfxShellStack; - ShellStack::const_iterator iSfxShell; - ShellStack::iterator iRequestedShell; + USHORT nIndex (0); + while (mrBase.GetSubShell(nIndex)!=NULL) + ++nIndex; + aSfxShellStack.reserve(nIndex); + while (nIndex-- > 0) + aSfxShellStack.push_back(mrBase.GetSubShell(nIndex)); - mbShellStackIsUpToDate = false; #ifdef VERBOSE - OSL_TRACE("UpdateShellStack"); OSL_TRACE("Current SFX Stack"); - DumpSfxShellStack(); - OSL_TRACE("Requested Stack"); - DumpShellStack(rRequestedStack); + DumpShellStack(aSfxShellStack); + OSL_TRACE("Target Stack"); + DumpShellStack(aTargetStack); #endif - // 1. Put the SFX shell stack in a local data structure so that it can - // be searched properly. - for (USHORT nIndex=0; true; nIndex++) - { - if (mrBase.GetSubShell(nIndex)==NULL) - { - aSfxShellStack.reserve(nIndex); - while (nIndex-- > 0) - aSfxShellStack.push_back(mrBase.GetSubShell(nIndex)); - break; - } - } - // 2. Find the lowest shell in which the two stacks differ. - iSfxShell = aSfxShellStack.begin(); - iRequestedShell = rRequestedStack.begin(); + // 4. Find the lowest shell in which the two stacks differ. + ShellStack::const_iterator iSfxShell (aSfxShellStack.begin()); + ShellStack::iterator iTargetShell (aTargetStack.begin()); while (iSfxShell != aSfxShellStack.end() - && iRequestedShell!=rRequestedStack.end() - && (*iSfxShell)==(*iRequestedShell)) + && iTargetShell!=aTargetStack.end() + && (*iSfxShell)==(*iTargetShell)) { ++iSfxShell; - ++iRequestedShell; + ++iTargetShell; } - // 3. Remove all shells above and including the differing shell from the + + // 5. Remove all shells above and including the differing shell from the // SFX stack starting with the shell on top of the stack. while (iSfxShell != aSfxShellStack.end()) { @@ -672,14 +1002,16 @@ void ViewShellManager::Implementation::UpdateShellStack (ShellStack& rRequestedS mrBase.RemoveSubShell(pShell); } - // 4. Push shells from the given stack onto the SFX stack. - while (iRequestedShell != rRequestedStack.end()) + + // 6. Push shells from the given stack onto the SFX stack. + mbShellStackIsUpToDate = false; + while (iTargetShell != aTargetStack.end()) { #ifdef VERBOSE - OSL_TRACE("pushing shell %p on stack", *iRequestedShell); + OSL_TRACE("pushing shell %p on stack", *iTargetShell); #endif - mrBase.AddSubShell(**iRequestedShell); - ++iRequestedShell; + mrBase.AddSubShell(**iTargetShell); + ++iTargetShell; // The pushing of the shell on to the shell stack may have lead to // another invocation of this method. In this case we have to abort @@ -687,12 +1019,16 @@ void ViewShellManager::Implementation::UpdateShellStack (ShellStack& rRequestedS if (mbShellStackIsUpToDate) break; } - - // 5. Tell the dispatcher to update the SFX shell. if (mrBase.GetDispatcher() != NULL) mrBase.GetDispatcher()->Flush(); - // 6. Finally Tell an invocation of this method on a higher level that it can (has + // Update the pointer to the top-most shell and set its undo manager + // to the one of the previous top-most shell. + mpTopShell = mrBase.GetSubShell(0); + if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL) + mpTopShell->SetUndoManager(pUndoManager); + + // Finally tell an invocation of this method on a higher level that it can (has // to) abort and return immediately. mbShellStackIsUpToDate = true; @@ -707,6 +1043,14 @@ void ViewShellManager::Implementation::UpdateShellStack (ShellStack& rRequestedS void ViewShellManager::Implementation::TakeShellsFromStack (const SfxShell* pShell) { + ::osl::MutexGuard aGuard (maMutex); + + // Remember the undo manager from the top-most shell on the stack. + SfxShell* pTopMostShell = mrBase.GetSubShell(0); + SfxUndoManager* pUndoManager = (pTopMostShell!=NULL) + ? pTopMostShell->GetUndoManager() + : NULL; + #ifdef VERBOSE OSL_TRACE("TakeShellsFromStack(%p)", pShell); DumpSfxShellStack(); @@ -755,6 +1099,12 @@ void ViewShellManager::Implementation::TakeShellsFromStack (const SfxShell* pShe // 3. Update the stack. if (mrBase.GetDispatcher() != NULL) mrBase.GetDispatcher()->Flush(); + + // Update the pointer to the top-most shell and set its undo manager + // to the one of the previous top-most shell. + mpTopShell = mrBase.GetSubShell(0); + if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL) + mpTopShell->SetUndoManager(pUndoManager); } #ifdef VERBOSE @@ -766,9 +1116,76 @@ void ViewShellManager::Implementation::TakeShellsFromStack (const SfxShell* pShe -ViewShellBase& ViewShellManager::Implementation::GetViewShellBase (void) const +void ViewShellManager::Implementation::CreateShells (void) { - return mrBase; + ::osl::MutexGuard aGuard (maMutex); + + // Iterate over all view shells. + ShellStack aShellStack; + ActiveShellList::reverse_iterator iShell; + for (iShell=maActiveViewShells.rbegin(); iShell!=maActiveViewShells.rend(); ++iShell) + { + // Get the list of associated sub shells. + SubShellList::iterator iList (maActiveSubShells.find(iShell->mpShell)); + if (iList != maActiveSubShells.end()) + { + SubShellSubList& rList (iList->second); + + // Iterate over all sub shells of the current view shell. + SubShellSubList::iterator iSubShell; + for (iSubShell=rList.begin(); iSubShell!=rList.end(); ++iSubShell) + { + if (iSubShell->mpShell == NULL) + { + *iSubShell = CreateSubShell(iShell->mpShell,iSubShell->mnId,NULL,NULL); + } + } + } + } +} + + + + +void ViewShellManager::Implementation::CreateTargetStack (ShellStack& rStack) const +{ + // Create a local stack of the shells that are to push on the shell + // stack. We can thus safly create the required shells wile still + // having a valid shell stack. + for (ActiveShellList::const_reverse_iterator iViewShell (maActiveViewShells.rbegin()); + iViewShell != maActiveViewShells.rend(); + ++iViewShell) + { + // Possibly place the form shell below the current view shell. + if ( ! mbFormShellAboveParent + && mpFormShell!=NULL + && iViewShell->mpShell==mpFormShellParent) + { + rStack.push_back(mpFormShell); + } + + // Put the view shell itself on the local stack. + rStack.push_back (iViewShell->mpShell); + + // Possibly place the form shell above the current view shell. + if (mbFormShellAboveParent + && mpFormShell!=NULL + && iViewShell->mpShell==mpFormShellParent) + { + rStack.push_back(mpFormShell); + } + + // Add all other sub shells. + SubShellList::const_iterator iList (maActiveSubShells.find(iViewShell->mpShell)); + if (iList != maActiveSubShells.end()) + { + const SubShellSubList& rList (iList->second); + SubShellSubList::const_reverse_iterator iSubShell; + for (iSubShell=rList.rbegin(); iSubShell!=rList.rend(); ++iSubShell) + if (iSubShell->mpShell != mpFormShell) + rStack.push_back(iSubShell->mpShell); + } + } } @@ -790,9 +1207,9 @@ IMPL_LINK(ViewShellManager::Implementation, WindowEventHandler, VclWindowEvent*, aI++) { if (pEventWindow == static_cast< ::Window*>( - aI->mpViewShell->GetActiveWindow())) + aI->mpShell->GetActiveWindow())) { - MoveToTop (aI->mpViewShell); + MoveToTop(*aI->mpShell); break; } } @@ -809,33 +1226,125 @@ IMPL_LINK(ViewShellManager::Implementation, WindowEventHandler, VclWindowEvent*, -ViewShell* ViewShellManager::Implementation::CreateViewShell ( +ShellDescriptor<ViewShell> ViewShellManager::Implementation::CreateViewShell ( ShellId nShellId, ::Window* pParentWindow, FrameView* pFrameView) { - ViewShell* pViewShell = NULL; + ShellDescriptor<ViewShell> aResult; - // Initialize with the default factory. - ViewShellFactory* pFactory = mpDefaultFactory.get(); + if (pParentWindow != NULL) + { + ShellDescriptor<SfxShell> aDescriptor ( + CreateSubShell(NULL,nShellId,pParentWindow,pFrameView)); + aResult.mpShell = dynamic_cast<ViewShell*>(aDescriptor.mpShell); + aResult.mpFactory = aDescriptor.mpFactory; + aResult.mnId = aDescriptor.mnId; + + // Register as window listener so that the shells of the current + // window can be moved to the top of the shell stack. + if (aResult.mpShell != NULL) + { + ::Window* pWindow = aResult.mpShell->GetActiveWindow(); + if (pWindow != NULL) + pWindow->AddEventListener( + LINK(this, ViewShellManager::Implementation, WindowEventHandler)); + else + { + DBG_ASSERT (aResult.mpShell->GetActiveWindow()!=NULL, + "ViewShellManager::ActivateViewShell: " + "new view shell has no active window"); + } + } + } - // Look up a specialized factory. - SpecializedFactoryList::iterator aI (maSpecializedFactories.find(nShellId)); - if (aI != maSpecializedFactories.end()) - pFactory = aI->second; + return aResult; +} - UpdateLock aLocker (*this); - if (pFactory!=NULL && pParentWindow!=NULL) + + +ShellDescriptor<SfxShell> ViewShellManager::Implementation::CreateSubShell ( + ViewShell* pParentShell, + ShellId nShellId, + ::Window* pParentWindow, + FrameView* pFrameView) +{ + ::osl::MutexGuard aGuard (maMutex); + ShellDescriptor<SfxShell> aResult; + + // Look up the factories for the parent shell. + ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange( + maShellFactories.equal_range(pParentShell)); + + // Try all factories to create the shell. + for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory) { - // Create view shell with the factory. - pViewShell = pFactory->CreateShell ( - nShellId, - pParentWindow, - pFrameView); + SharedShellFactory pFactory = iFactory->second; + if (pFactory != NULL) + aResult.mpShell = pFactory->CreateShell(nShellId, pParentWindow, pFrameView); + + // Exit the loop when the shell has been successfully created. + if (aResult.mpShell != NULL) + { + aResult.mpFactory = pFactory; + aResult.mnId = nShellId; + break; + } } - return pViewShell; + return aResult; +} + + + + +void ViewShellManager::Implementation::DestroyViewShell ( + const ShellDescriptor<ViewShell>& rDescriptor) +{ + OSL_ASSERT(rDescriptor.mpShell != NULL); + + rDescriptor.mpShell->GetActiveWindow()->RemoveEventListener( + LINK(this, ViewShellManager::Implementation, WindowEventHandler)); + + // Destroy the sub shell factories. + ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange( + maShellFactories.equal_range(rDescriptor.mpShell)); + if (aRange.first != maShellFactories.end()) + maShellFactories.erase(aRange.first, aRange.second); + + // Release the shell. + OSL_ASSERT(rDescriptor.mpFactory.get() != NULL); + rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell); +} + + + + +void ViewShellManager::Implementation::DestroySubShell ( + const ViewShell& rParentShell, + const ShellDescriptor<SfxShell>& rDescriptor) +{ + OSL_ASSERT(rDescriptor.mpFactory.get() != NULL); + rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell); +} + + + + +void ViewShellManager::Implementation::InvalidateAllSubShells (const ViewShell* pParentShell) +{ + ::osl::MutexGuard aGuard (maMutex); + + SubShellList::iterator iList (maActiveSubShells.find(pParentShell)); + if (iList != maActiveSubShells.end()) + { + SubShellSubList& rList (iList->second); + SubShellSubList::iterator iShell; + for (iShell=rList.begin(); iShell!=rList.end(); ++iShell) + if (iShell->mpShell != NULL) + iShell->mpShell->Invalidate(); + } } @@ -843,6 +1352,8 @@ ViewShell* ViewShellManager::Implementation::CreateViewShell ( void ViewShellManager::Implementation::Shutdown (void) { + ::osl::MutexGuard aGuard (maMutex); + // Take stacked shells from stack. if ( ! maActiveViewShells.empty()) { @@ -850,23 +1361,12 @@ void ViewShellManager::Implementation::Shutdown (void) while ( ! maActiveViewShells.empty()) { - DeactivateViewShell(maActiveViewShells.front().mpViewShell); + DeactivateViewShell(*maActiveViewShells.front().mpShell); } } mrBase.RemoveSubShell (NULL); - // We have the ownership of the factories and because they can not be - // auto_ptrs in an stl list we have to delete them now by hand. - for (SpecializedFactoryList::iterator aI (maSpecializedFactories.begin()); - aI!=maSpecializedFactories.end(); - aI++) - { - delete aI->second; - } - - // Destroy members. - maCache.Shutdown(); - mpDefaultFactory.reset(); + maShellFactories.clear(); } @@ -874,13 +1374,8 @@ void ViewShellManager::Implementation::Shutdown (void) void ViewShellManager::Implementation::DumpActiveShell (const ActiveShellList& rList) { - ActiveShellList::const_iterator aI; - for (aI=rList.begin(); aI!=rList.end(); ++aI) - { - OSL_TRACE (" %d %p", - aI->mnId, - aI->mpViewShell); - } + for (ActiveShellList::const_iterator aI=rList.begin(); aI!=rList.end(); ++aI) + OSL_TRACE (" %d %p", aI->mnId, aI->mpShell); } @@ -890,9 +1385,12 @@ void ViewShellManager::Implementation::DumpShellStack (const ShellStack& rStack) { ShellStack::const_reverse_iterator iEntry; for (iEntry=rStack.rbegin(); iEntry!=rStack.rend(); ++iEntry) - OSL_TRACE (" %p: %s", - *iEntry, - ::rtl::OUStringToOString((*iEntry)->GetName(),RTL_TEXTENCODING_UTF8).getStr()); + if (*iEntry != NULL) + OSL_TRACE (" %p : %s", + *iEntry, + ::rtl::OUStringToOString((*iEntry)->GetName(),RTL_TEXTENCODING_UTF8).getStr()); + else + OSL_TRACE(" null"); } @@ -900,17 +1398,14 @@ void ViewShellManager::Implementation::DumpShellStack (const ShellStack& rStack) void ViewShellManager::Implementation::DumpSfxShellStack (void) { - USHORT nIndex; - for (nIndex=0; true; nIndex++) - { - SfxShell* pShell = mrBase.GetSubShell(nIndex); - if (pShell == NULL) - break; - OSL_TRACE (" %d : %p: %s", - nIndex, - pShell, - ::rtl::OUStringToOString(pShell->GetName(),RTL_TEXTENCODING_UTF8).getStr()); - } + ShellStack aSfxShellStack; + USHORT nIndex (0); + while (mrBase.GetSubShell(nIndex)!=NULL) + ++nIndex; + aSfxShellStack.reserve(nIndex); + while (nIndex-- > 0) + aSfxShellStack.push_back(mrBase.GetSubShell(nIndex)); + DumpShellStack(aSfxShellStack); } @@ -943,29 +1438,34 @@ void ViewShellManager::Implementation::Deactivate (SfxShell* pShell) -//===== ViewShellManager::UpdateLock ========================================== - -ViewShellManager::UpdateLock::UpdateLock (ViewShellManager& rManager) - : mrManagerImplementation(*rManager.mpImpl.get()) +void ViewShellManager::Implementation::SetFormShell ( + const ViewShell* pFormShellParent, + FmFormShell* pFormShell, + bool bFormShellAboveParent) { - mrManagerImplementation.LockUpdate(); -} - - - + ::osl::MutexGuard aGuard (maMutex); -ViewShellManager::UpdateLock::UpdateLock (ViewShellManager::Implementation& rManagerImplementation) - : mrManagerImplementation(rManagerImplementation) -{ - mrManagerImplementation.LockUpdate(); + mpFormShellParent = pFormShellParent; + mpFormShell = pFormShell; + mbFormShellAboveParent = bFormShellAboveParent; } -ViewShellManager::UpdateLock::~UpdateLock (void) +void ViewShellManager::Implementation::DeactivateAllSubShells ( + const ViewShell& rViewShell) { - mrManagerImplementation.UnlockUpdate(); + ::osl::MutexGuard aGuard (maMutex); + + SubShellList::iterator iList (maActiveSubShells.find(&rViewShell)); + if (iList != maActiveSubShells.end()) + { + SubShellSubList& rList (iList->second); + UpdateLock aLock (*this); + while ( ! rList.empty()) + DeactivateSubShell(rViewShell, rList.front().mnId); + } } |