sd/inc/undo/undomanager.hxx                  |   10 ++++-
 sd/qa/unit/tiledrendering/tiledrendering.cxx |   39 +++++++++++++++++++++
 sd/source/core/undo/undomanager.cxx          |   50 +++++++++++++++++++++++++++
 sd/source/ui/view/viewshe3.cxx               |   11 +++++
 4 files changed, 109 insertions(+), 1 deletion(-)

New commits:
commit e0a3269183bf145511361a3968dca07824923dd4
Author: Miklos Vajna <vmik...@collabora.co.uk>
Date:   Wed Aug 17 07:53:16 2016 +0200

    sd lok: limit undo/redo access to undo actions created by the same view
    
    Unlike in Writer, the state and the exec method of .uno:Undo is
    different codepath so for now ignore the Repair argument of the command,
    assuming that the command is only dispatched if the command is enabled.
    
    Change-Id: I3bfe8d72522f32efe436e21c383c99b3612eab6b

diff --git a/sd/inc/undo/undomanager.hxx b/sd/inc/undo/undomanager.hxx
index a020038..5c3a082 100644
--- a/sd/inc/undo/undomanager.hxx
+++ b/sd/inc/undo/undomanager.hxx
@@ -22,11 +22,14 @@
 
 #include <misc/scopelock.hxx>
 #include <svx/sdrundomanager.hxx>
+#include "sddllapi.h"
+
+class SfxViewShell;
 
 namespace sd
 {
 
-class UndoManager : public SdrUndoManager
+class SD_DLLPUBLIC UndoManager : public SdrUndoManager
 {
 public:
     UndoManager( sal_uInt16 nMaxUndoActionCount = 20 );
@@ -34,6 +37,9 @@ public:
     virtual void            EnterListAction(const OUString &rComment, const 
OUString& rRepeatComment, sal_uInt16 nId, sal_Int32 nViewShellId) override;
 
     virtual void            AddUndoAction( SfxUndoAction *pAction, bool 
bTryMerg=false ) override;
+    size_t GetUndoActionCount(const bool bCurrentLevel = true) const override;
+    size_t GetRedoActionCount(const bool bCurrentLevel = true) const override;
+    void SetViewShell(SfxViewShell* pViewShell);
 
     /** Set or reset the undo manager linked with the called undo manager.
     */
@@ -47,6 +53,8 @@ private:
         synchronize the undo managers.
     */
     ::svl::IUndoManager* mpLinkedUndoManager;
+    /// Return undo/redo info for this view.
+    SfxViewShell* mpViewShell;
 
     /** Call ClearRedo() at the linked undo manager, when present.
 
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx 
b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 391366a..b5de222 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -69,6 +69,7 @@ public:
     void testViewCursorParts();
     void testCursorViews();
     void testViewLock();
+    void testUndoLimiting();
 
     CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -93,6 +94,7 @@ public:
     CPPUNIT_TEST(testViewCursorParts);
     CPPUNIT_TEST(testCursorViews);
     CPPUNIT_TEST(testViewLock);
+    CPPUNIT_TEST(testUndoLimiting);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -1071,6 +1073,43 @@ void SdTiledRenderingTest::testViewLock()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+void SdTiledRenderingTest::testUndoLimiting()
+{
+    comphelper::LibreOfficeKit::setActive();
+
+    // Create the first view.
+    SdXImpressDocument* pXImpressDocument = createDoc("title-shape.odp");
+    SfxViewShell& rViewShell1 = 
pXImpressDocument->GetDocShell()->GetViewShell()->GetViewShellBase();
+    SfxLokHelper::createView();
+    
pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+    SfxViewShell& rViewShell2 = 
pXImpressDocument->GetDocShell()->GetViewShell()->GetViewShellBase();
+
+    // Begin text edit on the only object on the slide.
+    sd::ViewShell* pViewShell = 
pXImpressDocument->GetDocShell()->GetViewShell();
+    SdrView* pView = pViewShell->GetView();
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT(pView->IsTextEdit());
+
+    // Now check what views see the undo action.
+    SdDrawDocument* pDocument = pXImpressDocument->GetDoc();
+    sd::UndoManager* pUndoManager = pDocument->GetUndoManager();
+    pUndoManager->SetViewShell(&rViewShell1);
+    // This was 1, undo action was visible to the first view, even if the
+    // action belongs to the second view.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), 
pUndoManager->GetUndoActionCount());
+    pUndoManager->SetViewShell(&rViewShell2);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
pUndoManager->GetUndoActionCount());
+    pUndoManager->SetViewShell(nullptr);
+
+    mxComponent->dispose();
+    mxComponent.clear();
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/core/undo/undomanager.cxx 
b/sd/source/core/undo/undomanager.cxx
index bbf2069..b0b9b68 100644
--- a/sd/source/core/undo/undomanager.cxx
+++ b/sd/source/core/undo/undomanager.cxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <comphelper/lok.hxx>
+#include <sfx2/viewsh.hxx>
 #include <undo/undomanager.hxx>
 
 using namespace sd;
@@ -24,6 +26,7 @@ using namespace sd;
 UndoManager::UndoManager( sal_uInt16 nMaxUndoActionCount /* = 20 */ )
   : SdrUndoManager( nMaxUndoActionCount )
   , mpLinkedUndoManager(nullptr)
+  , mpViewShell(nullptr)
 {
 }
 
@@ -49,6 +52,53 @@ void UndoManager::AddUndoAction( SfxUndoAction *pAction, 
bool bTryMerg /* = sal_
     }
 }
 
+size_t UndoManager::GetUndoActionCount(const bool bCurrentLevel) const
+{
+    size_t nRet = SdrUndoManager::GetUndoActionCount(bCurrentLevel);
+    if (!comphelper::LibreOfficeKit::isActive() || !mpViewShell)
+        return nRet;
+
+    if (!nRet || !SdrUndoManager::GetUndoActionCount())
+        return nRet;
+
+    const SfxUndoAction* pAction = SdrUndoManager::GetUndoAction();
+    if (!pAction)
+        return nRet;
+
+    // If an other view created the last undo action, prevent undoing it from 
this view.
+    sal_Int32 nViewShellId = mpViewShell->GetViewShellId();
+    if (pAction->GetViewShellId() != nViewShellId)
+        nRet = 0;
+
+    return nRet;
+}
+
+size_t UndoManager::GetRedoActionCount(const bool bCurrentLevel) const
+{
+    size_t nRet = SdrUndoManager::GetRedoActionCount(bCurrentLevel);
+    if (!comphelper::LibreOfficeKit::isActive() || !mpViewShell)
+        return nRet;
+
+    if (!nRet || !SdrUndoManager::GetRedoActionCount())
+        return nRet;
+
+    const SfxUndoAction* pAction = SdrUndoManager::GetRedoAction();
+    if (!pAction)
+        return nRet;
+
+    // If an other view created the first redo action, prevent redoing it from 
this view.
+    sal_Int32 nViewShellId = mpViewShell->GetViewShellId();
+    if (pAction->GetViewShellId() != nViewShellId)
+        nRet = 0;
+
+    return nRet;
+}
+
+void UndoManager::SetViewShell(SfxViewShell* pViewShell)
+{
+    mpViewShell = pViewShell;
+}
+
 void UndoManager::SetLinkedUndoManager (::svl::IUndoManager* 
pLinkedUndoManager)
 {
     mpLinkedUndoManager = pLinkedUndoManager;
diff --git a/sd/source/ui/view/viewshe3.cxx b/sd/source/ui/view/viewshe3.cxx
index a23c752..dbf6037 100644
--- a/sd/source/ui/view/viewshe3.cxx
+++ b/sd/source/ui/view/viewshe3.cxx
@@ -71,6 +71,7 @@
 #include "framework/FrameworkHelper.hxx"
 #include "optsitem.hxx"
 #include "sdresid.hxx"
+#include "undo/undomanager.hxx"
 
 #include <svx/svxids.hrc>
 #include <sfx2/request.hxx>
@@ -128,10 +129,15 @@ void  ViewShell::GetMenuState( SfxItemSet &rSet )
 
         if(pUndoManager)
         {
+            auto pSdUndoManager = dynamic_cast<sd::UndoManager*>(pUndoManager);
+            if (pSdUndoManager)
+                pSdUndoManager->SetViewShell(&GetViewShellBase());
             if(pUndoManager->GetUndoActionCount() != 0)
             {
                 bActivate = true;
             }
+            if (pSdUndoManager)
+                pSdUndoManager->SetViewShell(nullptr);
         }
 
         if(bActivate)
@@ -155,10 +161,15 @@ void  ViewShell::GetMenuState( SfxItemSet &rSet )
 
         if(pUndoManager)
         {
+            auto pSdUndoManager = dynamic_cast<sd::UndoManager*>(pUndoManager);
+            if (pSdUndoManager)
+                pSdUndoManager->SetViewShell(&GetViewShellBase());
             if(pUndoManager->GetRedoActionCount() != 0)
             {
                 bActivate = true;
             }
+            if (pSdUndoManager)
+                pSdUndoManager->SetViewShell(nullptr);
         }
 
         if(bActivate)
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to