[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.1' - 2 commits - libreofficekit/qa sfx2/sdi sfx2/source sw/inc sw/qa sw/source
Miklos Vajna
vmiklos at collabora.co.uk
Mon Aug 15 08:04:24 UTC 2016
libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 5 +
sfx2/sdi/sfx.sdi | 4 -
sfx2/source/control/dispatch.cxx | 18 ++++
sfx2/source/view/lokhelper.cxx | 10 ++
sw/inc/IDocumentUndoRedo.hxx | 5 +
sw/qa/extras/tiledrendering/tiledrendering.cxx | 78 ++++++++++++++++++++
sw/source/core/inc/UndoManager.hxx | 4 +
sw/source/core/undo/docundo.cxx | 15 +++
sw/source/uibase/shells/basesh.cxx | 17 ++++
9 files changed, 150 insertions(+), 6 deletions(-)
New commits:
commit d7ceb72ff0b1ce94118d3c85cdc7641e461e44a6
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
(cherry picked from commit e9bcd3475131b24b0b8818cfdfa256854ca5a59d)
diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index 5b95e35..b52c256 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 82838ee..aedca15 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -4724,7 +4724,7 @@ SfxBoolItem MacroRecordingFloat SID_RECORDING_FLOATWINDOW
SfxVoidItem Redo SID_REDO
-( SfxUInt16Item Redo SID_REDO )
+( SfxUInt16Item Redo SID_REDO, SfxBoolItem Repair SID_REPAIRPACKAGE )
[
/* flags: */
AutoUpdate = FALSE,
@@ -6228,7 +6228,7 @@ SfxVoidItem BasicIDEShowWindow SID_BASICIDE_SHOWWINDOW
SfxVoidItem Undo SID_UNDO
-( SfxUInt16Item Undo SID_UNDO )
+( SfxUInt16Item Undo SID_UNDO, SfxBoolItem Repair SID_REPAIRPACKAGE )
[
/* flags: */
AutoUpdate = FALSE,
diff --git a/sfx2/source/control/dispatch.cxx b/sfx2/source/control/dispatch.cxx
index c0a35de..bd0b86b 100644
--- a/sfx2/source/control/dispatch.cxx
+++ b/sfx2/source/control/dispatch.cxx
@@ -214,6 +214,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
*/
@@ -222,7 +238,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 1447248..a51d0c8 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -63,6 +63,7 @@ public:
void testUndoInvalidations();
void testUndoLimiting();
void testUndoDispatch();
+ void testUndoRepairDispatch();
void testShapeTextUndoShells();
void testShapeTextUndoGroupShells();
@@ -92,6 +93,7 @@ public:
CPPUNIT_TEST(testUndoInvalidations);
CPPUNIT_TEST(testUndoLimiting);
CPPUNIT_TEST(testUndoDispatch);
+ CPPUNIT_TEST(testUndoRepairDispatch);
CPPUNIT_TEST(testShapeTextUndoShells);
CPPUNIT_TEST(testShapeTextUndoGroupShells);
CPPUNIT_TEST_SUITE_END();
@@ -961,6 +963,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 46a6693..943de4b 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 4d3b743..8400b0b 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;
@@ -482,9 +483,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:
commit 01e160686140299002df52e76dc8e3411c6e01c2
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Wed Aug 10 15:51:51 2016 +0200
sfx2: make SfxLokHelper::setView() set also the active frame
Without this, comphelper::dispatchCommand() doesn't work on the current
frame. This causes e.g. undo not working when only a given view is
allowed to do undo.
In the desktop case vcl::Window::ImplGrabFocus() calls both
SfxViewFrame::MakeActive_Impl() and
framework::Desktop::setActiveFrame(), but in the LOK case the first was
called directly, that's how the active frame was outdated.
Change-Id: If97a9de316b4c8dd49e55cd273bdb2dfe9866f38
Reviewed-on: https://gerrit.libreoffice.org/28032
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins <ci at libreoffice.org>
(cherry picked from commit d6e8d4f773d970b69baedd8523a426f18a8d8eef)
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index 856a007..4113160 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -11,12 +11,17 @@
#include <boost/property_tree/json_parser.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+
+#include <comphelper/processfactory.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/request.hxx>
#include <sfx2/viewfrm.hxx>
#include <shellimpl.hxx>
+using namespace com::sun::star;
+
int SfxLokHelper::createView()
{
SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst();
@@ -59,6 +64,11 @@ void SfxLokHelper::setView(int nId)
SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
pViewFrame->MakeActive_Impl(false);
+
+ // Make comphelper::dispatchCommand() find the correct frame.
+ uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(comphelper::getProcessComponentContext());
+ xDesktop->setActiveFrame(xFrame);
return;
}
}
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index cba7997..1447248 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -62,6 +62,7 @@ public:
void testTextEditViewInvalidations();
void testUndoInvalidations();
void testUndoLimiting();
+ void testUndoDispatch();
void testShapeTextUndoShells();
void testShapeTextUndoGroupShells();
@@ -90,6 +91,7 @@ public:
CPPUNIT_TEST(testTextEditViewInvalidations);
CPPUNIT_TEST(testUndoInvalidations);
CPPUNIT_TEST(testUndoLimiting);
+ CPPUNIT_TEST(testUndoDispatch);
CPPUNIT_TEST(testShapeTextUndoShells);
CPPUNIT_TEST(testShapeTextUndoGroupShells);
CPPUNIT_TEST_SUITE_END();
@@ -924,6 +926,41 @@ void SwTiledRenderingTest::testUndoLimiting()
comphelper::LibreOfficeKit::setActive(false);
}
+void SwTiledRenderingTest::testUndoDispatch()
+{
+ // 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);
+
+ // Click before the first word in the second view.
+ SfxLokHelper::setView(nView2);
+ SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+ SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
+ Point aStart = pShellCursor->GetSttPos();
+ aStart.setX(aStart.getX() - 1000);
+ pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, aStart.getX(), aStart.getY(), 1, MOUSE_LEFT, 0);
+ pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, aStart.getX(), aStart.getY(), 1, MOUSE_LEFT, 0);
+ uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(comphelper::getProcessComponentContext());
+ uno::Reference<frame::XFrame> xFrame2 = xDesktop->getActiveFrame();
+
+ // Now switch back to the first view, and make sure that the active frame is updated.
+ SfxLokHelper::setView(nView1);
+ uno::Reference<frame::XFrame> xFrame1 = xDesktop->getActiveFrame();
+ // This failed: setView() did not update the active frame.
+ CPPUNIT_ASSERT(xFrame1 != xFrame2);
+
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
void SwTiledRenderingTest::testShapeTextUndoShells()
{
// Load a document and create a view.
More information about the Libreoffice-commits
mailing list