sw/qa/extras/unowriter/data/hyperlink.fodt | 9 ++ sw/qa/extras/unowriter/unowriter.cxx | 104 +++++++++++++++++++++++++++++ sw/source/uibase/wrtsh/wrtsh2.cxx | 11 +-- 3 files changed, 119 insertions(+), 5 deletions(-)
New commits: commit 8320568b4a069ce8549b76a641271333afa3cc26 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Wed Jan 29 20:43:58 2025 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Thu Jan 30 09:55:16 2025 +0500 tdf#164885: use SfxBindings::Execute instead of SfxDispatcher::ExecuteList Commit 502f7958d99e3aa27f4c1c1f33f4827055459da8 (pass a frame to use as parent for any dialog that may need to appear, 2023-11-16) switched to SfxDispatcher::ExecuteList, in order to pass there frame to be used as parent for dialogs. Later, in commit d7b33b1be8fee684e906f170f4001735c095056e (use SID_DOCFRAME for dialog parents if there is no SID_FILLFRAME, 2023-11-23), the fix was changed, and passing the frame got not needed. Since the change to SfxDispatcher::ExecuteList caused the regression (likely because SfxDispatcher unexpectedly uses a bit different method to find the slot server), and the original reason for the change is no more actual, let's revert to the older method. Change-Id: I6b126bf336dcf8cd3f49a3ce9682f3adc3bc208f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180909 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/extras/unowriter/data/hyperlink.fodt b/sw/qa/extras/unowriter/data/hyperlink.fodt new file mode 100644 index 000000000000..d3d73c750d15 --- /dev/null +++ b/sw/qa/extras/unowriter/data/hyperlink.fodt @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:body> + <office:text> + <text:p>A <text:a xlink:type="simple" xlink:href="https://www.libreoffice.org/" text:style-name="Internet_20_link" text:visited-style-name="Visited_20_Internet_20_Link">hyperlink</text:a> here.</text:p> + </office:text> + </office:body> +</office:document> \ No newline at end of file diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx index 7175e702d709..565d1b6d9433 100644 --- a/sw/qa/extras/unowriter/unowriter.cxx +++ b/sw/qa/extras/unowriter/unowriter.cxx @@ -12,6 +12,9 @@ #include <com/sun/star/awt/FontSlant.hpp> #include <com/sun/star/datatransfer/XTransferableSupplier.hpp> #include <com/sun/star/datatransfer/XTransferableTextSupplier.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XDispatchProviderInterception.hpp> +#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp> #include <com/sun/star/table/XCellRange.hpp> #include <com/sun/star/text/TextContentAnchorType.hpp> #include <com/sun/star/text/AutoTextContainer.hpp> @@ -42,6 +45,7 @@ #include <vcl/graphicfilter.hxx> #include <comphelper/sequenceashashmap.hxx> #include <comphelper/processfactory.hxx> +#include <cppuhelper/compbase.hxx> #include <wrtsh.hxx> #include <ndtxt.hxx> @@ -1249,6 +1253,106 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf161035) CPPUNIT_ASSERT(!xRunEnum->hasMoreElements()); // Empty enumeration for empty selection } +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf164885) +{ + class LocalDispatch : public cppu::WeakImplHelper<css::frame::XDispatch> + { + public: + LocalDispatch() = default; + + void SAL_CALL dispatch(const css::util::URL& URL, + const css::uno::Sequence<css::beans::PropertyValue>&) override + { + sLastCommand = URL.Complete; + } + void SAL_CALL addStatusListener(const css::uno::Reference<css::frame::XStatusListener>&, + const css::util::URL&) override + { + // empty + } + void SAL_CALL removeStatusListener(const css::uno::Reference<css::frame::XStatusListener>&, + const css::util::URL&) override + { + // empty + } + + OUString sLastCommand; + }; + + class LocalInterceptor : public cppu::WeakImplHelper<css::frame::XDispatchProviderInterceptor> + { + public: + LocalInterceptor() = default; + + // XDispatchProvider + css::uno::Reference<css::frame::XDispatch> + SAL_CALL queryDispatch(const css::util::URL& URL, const OUString& TargetFrameName, + sal_Int32 SearchFlags) override + { + if (URL.Complete == ".uno:Open") + return pDispatch; + if (m_slave) + return m_slave->queryDispatch(URL, TargetFrameName, SearchFlags); + return {}; + } + css::uno::Sequence<css::uno::Reference<css::frame::XDispatch>> SAL_CALL + queryDispatches(const css::uno::Sequence<css::frame::DispatchDescriptor>&) override + { + return {}; + } + + // XDispatchProviderInterceptor + css::uno::Reference<css::frame::XDispatchProvider> + SAL_CALL getSlaveDispatchProvider() override + { + return m_slave; + } + void SAL_CALL setSlaveDispatchProvider( + const css::uno::Reference<css::frame::XDispatchProvider>& val) override + { + m_slave = val; + } + css::uno::Reference<css::frame::XDispatchProvider> + SAL_CALL getMasterDispatchProvider() override + { + return m_master; + } + void SAL_CALL setMasterDispatchProvider( + const css::uno::Reference<css::frame::XDispatchProvider>& val) override + { + m_master = val; + } + + rtl::Reference<LocalDispatch> pDispatch{ new LocalDispatch }; + + private: + css::uno::Reference<css::frame::XDispatchProvider> m_master; + css::uno::Reference<css::frame::XDispatchProvider> m_slave; + }; + + // Given a document with a hyperlink + createSwDoc("hyperlink.fodt"); + auto controller(mxComponent.queryThrow<frame::XModel>()->getCurrentController()); + auto xProvider(controller->getFrame().queryThrow<css::frame::XDispatchProviderInterception>()); + + rtl::Reference<LocalInterceptor> interceptor(new LocalInterceptor); + xProvider->registerDispatchProviderInterceptor(interceptor); + + auto xCursor = controller.queryThrow<text::XTextViewCursorSupplier>()->getViewCursor(); + xCursor->goRight(5, false); // put cursor inside the hyperlink + + // Initiale "open hyperlink" + dispatchCommand(mxComponent, u".uno:OpenHyperlinkOnCursor"_ustr, {}); + + xProvider->releaseDispatchProviderInterceptor(interceptor); + + // Without the fix, this failed with + // - Expected: .uno:Open + // - Actual : + // because the interception didn't happen + CPPUNIT_ASSERT_EQUAL(u".uno:Open"_ustr, interceptor->pDispatch->sLastCommand); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/wrtsh/wrtsh2.cxx b/sw/source/uibase/wrtsh/wrtsh2.cxx index 3a9e51136fd0..946e651526f3 100644 --- a/sw/source/uibase/wrtsh/wrtsh2.cxx +++ b/sw/source/uibase/wrtsh/wrtsh2.cxx @@ -597,15 +597,16 @@ static void LoadURL(SwView& rView, const OUString& rURL, LoadUrlFlags nFilter, if ((nFilter & LoadUrlFlags::NewView) && !comphelper::LibreOfficeKit::isActive()) aTargetFrameName.SetValue( "_blank" ); - rViewFrame.GetDispatcher()->ExecuteList(SID_OPENDOC, - SfxCallMode::ASYNCHRON|SfxCallMode::RECORD, - { + const SfxPoolItem* aArr[] = { &aName, &aNewView, /*&aSilent,*/ &aReferer, &aView, &aTargetFrameName, - &aBrowse - }); + &aBrowse, + nullptr + }; + rViewFrame.GetDispatcher()->GetBindings()->Execute( + SID_OPENDOC, aArr, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); } void LoadURL( SwViewShell& rVSh, const OUString& rURL, LoadUrlFlags nFilter,