Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #define LOK_USE_UNSTABLE_API
11 : #include <LibreOfficeKit/LibreOfficeKitEnums.h>
12 : #include <com/sun/star/frame/Desktop.hpp>
13 : #include <comphelper/dispatchcommand.hxx>
14 : #include <comphelper/processfactory.hxx>
15 : #include <comphelper/propertysequence.hxx>
16 : #include <comphelper/string.hxx>
17 : #include <editeng/editids.hrc>
18 : #include <editeng/editview.hxx>
19 : #include <editeng/outliner.hxx>
20 : #include <sfx2/dispatch.hxx>
21 : #include <sfx2/viewfrm.hxx>
22 : #include <test/bootstrapfixture.hxx>
23 : #include <test/xmltesttools.hxx>
24 : #include <unotest/macros_test.hxx>
25 :
26 : #include <DrawDocShell.hxx>
27 : #include <ViewShell.hxx>
28 : #include <sdpage.hxx>
29 : #include <unomodel.hxx>
30 :
31 : using namespace css;
32 :
33 : #if !defined(WNT) && !defined(MACOSX)
34 : static const char* DATA_DIRECTORY = "/sd/qa/unit/tiledrendering/data/";
35 : #endif
36 :
37 14 : class SdTiledRenderingTest : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools
38 : {
39 : public:
40 : SdTiledRenderingTest();
41 : virtual void setUp() SAL_OVERRIDE;
42 : virtual void tearDown() SAL_OVERRIDE;
43 :
44 : #if !defined(WNT) && !defined(MACOSX)
45 : void testRegisterCallback();
46 : void testPostKeyEvent();
47 : void testPostMouseEvent();
48 : void testSetTextSelection();
49 : void testSetGraphicSelection();
50 : void testResetSelection();
51 : void testSearch();
52 : #endif
53 :
54 2 : CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
55 : #if !defined(WNT) && !defined(MACOSX)
56 1 : CPPUNIT_TEST(testRegisterCallback);
57 1 : CPPUNIT_TEST(testPostKeyEvent);
58 1 : CPPUNIT_TEST(testPostMouseEvent);
59 1 : CPPUNIT_TEST(testSetTextSelection);
60 1 : CPPUNIT_TEST(testSetGraphicSelection);
61 1 : CPPUNIT_TEST(testResetSelection);
62 1 : CPPUNIT_TEST(testSearch);
63 : #endif
64 5 : CPPUNIT_TEST_SUITE_END();
65 :
66 : private:
67 : #if !defined(WNT) && !defined(MACOSX)
68 : SdXImpressDocument* createDoc(const char* pName);
69 : static void callback(int nType, const char* pPayload, void* pData);
70 : void callbackImpl(int nType, const char* pPayload);
71 : #endif
72 :
73 : uno::Reference<lang::XComponent> mxComponent;
74 : #if !defined(WNT) && !defined(MACOSX)
75 : Rectangle m_aInvalidation;
76 : std::vector<Rectangle> m_aSelection;
77 : bool m_bFound;
78 : sal_Int32 m_nPart;
79 : #endif
80 : };
81 :
82 7 : SdTiledRenderingTest::SdTiledRenderingTest()
83 : #if !defined(WNT) && !defined(MACOSX)
84 : : m_bFound(true),
85 7 : m_nPart(0)
86 : #endif
87 : {
88 7 : }
89 :
90 7 : void SdTiledRenderingTest::setUp()
91 : {
92 7 : test::BootstrapFixture::setUp();
93 :
94 7 : mxDesktop.set(css::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())));
95 7 : }
96 :
97 7 : void SdTiledRenderingTest::tearDown()
98 : {
99 7 : if (mxComponent.is())
100 7 : mxComponent->dispose();
101 :
102 7 : test::BootstrapFixture::tearDown();
103 7 : }
104 :
105 : #if !defined(WNT) && !defined(MACOSX)
106 7 : SdXImpressDocument* SdTiledRenderingTest::createDoc(const char* pName)
107 : {
108 7 : if (mxComponent.is())
109 0 : mxComponent->dispose();
110 7 : mxComponent = loadFromDesktop(getURLFromSrc(DATA_DIRECTORY) + OUString::createFromAscii(pName), "com.sun.star.presentation.PresentationDocument");
111 7 : SdXImpressDocument* pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
112 7 : CPPUNIT_ASSERT(pImpressDocument);
113 7 : pImpressDocument->initializeForTiledRendering();
114 7 : return pImpressDocument;
115 : }
116 :
117 244 : void SdTiledRenderingTest::callback(int nType, const char* pPayload, void* pData)
118 : {
119 244 : static_cast<SdTiledRenderingTest*>(pData)->callbackImpl(nType, pPayload);
120 244 : }
121 :
122 16 : static std::vector<OUString> lcl_convertSeparated(const OUString& rString, sal_Unicode nSeparator)
123 : {
124 16 : std::vector<OUString> aRet;
125 :
126 16 : sal_Int32 nIndex = 0;
127 16 : do
128 : {
129 16 : OUString aToken = rString.getToken(0, nSeparator, nIndex);
130 16 : aToken = aToken.trim();
131 16 : if (!aToken.isEmpty())
132 4 : aRet.push_back(aToken);
133 : }
134 16 : while (nIndex >= 0);
135 :
136 16 : return aRet;
137 : }
138 :
139 6 : static void lcl_convertRectangle(const OUString& rString, Rectangle& rRectangle)
140 : {
141 6 : uno::Sequence<OUString> aSeq = comphelper::string::convertCommaSeparated(rString);
142 6 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), aSeq.getLength());
143 6 : rRectangle.setX(aSeq[0].toInt32());
144 6 : rRectangle.setY(aSeq[1].toInt32());
145 6 : rRectangle.setWidth(aSeq[2].toInt32());
146 6 : rRectangle.setHeight(aSeq[3].toInt32());
147 6 : }
148 :
149 244 : void SdTiledRenderingTest::callbackImpl(int nType, const char* pPayload)
150 : {
151 244 : switch (nType)
152 : {
153 : case LOK_CALLBACK_INVALIDATE_TILES:
154 : {
155 106 : OUString aPayload = OUString::createFromAscii(pPayload);
156 106 : if (aPayload != "EMPTY" && m_aInvalidation.IsEmpty())
157 2 : lcl_convertRectangle(aPayload, m_aInvalidation);
158 : }
159 106 : break;
160 : case LOK_CALLBACK_TEXT_SELECTION:
161 : {
162 16 : OUString aPayload = OUString::createFromAscii(pPayload);
163 16 : m_aSelection.clear();
164 20 : for (const OUString& rString : lcl_convertSeparated(aPayload, static_cast<sal_Unicode>(';')))
165 : {
166 4 : Rectangle aRectangle;
167 4 : lcl_convertRectangle(rString, aRectangle);
168 4 : m_aSelection.push_back(aRectangle);
169 16 : }
170 : }
171 16 : break;
172 : case LOK_CALLBACK_SEARCH_NOT_FOUND:
173 : {
174 1 : m_bFound = false;
175 : }
176 1 : break;
177 : case LOK_CALLBACK_SET_PART:
178 : {
179 2 : OUString aPayload = OUString::createFromAscii(pPayload);
180 2 : m_nPart = aPayload.toInt32();
181 : }
182 2 : break;
183 : }
184 244 : }
185 :
186 1 : void SdTiledRenderingTest::testRegisterCallback()
187 : {
188 1 : SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
189 1 : pXImpressDocument->registerCallback(&SdTiledRenderingTest::callback, this);
190 1 : sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
191 :
192 : // Start text edit of the empty title shape.
193 1 : SdPage* pActualPage = pViewShell->GetActualPage();
194 1 : SdrObject* pObject = pActualPage->GetObj(0);
195 1 : SdrView* pView = pViewShell->GetView();
196 1 : pView->SdrBeginTextEdit(pObject);
197 1 : CPPUNIT_ASSERT(pView->GetTextEditObject());
198 :
199 : // Check that the top left 256x256px tile would be invalidated.
200 1 : CPPUNIT_ASSERT(!m_aInvalidation.IsEmpty());
201 1 : Rectangle aTopLeft(0, 0, 256*15, 256*15); // 1 px = 15 twips, assuming 96 DPI.
202 1 : CPPUNIT_ASSERT(m_aInvalidation.IsOver(aTopLeft));
203 1 : }
204 :
205 1 : void SdTiledRenderingTest::testPostKeyEvent()
206 : {
207 1 : SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
208 1 : sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
209 1 : SdPage* pActualPage = pViewShell->GetActualPage();
210 1 : SdrObject* pObject = pActualPage->GetObj(0);
211 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_TITLETEXT), pObject->GetObjIdentifier());
212 1 : SdrTextObj* pTextObj = static_cast<SdrTextObj*>(pObject);
213 1 : SdrView* pView = pViewShell->GetView();
214 1 : pView->MarkObj(pTextObj, pView->GetSdrPageView());
215 1 : SfxStringItem aInputString(SID_ATTR_CHAR, "x");
216 1 : pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_ATTR_CHAR, SfxCallMode::SYNCHRON, &aInputString, 0);
217 :
218 1 : pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
219 1 : pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
220 :
221 1 : CPPUNIT_ASSERT(pView->GetTextEditObject());
222 1 : EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
223 : // Did we manage to enter a second character?
224 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), rEditView.GetSelection().nStartPos);
225 1 : ESelection aWordSelection(0, 0, 0, 2); // start para, start char, end para, end char.
226 1 : rEditView.SetSelection(aWordSelection);
227 : // Did we enter the expected character?
228 1 : CPPUNIT_ASSERT_EQUAL(OUString("xx"), rEditView.GetSelected());
229 1 : }
230 :
231 1 : void SdTiledRenderingTest::testPostMouseEvent()
232 : {
233 1 : SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
234 1 : sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
235 1 : SdPage* pActualPage = pViewShell->GetActualPage();
236 1 : SdrObject* pObject = pActualPage->GetObj(0);
237 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_TITLETEXT), pObject->GetObjIdentifier());
238 1 : SdrTextObj* pTextObj = static_cast<SdrTextObj*>(pObject);
239 1 : SdrView* pView = pViewShell->GetView();
240 1 : pView->MarkObj(pTextObj, pView->GetSdrPageView());
241 1 : SfxStringItem aInputString(SID_ATTR_CHAR, "x");
242 1 : pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_ATTR_CHAR, SfxCallMode::SYNCHRON, &aInputString, 0);
243 1 : CPPUNIT_ASSERT(pView->GetTextEditObject());
244 1 : EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
245 : // Did we manage to go after the first character?
246 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), rEditView.GetSelection().nStartPos);
247 :
248 1 : vcl::Cursor* pCursor = rEditView.GetCursor();
249 1 : Point aPosition = pCursor->GetPos();
250 1 : aPosition.setX(aPosition.getX() - 1000);
251 1 : pXImpressDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, convertMm100ToTwip(aPosition.getX()), convertMm100ToTwip(aPosition.getY()), 1);
252 1 : pXImpressDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, convertMm100ToTwip(aPosition.getX()), convertMm100ToTwip(aPosition.getY()), 1);
253 1 : CPPUNIT_ASSERT(pView->GetTextEditObject());
254 : // The new cursor position must be before the first word.
255 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), rEditView.GetSelection().nStartPos);
256 1 : }
257 :
258 1 : void SdTiledRenderingTest::testSetTextSelection()
259 : {
260 1 : SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
261 1 : uno::Reference<container::XIndexAccess> xDrawPage(pXImpressDocument->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
262 2 : uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
263 1 : xShape->setString("Aaa bbb.");
264 : // Create a selection on the second word.
265 1 : sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
266 1 : SdPage* pActualPage = pViewShell->GetActualPage();
267 1 : SdrObject* pObject = pActualPage->GetObj(0);
268 1 : SdrView* pView = pViewShell->GetView();
269 1 : pView->SdrBeginTextEdit(pObject);
270 1 : CPPUNIT_ASSERT(pView->GetTextEditObject());
271 1 : EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
272 1 : ESelection aWordSelection(0, 4, 0, 7);
273 1 : rEditView.SetSelection(aWordSelection);
274 : // Did we indeed manage to select the second word?
275 1 : CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView.GetSelected());
276 :
277 : // Now use setTextSelection() to move the end of the selection 1000 twips right.
278 1 : vcl::Cursor* pCursor = rEditView.GetCursor();
279 1 : Point aEnd = pCursor->GetPos();
280 1 : aEnd.setX(aEnd.getX() + 1000);
281 1 : pXImpressDocument->setTextSelection(LOK_SETTEXTSELECTION_END, aEnd.getX(), aEnd.getY());
282 : // The new selection must include the ending dot, too -- but not the first word.
283 2 : CPPUNIT_ASSERT_EQUAL(OUString("bbb."), rEditView.GetSelected());
284 1 : }
285 :
286 1 : void SdTiledRenderingTest::testSetGraphicSelection()
287 : {
288 1 : SdXImpressDocument* pXImpressDocument = createDoc("shape.odp");
289 1 : sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
290 1 : SdPage* pPage = pViewShell->GetActualPage();
291 1 : SdrObject* pObject = pPage->GetObj(0);
292 : // Make sure the rectangle has 8 handles: at each corner and at the center of each edge.
293 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(8), pObject->GetHdlCount());
294 : // Take the bottom center one.
295 1 : SdrHdl* pHdl = pObject->GetHdl(6);
296 1 : CPPUNIT_ASSERT_EQUAL(HDL_LOWER, pHdl->GetKind());
297 1 : Rectangle aShapeBefore = pObject->GetSnapRect();
298 : // Resize.
299 1 : pXImpressDocument->setGraphicSelection(LOK_SETGRAPHICSELECTION_START, convertMm100ToTwip(pHdl->GetPos().getX()), convertMm100ToTwip(pHdl->GetPos().getY()));
300 1 : pXImpressDocument->setGraphicSelection(LOK_SETGRAPHICSELECTION_END, convertMm100ToTwip(pHdl->GetPos().getX()), convertMm100ToTwip(pHdl->GetPos().getY() + 1000));
301 1 : Rectangle aShapeAfter = pObject->GetSnapRect();
302 : // Check that a resize happened, but aspect ratio is not kept.
303 1 : CPPUNIT_ASSERT_EQUAL(aShapeBefore.getWidth(), aShapeAfter.getWidth());
304 1 : CPPUNIT_ASSERT(aShapeBefore.getHeight() < aShapeAfter.getHeight());
305 1 : }
306 :
307 1 : void SdTiledRenderingTest::testResetSelection()
308 : {
309 1 : SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
310 1 : uno::Reference<container::XIndexAccess> xDrawPage(pXImpressDocument->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
311 2 : uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
312 1 : xShape->setString("Aaa bbb.");
313 : // Create a selection on the second word.
314 1 : sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
315 1 : SdPage* pActualPage = pViewShell->GetActualPage();
316 1 : SdrObject* pObject = pActualPage->GetObj(0);
317 1 : SdrView* pView = pViewShell->GetView();
318 1 : pView->SdrBeginTextEdit(pObject);
319 1 : CPPUNIT_ASSERT(pView->GetTextEditObject());
320 1 : EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
321 1 : ESelection aWordSelection(0, 4, 0, 7);
322 1 : rEditView.SetSelection(aWordSelection);
323 : // Did we indeed manage to select the second word?
324 1 : CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView.GetSelected());
325 :
326 : // Now use resetSelection() to reset the selection.
327 1 : pXImpressDocument->resetSelection();
328 2 : CPPUNIT_ASSERT(!pView->GetTextEditObject());
329 1 : }
330 :
331 3 : static void lcl_search(const OUString& rKey)
332 : {
333 : uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
334 : {
335 : {"SearchItem.SearchString", uno::makeAny(rKey)},
336 : {"SearchItem.Backward", uno::makeAny(false)}
337 3 : }));
338 3 : comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues);
339 3 : }
340 :
341 1 : void SdTiledRenderingTest::testSearch()
342 : {
343 1 : SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
344 1 : pXImpressDocument->registerCallback(&SdTiledRenderingTest::callback, this);
345 1 : uno::Reference<container::XIndexAccess> xDrawPage(pXImpressDocument->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
346 2 : uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
347 1 : xShape->setString("Aaa bbb.");
348 :
349 1 : lcl_search("bbb");
350 :
351 1 : sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
352 1 : SdrView* pView = pViewShell->GetView();
353 1 : EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
354 : // Did we indeed manage to select the second word?
355 1 : CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView.GetSelected());
356 :
357 : // Did the selection callback fire?
358 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), m_aSelection.size());
359 :
360 : // Search for something on the second slide, and make sure that the set-part callback fired.
361 1 : lcl_search("bbb");
362 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), m_nPart);
363 1 : CPPUNIT_ASSERT_EQUAL(true, m_bFound);
364 :
365 : // This should trigger the not-found callback.
366 1 : Application::EnableHeadlessMode(false);
367 1 : lcl_search("ccc");
368 2 : CPPUNIT_ASSERT_EQUAL(false, m_bFound);
369 1 : }
370 :
371 : #endif
372 :
373 1 : CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
374 :
375 4 : CPPUNIT_PLUGIN_IMPLEMENT();
376 :
377 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|