/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include using namespace ::com::sun::star; namespace { /// Sample interception implementation that asserts getInterceptedURLs() and queryDispatch() is in sync. class MyInterceptor : public cppu::WeakImplHelper < frame::XDispatchProviderInterceptor, frame::XInterceptorInfo > { uno::Reference m_xMaster; uno::Reference m_xSlave; uno::Sequence m_aDisabledCommands; int m_nExpected; int m_nUnexpected; public: MyInterceptor(); /// Number of queryDispatch() calls that operate on a command advertised by getInterceptedURLs(). int getExpected(); /// Number of queryDispatch() calls that operate on a command not advertised by getInterceptedURLs(). int getUnexpected(); // frame::XInterceptorInfo virtual uno::Sequence SAL_CALL getInterceptedURLs() override; // frame::XDispatchProviderInterceptor virtual void SAL_CALL setMasterDispatchProvider(const uno::Reference& xNewSupplier) override; virtual uno::Reference SAL_CALL getMasterDispatchProvider() override; virtual void SAL_CALL setSlaveDispatchProvider(const uno::Reference& xNewSupplier) override; virtual uno::Reference SAL_CALL getSlaveDispatchProvider() override; // frame::XDispatchProvider virtual uno::Sequence> SAL_CALL queryDispatches(const uno::Sequence& xRequests) override; virtual uno::Reference SAL_CALL queryDispatch(const util::URL& rURL, const OUString& rTargetFrameName, sal_Int32 SearchFlags) override; }; MyInterceptor::MyInterceptor() : m_nExpected(0), m_nUnexpected(0) { // Not part of the initializer list as MSVC 2013 would not handle that. m_aDisabledCommands = {".uno:Bold"}; } int MyInterceptor::getExpected() { int nRet = m_nExpected; m_nExpected = 0; return nRet; } int MyInterceptor::getUnexpected() { int nRet = m_nUnexpected; m_nUnexpected = 0; return nRet; } uno::Sequence MyInterceptor::getInterceptedURLs() { return m_aDisabledCommands; } void MyInterceptor::setMasterDispatchProvider(const uno::Reference& xNewSupplier) { m_xMaster = xNewSupplier; } uno::Reference MyInterceptor::getMasterDispatchProvider() { return m_xMaster; } void MyInterceptor::setSlaveDispatchProvider(const uno::Reference& xNewSupplier) { m_xSlave = xNewSupplier; } uno::Reference MyInterceptor::getSlaveDispatchProvider() { return m_xSlave; } uno::Sequence> MyInterceptor::queryDispatches(const uno::Sequence& rRequests) { uno::Sequence> aResult(rRequests.getLength()); for (sal_Int32 i = 0; i < rRequests.getLength(); ++i) { aResult[i] = queryDispatch(rRequests[i].FeatureURL, rRequests[i].FrameName, rRequests[i].SearchFlags); } return aResult; } uno::Reference MyInterceptor::queryDispatch(const util::URL& rURL, const OUString& /*rTargetFrameName*/, sal_Int32 /*SearchFlags*/) { if (std::find(m_aDisabledCommands.begin(), m_aDisabledCommands.end(), rURL.Complete) != m_aDisabledCommands.end()) ++m_nExpected; else ++m_nUnexpected; return uno::Reference(); } /// Tests how InterceptionHelper invokes a registered interceptor. class DispatchTest : public test::BootstrapFixture, public unotest::MacrosTest { uno::Reference mxComponentContext; uno::Reference mxComponent; void dispatchCommand(const uno::Reference& xComponent, const OUString& rCommand, const uno::Sequence& rPropertyValues); public: virtual void setUp() override; virtual void tearDown() override; void testInterception(); CPPUNIT_TEST_SUITE(DispatchTest); CPPUNIT_TEST(testInterception); CPPUNIT_TEST_SUITE_END(); }; void DispatchTest::setUp() { test::BootstrapFixture::setUp(); mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory())); mxDesktop.set(frame::Desktop::create(mxComponentContext)); } void DispatchTest::tearDown() { if (mxComponent.is()) mxComponent->dispose(); test::BootstrapFixture::tearDown(); } void DispatchTest::dispatchCommand(const uno::Reference& xComponent, const OUString& rCommand, const uno::Sequence& rPropertyValues) { uno::Reference xController = uno::Reference(xComponent, uno::UNO_QUERY)->getCurrentController(); CPPUNIT_ASSERT(xController.is()); uno::Reference xFrame(xController->getFrame(), uno::UNO_QUERY); CPPUNIT_ASSERT(xFrame.is()); uno::Reference xContext = ::comphelper::getProcessComponentContext(); uno::Reference xDispatchHelper(frame::DispatchHelper::create(xContext)); CPPUNIT_ASSERT(xDispatchHelper.is()); xDispatchHelper->executeDispatch(xFrame, rCommand, OUString(), 0, rPropertyValues); } void DispatchTest::testInterception() { mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument"); CPPUNIT_ASSERT(mxComponent.is()); uno::Reference xModel(mxComponent, uno::UNO_QUERY); CPPUNIT_ASSERT(xModel.is()); uno::Reference xRegistration(xModel->getCurrentController()->getFrame(), uno::UNO_QUERY); CPPUNIT_ASSERT(xRegistration.is()); rtl::Reference pInterceptor(new MyInterceptor()); xRegistration->registerDispatchProviderInterceptor(uno::Reference(pInterceptor.get())); dispatchCommand(mxComponent, ".uno:Bold", {}); CPPUNIT_ASSERT_EQUAL(1, pInterceptor->getExpected()); CPPUNIT_ASSERT_EQUAL(0, pInterceptor->getUnexpected()); dispatchCommand(mxComponent, ".uno:Italic", {}); CPPUNIT_ASSERT_EQUAL(0, pInterceptor->getExpected()); // This was 1: MyInterceptor::queryDispatch() was called for .uno:Italic. CPPUNIT_ASSERT_EQUAL(0, pInterceptor->getUnexpected()); } CPPUNIT_TEST_SUITE_REGISTRATION(DispatchTest); } CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */