1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <cppuhelper/implbase.hxx>
11 #include <test/unoapi_test.hxx>
13 #include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
14 #include <com/sun/star/frame/XInterceptorInfo.hpp>
15 #include <com/sun/star/util/URLTransformer.hpp>
17 #include <rtl/ref.hxx>
20 using namespace ::com::sun::star
;
24 /// Sample interception implementation that asserts getInterceptedURLs() and queryDispatch() is in sync.
26 : public cppu::WeakImplHelper
<frame::XDispatchProviderInterceptor
, frame::XInterceptorInfo
>
29 uno::Reference
<frame::XDispatchProvider
> m_xMaster
;
30 uno::Reference
<frame::XDispatchProvider
> m_xSlave
;
31 uno::Sequence
<OUString
> m_aDisabledCommands
;
38 /// Number of queryDispatch() calls that operate on a command advertised by getInterceptedURLs().
40 /// Number of queryDispatch() calls that operate on a command not advertised by getInterceptedURLs().
43 // frame::XInterceptorInfo
44 virtual uno::Sequence
<OUString
> SAL_CALL
getInterceptedURLs() override
;
46 // frame::XDispatchProviderInterceptor
47 virtual void SAL_CALL
setMasterDispatchProvider(
48 const uno::Reference
<frame::XDispatchProvider
>& xNewSupplier
) override
;
49 virtual uno::Reference
<frame::XDispatchProvider
> SAL_CALL
getMasterDispatchProvider() override
;
51 setSlaveDispatchProvider(const uno::Reference
<frame::XDispatchProvider
>& xNewSupplier
) override
;
52 virtual uno::Reference
<frame::XDispatchProvider
> SAL_CALL
getSlaveDispatchProvider() override
;
54 // frame::XDispatchProvider
55 virtual uno::Sequence
<uno::Reference
<frame::XDispatch
>> SAL_CALL
56 queryDispatches(const uno::Sequence
<frame::DispatchDescriptor
>& rRequests
) override
;
57 virtual uno::Reference
<frame::XDispatch
>
58 SAL_CALL
queryDispatch(const util::URL
& rURL
, const OUString
& rTargetFrameName
,
59 sal_Int32 SearchFlags
) override
;
62 MyInterceptor::MyInterceptor()
63 : m_aDisabledCommands
{ ".uno:Bold" }
69 int MyInterceptor::getExpected()
71 std::unique_lock
aGuard(maMutex
);
72 int nRet
= m_nExpected
;
77 int MyInterceptor::getUnexpected()
79 std::unique_lock
aGuard(maMutex
);
80 int nRet
= m_nUnexpected
;
85 uno::Sequence
<OUString
> MyInterceptor::getInterceptedURLs() { return m_aDisabledCommands
; }
87 void MyInterceptor::setMasterDispatchProvider(
88 const uno::Reference
<frame::XDispatchProvider
>& xNewSupplier
)
90 std::unique_lock
aGuard(maMutex
);
91 m_xMaster
= xNewSupplier
;
94 uno::Reference
<frame::XDispatchProvider
> MyInterceptor::getMasterDispatchProvider()
96 std::unique_lock
aGuard(maMutex
);
100 void MyInterceptor::setSlaveDispatchProvider(
101 const uno::Reference
<frame::XDispatchProvider
>& xNewSupplier
)
103 std::unique_lock
aGuard(maMutex
);
104 m_xSlave
= xNewSupplier
;
107 uno::Reference
<frame::XDispatchProvider
> MyInterceptor::getSlaveDispatchProvider()
109 std::unique_lock
aGuard(maMutex
);
113 uno::Sequence
<uno::Reference
<frame::XDispatch
>>
114 MyInterceptor::queryDispatches(const uno::Sequence
<frame::DispatchDescriptor
>& rRequests
)
116 uno::Sequence
<uno::Reference
<frame::XDispatch
>> aResult(rRequests
.getLength());
117 auto aResultRange
= asNonConstRange(aResult
);
119 for (sal_Int32 i
= 0; i
< rRequests
.getLength(); ++i
)
121 aResultRange
[i
] = queryDispatch(rRequests
[i
].FeatureURL
, rRequests
[i
].FrameName
,
122 rRequests
[i
].SearchFlags
);
128 uno::Reference
<frame::XDispatch
> MyInterceptor::queryDispatch(const util::URL
& rURL
,
129 const OUString
& /*rTargetFrameName*/,
130 sal_Int32
/*SearchFlags*/)
132 std::unique_lock
aGuard(maMutex
);
133 if (std::find(std::cbegin(m_aDisabledCommands
), std::cend(m_aDisabledCommands
), rURL
.Complete
)
134 != std::cend(m_aDisabledCommands
))
139 return uno::Reference
<frame::XDispatch
>();
142 /// Tests how InterceptionHelper invokes a registered interceptor.
143 class DispatchTest
: public UnoApiTest
147 : UnoApiTest("/framework/qa/cppunit/data/")
152 CPPUNIT_TEST_FIXTURE(DispatchTest
, testInterception
)
154 mxComponent
= loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
155 uno::Reference
<frame::XModel
> xModel(mxComponent
, uno::UNO_QUERY
);
156 CPPUNIT_ASSERT(xModel
.is());
158 uno::Reference
<frame::XDispatchProviderInterception
> xRegistration(
159 xModel
->getCurrentController()->getFrame(), uno::UNO_QUERY
);
160 CPPUNIT_ASSERT(xRegistration
.is());
162 rtl::Reference
<MyInterceptor
> pInterceptor(new MyInterceptor());
163 xRegistration
->registerDispatchProviderInterceptor(pInterceptor
);
165 dispatchCommand(mxComponent
, ".uno:Bold", {});
166 CPPUNIT_ASSERT_EQUAL(1, pInterceptor
->getExpected());
167 CPPUNIT_ASSERT_EQUAL(0, pInterceptor
->getUnexpected());
168 dispatchCommand(mxComponent
, ".uno:Italic", {});
169 CPPUNIT_ASSERT_EQUAL(1, pInterceptor
->getExpected());
170 // This was 1: MyInterceptor::queryDispatch() was called for .uno:Italic.
171 CPPUNIT_ASSERT_EQUAL(0, pInterceptor
->getUnexpected());
174 CPPUNIT_TEST_FIXTURE(DispatchTest
, testSfxOfficeDispatchDispose
)
176 // this test doesn't work with a new document because of aURL.Main check in SfxBaseController::dispatch()
177 loadFromURL(u
"empty.fodp");
178 uno::Reference
<frame::XModel
> xModel(mxComponent
, uno::UNO_QUERY
);
179 CPPUNIT_ASSERT(xModel
.is());
180 uno::Reference
<frame::XController
> xController(xModel
->getCurrentController());
181 CPPUNIT_ASSERT(xController
.is());
182 uno::Reference
<frame::XDispatchProvider
> xFrame(xController
->getFrame(), uno::UNO_QUERY
);
183 CPPUNIT_ASSERT(xFrame
.is());
185 uno::Reference
<util::XURLTransformer
> xParser(util::URLTransformer::create(mxComponentContext
));
187 url
.Complete
= xModel
->getURL() + "#dummy";
188 xParser
->parseStrict(url
);
190 uno::Reference
<frame::XDispatch
> xDisp(xFrame
->queryDispatch(url
, "", 0));
191 CPPUNIT_ASSERT(xDisp
.is());
193 mxComponent
->dispose();
196 urlSlot
.Complete
= "slot:5598";
197 xParser
->parseStrict(urlSlot
);
199 xDisp
->dispatch(urlSlot
, {});
203 CPPUNIT_PLUGIN_IMPLEMENT();
205 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */