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 #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>
29 #include <unomodel.hxx>
33 #if !defined(WNT) && !defined(MACOSX)
34 static const char* DATA_DIRECTORY
= "/sd/qa/unit/tiledrendering/data/";
37 class SdTiledRenderingTest
: public test::BootstrapFixture
, public unotest::MacrosTest
, public XmlTestTools
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();
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
);
66 CPPUNIT_TEST_SUITE_END();
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
);
75 uno::Reference
<lang::XComponent
> mxComponent
;
76 #if !defined(WNT) && !defined(MACOSX)
77 Rectangle m_aInvalidation
;
78 std::vector
<Rectangle
> m_aSelection
;
84 SdTiledRenderingTest::SdTiledRenderingTest()
85 #if !defined(WNT) && !defined(MACOSX)
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
);
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
)
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
);
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
);
174 case LOK_CALLBACK_SEARCH_NOT_FOUND
:
179 case LOK_CALLBACK_SET_PART
:
181 OUString aPayload
= OUString::createFromAscii(pPayload
);
182 m_nPart
= aPayload
.toInt32();
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?
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();
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)}
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.");
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.
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);
394 CPPUNIT_ASSERT_EQUAL(false, m_bFound
);
399 CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest
);
401 CPPUNIT_PLUGIN_IMPLEMENT();
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */