summaryrefslogtreecommitdiff
path: root/sw/qa/extras/unowriter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2019-01-24 09:36:46 +0100
committerMiklos Vajna <vmiklos@collabora.com>2019-01-24 12:48:24 +0100
commite14fafaafb3500d65be9c1b69fcb86b31d36468c (patch)
treea308d8f2adf477aef41f25fbf9d0cb600627cf41 /sw/qa/extras/unowriter
parentb473896d31e4c198100fde582f5b4d12d8e2a1d7 (diff)
sw: make it possible to listen to paste events
The use-case is that the user pastes content and custom postprocessing is necessary for the pasted content. This is not easy by default, since the cursor is at the end of the pasted content, so the start is not known -- even if you intercept the paste UNO command. Precisely tracking the start is possible when using the internal API, SwReader::Read() does something similar already to track the undo range. Only expose the text selection after paste (as a start), but design the API in a way so that other pasted content type (e.g. image) can be added in a backwards-compatible way later. Change-Id: If35bda4244cc417e4858124fb75f7608b95fc556 Reviewed-on: https://gerrit.libreoffice.org/66807 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw/qa/extras/unowriter')
-rw-r--r--sw/qa/extras/unowriter/unowriter.cxx77
1 files changed, 77 insertions, 0 deletions
diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index a0e093dc35d5..77186c1d9350 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -20,6 +20,7 @@
#include <toolkit/helper/vclunohelper.hxx>
#include <wrtsh.hxx>
#include <ndtxt.hxx>
+#include <swdtflvr.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
@@ -28,6 +29,31 @@ using namespace ::com::sun::star::text;
namespace
{
char const DATA_DIRECTORY[] = "/sw/qa/extras/unowriter/data/";
+
+/// Listener implementation for testPasteListener.
+class PasteListener : public cppu::WeakImplHelper<text::XPasteListener>
+{
+ OUString m_aString;
+
+public:
+ void SAL_CALL notifyPasteEvent(const uno::Sequence<beans::PropertyValue>& rEvent) override;
+
+ OUString& GetString();
+};
+
+void PasteListener::notifyPasteEvent(const uno::Sequence<beans::PropertyValue>& rEvent)
+{
+ comphelper::SequenceAsHashMap aMap(rEvent);
+ auto it = aMap.find("TextRange");
+ if (it != aMap.end())
+ {
+ auto xTextRange = it->second.get<uno::Reference<text::XTextRange>>();
+ if (xTextRange.is())
+ m_aString = xTextRange->getString();
+ }
+}
+
+OUString& PasteListener::GetString() { return m_aString; }
}
/// Test to assert UNO API call results of Writer.
@@ -463,6 +489,57 @@ DECLARE_UNOAPI_TEST_FILE(testRenderablePagePosition, "renderable-page-position.o
CPPUNIT_ASSERT_GREATER(aPosition1.Y, aPosition2.Y);
}
+DECLARE_UNOAPI_TEST(testPasteListener)
+{
+ loadURL("private:factory/swriter", nullptr);
+
+ // Insert initial string.
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XSimpleText> xBodyText(xTextDocument->getText(), uno::UNO_QUERY);
+ xBodyText->insertString(xBodyText->getStart(), "ABCDEF", false);
+
+ // Add paste listener.
+ uno::Reference<text::XPasteBroadcaster> xBroadcaster(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XPasteListener> xListener(new PasteListener);
+ auto pListener = static_cast<PasteListener*>(xListener.get());
+ xBroadcaster->addPasteEventListener(xListener);
+
+ // Cut "DE" and then paste it.
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+ SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+ pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 3, /*bBasicCall=*/false);
+ pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, /*bBasicCall=*/false);
+ rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
+ pTransfer->Cut();
+ TransferableDataHelper aHelper(pTransfer.get());
+ SwTransferable::Paste(*pWrtShell, aHelper);
+ // Without working listener registration in place, this test would have
+ // failed with 'Expected: DE; Actual:', i.e. the paste listener was not
+ // invoked.
+ CPPUNIT_ASSERT_EQUAL(OUString("DE"), pListener->GetString());
+
+ // Make sure that paste did not overwrite anything.
+ CPPUNIT_ASSERT_EQUAL(OUString("ABCDEF"), xBodyText->getString());
+
+ // Paste again, this time overwriting "BC".
+ pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 4, /*bBasicCall=*/false);
+ pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, /*bBasicCall=*/false);
+ pListener->GetString().clear();
+ SwTransferable::Paste(*pWrtShell, aHelper);
+ CPPUNIT_ASSERT_EQUAL(OUString("DE"), pListener->GetString());
+
+ // Make sure that paste overwrote "BC".
+ CPPUNIT_ASSERT_EQUAL(OUString("ADEDEF"), xBodyText->getString());
+
+ // Deregister paste listener, make sure it's not invoked.
+ xBroadcaster->removePasteEventListener(xListener);
+ pListener->GetString().clear();
+ SwTransferable::Paste(*pWrtShell, aHelper);
+ CPPUNIT_ASSERT(pListener->GetString().isEmpty());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */