bump product version to 5.0.4.1
[LibreOffice.git] / sd / qa / unit / tiledrendering / tiledrendering.cxx
blob8ed091998ef15c1ddca0196064e8055d4a23c102
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 #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>
26 #include <DrawDocShell.hxx>
27 #include <ViewShell.hxx>
28 #include <sdpage.hxx>
29 #include <unomodel.hxx>
31 using namespace css;
33 #if !defined(WNT) && !defined(MACOSX)
34 static const char* DATA_DIRECTORY = "/sd/qa/unit/tiledrendering/data/";
35 #endif
37 class SdTiledRenderingTest : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools
39 public:
40 SdTiledRenderingTest();
41 virtual void setUp() SAL_OVERRIDE;
42 virtual void tearDown() SAL_OVERRIDE;
44 #if !defined(WNT) && !defined(MACOSX)
45 void testRegisterCallback();
46 void testPostKeyEvent();
47 void testPostMouseEvent();
48 void testSetTextSelection();
49 void testGetTextSelection();
50 void testSetGraphicSelection();
51 void testResetSelection();
52 void testSearch();
53 #endif
55 CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
56 #if !defined(WNT) && !defined(MACOSX)
57 CPPUNIT_TEST(testRegisterCallback);
58 CPPUNIT_TEST(testPostKeyEvent);
59 CPPUNIT_TEST(testPostMouseEvent);
60 CPPUNIT_TEST(testSetTextSelection);
61 CPPUNIT_TEST(testGetTextSelection);
62 CPPUNIT_TEST(testSetGraphicSelection);
63 CPPUNIT_TEST(testResetSelection);
64 CPPUNIT_TEST(testSearch);
65 #endif
66 CPPUNIT_TEST_SUITE_END();
68 private:
69 #if !defined(WNT) && !defined(MACOSX)
70 SdXImpressDocument* createDoc(const char* pName);
71 static void callback(int nType, const char* pPayload, void* pData);
72 void callbackImpl(int nType, const char* pPayload);
73 #endif
75 uno::Reference<lang::XComponent> mxComponent;
76 #if !defined(WNT) && !defined(MACOSX)
77 Rectangle m_aInvalidation;
78 std::vector<Rectangle> m_aSelection;
79 bool m_bFound;
80 sal_Int32 m_nPart;
81 #endif
84 SdTiledRenderingTest::SdTiledRenderingTest()
85 #if !defined(WNT) && !defined(MACOSX)
86 : m_bFound(true),
87 m_nPart(0)
88 #endif
92 void SdTiledRenderingTest::setUp()
94 test::BootstrapFixture::setUp();
96 mxDesktop.set(css::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())));
99 void SdTiledRenderingTest::tearDown()
101 if (mxComponent.is())
102 mxComponent->dispose();
104 test::BootstrapFixture::tearDown();
107 #if !defined(WNT) && !defined(MACOSX)
108 SdXImpressDocument* SdTiledRenderingTest::createDoc(const char* pName)
110 if (mxComponent.is())
111 mxComponent->dispose();
112 mxComponent = loadFromDesktop(getURLFromSrc(DATA_DIRECTORY) + OUString::createFromAscii(pName), "com.sun.star.presentation.PresentationDocument");
113 SdXImpressDocument* pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
114 CPPUNIT_ASSERT(pImpressDocument);
115 pImpressDocument->initializeForTiledRendering();
116 return pImpressDocument;
119 void SdTiledRenderingTest::callback(int nType, const char* pPayload, void* pData)
121 static_cast<SdTiledRenderingTest*>(pData)->callbackImpl(nType, pPayload);
124 static std::vector<OUString> lcl_convertSeparated(const OUString& rString, sal_Unicode nSeparator)
126 std::vector<OUString> aRet;
128 sal_Int32 nIndex = 0;
131 OUString aToken = rString.getToken(0, nSeparator, nIndex);
132 aToken = aToken.trim();
133 if (!aToken.isEmpty())
134 aRet.push_back(aToken);
136 while (nIndex >= 0);
138 return aRet;
141 static void lcl_convertRectangle(const OUString& rString, Rectangle& rRectangle)
143 uno::Sequence<OUString> aSeq = comphelper::string::convertCommaSeparated(rString);
144 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), aSeq.getLength());
145 rRectangle.setX(aSeq[0].toInt32());
146 rRectangle.setY(aSeq[1].toInt32());
147 rRectangle.setWidth(aSeq[2].toInt32());
148 rRectangle.setHeight(aSeq[3].toInt32());
151 void SdTiledRenderingTest::callbackImpl(int nType, const char* pPayload)
153 switch (nType)
155 case LOK_CALLBACK_INVALIDATE_TILES:
157 OUString aPayload = OUString::createFromAscii(pPayload);
158 if (aPayload != "EMPTY" && m_aInvalidation.IsEmpty())
159 lcl_convertRectangle(aPayload, m_aInvalidation);
161 break;
162 case LOK_CALLBACK_TEXT_SELECTION:
164 OUString aPayload = OUString::createFromAscii(pPayload);
165 m_aSelection.clear();
166 for (const OUString& rString : lcl_convertSeparated(aPayload, static_cast<sal_Unicode>(';')))
168 Rectangle aRectangle;
169 lcl_convertRectangle(rString, aRectangle);
170 m_aSelection.push_back(aRectangle);
173 break;
174 case LOK_CALLBACK_SEARCH_NOT_FOUND:
176 m_bFound = false;
178 break;
179 case LOK_CALLBACK_SET_PART:
181 OUString aPayload = OUString::createFromAscii(pPayload);
182 m_nPart = aPayload.toInt32();
184 break;
188 void SdTiledRenderingTest::testRegisterCallback()
190 SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
191 pXImpressDocument->registerCallback(&SdTiledRenderingTest::callback, this);
192 sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
194 // Start text edit of the empty title shape.
195 SdPage* pActualPage = pViewShell->GetActualPage();
196 SdrObject* pObject = pActualPage->GetObj(0);
197 SdrView* pView = pViewShell->GetView();
198 pView->SdrBeginTextEdit(pObject);
199 CPPUNIT_ASSERT(pView->GetTextEditObject());
201 // Check that the top left 256x256px tile would be invalidated.
202 CPPUNIT_ASSERT(!m_aInvalidation.IsEmpty());
203 Rectangle aTopLeft(0, 0, 256*15, 256*15); // 1 px = 15 twips, assuming 96 DPI.
204 CPPUNIT_ASSERT(m_aInvalidation.IsOver(aTopLeft));
207 void SdTiledRenderingTest::testPostKeyEvent()
209 SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
210 sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
211 SdPage* pActualPage = pViewShell->GetActualPage();
212 SdrObject* pObject = pActualPage->GetObj(0);
213 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_TITLETEXT), pObject->GetObjIdentifier());
214 SdrTextObj* pTextObj = static_cast<SdrTextObj*>(pObject);
215 SdrView* pView = pViewShell->GetView();
216 pView->MarkObj(pTextObj, pView->GetSdrPageView());
217 SfxStringItem aInputString(SID_ATTR_CHAR, "x");
218 pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_ATTR_CHAR, SfxCallMode::SYNCHRON, &aInputString, 0);
220 pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
221 pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
223 CPPUNIT_ASSERT(pView->GetTextEditObject());
224 EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
225 // Did we manage to enter a second character?
226 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), rEditView.GetSelection().nStartPos);
227 ESelection aWordSelection(0, 0, 0, 2); // start para, start char, end para, end char.
228 rEditView.SetSelection(aWordSelection);
229 // Did we enter the expected character?
230 CPPUNIT_ASSERT_EQUAL(OUString("xx"), rEditView.GetSelected());
233 void SdTiledRenderingTest::testPostMouseEvent()
235 SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
236 sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
237 SdPage* pActualPage = pViewShell->GetActualPage();
238 SdrObject* pObject = pActualPage->GetObj(0);
239 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(OBJ_TITLETEXT), pObject->GetObjIdentifier());
240 SdrTextObj* pTextObj = static_cast<SdrTextObj*>(pObject);
241 SdrView* pView = pViewShell->GetView();
242 pView->MarkObj(pTextObj, pView->GetSdrPageView());
243 SfxStringItem aInputString(SID_ATTR_CHAR, "x");
244 pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_ATTR_CHAR, SfxCallMode::SYNCHRON, &aInputString, 0);
245 CPPUNIT_ASSERT(pView->GetTextEditObject());
246 EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
247 // Did we manage to go after the first character?
248 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), rEditView.GetSelection().nStartPos);
250 vcl::Cursor* pCursor = rEditView.GetCursor();
251 Point aPosition = pCursor->GetPos();
252 aPosition.setX(aPosition.getX() - 1000);
253 pXImpressDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN, convertMm100ToTwip(aPosition.getX()), convertMm100ToTwip(aPosition.getY()), 1);
254 pXImpressDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, convertMm100ToTwip(aPosition.getX()), convertMm100ToTwip(aPosition.getY()), 1);
255 CPPUNIT_ASSERT(pView->GetTextEditObject());
256 // The new cursor position must be before the first word.
257 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), rEditView.GetSelection().nStartPos);
260 void SdTiledRenderingTest::testSetTextSelection()
262 SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
263 uno::Reference<container::XIndexAccess> xDrawPage(pXImpressDocument->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
264 uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
265 xShape->setString("Aaa bbb.");
266 // Create a selection on the second word.
267 sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
268 SdPage* pActualPage = pViewShell->GetActualPage();
269 SdrObject* pObject = pActualPage->GetObj(0);
270 SdrView* pView = pViewShell->GetView();
271 pView->SdrBeginTextEdit(pObject);
272 CPPUNIT_ASSERT(pView->GetTextEditObject());
273 EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
274 ESelection aWordSelection(0, 4, 0, 7);
275 rEditView.SetSelection(aWordSelection);
276 // Did we indeed manage to select the second word?
277 CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView.GetSelected());
279 // Now use setTextSelection() to move the end of the selection 1000 twips right.
280 vcl::Cursor* pCursor = rEditView.GetCursor();
281 Point aEnd = pCursor->GetPos();
282 aEnd.setX(aEnd.getX() + 1000);
283 pXImpressDocument->setTextSelection(LOK_SETTEXTSELECTION_END, aEnd.getX(), aEnd.getY());
284 // The new selection must include the ending dot, too -- but not the first word.
285 CPPUNIT_ASSERT_EQUAL(OUString("bbb."), rEditView.GetSelected());
288 void SdTiledRenderingTest::testGetTextSelection()
290 SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
291 uno::Reference<container::XIndexAccess> xDrawPage(pXImpressDocument->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
292 uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
293 xShape->setString("Shape");
294 // Create a selection on the shape text.
295 sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
296 SdPage* pActualPage = pViewShell->GetActualPage();
297 SdrObject* pObject = pActualPage->GetObj(0);
298 SdrView* pView = pViewShell->GetView();
299 pView->SdrBeginTextEdit(pObject);
300 CPPUNIT_ASSERT(pView->GetTextEditObject());
301 EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
302 ESelection aWordSelection(0, 0, 0, 5);
303 rEditView.SetSelection(aWordSelection);
304 // Did we indeed manage to copy the selected text?
305 OString aUsedFormat;
306 CPPUNIT_ASSERT_EQUAL(OString("Shape"), pXImpressDocument->getTextSelection("text/plain;charset=utf-8", aUsedFormat));
308 // Make sure returned RTF is not empty.
309 CPPUNIT_ASSERT(!OString(pXImpressDocument->getTextSelection("text/richtext", aUsedFormat)).isEmpty());
312 void SdTiledRenderingTest::testSetGraphicSelection()
314 SdXImpressDocument* pXImpressDocument = createDoc("shape.odp");
315 sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
316 SdPage* pPage = pViewShell->GetActualPage();
317 SdrObject* pObject = pPage->GetObj(0);
318 // Make sure the rectangle has 8 handles: at each corner and at the center of each edge.
319 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(8), pObject->GetHdlCount());
320 // Take the bottom center one.
321 SdrHdl* pHdl = pObject->GetHdl(6);
322 CPPUNIT_ASSERT_EQUAL(HDL_LOWER, pHdl->GetKind());
323 Rectangle aShapeBefore = pObject->GetSnapRect();
324 // Resize.
325 pXImpressDocument->setGraphicSelection(LOK_SETGRAPHICSELECTION_START, convertMm100ToTwip(pHdl->GetPos().getX()), convertMm100ToTwip(pHdl->GetPos().getY()));
326 pXImpressDocument->setGraphicSelection(LOK_SETGRAPHICSELECTION_END, convertMm100ToTwip(pHdl->GetPos().getX()), convertMm100ToTwip(pHdl->GetPos().getY() + 1000));
327 Rectangle aShapeAfter = pObject->GetSnapRect();
328 // Check that a resize happened, but aspect ratio is not kept.
329 CPPUNIT_ASSERT_EQUAL(aShapeBefore.getWidth(), aShapeAfter.getWidth());
330 CPPUNIT_ASSERT(aShapeBefore.getHeight() < aShapeAfter.getHeight());
333 void SdTiledRenderingTest::testResetSelection()
335 SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
336 uno::Reference<container::XIndexAccess> xDrawPage(pXImpressDocument->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
337 uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
338 xShape->setString("Aaa bbb.");
339 // Create a selection on the second word.
340 sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
341 SdPage* pActualPage = pViewShell->GetActualPage();
342 SdrObject* pObject = pActualPage->GetObj(0);
343 SdrView* pView = pViewShell->GetView();
344 pView->SdrBeginTextEdit(pObject);
345 CPPUNIT_ASSERT(pView->GetTextEditObject());
346 EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
347 ESelection aWordSelection(0, 4, 0, 7);
348 rEditView.SetSelection(aWordSelection);
349 // Did we indeed manage to select the second word?
350 CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView.GetSelected());
352 // Now use resetSelection() to reset the selection.
353 pXImpressDocument->resetSelection();
354 CPPUNIT_ASSERT(!pView->GetTextEditObject());
357 static void lcl_search(const OUString& rKey)
359 uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
361 {"SearchItem.SearchString", uno::makeAny(rKey)},
362 {"SearchItem.Backward", uno::makeAny(false)}
363 }));
364 comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues);
367 void SdTiledRenderingTest::testSearch()
369 SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
370 pXImpressDocument->registerCallback(&SdTiledRenderingTest::callback, this);
371 uno::Reference<container::XIndexAccess> xDrawPage(pXImpressDocument->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
372 uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
373 xShape->setString("Aaa bbb.");
375 lcl_search("bbb");
377 sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
378 SdrView* pView = pViewShell->GetView();
379 EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
380 // Did we indeed manage to select the second word?
381 CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView.GetSelected());
383 // Did the selection callback fire?
384 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), m_aSelection.size());
386 // Search for something on the second slide, and make sure that the set-part callback fired.
387 lcl_search("bbb");
388 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), m_nPart);
389 CPPUNIT_ASSERT_EQUAL(true, m_bFound);
391 // This should trigger the not-found callback.
392 Application::EnableHeadlessMode(false);
393 lcl_search("ccc");
394 CPPUNIT_ASSERT_EQUAL(false, m_bFound);
397 #endif
399 CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
401 CPPUNIT_PLUGIN_IMPLEMENT();
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */