diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2019-01-24 09:36:46 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2019-01-24 12:48:24 +0100 |
commit | e14fafaafb3500d65be9c1b69fcb86b31d36468c (patch) | |
tree | a308d8f2adf477aef41f25fbf9d0cb600627cf41 /sw/qa/extras/unowriter | |
parent | b473896d31e4c198100fde582f5b4d12d8e2a1d7 (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.cxx | 77 |
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: */ |