From 967a386bccb15b99915a1e878e42450fbe9a2d0e Mon Sep 17 00:00:00 2001 From: Marco Cecchetti Date: Wed, 5 Nov 2014 20:15:32 +0100 Subject: Fix for SUSE L3 bug 624546 (freedesktop 83733) Problem: When I'm in outline mode, if I select a slide in the left slide preview pane, ctrl-c, then select another slide I would like it after and hit ctrl-v; it refuses to cut/paste. Analysis: This issue is due to the fact that the outline view always grabs focus when activated and a view is activated whenever is pushed to the sfx shell stack even if it is not the new top-most active view shell (see `ViewShellManager`, `SfxViewShell`, `SfxDispacther`). Solution: Make the `OutlineViewShell` grabs focus only if it is the top-most active view shell. Rationale: When `OutlineViewShell::Activate` is invoked, instead of removing the focus grabbing action completely, we check if the `OutlineViewShell` instance is the the top-most view shell and perform the focus grabbing action only in such a case. This change required to have also the `DrawViewShell` grabbing focus on activation (only when it is the top-most view shell). In order to implement this solution I needed to add a new method (and data member) to the `ViewShellManager` class. I named it `GetTopViewShell`. This method returns a pointer to the top-most active view shell of the internal stack. The returned pointer is updated in the `UpdateShellStack` method, before the sfx shell stack is updated. For more details see : https://gist.github.com/mcecchetti/15b3ebc505d6582ea0db Change-Id: I619a406864f50f0e62dee3fcb9ac5d46e3d48272 --- sd/source/ui/inc/ViewShellManager.hxx | 4 ++++ sd/source/ui/view/ViewShellManager.cxx | 23 ++++++++++++++++++++++- sd/source/ui/view/drviews1.cxx | 9 +++++++++ sd/source/ui/view/outlview.cxx | 11 ++++++++++- 4 files changed, 45 insertions(+), 2 deletions(-) (limited to 'sd') diff --git a/sd/source/ui/inc/ViewShellManager.hxx b/sd/source/ui/inc/ViewShellManager.hxx index a88408ff27e3..683eb2387de4 100644 --- a/sd/source/ui/inc/ViewShellManager.hxx +++ b/sd/source/ui/inc/ViewShellManager.hxx @@ -164,6 +164,10 @@ public: */ SfxShell* GetTopShell (void) const; + /** Return the top-most active view shell on the internal shell stack. + */ + SfxShell* GetTopViewShell (void) const; + /** Use this class to safely lock updates of the view shell stack. */ class UpdateLock diff --git a/sd/source/ui/view/ViewShellManager.cxx b/sd/source/ui/view/ViewShellManager.cxx index 59dd054fed19..91f82cd47e6d 100644 --- a/sd/source/ui/view/ViewShellManager.cxx +++ b/sd/source/ui/view/ViewShellManager.cxx @@ -116,6 +116,7 @@ public: void MoveToTop (const SfxShell& rParentShell); SfxShell* GetShell (ShellId nId) const; SfxShell* GetTopShell (void) const; + SfxShell* GetTopViewShell (void) const; void Shutdown (void); void InvalidateAllSubShells (const SfxShell* pParentShell); @@ -191,6 +192,8 @@ private: bool mbFormShellAboveParent; SfxShell* mpTopShell; + SfxShell* mpTopViewShell; + void UpdateShellStack (void); @@ -327,6 +330,14 @@ SfxShell* ViewShellManager::GetTopShell (void) const return NULL; } +SfxShell* ViewShellManager::GetTopViewShell (void) const +{ + if (mbValid) + return mpImpl->GetTopViewShell(); + else + return NULL; +} + void ViewShellManager::Shutdown (void) { if (mbValid) @@ -361,7 +372,8 @@ ViewShellManager::Implementation::Implementation ( mpFormShell(NULL), mpFormShellParent(NULL), mbFormShellAboveParent(true), - mpTopShell(NULL) + mpTopShell(NULL), + mpTopViewShell(NULL) { (void)rManager; } @@ -706,6 +718,11 @@ SfxShell* ViewShellManager::Implementation::GetTopShell (void) const return mpTopShell; } +SfxShell* ViewShellManager::Implementation::GetTopViewShell (void) const +{ + return mpTopViewShell; +} + void ViewShellManager::Implementation::LockUpdate (void) { mnUpdateLockCount++; @@ -749,6 +766,10 @@ void ViewShellManager::Implementation::UpdateShellStack (void) // 1. Create the missing shells. CreateShells(); + // Update the pointer to the top-most active view shell. + mpTopViewShell = maActiveViewShells.begin()->mpShell; + + // 2. Create the internal target stack. ShellStack aTargetStack; CreateTargetStack(aTargetStack); diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx index 8bf432bdf44e..a2c2622f000b 100644 --- a/sd/source/ui/view/drviews1.cxx +++ b/sd/source/ui/view/drviews1.cxx @@ -89,6 +89,15 @@ namespace sd { void DrawViewShell::Activate(bool bIsMDIActivate) { ViewShell::Activate(bIsMDIActivate); + + // When the mode is switched to normal the main view shell grabs focus. + // This is done for getting cut/copy/paste commands on slides in the left + // pane (slide sorter view shell) to work properly. + SfxShell* pTopViewShell = this->GetViewShellBase().GetViewShellManager()->GetTopViewShell(); + if (pTopViewShell && pTopViewShell == this) + { + this->GetActiveWindow()->GrabFocus(); + } } void DrawViewShell::UIActivating( SfxInPlaceClient* pCli ) diff --git a/sd/source/ui/view/outlview.cxx b/sd/source/ui/view/outlview.cxx index 7b0384ea9524..ddf05e2f8626 100644 --- a/sd/source/ui/view/outlview.cxx +++ b/sd/source/ui/view/outlview.cxx @@ -63,6 +63,7 @@ #include "strings.hrc" #include "EventMultiplexer.hxx" #include "ViewShellBase.hxx" +#include "ViewShellManager.hxx" #include "undo/undoobjects.hxx" #include "undo/undomanager.hxx" #include "stlsheet.hxx" @@ -203,7 +204,15 @@ OutlineView::~OutlineView() void OutlineView::ConnectToApplication (void) { - mrOutlineViewShell.GetActiveWindow()->GrabFocus(); + // When the mode is switched to outline the main view shell grabs focus. + // This is done for getting cut/copy/paste commands on slides in the left + // pane (slide sorter view shell) to work properly. + SfxShell* pTopViewShell = mrOutlineViewShell.GetViewShellBase().GetViewShellManager()->GetTopViewShell(); + if (pTopViewShell && pTopViewShell == &mrOutlineViewShell) + { + mrOutlineViewShell.GetActiveWindow()->GrabFocus(); + } + Application::AddEventListener(LINK(this, OutlineView, AppEventListenerHdl)); } -- cgit