[Libreoffice-commits] core.git: libreofficekit/qa sfx2/sdi sfx2/source sw/inc sw/qa sw/source

Miklos Vajna vmiklos at collabora.co.uk
Wed Aug 10 18:30:56 UTC 2016


 libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx |    5 ++
 sfx2/sdi/sfx.sdi                                    |    4 -
 sfx2/source/control/dispatch.cxx                    |   18 ++++++++
 sw/inc/IDocumentUndoRedo.hxx                        |    5 ++
 sw/qa/extras/tiledrendering/tiledrendering.cxx      |   41 ++++++++++++++++++++
 sw/source/core/inc/UndoManager.hxx                  |    4 +
 sw/source/core/undo/docundo.cxx                     |   15 ++++++-
 sw/source/uibase/shells/basesh.cxx                  |   17 +++++++-
 8 files changed, 103 insertions(+), 6 deletions(-)

New commits:
commit e9bcd3475131b24b0b8818cfdfa256854ca5a59d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Aug 10 17:42:54 2016 +0200

    sw undo: add a Repair argument to the .uno:Undo/Redo commands
    
    Undo/redo is limited to undo actions created by the same view in the LOK
    case, this argument removes this limit. This can be used by a client for
    "document repair" purposes, where undo/redo of others' changes is
    intentional.
    
    The sfx command dispatch has support for FASTCALL slots (a state
    function is not called, the command is always enabled) and also has
    support for state functions, but those functions only get the ID of the
    slots, not its parameters. What is needed here is a command that's
    disabled by default, but in case a Repair argument is used, then it's
    unconditionally enabled. So handle that case in the sfx dispatcher
    directly for now.
    
    Change-Id: I96c1130bf51abcdd722684b1fa4a8277f92fd555

diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index 6c8e2d5..a53bd00 100644
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
@@ -535,6 +535,11 @@ static void documentRepair(GtkWidget* pButton, gpointer /*pItem*/)
             boost::property_tree::ptree aTree;
             aTree.put(boost::property_tree::ptree::path_type(aKey + "/type", '/'), "unsigned short");
             aTree.put(boost::property_tree::ptree::path_type(aKey + "/value", '/'), nIndex + 1);
+
+            // Without this, we could only undo our own commands.
+            aTree.put(boost::property_tree::ptree::path_type("Repair/type", '/'), "boolean");
+            aTree.put(boost::property_tree::ptree::path_type("Repair/value", '/'), true);
+
             std::stringstream aStream;
             boost::property_tree::write_json(aStream, aTree);
             std::string aArguments = aStream.str();
diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi
index f5e366a..5275aef 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -3428,7 +3428,7 @@ SfxBoolItem MacroRecordingFloat SID_RECORDING_FLOATWINDOW
 
 
 SfxVoidItem Redo SID_REDO
-( SfxUInt16Item Redo SID_REDO )
+( SfxUInt16Item Redo SID_REDO, SfxBoolItem Repair SID_REPAIRPACKAGE )
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
@@ -4555,7 +4555,7 @@ SfxVoidItem BasicIDEShowWindow SID_BASICIDE_SHOWWINDOW
 
 
 SfxVoidItem Undo SID_UNDO
-( SfxUInt16Item Undo SID_UNDO )
+( SfxUInt16Item Undo SID_UNDO, SfxBoolItem Repair SID_REPAIRPACKAGE )
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index 0d973a9..c464fba 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -313,6 +313,22 @@ bool SfxDispatcher::IsAppDispatcher() const
     return !xImp->pFrame;
 }
 
+/// Decides if the request is FASTCALL or not, depending on arguments.
+bool lcl_IsConditionalFastCall(SfxRequest &rReq)
+{
+    sal_uInt16 nId = rReq.GetSlot();
+    bool bRet = false;
+
+    if (nId == SID_UNDO || nId == SID_REDO)
+    {
+        const SfxItemSet* pArgs = rReq.GetArgs();
+        if (pArgs && pArgs->HasItem(SID_REPAIRPACKAGE))
+            bRet = true;
+    }
+
+    return bRet;
+}
+
 /** Helper function to check whether a slot can be executed and
     check the execution itself
 */
@@ -321,7 +337,7 @@ void SfxDispatcher::Call_Impl(SfxShell& rShell, const SfxSlot &rSlot, SfxRequest
     SFX_STACK(SfxDispatcher::Call_Impl);
 
     // The slot may be called (meaning enabled)
-    if ( rSlot.IsMode(SfxSlotMode::FASTCALL) || rShell.CanExecuteSlot_Impl(rSlot) )
+    if ( rSlot.IsMode(SfxSlotMode::FASTCALL) || rShell.CanExecuteSlot_Impl(rSlot) || lcl_IsConditionalFastCall(rReq))
     {
         if ( GetFrame() )
         {
diff --git a/sw/inc/IDocumentUndoRedo.hxx b/sw/inc/IDocumentUndoRedo.hxx
index 6c044f6..2266f30 100644
--- a/sw/inc/IDocumentUndoRedo.hxx
+++ b/sw/inc/IDocumentUndoRedo.hxx
@@ -64,6 +64,11 @@ public:
      */
     virtual bool DoesDrawUndo() const = 0;
 
+    /// Enable repair mode.
+    virtual void DoRepair(bool bRepair) = 0;
+    /// Is repair mode active?
+    virtual bool DoesRepair() const = 0;
+
     /** Set the position at which the document is in the "unmodified" state
         to the current position in the Undo stack.
     */
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 1219d01..504de6c 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -62,6 +62,7 @@ public:
     void testUndoInvalidations();
     void testUndoLimiting();
     void testUndoDispatch();
+    void testUndoRepairDispatch();
     void testShapeTextUndoShells();
     void testShapeTextUndoGroupShells();
 
@@ -91,6 +92,7 @@ public:
     CPPUNIT_TEST(testUndoInvalidations);
     CPPUNIT_TEST(testUndoLimiting);
     CPPUNIT_TEST(testUndoDispatch);
+    CPPUNIT_TEST(testUndoRepairDispatch);
     CPPUNIT_TEST(testShapeTextUndoShells);
     CPPUNIT_TEST(testShapeTextUndoGroupShells);
     CPPUNIT_TEST_SUITE_END();
@@ -960,6 +962,45 @@ void SwTiledRenderingTest::testUndoDispatch()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+void SwTiledRenderingTest::testUndoRepairDispatch()
+{
+    // Load a document and create two views.
+    comphelper::LibreOfficeKit::setActive();
+    SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
+    int nView1 = SfxLokHelper::getView();
+    SfxLokHelper::createView();
+    pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+    int nView2 = SfxLokHelper::getView();
+
+    // Insert a character in the first view.
+    SfxLokHelper::setView(nView1);
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0);
+    pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0);
+
+    // Assert that by default the second view can't undo the action.
+    SfxLokHelper::setView(nView2);
+    SwDoc* pDoc = pXTextDocument->GetDocShell()->GetDoc();
+    sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rUndoManager.GetUndoActionCount());
+    comphelper::dispatchCommand(".uno:Undo", {});
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rUndoManager.GetUndoActionCount());
+
+    // But the same is allowed in repair mode.
+    SfxLokHelper::setView(nView2);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rUndoManager.GetUndoActionCount());
+    uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
+    {
+        {"Repair", uno::makeAny(true)}
+    }));
+    comphelper::dispatchCommand(".uno:Undo", aPropertyValues);
+    Scheduler::ProcessEventsToIdle();
+    // This was 1: repair mode couldn't undo the action, either.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rUndoManager.GetUndoActionCount());
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 void SwTiledRenderingTest::testShapeTextUndoShells()
 {
     // Load a document and create a view.
diff --git a/sw/source/core/inc/UndoManager.hxx b/sw/source/core/inc/UndoManager.hxx
index 5092e95..0013262 100644
--- a/sw/source/core/inc/UndoManager.hxx
+++ b/sw/source/core/inc/UndoManager.hxx
@@ -49,6 +49,8 @@ public:
     virtual bool DoesGroupUndo() const override;
     virtual void DoDrawUndo(bool const bDoUndo) override;
     virtual bool DoesDrawUndo() const override;
+    void DoRepair(bool bRepair) override;
+    bool DoesRepair() const override;
     virtual void SetUndoNoModifiedPosition() override;
     virtual void LockUndoNoModifiedPosition() override;
     virtual void UnLockUndoNoModifiedPosition() override;
@@ -100,6 +102,8 @@ private:
 
     bool m_bGroupUndo       : 1;    // TRUE: Undo grouping enabled
     bool m_bDrawUndo        : 1;    // TRUE: Draw Undo enabled
+    /// If true, then repair mode is enabled.
+    bool m_bRepair;
     bool m_bLockUndoNoModifiedPosition : 1;
     /// position in Undo-Array at which Doc was saved (and is not modified)
     UndoStackMark m_UndoSaveMark;
diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx
index ba4aeff..127d928 100644
--- a/sw/source/core/undo/docundo.cxx
+++ b/sw/source/core/undo/docundo.cxx
@@ -58,6 +58,7 @@ UndoManager::UndoManager(std::shared_ptr<SwNodes> xUndoNodes,
     ,   m_xUndoNodes(xUndoNodes)
     ,   m_bGroupUndo(true)
     ,   m_bDrawUndo(true)
+    ,   m_bRepair(false)
     ,   m_bLockUndoNoModifiedPosition(false)
     ,   m_UndoSaveMark(MARK_INVALID)
 {
@@ -138,6 +139,16 @@ bool UndoManager::DoesDrawUndo() const
     return m_bDrawUndo;
 }
 
+void UndoManager::DoRepair(bool bRepair)
+{
+    m_bRepair = bRepair;
+}
+
+bool UndoManager::DoesRepair() const
+{
+    return m_bRepair;
+}
+
 bool UndoManager::IsUndoNoResetModified() const
 {
     return MARK_INVALID == m_UndoSaveMark;
@@ -308,7 +319,7 @@ UndoManager::GetLastUndoInfo(
 
     SfxUndoAction *const pAction( SdrUndoManager::GetUndoAction() );
 
-    if (comphelper::LibreOfficeKit::isActive())
+    if (comphelper::LibreOfficeKit::isActive() && !m_bRepair)
     {
         // If an other view created the undo action, prevent undoing it from this view.
         sal_Int32 nViewShellId = pView ? pView->GetViewShellId() : m_pDocShell->GetView()->GetViewShellId();
@@ -361,7 +372,7 @@ bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr,
         return false;
     }
 
-    if (comphelper::LibreOfficeKit::isActive())
+    if (comphelper::LibreOfficeKit::isActive() && !m_bRepair)
     {
         // If an other view created the undo action, prevent redoing it from this view.
         sal_Int32 nViewShellId = pView ? pView->GetViewShellId() : m_pDocShell->GetView()->GetViewShellId();
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index 6f802be..7c281a5 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -94,6 +94,7 @@
 #include <fmtinfmt.hxx>
 #include <doc.hxx>
 #include <IDocumentSettingAccess.hxx>
+#include <IDocumentUndoRedo.hxx>
 #include "swabstdlg.hxx"
 #include "dialog.hrc"
 #include "fldui.hrc"
@@ -108,8 +109,8 @@
 #include <com/sun/star/gallery/GalleryItemType.hpp>
 #include <memory>
 
-//UUUU
 #include <svx/unobrushitemhelper.hxx>
+#include <comphelper/scopeguard.hxx>
 
 FlyMode SwBaseShell::eFrameMode = FLY_DRAG_END;
 
@@ -483,9 +484,23 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq)
     if( pArgs && SfxItemState::SET == pArgs->GetItemState( nId, false, &pItem ))
         nCnt = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
 
+    // Repair mode: allow undo/redo of all undo actions, even if access would
+    // be limited based on the view shell ID.
+    bool bRepair = false;
+    if (pArgs && pArgs->GetItemState(SID_REPAIRPACKAGE, false, &pItem) == SfxItemState::SET)
+        bRepair = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+
     // #i106349#: save pointer: undo/redo may delete the shell, i.e., this!
     SfxViewFrame *const pViewFrame( GetView().GetViewFrame() );
 
+    IDocumentUndoRedo& rUndoRedo = rWrtShell.GetIDocumentUndoRedo();
+    bool bWasRepair = rUndoRedo.DoesRepair();
+    rUndoRedo.DoRepair(bRepair);
+    comphelper::ScopeGuard aGuard([&rUndoRedo, bWasRepair]()
+    {
+        rUndoRedo.DoRepair(bWasRepair);
+    });
+
     switch( nId )
     {
         case SID_UNDO:


More information about the Libreoffice-commits mailing list