diff options
author | Kurt Zenker <kz@openoffice.org> | 2005-07-14 09:21:08 +0000 |
---|---|---|
committer | Kurt Zenker <kz@openoffice.org> | 2005-07-14 09:21:08 +0000 |
commit | edeb6051e4957ae2fd5a850e3e25face791e5205 (patch) | |
tree | 8defb44cd8fda73e4fc7cdd895ad894817eb1cba /sd/source/ui/toolpanel | |
parent | fda0e5aa4f7b2d6c0cba2675aa36d53eed2c27f3 (diff) |
INTEGRATION: CWS impress51 (1.2.320); FILE MERGED
2005/06/10 12:30:25 af 1.2.320.2: #i50190# Fixed solaris compiler warning.
2005/06/06 12:14:55 af 1.2.320.1: #i50190# Made the focus management more general.
Diffstat (limited to 'sd/source/ui/toolpanel')
-rw-r--r-- | sd/source/ui/toolpanel/TaskPaneFocusManager.cxx | 170 |
1 files changed, 135 insertions, 35 deletions
diff --git a/sd/source/ui/toolpanel/TaskPaneFocusManager.cxx b/sd/source/ui/toolpanel/TaskPaneFocusManager.cxx index 9be1135cd06b..97e909c3f55e 100644 --- a/sd/source/ui/toolpanel/TaskPaneFocusManager.cxx +++ b/sd/source/ui/toolpanel/TaskPaneFocusManager.cxx @@ -2,9 +2,9 @@ * * $RCSfile: TaskPaneFocusManager.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: rt $ $Date: 2004-07-13 14:36:21 $ + * last change: $Author: kz $ $Date: 2005-07-14 10:21:08 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -71,11 +71,41 @@ #ifndef _SV_EVENT_HXX #include <vcl/event.hxx> #endif +#include <hash_map> + +namespace { + +class WindowHash +{ +public: + size_t operator()(::Window* argument) const + { return reinterpret_cast<unsigned long>(argument); } +}; + +class EventDescriptor +{ +public: + EventDescriptor (const KeyCode& rKey, ::Window* pWindow) + : maKeyCode(rKey), mpTargetWindow(pWindow) {} + KeyCode maKeyCode; + ::Window* mpTargetWindow; +}; + +} // end of anonymous namespace + + namespace sd { namespace toolpanel { + +class FocusManager::LinkMap : public ::std::hash_multimap< ::Window*, EventDescriptor, WindowHash> +{ +}; + + + FocusManager* FocusManager::spInstance = NULL; @@ -94,6 +124,7 @@ FocusManager& FocusManager::Instance (void) FocusManager::FocusManager (void) + : mpLinks(new LinkMap()) { } @@ -107,67 +138,135 @@ FocusManager::~FocusManager (void) -void FocusManager::RegisterLink (::Window* pParent, ::Window* pChild) +void FocusManager::RegisterUpLink (::Window* pSource, ::Window* pTarget) { - RegisterUpLink (pChild, pParent); - RegisterDownLink (pParent, pChild); + RegisterLink(pSource, pTarget, KEY_ESCAPE); } -void FocusManager::RegisterUpLink (::Window* pSource, ::Window* pTarget) +void FocusManager::RegisterDownLink (::Window* pSource, ::Window* pTarget) { - maUpLinks[pSource] = pTarget; - pSource->AddEventListener (LINK (this, FocusManager, WindowEventListener)); + RegisterLink(pSource, pTarget, KEY_RETURN); } -void FocusManager::RegisterDownLink (::Window* pSource, ::Window* pTarget) +void FocusManager::RegisterLink ( + ::Window* pSource, + ::Window* pTarget, + const KeyCode& rKey) { - maDownLinks[pSource] = pTarget; - pSource->AddEventListener (LINK (this, FocusManager, WindowEventListener)); + // Register this focus manager as event listener at the source window. + if (mpLinks->equal_range(pSource).first == mpLinks->end()) + pSource->AddEventListener (LINK (this, FocusManager, WindowEventListener)); + mpLinks->insert(LinkMap::value_type(pSource, EventDescriptor(rKey,pTarget))); } -bool FocusManager::TransferFocusUp (::Window* pWindow) +void FocusManager::RemoveLinks ( + ::Window* pSourceWindow, + ::Window* pTargetWindow) { - bool bSuccess (false); - - HashMap::iterator aTarget = maUpLinks.find (pWindow); - if (aTarget != maUpLinks.end()) + ::std::pair<LinkMap::iterator,LinkMap::iterator> aCandidates; + LinkMap::iterator iCandidate; + bool bLoop (mpLinks->size() > 0); + while (bLoop) { - aTarget->second->GrabFocus(); - bSuccess = true; + aCandidates = mpLinks->equal_range(pSourceWindow); + if (aCandidates.first == mpLinks->end()) + { + // No links for the source window found -> nothing more to do. + bLoop = false; + } + else + { + // Set the loop control to false so that when no candidate for + // deletion is found the loop is left. + bLoop = false; + for (iCandidate=aCandidates.first; iCandidate!=aCandidates.second; ++iCandidate) + if (iCandidate->second.mpTargetWindow == pTargetWindow) + { + mpLinks->erase(iCandidate); + // One link erased. The iterators have become invalid so + // start the search for links to delete anew. + bLoop = true; + break; + } + } } - return bSuccess; + RemoveUnusedEventListener(pSourceWindow); } -bool FocusManager::TransferFocusDown (::Window* pWindow) +void FocusManager::RemoveLinks (::Window* pWindow) { - bool bSuccess (false); - - HashMap::iterator aTarget = maDownLinks.find (pWindow); - if (aTarget != maDownLinks.end()) + // Remove the links from the given window. + ::std::pair<LinkMap::iterator,LinkMap::iterator> aCandidates(mpLinks->equal_range(pWindow)); + mpLinks->erase(aCandidates.first, aCandidates.second); + pWindow->RemoveEventListener (LINK (this, FocusManager, WindowEventListener)); + + // Remove links to the given window. + bool bLinkRemoved (false); + do { - aTarget->second->GrabFocus(); - bSuccess = true; + LinkMap::iterator iLink; + for (iLink=mpLinks->begin(); iLink!=mpLinks->end(); ++iLink) + { + if (iLink->second.mpTargetWindow == pWindow) + { + mpLinks->erase(iLink); + RemoveUnusedEventListener(iLink->first); + bLinkRemoved; + break; + } + } } + while (bLinkRemoved); +} - return bSuccess; + + + +void FocusManager::RemoveUnusedEventListener (::Window* pWindow) +{ + // When there are no more links from the window to another window + // then remove the event listener from the window. + if (mpLinks->find(pWindow) == mpLinks->end()) + pWindow->RemoveEventListener (LINK (this, FocusManager, WindowEventListener)); } +bool FocusManager::TransferFocus ( + ::Window* pSourceWindow, + const KeyCode& rKeyCode) +{ + bool bSuccess (false); + + ::std::pair<LinkMap::iterator,LinkMap::iterator> aCandidates ( + mpLinks->equal_range(pSourceWindow)); + LinkMap::const_iterator iCandidate; + for (iCandidate=aCandidates.first; iCandidate!=aCandidates.second; ++iCandidate) + if (iCandidate->second.maKeyCode == rKeyCode) + { + iCandidate->second.mpTargetWindow->GrabFocus(); + bSuccess = true; + break; + } + + return bSuccess; +} + + IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent) @@ -177,19 +276,20 @@ IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent) VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent); switch (pWindowEvent->GetId()) { - // case VCLEVENT_WINDOW_KEYUP: case VCLEVENT_WINDOW_KEYINPUT: + { Window* pSource = pWindowEvent->GetWindow(); - KeyEvent* pKeyEvent = - static_cast<KeyEvent*>(pWindowEvent->GetData()); - if (pKeyEvent->GetKeyCode() == KEY_RETURN) - TransferFocusDown (pSource); - else if (pKeyEvent->GetKeyCode() == KEY_ESCAPE) - TransferFocusUp (pSource); + KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData()); + TransferFocus(pSource, pKeyEvent->GetKeyCode()); + } + break; + + case VCLEVENT_OBJECT_DYING: + RemoveLinks(pWindowEvent->GetWindow()); break; } } - return 0; + return 1; } |