summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-08-05 13:53:57 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-08-09 09:45:13 +0200
commite37a16146b2c17d85472fb4ffb18acb5f3ab93aa (patch)
tree4c9399d485cddfd4ce9e35b42cfbbcb70202e247
parent210072c9adfb2549f639e296d82c5f4b79cb4315 (diff)
desktop: add undo/redo support to lok::Document::getCommandValues()
Expose the undo/redo stack and the metadata of each item. Reviewed-on: https://gerrit.libreoffice.org/27905 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit 9dd8a0dcfdff21269f6423224d39d168519fb67e) Conflicts: include/svl/undo.hxx Change-Id: I66b81e855a945c97be3d491ed709959f310d4b73
-rw-r--r--desktop/qa/desktop_lib/test_desktop_lib.cxx23
-rw-r--r--desktop/source/lib/init.cxx44
-rw-r--r--include/svl/undo.hxx6
-rw-r--r--svl/source/undo/undo.cxx46
4 files changed, 118 insertions, 1 deletions
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 74a75ed31983..5a34036586cd 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -79,6 +79,7 @@ public:
void testSaveAsCalc();
void testPasteWriter();
void testPasteWriterJPEG();
+ void testUndoWriter();
void testRowColumnHeaders();
void testHiddenRowHeaders();
void testCellCursor();
@@ -106,6 +107,7 @@ public:
CPPUNIT_TEST(testSaveAsCalc);
CPPUNIT_TEST(testPasteWriter);
CPPUNIT_TEST(testPasteWriterJPEG);
+ CPPUNIT_TEST(testUndoWriter);
CPPUNIT_TEST(testRowColumnHeaders);
CPPUNIT_TEST(testHiddenRowHeaders);
CPPUNIT_TEST(testCellCursor);
@@ -501,6 +503,27 @@ void DesktopLOKTest::testPasteWriterJPEG()
comphelper::LibreOfficeKit::setActive(false);
}
+void DesktopLOKTest::testUndoWriter()
+{
+ // Load a Writer document and press a key.
+ comphelper::LibreOfficeKit::setActive();
+ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
+ pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0);
+ pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYUP, 't', 0);
+
+ // Get undo info.
+ boost::property_tree::ptree aTree;
+ char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:Undo");
+ std::stringstream aStream(pJSON);
+ free(pJSON);
+ CPPUNIT_ASSERT(!aStream.str().empty());
+ boost::property_tree::read_json(aStream, aTree);
+ // Make sure that pressing a key creates exactly one undo action.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aTree.get_child("actions").size());
+
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
void DesktopLOKTest::testRowColumnHeaders()
{
/*
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index fe1245e1b936..851fc915d74d 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -81,6 +81,8 @@
#include <unotools/mediadescriptor.hxx>
#include <osl/module.hxx>
#include <comphelper/sequence.hxx>
+#include <sfx2/sfxbasemodel.hxx>
+#include <svl/undo.hxx>
#include <app.hxx>
@@ -88,7 +90,7 @@
// We also need to hackily be able to start the main libreoffice thread:
#include "../app/sofficemain.h"
#include "../app/officeipcthread.hxx"
-#include "../../inc/lib/init.hxx"
+#include <lib/init.hxx>
#include "lokinteractionhandler.hxx"
#include <lokclipboard.hxx>
@@ -1792,6 +1794,38 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand)
return pJson;
}
+enum class UndoOrRedo
+{
+ UNDO,
+ REDO
+};
+
+/// Returns the JSON representation of either an undo or a redo stack.
+static char* getUndoOrRedo(LibreOfficeKitDocument* pThis, UndoOrRedo eCommand)
+{
+ LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+
+ auto pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
+ if (!pBaseModel)
+ return nullptr;
+
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ if (!pObjectShell)
+ return nullptr;
+
+ svl::IUndoManager* pUndoManager = pObjectShell->GetUndoManager();
+ if (!pUndoManager)
+ return nullptr;
+
+ OUString aString;
+ if (eCommand == UndoOrRedo::UNDO)
+ aString = pUndoManager->GetUndoActionsInfo();
+ else
+ aString = pUndoManager->GetRedoActionsInfo();
+ char* pJson = strdup(aString.toUtf8().getStr());
+ return pJson;
+}
+
static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand)
{
OString aCommand(pCommand);
@@ -1806,6 +1840,14 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
{
return getStyles(pThis, pCommand);
}
+ else if (aCommand == ".uno:Undo")
+ {
+ return getUndoOrRedo(pThis, UndoOrRedo::UNDO);
+ }
+ else if (aCommand == ".uno:Redo")
+ {
+ return getUndoOrRedo(pThis, UndoOrRedo::REDO);
+ }
else if (aCommand.startsWith(aViewRowColumnHeaders))
{
ITiledRenderable* pDoc = getTiledRenderable(pThis);
diff --git a/include/svl/undo.hxx b/include/svl/undo.hxx
index 95684f50690c..61daea5bdc49 100644
--- a/include/svl/undo.hxx
+++ b/include/svl/undo.hxx
@@ -205,10 +205,14 @@ namespace svl
virtual sal_uInt16 GetUndoActionId() const = 0;
virtual OUString GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
virtual SfxUndoAction* GetUndoAction( size_t nNo=0 ) const = 0;
+ /// Get info about all undo actions (comment, view shell id, etc.)
+ virtual OUString GetUndoActionsInfo() const = 0;
virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
virtual OUString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
virtual SfxUndoAction* GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
+ /// Get info about all redo actions (comment, view shell id, etc.)
+ virtual OUString GetRedoActionsInfo() const = 0;
virtual bool Undo() = 0;
virtual bool Redo() = 0;
@@ -324,9 +328,11 @@ public:
virtual sal_uInt16 GetUndoActionId() const override;
virtual OUString GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const override;
virtual SfxUndoAction* GetUndoAction( size_t nNo=0 ) const override;
+ OUString GetUndoActionsInfo() const override;
virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const override;
virtual OUString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const override;
virtual SfxUndoAction* GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const override;
+ OUString GetRedoActionsInfo() const override;
virtual bool Undo() override;
virtual bool Redo() override;
virtual void Clear() override;
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
index 0fa3867326f3..9a240ba7b1ab 100644
--- a/svl/source/undo/undo.cxx
+++ b/svl/source/undo/undo.cxx
@@ -26,6 +26,7 @@
#include <comphelper/flagguard.hxx>
#include <tools/diagnose_ex.h>
#include <libxml/xmlwriter.h>
+#include <boost/property_tree/json_parser.hpp>
#include <unotools/datetime.hxx>
#include <vector>
@@ -1331,6 +1332,51 @@ void SfxUndoManager::dumpAsXml(xmlTextWriterPtr pWriter) const
}
}
+/// Returns a JSON representation of pAction.
+boost::property_tree::ptree lcl_ActionToJson(size_t nIndex, SfxUndoAction* pAction)
+{
+ boost::property_tree::ptree aRet;
+ aRet.put("index", nIndex);
+ aRet.put("comment", pAction->GetComment().toUtf8().getStr());
+ aRet.put("viewId", pAction->GetViewShellId());
+ aRet.put("dateTime", utl::toISO8601(pAction->GetDateTime().GetUNODateTime()).toUtf8().getStr());
+ return aRet;
+}
+
+OUString SfxUndoManager::GetUndoActionsInfo() const
+{
+ boost::property_tree::ptree aActions;
+ const SfxUndoArray* pUndoArray = m_xData->pActUndoArray;
+ for (size_t i = 0; i < GetUndoActionCount(); ++i)
+ {
+ boost::property_tree::ptree aAction = lcl_ActionToJson(i, pUndoArray->aUndoActions[pUndoArray->nCurUndoAction - 1 - i].pAction);
+ aActions.push_back(std::make_pair("", aAction));
+ }
+
+ boost::property_tree::ptree aTree;
+ aTree.add_child("actions", aActions);
+ std::stringstream aStream;
+ boost::property_tree::write_json(aStream, aTree);
+ return OUString::fromUtf8(aStream.str().c_str());
+}
+
+OUString SfxUndoManager::GetRedoActionsInfo() const
+{
+ boost::property_tree::ptree aActions;
+ const SfxUndoArray* pUndoArray = m_xData->pActUndoArray;
+ for (size_t i = 0; i < GetRedoActionCount(); ++i)
+ {
+ boost::property_tree::ptree aAction = lcl_ActionToJson(i, pUndoArray->aUndoActions[pUndoArray->nCurUndoAction + i].pAction);
+ aActions.push_back(std::make_pair("", aAction));
+ }
+
+ boost::property_tree::ptree aTree;
+ aTree.add_child("actions", aActions);
+ std::stringstream aStream;
+ boost::property_tree::write_json(aStream, aTree);
+ return OUString::fromUtf8(aStream.str().c_str());
+}
+
struct SfxListUndoAction::Impl
{
sal_uInt16 mnId;