Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / qa / uibase / docvw / docvw.cxx
blob280a0459109ea7566ec327401d40d4f7a185f777
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/text/XTextDocument.hpp>
14 #include <vcl/event.hxx>
16 #include <docsh.hxx>
17 #include <edtwin.hxx>
18 #include <flyfrm.hxx>
19 #include <frameformats.hxx>
20 #include <view.hxx>
21 #include <wrtsh.hxx>
23 namespace
25 /// Covers sw/source/uibase/docvw/ fixes.
26 class Test : public SwModelTestBase
31 CPPUNIT_TEST_FIXTURE(Test, testShiftClickOnImage)
33 // Given a document with a fly frame:
34 createSwDoc();
35 SwDoc* pDoc = getSwDoc();
36 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
37 uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, uno::UNO_QUERY);
38 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
39 uno::Reference<text::XText> xText = xTextDocument->getText();
40 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
41 uno::Reference<beans::XPropertySet> xTextGraphic(
42 xMSF->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY);
43 xTextGraphic->setPropertyValue("AnchorType",
44 uno::Any(text::TextContentAnchorType_AS_CHARACTER));
45 xTextGraphic->setPropertyValue("Size", uno::Any(awt::Size(5000, 5000)));
46 uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY);
47 xText->insertTextContent(xCursor, xTextContent, false);
48 pWrtShell->SttEndDoc(/*bStt=*/false);
50 // When shift-clicking on that fly frame:
51 auto& rSpzFormats = *pDoc->GetSpzFrameFormats();
52 auto pFrameFormat = dynamic_cast<SwFlyFrameFormat*>(rSpzFormats[0]);
53 CPPUNIT_ASSERT(pFrameFormat);
54 SwFlyFrame* pFlyFrame = pFrameFormat->GetFrame();
55 vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
56 Point aFlyCenter = rEditWin.LogicToPixel(pFlyFrame->getFrameArea().Center());
57 MouseEvent aClickEvent(aFlyCenter, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT, KEY_SHIFT);
58 rEditWin.MouseButtonDown(aClickEvent);
59 rEditWin.MouseButtonUp(aClickEvent);
61 // Then make sure that the fly frame is selected:
62 SelectionType eType = pWrtShell->GetSelectionType();
63 // Without the accompanying fix in place, this test would have failed with:
64 // - Expected: 2 (SelectionType::Graphic)
65 // - Actual : 1 (SelectionType::Text)
66 // i.e. the fly frame was not selected, while a plain click or ctrl-click selected it.
67 CPPUNIT_ASSERT_EQUAL(SelectionType::Graphic, eType);
70 namespace
72 /// Interception implementation that catches the graphic dialog.
73 class GraphicDialogInterceptor : public cppu::WeakImplHelper<frame::XDispatchProviderInterceptor>
75 uno::Reference<frame::XDispatchProvider> m_xMaster;
76 uno::Reference<frame::XDispatchProvider> m_xSlave;
77 int m_nGraphicDialogs = 0;
79 public:
80 // XDispatchProviderInterceptor
81 uno::Reference<frame::XDispatchProvider> SAL_CALL getMasterDispatchProvider() override;
82 uno::Reference<frame::XDispatchProvider> SAL_CALL getSlaveDispatchProvider() override;
83 void SAL_CALL setMasterDispatchProvider(
84 const uno::Reference<frame::XDispatchProvider>& xNewSupplier) override;
85 void SAL_CALL
86 setSlaveDispatchProvider(const uno::Reference<frame::XDispatchProvider>& xNewSupplier) override;
88 // XDispatchProvider
89 uno::Reference<frame::XDispatch> SAL_CALL queryDispatch(const util::URL& rURL,
90 const OUString& rTargetFrameName,
91 sal_Int32 SearchFlags) override;
92 uno::Sequence<uno::Reference<frame::XDispatch>> SAL_CALL
93 queryDispatches(const uno::Sequence<frame::DispatchDescriptor>& rRequests) override;
95 int GetGraphicDialogs() const;
99 uno::Reference<frame::XDispatchProvider> GraphicDialogInterceptor::getMasterDispatchProvider()
101 return m_xMaster;
104 uno::Reference<frame::XDispatchProvider> GraphicDialogInterceptor::getSlaveDispatchProvider()
106 return m_xSlave;
109 void GraphicDialogInterceptor::setMasterDispatchProvider(
110 const uno::Reference<frame::XDispatchProvider>& xNewSupplier)
112 m_xMaster = xNewSupplier;
115 void GraphicDialogInterceptor::setSlaveDispatchProvider(
116 const uno::Reference<frame::XDispatchProvider>& xNewSupplier)
118 m_xSlave = xNewSupplier;
121 uno::Reference<frame::XDispatch>
122 GraphicDialogInterceptor::queryDispatch(const util::URL& rURL, const OUString& rTargetFrameName,
123 sal_Int32 nSearchFlags)
125 if (rURL.Complete == ".uno:GraphicDialog")
127 ++m_nGraphicDialogs;
130 return m_xSlave->queryDispatch(rURL, rTargetFrameName, nSearchFlags);
133 uno::Sequence<uno::Reference<frame::XDispatch>> GraphicDialogInterceptor::queryDispatches(
134 const uno::Sequence<frame::DispatchDescriptor>& /*rRequests*/)
136 return {};
139 int GraphicDialogInterceptor::GetGraphicDialogs() const { return m_nGraphicDialogs; }
141 CPPUNIT_TEST_FIXTURE(Test, testShiftDoubleClickOnImage)
143 // Given a document with a fly frame, and an interceptor to catch the graphic dialog:
144 createSwDoc();
145 SwDoc* pDoc = getSwDoc();
146 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
147 uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, uno::UNO_QUERY);
148 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
149 uno::Reference<text::XText> xText = xTextDocument->getText();
150 uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor();
151 uno::Reference<beans::XPropertySet> xTextGraphic(
152 xMSF->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY);
153 xTextGraphic->setPropertyValue("AnchorType",
154 uno::Any(text::TextContentAnchorType_AS_CHARACTER));
155 xTextGraphic->setPropertyValue("Size", uno::Any(awt::Size(5000, 5000)));
156 uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY);
157 xText->insertTextContent(xCursor, xTextContent, false);
158 pWrtShell->SttEndDoc(/*bStt=*/false);
159 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
160 uno::Reference<frame::XDispatchProviderInterception> xRegistration(
161 xModel->getCurrentController()->getFrame(), uno::UNO_QUERY);
162 rtl::Reference pInterceptor(new GraphicDialogInterceptor);
163 xRegistration->registerDispatchProviderInterceptor(pInterceptor);
165 // When shift-double-clicking on that fly frame:
166 auto& rSpzFormats = *pDoc->GetSpzFrameFormats();
167 auto pFrameFormat = dynamic_cast<SwFlyFrameFormat*>(rSpzFormats[0]);
168 CPPUNIT_ASSERT(pFrameFormat);
169 SwFlyFrame* pFlyFrame = pFrameFormat->GetFrame();
170 vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
171 Point aFlyCenter = rEditWin.LogicToPixel(pFlyFrame->getFrameArea().Center());
172 MouseEvent aClickEvent(aFlyCenter, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT, KEY_SHIFT);
173 rEditWin.MouseButtonDown(aClickEvent);
174 rEditWin.MouseButtonUp(aClickEvent);
175 aClickEvent
176 = MouseEvent(aFlyCenter, 2, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT, KEY_SHIFT);
177 rEditWin.MouseButtonDown(aClickEvent);
178 rEditWin.MouseButtonUp(aClickEvent);
180 // Then make sure that the fly frame's dialog is dispatched:
181 int nGraphicDialogs = pInterceptor->GetGraphicDialogs();
182 // Without the accompanying fix in place, this test would have failed with:
183 // - Expected greater than: 0 (2)
184 // - Actual : 0
185 // i.e. the fly frame's dialog was not dispatched, while a plain click or ctrl-click dispatched
186 // it.
187 CPPUNIT_ASSERT_GREATER(0, nGraphicDialogs);
190 CPPUNIT_PLUGIN_IMPLEMENT();
192 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */