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 #include "../sdmodeltestbase.hxx"
12 #include <test/bootstrapfixture.hxx>
13 #include <test/helper/transferable.hxx>
14 #include <test/xmltesttools.hxx>
15 #include <boost/property_tree/json_parser.hpp>
16 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
17 #include <sfx2/lokhelper.hxx>
18 #include <com/sun/star/frame/Desktop.hpp>
19 #include <comphelper/dispatchcommand.hxx>
20 #include <comphelper/processfactory.hxx>
21 #include <comphelper/propertysequence.hxx>
22 #include <comphelper/string.hxx>
23 #include <editeng/eeitem.hxx>
24 #include <editeng/editids.hrc>
25 #include <editeng/editobj.hxx>
26 #include <editeng/editview.hxx>
27 #include <editeng/outliner.hxx>
28 #include <editeng/fhgtitem.hxx>
29 #include <editeng/outlobj.hxx>
30 #include <osl/conditn.hxx>
31 #include <sfx2/dispatch.hxx>
32 #include <sfx2/viewfrm.hxx>
33 #include <svl/srchitem.hxx>
34 #include <svl/stritem.hxx>
35 #include <svl/intitem.hxx>
36 #include <comphelper/lok.hxx>
37 #include <svx/svdotable.hxx>
38 #include <svx/svdoutl.hxx>
39 #include <unotools/datetime.hxx>
41 #include <DrawDocShell.hxx>
42 #include <ViewShellBase.hxx>
43 #include <ViewShell.hxx>
45 #include <unomodel.hxx>
46 #include <drawdoc.hxx>
47 #include <undo/undomanager.hxx>
48 #include <sfx2/request.hxx>
49 #include <svx/svxids.hrc>
51 #include <navigatr.hxx>
52 #include <vcl/cursor.hxx>
53 #include <vcl/scheduler.hxx>
54 #include <vcl/vclevent.hxx>
61 static char const DATA_DIRECTORY
[] = "/sd/qa/unit/tiledrendering/data/";
63 static std::ostream
& operator<<(std::ostream
& os
, ViewShellId id
)
65 os
<< static_cast<sal_Int32
>(id
);
69 class SdTiledRenderingTest
: public SdModelTestBase
, public XmlTestTools
72 SdTiledRenderingTest();
73 virtual void setUp() override
;
74 virtual void tearDown() override
;
76 void testCreateDestroy();
77 void testCreateView();
78 void testRegisterCallback();
79 void testPostKeyEvent();
80 void testPostMouseEvent();
81 void testSetTextSelection();
82 void testGetTextSelection();
83 void testSetGraphicSelection();
84 void testUndoShells();
85 void testResetSelection();
88 void testSearchAllSelections();
89 void testSearchAllNotifications();
90 void testSearchAllFollowedBySearch();
91 void testDontSearchInMasterPages();
92 void testInsertDeletePage();
93 void testInsertTable();
95 void testResizeTable();
96 void testResizeTableColumn();
97 void testViewCursors();
98 void testViewCursorParts();
99 void testCursorViews();
101 void testUndoLimiting();
102 void testCreateViewGraphicSelection();
103 void testCreateViewTextCursor();
104 void testTdf102223();
105 void testPostKeyEventInvalidation();
106 void testTdf103083();
107 void testTdf104405();
109 void testTdf105502();
110 void testCommentCallbacks();
111 void testMultiViewInsertDeletePage();
112 void testDisableUndoRepair();
113 void testDocumentRepair();
114 void testLanguageStatus();
115 void testDefaultView();
116 void testIMESupport();
117 void testTdf115783();
118 void testPasteTextOnSlide();
119 void testTdf115873();
120 void testTdf115873Group();
121 void testCutSelectionChange();
122 void testRegenerateDiagram();
123 void testLanguageAllText();
124 void testInsertDeletePageInvalidation();
126 CPPUNIT_TEST_SUITE(SdTiledRenderingTest
);
127 CPPUNIT_TEST(testCreateDestroy
);
128 CPPUNIT_TEST(testCreateView
);
129 CPPUNIT_TEST(testRegisterCallback
);
130 CPPUNIT_TEST(testPostKeyEvent
);
131 CPPUNIT_TEST(testPostMouseEvent
);
132 CPPUNIT_TEST(testSetTextSelection
);
133 CPPUNIT_TEST(testGetTextSelection
);
134 CPPUNIT_TEST(testSetGraphicSelection
);
135 CPPUNIT_TEST(testUndoShells
);
136 CPPUNIT_TEST(testResetSelection
);
137 CPPUNIT_TEST(testSearch
);
138 CPPUNIT_TEST(testSearchAll
);
139 CPPUNIT_TEST(testSearchAllSelections
);
140 CPPUNIT_TEST(testSearchAllNotifications
);
141 CPPUNIT_TEST(testSearchAllFollowedBySearch
);
142 CPPUNIT_TEST(testDontSearchInMasterPages
);
143 CPPUNIT_TEST(testInsertDeletePage
);
144 CPPUNIT_TEST(testInsertTable
);
145 CPPUNIT_TEST(testPartHash
);
146 CPPUNIT_TEST(testResizeTable
);
147 CPPUNIT_TEST(testResizeTableColumn
);
148 CPPUNIT_TEST(testViewCursors
);
149 CPPUNIT_TEST(testViewCursorParts
);
150 CPPUNIT_TEST(testCursorViews
);
151 CPPUNIT_TEST(testViewLock
);
152 CPPUNIT_TEST(testUndoLimiting
);
153 CPPUNIT_TEST(testCreateViewGraphicSelection
);
154 CPPUNIT_TEST(testCreateViewTextCursor
);
155 CPPUNIT_TEST(testTdf102223
);
156 CPPUNIT_TEST(testPostKeyEventInvalidation
);
157 CPPUNIT_TEST(testTdf103083
);
158 CPPUNIT_TEST(testTdf104405
);
159 CPPUNIT_TEST(testTdf81754
);
160 CPPUNIT_TEST(testTdf105502
);
161 CPPUNIT_TEST(testCommentCallbacks
);
162 CPPUNIT_TEST(testMultiViewInsertDeletePage
);
163 CPPUNIT_TEST(testDisableUndoRepair
);
164 CPPUNIT_TEST(testDocumentRepair
);
165 CPPUNIT_TEST(testLanguageStatus
);
166 CPPUNIT_TEST(testDefaultView
);
167 CPPUNIT_TEST(testIMESupport
);
168 CPPUNIT_TEST(testTdf115783
);
169 CPPUNIT_TEST(testPasteTextOnSlide
);
170 CPPUNIT_TEST(testTdf115873
);
171 CPPUNIT_TEST(testTdf115873Group
);
172 CPPUNIT_TEST(testCutSelectionChange
);
173 CPPUNIT_TEST(testRegenerateDiagram
);
174 CPPUNIT_TEST(testLanguageAllText
);
175 CPPUNIT_TEST(testInsertDeletePageInvalidation
);
177 CPPUNIT_TEST_SUITE_END();
180 SdXImpressDocument
* createDoc(const char* pName
, const uno::Sequence
<beans::PropertyValue
>& rArguments
= uno::Sequence
<beans::PropertyValue
>());
181 static void callback(int nType
, const char* pPayload
, void* pData
);
182 void callbackImpl(int nType
, const char* pPayload
);
183 xmlDocPtr
parseXmlDump();
185 uno::Reference
<lang::XComponent
> mxComponent
;
186 ::tools::Rectangle m_aInvalidation
;
187 std::vector
<::tools::Rectangle
> m_aSelection
;
190 std::vector
<OString
> m_aSearchResultSelection
;
191 std::vector
<int> m_aSearchResultPart
;
192 int m_nSelectionBeforeSearchResult
;
193 int m_nSelectionAfterSearchResult
;
195 /// For document size changed callback.
196 osl::Condition m_aDocumentSizeCondition
;
197 xmlBufferPtr m_pXmlBuffer
;
200 SdTiledRenderingTest::SdTiledRenderingTest()
203 m_nSelectionBeforeSearchResult(0),
204 m_nSelectionAfterSearchResult(0),
205 m_pXmlBuffer(nullptr)
209 void SdTiledRenderingTest::setUp()
211 test::BootstrapFixture::setUp();
213 // prevent showing warning message box
214 setenv("OOX_NO_SMARTART_WARNING", "1", 1);
215 comphelper::LibreOfficeKit::setActive(true);
217 mxDesktop
.set(css::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())));
220 void SdTiledRenderingTest::tearDown()
222 if (mxComponent
.is())
223 mxComponent
->dispose();
226 xmlBufferFree(m_pXmlBuffer
);
228 comphelper::LibreOfficeKit::setActive(false);
230 test::BootstrapFixture::tearDown();
233 SdXImpressDocument
* SdTiledRenderingTest::createDoc(const char* pName
, const uno::Sequence
<beans::PropertyValue
>& rArguments
)
235 if (mxComponent
.is())
236 mxComponent
->dispose();
237 mxComponent
= loadFromDesktop(m_directories
.getURLFromSrc(DATA_DIRECTORY
) + OUString::createFromAscii(pName
), "com.sun.star.presentation.PresentationDocument");
238 SdXImpressDocument
* pImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
239 CPPUNIT_ASSERT(pImpressDocument
);
240 pImpressDocument
->initializeForTiledRendering(rArguments
);
241 return pImpressDocument
;
244 void SdTiledRenderingTest::callback(int nType
, const char* pPayload
, void* pData
)
246 static_cast<SdTiledRenderingTest
*>(pData
)->callbackImpl(nType
, pPayload
);
249 static std::vector
<OUString
> lcl_convertSeparated(const OUString
& rString
, sal_Unicode nSeparator
)
251 std::vector
<OUString
> aRet
;
253 sal_Int32 nIndex
= 0;
256 OUString aToken
= rString
.getToken(0, nSeparator
, nIndex
);
257 aToken
= aToken
.trim();
258 if (!aToken
.isEmpty())
259 aRet
.push_back(aToken
);
266 static void lcl_convertRectangle(const OUString
& rString
, ::tools::Rectangle
& rRectangle
)
268 uno::Sequence
<OUString
> aSeq
= comphelper::string::convertCommaSeparated(rString
);
269 CPPUNIT_ASSERT(aSeq
.getLength() == 4 || aSeq
.getLength() == 5);
270 rRectangle
.setX(aSeq
[0].toInt32());
271 rRectangle
.setY(aSeq
[1].toInt32());
272 rRectangle
.setWidth(aSeq
[2].toInt32());
273 rRectangle
.setHeight(aSeq
[3].toInt32());
276 void SdTiledRenderingTest::callbackImpl(int nType
, const char* pPayload
)
280 case LOK_CALLBACK_INVALIDATE_TILES
:
282 OUString aPayload
= OUString::createFromAscii(pPayload
);
283 if (aPayload
!= "EMPTY" && m_aInvalidation
.IsEmpty())
284 lcl_convertRectangle(aPayload
, m_aInvalidation
);
287 case LOK_CALLBACK_TEXT_SELECTION
:
289 OUString aPayload
= OUString::createFromAscii(pPayload
);
290 m_aSelection
.clear();
291 for (const OUString
& rString
: lcl_convertSeparated(aPayload
, u
';'))
293 ::tools::Rectangle aRectangle
;
294 lcl_convertRectangle(rString
, aRectangle
);
295 m_aSelection
.push_back(aRectangle
);
297 if (m_aSearchResultSelection
.empty())
298 ++m_nSelectionBeforeSearchResult
;
300 ++m_nSelectionAfterSearchResult
;
303 case LOK_CALLBACK_SEARCH_NOT_FOUND
:
308 case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED
:
310 m_aDocumentSizeCondition
.set();
313 case LOK_CALLBACK_SET_PART
:
315 OUString aPayload
= OUString::createFromAscii(pPayload
);
316 m_nPart
= aPayload
.toInt32();
319 case LOK_CALLBACK_SEARCH_RESULT_SELECTION
:
321 m_aSearchResultSelection
.clear();
322 m_aSearchResultPart
.clear();
323 boost::property_tree::ptree aTree
;
324 std::stringstream
aStream(pPayload
);
325 boost::property_tree::read_json(aStream
, aTree
);
326 for (const boost::property_tree::ptree::value_type
& rValue
: aTree
.get_child("searchResultSelection"))
328 m_aSearchResultSelection
.emplace_back(rValue
.second
.get
<std::string
>("rectangles").c_str());
329 m_aSearchResultPart
.push_back(std::atoi(rValue
.second
.get
<std::string
>("part").c_str()));
336 xmlDocPtr
SdTiledRenderingTest::parseXmlDump()
339 xmlBufferFree(m_pXmlBuffer
);
341 // Create the xml writer.
342 m_pXmlBuffer
= xmlBufferCreate();
343 xmlTextWriterPtr pXmlWriter
= xmlNewTextWriterMemory(m_pXmlBuffer
, 0);
344 xmlTextWriterStartDocument(pXmlWriter
, nullptr, nullptr, nullptr);
347 SdXImpressDocument
* pImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
348 CPPUNIT_ASSERT(pImpressDocument
);
349 pImpressDocument
->GetDoc()->dumpAsXml(pXmlWriter
);
351 // Delete the xml writer.
352 xmlTextWriterEndDocument(pXmlWriter
);
353 xmlFreeTextWriter(pXmlWriter
);
355 return xmlParseMemory(reinterpret_cast<const char*>(xmlBufferContent(m_pXmlBuffer
)), xmlBufferLength(m_pXmlBuffer
));
358 void SdTiledRenderingTest::testCreateDestroy()
360 createDoc("dummy.odp");
361 // Nothing to do, the tearDown call should cleanup.
364 void SdTiledRenderingTest::testCreateView()
366 createDoc("dummy.odp");
368 SfxLokHelper::createView();
371 void SdTiledRenderingTest::testRegisterCallback()
373 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
374 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
375 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
377 // Start text edit of the empty title shape.
378 SdPage
* pActualPage
= pViewShell
->GetActualPage();
379 SdrObject
* pObject
= pActualPage
->GetObj(0);
380 SdrView
* pView
= pViewShell
->GetView();
381 pView
->SdrBeginTextEdit(pObject
);
382 CPPUNIT_ASSERT(pView
->GetTextEditObject());
384 // Check that the top left 256x256px tile would be invalidated.
385 CPPUNIT_ASSERT(!m_aInvalidation
.IsEmpty());
386 ::tools::Rectangle
aTopLeft(0, 0, 256*15, 256*15); // 1 px = 15 twips, assuming 96 DPI.
387 CPPUNIT_ASSERT(m_aInvalidation
.IsOver(aTopLeft
));
390 void SdTiledRenderingTest::testPostKeyEvent()
392 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
393 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
394 SdPage
* pActualPage
= pViewShell
->GetActualPage();
395 SdrObject
* pObject
= pActualPage
->GetObj(0);
396 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(OBJ_TITLETEXT
), pObject
->GetObjIdentifier());
397 SdrTextObj
* pTextObj
= static_cast<SdrTextObj
*>(pObject
);
398 SdrView
* pView
= pViewShell
->GetView();
399 pView
->MarkObj(pTextObj
, pView
->GetSdrPageView());
400 SfxStringItem
aInputString(SID_ATTR_CHAR
, "x");
401 pViewShell
->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR
,
402 SfxCallMode::SYNCHRON
, { &aInputString
});
404 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'x', 0);
405 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'x', 0);
406 Scheduler::ProcessEventsToIdle();
408 CPPUNIT_ASSERT(pView
->GetTextEditObject());
409 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
410 // Did we manage to enter a second character?
411 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(2), rEditView
.GetSelection().nStartPos
);
412 ESelection
aWordSelection(0, 0, 0, 2); // start para, start char, end para, end char.
413 rEditView
.SetSelection(aWordSelection
);
414 // Did we enter the expected character?
415 CPPUNIT_ASSERT_EQUAL(OUString("xx"), rEditView
.GetSelected());
418 void SdTiledRenderingTest::testPostMouseEvent()
420 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
421 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
422 SdPage
* pActualPage
= pViewShell
->GetActualPage();
423 SdrObject
* pObject
= pActualPage
->GetObj(0);
424 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(OBJ_TITLETEXT
), pObject
->GetObjIdentifier());
425 SdrTextObj
* pTextObj
= static_cast<SdrTextObj
*>(pObject
);
426 SdrView
* pView
= pViewShell
->GetView();
427 pView
->MarkObj(pTextObj
, pView
->GetSdrPageView());
428 SfxStringItem
aInputString(SID_ATTR_CHAR
, "x");
429 pViewShell
->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR
,
430 SfxCallMode::SYNCHRON
, { &aInputString
});
431 CPPUNIT_ASSERT(pView
->GetTextEditObject());
432 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
433 // Did we manage to go after the first character?
434 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), rEditView
.GetSelection().nStartPos
);
436 vcl::Cursor
* pCursor
= rEditView
.GetCursor();
437 Point
aPosition(pCursor
->GetPos().getX(), pCursor
->GetPos().getY() + pCursor
->GetSize().Height() / 2);
438 aPosition
.setX(aPosition
.getX() - 1000);
439 pXImpressDocument
->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
440 convertMm100ToTwip(aPosition
.getX()), convertMm100ToTwip(aPosition
.getY()),
442 pXImpressDocument
->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP
,
443 convertMm100ToTwip(aPosition
.getX()), convertMm100ToTwip(aPosition
.getY()),
445 Scheduler::ProcessEventsToIdle();
446 CPPUNIT_ASSERT(pView
->GetTextEditObject());
447 // The new cursor position must be before the first word.
448 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), rEditView
.GetSelection().nStartPos
);
451 void SdTiledRenderingTest::testSetTextSelection()
453 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
454 uno::Reference
<container::XIndexAccess
> xDrawPage(pXImpressDocument
->getDrawPages()->getByIndex(0), uno::UNO_QUERY
);
455 uno::Reference
<text::XTextRange
> xShape(xDrawPage
->getByIndex(0), uno::UNO_QUERY
);
456 xShape
->setString("Aaa bbb.");
457 // Create a selection on the second word.
458 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
459 SdPage
* pActualPage
= pViewShell
->GetActualPage();
460 SdrObject
* pObject
= pActualPage
->GetObj(0);
461 SdrView
* pView
= pViewShell
->GetView();
462 pView
->SdrBeginTextEdit(pObject
);
463 CPPUNIT_ASSERT(pView
->GetTextEditObject());
464 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
465 ESelection
aWordSelection(0, 4, 0, 7);
466 rEditView
.SetSelection(aWordSelection
);
467 // Did we indeed manage to select the second word?
468 CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView
.GetSelected());
470 // Now use setTextSelection() to move the end of the selection 1000 twips right.
471 vcl::Cursor
* pCursor
= rEditView
.GetCursor();
472 Point aEnd
= pCursor
->GetPos();
473 aEnd
.setX(aEnd
.getX() + 1000);
474 pXImpressDocument
->setTextSelection(LOK_SETTEXTSELECTION_END
, aEnd
.getX(), aEnd
.getY());
475 // The new selection must include the ending dot, too -- but not the first word.
476 CPPUNIT_ASSERT_EQUAL(OUString("bbb."), rEditView
.GetSelected());
479 void SdTiledRenderingTest::testGetTextSelection()
481 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
482 uno::Reference
<container::XIndexAccess
> xDrawPage(pXImpressDocument
->getDrawPages()->getByIndex(0), uno::UNO_QUERY
);
483 uno::Reference
<text::XTextRange
> xShape(xDrawPage
->getByIndex(0), uno::UNO_QUERY
);
484 xShape
->setString("Shape");
485 // Create a selection on the shape text.
486 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
487 SdPage
* pActualPage
= pViewShell
->GetActualPage();
488 SdrObject
* pObject
= pActualPage
->GetObj(0);
489 SdrView
* pView
= pViewShell
->GetView();
490 pView
->SdrBeginTextEdit(pObject
);
491 CPPUNIT_ASSERT(pView
->GetTextEditObject());
492 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
493 ESelection
aWordSelection(0, 0, 0, 5);
494 rEditView
.SetSelection(aWordSelection
);
495 // Did we indeed manage to copy the selected text?
496 CPPUNIT_ASSERT_EQUAL(OString("Shape"), apitest::helper::transferable::getTextSelection(pXImpressDocument
->getSelection(), "text/plain;charset=utf-8"));
498 // Make sure returned RTF is not empty.
499 CPPUNIT_ASSERT(!apitest::helper::transferable::getTextSelection(pXImpressDocument
->getSelection(), "text/rtf").isEmpty());
502 void SdTiledRenderingTest::testSetGraphicSelection()
504 SdXImpressDocument
* pXImpressDocument
= createDoc("shape.odp");
505 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
506 SdPage
* pPage
= pViewShell
->GetActualPage();
507 SdrObject
* pObject
= pPage
->GetObj(0);
508 SdrHdlList
handleList(nullptr);
509 pObject
->AddToHdlList(handleList
);
510 // Make sure the rectangle has 8 handles: at each corner and at the center of each edge.
511 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(8), handleList
.GetHdlCount());
512 // Take the bottom center one.
513 SdrHdl
* pHdl
= handleList
.GetHdl(6);
514 CPPUNIT_ASSERT_EQUAL(int(SdrHdlKind::Lower
), static_cast<int>(pHdl
->GetKind()));
515 ::tools::Rectangle aShapeBefore
= pObject
->GetSnapRect();
517 pXImpressDocument
->setGraphicSelection(LOK_SETGRAPHICSELECTION_START
, convertMm100ToTwip(pHdl
->GetPos().getX()), convertMm100ToTwip(pHdl
->GetPos().getY()));
518 pXImpressDocument
->setGraphicSelection(LOK_SETGRAPHICSELECTION_END
, convertMm100ToTwip(pHdl
->GetPos().getX()), convertMm100ToTwip(pHdl
->GetPos().getY() + 1000));
520 // Assert that view shell ID tracking works.
521 sal_Int32 nView1
= SfxLokHelper::getView();
522 SdDrawDocument
* pDocument
= pXImpressDocument
->GetDoc();
523 sd::UndoManager
* pUndoManager
= pDocument
->GetUndoManager();
524 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pUndoManager
->GetUndoActionCount());
525 auto pListAction
= dynamic_cast<SfxListUndoAction
*>(pUndoManager
->GetUndoAction());
526 CPPUNIT_ASSERT(pListAction
);
527 for (size_t i
= 0; i
< pListAction
->maUndoActions
.size(); ++i
)
528 // The second item was -1 here, view shell ID wasn't known.
529 CPPUNIT_ASSERT_EQUAL(ViewShellId(nView1
), pListAction
->GetUndoAction(i
)->GetViewShellId());
531 ::tools::Rectangle aShapeAfter
= pObject
->GetSnapRect();
532 // Check that a resize happened, but aspect ratio is not kept.
533 CPPUNIT_ASSERT_EQUAL(aShapeBefore
.getWidth(), aShapeAfter
.getWidth());
534 CPPUNIT_ASSERT(aShapeBefore
.getHeight() < aShapeAfter
.getHeight());
537 void SdTiledRenderingTest::testUndoShells()
539 // Load a document and set the page size.
540 SdXImpressDocument
* pXImpressDocument
= createDoc("shape.odp");
541 uno::Sequence
<beans::PropertyValue
> aPropertyValues(comphelper::InitPropertySequence(
543 {"AttributePageSize.Width", uno::makeAny(static_cast<sal_Int32
>(10000))},
544 {"AttributePageSize.Height", uno::makeAny(static_cast<sal_Int32
>(10000))},
546 comphelper::dispatchCommand(".uno:AttributePageSize", aPropertyValues
);
547 Scheduler::ProcessEventsToIdle();
549 // Assert that view shell ID tracking works for SdUndoAction subclasses.
550 SdDrawDocument
* pDocument
= pXImpressDocument
->GetDoc();
551 sd::UndoManager
* pUndoManager
= pDocument
->GetUndoManager();
552 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pUndoManager
->GetUndoActionCount());
553 sal_Int32 nView1
= SfxLokHelper::getView();
554 // This was -1, SdUndoGroup did not track what view shell created it.
555 CPPUNIT_ASSERT_EQUAL(ViewShellId(nView1
), pUndoManager
->GetUndoAction()->GetViewShellId());
558 void SdTiledRenderingTest::testResetSelection()
560 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
561 uno::Reference
<container::XIndexAccess
> xDrawPage(pXImpressDocument
->getDrawPages()->getByIndex(0), uno::UNO_QUERY
);
562 uno::Reference
<text::XTextRange
> xShape(xDrawPage
->getByIndex(0), uno::UNO_QUERY
);
563 xShape
->setString("Aaa bbb.");
564 // Create a selection on the second word.
565 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
566 SdPage
* pActualPage
= pViewShell
->GetActualPage();
567 SdrObject
* pObject
= pActualPage
->GetObj(0);
568 SdrView
* pView
= pViewShell
->GetView();
569 pView
->SdrBeginTextEdit(pObject
);
570 CPPUNIT_ASSERT(pView
->GetTextEditObject());
571 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
572 ESelection
aWordSelection(0, 4, 0, 7);
573 rEditView
.SetSelection(aWordSelection
);
574 // Did we indeed manage to select the second word?
575 CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView
.GetSelected());
577 // Now use resetSelection() to reset the selection.
578 pXImpressDocument
->resetSelection();
579 CPPUNIT_ASSERT(!pView
->GetTextEditObject());
582 static void lcl_search(const OUString
& rKey
, bool bFindAll
= false)
584 uno::Sequence
<beans::PropertyValue
> aPropertyValues(comphelper::InitPropertySequence(
586 {"SearchItem.SearchString", uno::makeAny(rKey
)},
587 {"SearchItem.Backward", uno::makeAny(false)},
588 {"SearchItem.Command", uno::makeAny(static_cast<sal_uInt16
>(bFindAll
? SvxSearchCmd::FIND_ALL
: SvxSearchCmd::FIND
))},
590 comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues
);
593 void SdTiledRenderingTest::testSearch()
595 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
596 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
597 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
598 uno::Reference
<container::XIndexAccess
> xDrawPage(pXImpressDocument
->getDrawPages()->getByIndex(0), uno::UNO_QUERY
);
599 uno::Reference
<text::XTextRange
> xShape(xDrawPage
->getByIndex(0), uno::UNO_QUERY
);
600 xShape
->setString("Aaa bbb.");
604 SdrView
* pView
= pViewShell
->GetView();
605 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
606 // Did we indeed manage to select the second word?
607 CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView
.GetSelected());
609 // Did the selection callback fire?
610 CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), m_aSelection
.size());
612 // Search for something on the second slide, and make sure that the set-part callback fired.
614 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), m_nPart
);
615 CPPUNIT_ASSERT_EQUAL(true, m_bFound
);
616 // This was 0; should be 1 match for "find".
617 CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), m_aSearchResultSelection
.size());
618 // Result is on the second slide.
619 CPPUNIT_ASSERT_EQUAL(1, m_aSearchResultPart
[0]);
621 // This should trigger the not-found callback.
623 CPPUNIT_ASSERT_EQUAL(false, m_bFound
);
626 void SdTiledRenderingTest::testSearchAll()
628 SdXImpressDocument
* pXImpressDocument
= createDoc("search-all.odp");
629 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
630 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
632 lcl_search("match", /*bFindAll=*/true);
634 // This was empty: find-all did not highlight the first match.
635 CPPUNIT_ASSERT_EQUAL(OString("match"), apitest::helper::transferable::getTextSelection(pXImpressDocument
->getSelection(), "text/plain;charset=utf-8"));
637 // We're on the first slide, search for something on the second slide and make sure we get a SET_PART.
639 lcl_search("second", /*bFindAll=*/true);
640 // This was 0: no SET_PART was emitted.
641 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), m_nPart
);
644 void SdTiledRenderingTest::testSearchAllSelections()
646 SdXImpressDocument
* pXImpressDocument
= createDoc("search-all.odp");
647 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
648 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
650 lcl_search("third", /*bFindAll=*/true);
651 // Make sure this is found on the 3rd slide.
652 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(2), m_nPart
);
653 // This was 1: only the first match was highlighted.
654 CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), m_aSelection
.size());
657 void SdTiledRenderingTest::testSearchAllNotifications()
659 SdXImpressDocument
* pXImpressDocument
= createDoc("search-all.odp");
660 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
661 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
663 lcl_search("third", /*bFindAll=*/true);
664 // Make sure that we get no notifications about selection changes during search.
665 CPPUNIT_ASSERT_EQUAL(0, m_nSelectionBeforeSearchResult
);
666 // But we do get the selection of the first hit.
667 CPPUNIT_ASSERT(m_nSelectionAfterSearchResult
> 0);
670 void SdTiledRenderingTest::testSearchAllFollowedBySearch()
672 SdXImpressDocument
* pXImpressDocument
= createDoc("search-all.odp");
673 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
674 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
676 lcl_search("third", /*bFindAll=*/true);
677 lcl_search("match" /*,bFindAll=false*/);
679 // This used to give wrong result: 'search' after 'search all' still
681 CPPUNIT_ASSERT_EQUAL(OString("match"), apitest::helper::transferable::getTextSelection(pXImpressDocument
->getSelection(), "text/plain;charset=utf-8"));
684 void SdTiledRenderingTest::testDontSearchInMasterPages()
686 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
687 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
688 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
690 // This should trigger the not-found callback ("date" is present only on
693 CPPUNIT_ASSERT_EQUAL(false, m_bFound
);
699 std::vector
<OUString
> getCurrentParts(SdXImpressDocument
* pDocument
)
701 int parts
= pDocument
->getParts();
702 std::vector
<OUString
> result
;
704 result
.reserve(parts
);
705 for (int i
= 0; i
< parts
; i
++)
707 result
.push_back(pDocument
->getPartName(i
));
715 void SdTiledRenderingTest::testInsertDeletePage()
717 SdXImpressDocument
* pXImpressDocument
= createDoc("insert-delete.odp");
718 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
719 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
721 SdDrawDocument
* pDoc
= pXImpressDocument
->GetDocShell()->GetDoc();
722 CPPUNIT_ASSERT(pDoc
);
724 std::vector
<OUString
> aInserted
=
726 "Slide 1", "Slide 2", "Slide 3", "Slide 4", "Slide 5",
727 "Slide 6", "Slide 7", "Slide 8", "Slide 9", "Slide 10", "Slide 11"
730 std::vector
<OUString
> aDeleted
=
735 // the document has 1 slide
736 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(1), pDoc
->GetSdPageCount(PageKind::Standard
));
738 uno::Sequence
<beans::PropertyValue
> aArgs
;
741 m_aDocumentSizeCondition
.reset();
742 for (unsigned it
= 1; it
<= 10; it
++)
743 comphelper::dispatchCommand(".uno:InsertPage", aArgs
);
745 osl::Condition::Result aResult
= m_aDocumentSizeCondition
.wait(std::chrono::seconds(2));
746 CPPUNIT_ASSERT_EQUAL(osl::Condition::result_ok
, aResult
);
748 // Verify inserted slides
749 std::vector
<OUString
> aPageList(getCurrentParts(pXImpressDocument
));
750 CPPUNIT_ASSERT_EQUAL(aPageList
.size(), aInserted
.size());
752 for (auto it1
= aPageList
.begin(), it2
= aInserted
.begin(); it1
!= aPageList
.end(); ++it1
, ++it2
)
754 CPPUNIT_ASSERT_EQUAL(*it1
, *it2
);
758 m_aDocumentSizeCondition
.reset();
759 for (unsigned it
= 1; it
<= 10; it
++)
760 comphelper::dispatchCommand(".uno:DeletePage", aArgs
);
762 aResult
= m_aDocumentSizeCondition
.wait(std::chrono::seconds(2));
763 CPPUNIT_ASSERT_EQUAL(osl::Condition::result_ok
, aResult
);
765 // Verify deleted slides
766 aPageList
= getCurrentParts(pXImpressDocument
);
767 CPPUNIT_ASSERT_EQUAL(aPageList
.size(), aDeleted
.size());
768 for (auto it1
= aPageList
.begin(), it2
= aDeleted
.begin(); it1
!= aPageList
.end(); ++it1
, ++it2
)
770 CPPUNIT_ASSERT_EQUAL(*it1
, *it2
);
773 // Undo deleted slides
774 m_aDocumentSizeCondition
.reset();
775 for (unsigned it
= 1; it
<= 10; it
++)
776 comphelper::dispatchCommand(".uno:Undo", aArgs
);
778 aResult
= m_aDocumentSizeCondition
.wait(std::chrono::seconds(2));
779 CPPUNIT_ASSERT_EQUAL(osl::Condition::result_ok
, aResult
);
781 // Verify inserted slides
782 aPageList
= getCurrentParts(pXImpressDocument
);
783 CPPUNIT_ASSERT_EQUAL(aPageList
.size(), aInserted
.size());
784 for (auto it1
= aPageList
.begin(), it2
= aInserted
.begin(); it1
!= aPageList
.end(); ++it1
, ++it2
)
786 CPPUNIT_ASSERT_EQUAL(*it1
, *it2
);
789 // Redo deleted slides
790 m_aDocumentSizeCondition
.reset();
791 for (unsigned it
= 1; it
<= 10; it
++)
792 comphelper::dispatchCommand(".uno:Redo", aArgs
);
794 aResult
= m_aDocumentSizeCondition
.wait(std::chrono::seconds(2));
795 CPPUNIT_ASSERT_EQUAL(osl::Condition::result_ok
, aResult
);
797 // Verify deleted slides
798 aPageList
= getCurrentParts(pXImpressDocument
);
799 CPPUNIT_ASSERT_EQUAL(aPageList
.size(), aDeleted
.size());
800 for (auto it1
= aPageList
.begin(), it2
= aDeleted
.begin(); it1
!= aPageList
.end(); ++it1
, ++it2
)
802 CPPUNIT_ASSERT_EQUAL(*it1
, *it2
);
805 // the document has 1 slide
806 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(1), pDoc
->GetSdPageCount(PageKind::Standard
));
809 void SdTiledRenderingTest::testInsertTable()
811 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
813 uno::Sequence
<beans::PropertyValue
> aArgs(comphelper::InitPropertySequence(
815 { "Rows", uno::makeAny(sal_Int32(3)) },
816 { "Columns", uno::makeAny(sal_Int32(5)) }
819 comphelper::dispatchCommand(".uno:InsertTable", aArgs
);
820 Scheduler::ProcessEventsToIdle();
823 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
824 SdPage
* pActualPage
= pViewShell
->GetActualPage();
825 SdrObject
* pObject
= pActualPage
->GetObj(1);
826 CPPUNIT_ASSERT(pObject
);
828 // check that the table is not in the top left corner
829 Point
aPos(pObject
->GetRelativePos());
831 CPPUNIT_ASSERT(aPos
.X() != 0);
832 CPPUNIT_ASSERT(aPos
.Y() != 0);
835 void SdTiledRenderingTest::testPartHash()
837 SdXImpressDocument
* pDoc
= createDoc("dummy.odp");
839 int nParts
= pDoc
->getParts();
840 for (int it
= 0; it
< nParts
; it
++)
842 CPPUNIT_ASSERT(!pDoc
->getPartHash(it
).isEmpty());
845 // check part that it does not exists
846 CPPUNIT_ASSERT(pDoc
->getPartHash(100).isEmpty());
849 void SdTiledRenderingTest::testResizeTable()
851 // Load the document.
852 SdXImpressDocument
* pXImpressDocument
= createDoc("table.odp");
853 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
854 SdPage
* pActualPage
= pViewShell
->GetActualPage();
855 SdrObject
* pObject
= pActualPage
->GetObj(0);
856 auto pTableObject
= dynamic_cast<sdr::table::SdrTableObj
*>(pObject
);
857 CPPUNIT_ASSERT(pTableObject
);
859 // Select the table by marking it + starting and ending text edit.
860 SdrView
* pView
= pViewShell
->GetView();
861 pView
->MarkObj(pObject
, pView
->GetSdrPageView());
862 pView
->SdrBeginTextEdit(pObject
);
863 pView
->SdrEndTextEdit();
865 // Remember the original row heights.
866 uno::Reference
<table::XColumnRowRange
> xTable
= pTableObject
->getTable();
867 uno::Reference
<container::XIndexAccess
> xRows
= xTable
->getRows();
868 uno::Reference
<beans::XPropertySet
> xRow1(xRows
->getByIndex(0), uno::UNO_QUERY
);
869 sal_Int32 nExpectedRow1
= xRow1
->getPropertyValue("Size").get
<sal_Int32
>();
870 uno::Reference
<beans::XPropertySet
> xRow2(xRows
->getByIndex(1), uno::UNO_QUERY
);
871 sal_Int32 nExpectedRow2
= xRow2
->getPropertyValue("Size").get
<sal_Int32
>();
873 // Resize the upper row, decrease its height by 1 cm.
874 Point aInnerRowEdge
= pObject
->GetSnapRect().Center();
875 pXImpressDocument
->setGraphicSelection(LOK_SETGRAPHICSELECTION_START
, convertMm100ToTwip(aInnerRowEdge
.getX()), convertMm100ToTwip(aInnerRowEdge
.getY()));
876 pXImpressDocument
->setGraphicSelection(LOK_SETGRAPHICSELECTION_END
, convertMm100ToTwip(aInnerRowEdge
.getX()), convertMm100ToTwip(aInnerRowEdge
.getY() - 1000));
878 // Remember the resized row heights.
879 sal_Int32 nResizedRow1
= xRow1
->getPropertyValue("Size").get
<sal_Int32
>();
880 CPPUNIT_ASSERT(nResizedRow1
< nExpectedRow1
);
881 sal_Int32 nResizedRow2
= xRow2
->getPropertyValue("Size").get
<sal_Int32
>();
882 CPPUNIT_ASSERT_EQUAL(nExpectedRow2
, nResizedRow2
);
884 // Now undo the resize.
885 pXImpressDocument
->GetDocShell()->GetUndoManager()->Undo();
887 // Check the undo result.
888 sal_Int32 nActualRow1
= xRow1
->getPropertyValue("Size").get
<sal_Int32
>();
889 CPPUNIT_ASSERT_EQUAL(nExpectedRow1
, nActualRow1
);
890 sal_Int32 nActualRow2
= xRow2
->getPropertyValue("Size").get
<sal_Int32
>();
891 // Expected was 4000, actual was 4572, i.e. the second row after undo was larger than expected.
892 CPPUNIT_ASSERT_EQUAL(nExpectedRow2
, nActualRow2
);
895 void SdTiledRenderingTest::testResizeTableColumn()
897 // Load the document.
898 SdXImpressDocument
* pXImpressDocument
= createDoc("table-column.odp");
899 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
900 SdPage
* pActualPage
= pViewShell
->GetActualPage();
901 SdrObject
* pObject
= pActualPage
->GetObj(0);
902 auto pTableObject
= dynamic_cast<sdr::table::SdrTableObj
*>(pObject
);
903 CPPUNIT_ASSERT(pTableObject
);
905 // Select the table by marking it + starting and ending text edit.
906 SdrView
* pView
= pViewShell
->GetView();
907 pView
->MarkObj(pObject
, pView
->GetSdrPageView());
908 pView
->SdrBeginTextEdit(pObject
);
909 pView
->SdrEndTextEdit();
911 // Remember the original cell widths.
912 xmlDocPtr pXmlDoc
= parseXmlDump();
913 OString aPrefix
= "/SdDrawDocument/SdrModel/SdPage/SdrObjList/SdrTableObj/SdrTableObjImpl/TableLayouter/columns/";
914 sal_Int32 nExpectedColumn1
= getXPath(pXmlDoc
, aPrefix
+ "TableLayouter_Layout[1]", "size").toInt32();
915 sal_Int32 nExpectedColumn2
= getXPath(pXmlDoc
, aPrefix
+ "TableLayouter_Layout[2]", "size").toInt32();
919 // Resize the left column, decrease its width by 1 cm.
920 Point aInnerRowEdge
= pObject
->GetSnapRect().Center();
921 pXImpressDocument
->setGraphicSelection(LOK_SETGRAPHICSELECTION_START
, convertMm100ToTwip(aInnerRowEdge
.getX()), convertMm100ToTwip(aInnerRowEdge
.getY()));
922 pXImpressDocument
->setGraphicSelection(LOK_SETGRAPHICSELECTION_END
, convertMm100ToTwip(aInnerRowEdge
.getX() - 1000), convertMm100ToTwip(aInnerRowEdge
.getY()));
924 // Remember the resized column widths.
925 pXmlDoc
= parseXmlDump();
926 sal_Int32 nResizedColumn1
= getXPath(pXmlDoc
, aPrefix
+ "TableLayouter_Layout[1]", "size").toInt32();
927 CPPUNIT_ASSERT(nResizedColumn1
< nExpectedColumn1
);
928 sal_Int32 nResizedColumn2
= getXPath(pXmlDoc
, aPrefix
+ "TableLayouter_Layout[2]", "size").toInt32();
929 CPPUNIT_ASSERT(nResizedColumn2
> nExpectedColumn2
);
933 // Now undo the resize.
934 pXImpressDocument
->GetDocShell()->GetUndoManager()->Undo();
936 // Check the undo result.
937 pXmlDoc
= parseXmlDump();
938 sal_Int32 nActualColumn1
= getXPath(pXmlDoc
, aPrefix
+ "TableLayouter_Layout[1]", "size").toInt32();
939 // Expected was 7049, actual was 6048, i.e. the first column width after undo was 1cm smaller than expected.
940 CPPUNIT_ASSERT_EQUAL(nExpectedColumn1
, nActualColumn1
);
941 sal_Int32 nActualColumn2
= getXPath(pXmlDoc
, aPrefix
+ "TableLayouter_Layout[2]", "size").toInt32();
942 CPPUNIT_ASSERT_EQUAL(nExpectedColumn2
, nActualColumn2
);
947 /// A view callback tracks callbacks invoked on one specific view.
950 SfxViewShell
* mpViewShell
;
953 bool m_bGraphicSelectionInvalidated
;
954 bool m_bGraphicViewSelectionInvalidated
;
955 /// Our current part, to be able to decide if a view cursor/selection is relevant for us.
957 bool m_bCursorVisibleChanged
;
959 bool m_bTilesInvalidated
;
960 std::vector
<tools::Rectangle
> m_aInvalidations
;
961 std::map
<int, bool> m_aViewCursorInvalidations
;
962 std::map
<int, bool> m_aViewCursorVisibilities
;
963 bool m_bViewSelectionSet
;
964 boost::property_tree::ptree m_aCommentCallbackResult
;
967 : m_bGraphicSelectionInvalidated(false),
968 m_bGraphicViewSelectionInvalidated(false),
970 m_bCursorVisibleChanged(false),
972 m_bTilesInvalidated(false),
973 m_bViewSelectionSet(false)
975 mpViewShell
= SfxViewShell::Current();
976 mpViewShell
->registerLibreOfficeKitViewCallback(&ViewCallback::callback
, this);
977 mnView
= SfxLokHelper::getView();
982 SfxLokHelper::setView(mnView
);
983 mpViewShell
->registerLibreOfficeKitViewCallback(nullptr, nullptr);
986 static void callback(int nType
, const char* pPayload
, void* pData
)
988 static_cast<ViewCallback
*>(pData
)->callbackImpl(nType
, pPayload
);
991 void callbackImpl(int nType
, const char* pPayload
)
995 case LOK_CALLBACK_INVALIDATE_TILES
:
997 m_bTilesInvalidated
= true;
998 OString
text(pPayload
);
999 if (!text
.startsWith("EMPTY"))
1001 uno::Sequence
<OUString
> aSeq
= comphelper::string::convertCommaSeparated(OUString::createFromAscii(pPayload
));
1002 CPPUNIT_ASSERT(aSeq
.getLength() == 4 || aSeq
.getLength() == 5);
1003 tools::Rectangle aInvalidationRect
;
1004 aInvalidationRect
.setX(aSeq
[0].toInt32());
1005 aInvalidationRect
.setY(aSeq
[1].toInt32());
1006 aInvalidationRect
.setWidth(aSeq
[2].toInt32());
1007 aInvalidationRect
.setHeight(aSeq
[3].toInt32());
1008 m_aInvalidations
.push_back(aInvalidationRect
);
1012 case LOK_CALLBACK_GRAPHIC_SELECTION
:
1014 m_bGraphicSelectionInvalidated
= true;
1017 case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION
:
1019 std::stringstream
aStream(pPayload
);
1020 boost::property_tree::ptree aTree
;
1021 boost::property_tree::read_json(aStream
, aTree
);
1022 if (aTree
.get_child("part").get_value
<int>() == m_nPart
)
1023 // Ignore callbacks which are for a different part.
1024 m_bGraphicViewSelectionInvalidated
= true;
1027 case LOK_CALLBACK_CURSOR_VISIBLE
:
1029 m_bCursorVisibleChanged
= true;
1032 case LOK_CALLBACK_VIEW_LOCK
:
1034 std::stringstream
aStream(pPayload
);
1035 boost::property_tree::ptree aTree
;
1036 boost::property_tree::read_json(aStream
, aTree
);
1037 m_bViewLock
= aTree
.get_child("rectangle").get_value
<std::string
>() != "EMPTY";
1040 case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR
:
1042 std::stringstream
aStream(pPayload
);
1043 boost::property_tree::ptree aTree
;
1044 boost::property_tree::read_json(aStream
, aTree
);
1045 int nViewId
= aTree
.get_child("viewId").get_value
<int>();
1046 m_aViewCursorInvalidations
[nViewId
] = true;
1049 case LOK_CALLBACK_VIEW_CURSOR_VISIBLE
:
1051 std::stringstream
aStream(pPayload
);
1052 boost::property_tree::ptree aTree
;
1053 boost::property_tree::read_json(aStream
, aTree
);
1054 int nViewId
= aTree
.get_child("viewId").get_value
<int>();
1055 m_aViewCursorVisibilities
[nViewId
] = OString("true") == pPayload
;
1058 case LOK_CALLBACK_TEXT_VIEW_SELECTION
:
1060 m_bViewSelectionSet
= true;
1063 case LOK_CALLBACK_COMMENT
:
1065 m_aCommentCallbackResult
.clear();
1066 std::stringstream
aStream(pPayload
);
1067 boost::property_tree::read_json(aStream
, m_aCommentCallbackResult
);
1068 m_aCommentCallbackResult
= m_aCommentCallbackResult
.get_child("comment");
1075 void SdTiledRenderingTest::testViewCursors()
1077 // Create two views.
1078 SdXImpressDocument
* pXImpressDocument
= createDoc("shape.odp");
1079 ViewCallback aView1
;
1080 SfxLokHelper::createView();
1081 ViewCallback aView2
;
1083 // Select the shape in the second view.
1084 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1085 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1086 SdrObject
* pObject
= pActualPage
->GetObj(0);
1087 SdrView
* pView
= pViewShell
->GetView();
1088 pView
->MarkObj(pObject
, pView
->GetSdrPageView());
1089 Scheduler::ProcessEventsToIdle();
1091 // First view notices that there was a selection change in the other view.
1092 CPPUNIT_ASSERT(aView1
.m_bGraphicViewSelectionInvalidated
);
1093 // Second view notices that there was a selection change in its own view.
1094 CPPUNIT_ASSERT(aView2
.m_bGraphicSelectionInvalidated
);
1097 void SdTiledRenderingTest::testViewCursorParts()
1099 // Create two views.
1100 SdXImpressDocument
* pXImpressDocument
= createDoc("shape.odp");
1101 ViewCallback aView1
;
1102 SfxLokHelper::createView();
1103 pXImpressDocument
->initializeForTiledRendering(uno::Sequence
<beans::PropertyValue
>());
1104 ViewCallback aView2
;
1106 // Select the shape in the second view.
1107 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1108 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1109 SdrObject
* pObject
= pActualPage
->GetObj(0);
1110 SdrView
* pView
= pViewShell
->GetView();
1111 pView
->MarkObj(pObject
, pView
->GetSdrPageView());
1112 Scheduler::ProcessEventsToIdle();
1113 // First view notices that there was a selection change in the other view.
1114 CPPUNIT_ASSERT(aView1
.m_bGraphicViewSelectionInvalidated
);
1115 pView
->UnmarkAllObj(pView
->GetSdrPageView());
1117 // Now switch to the second part in the second view.
1118 pXImpressDocument
->setPart(1);
1120 aView1
.m_bGraphicViewSelectionInvalidated
= false;
1121 pActualPage
= pViewShell
->GetActualPage();
1122 pObject
= pActualPage
->GetObj(0);
1123 pView
->MarkObj(pObject
, pView
->GetSdrPageView());
1124 Scheduler::ProcessEventsToIdle();
1125 // First view ignores view selection, as it would be for part 1, and it's in part 0.
1126 // This failed when the "part" was always 0 in the callback.
1127 CPPUNIT_ASSERT(!aView1
.m_bGraphicViewSelectionInvalidated
);
1130 void SdTiledRenderingTest::testCursorViews()
1132 // Create the first view.
1133 SdXImpressDocument
* pXImpressDocument
= createDoc("title-shape.odp");
1134 int nView1
= SfxLokHelper::getView();
1135 ViewCallback aView1
;
1137 // Begin text edit on the only object on the slide.
1138 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1139 SdrView
* pView
= pViewShell
->GetView();
1140 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
1141 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
1142 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'x', 0);
1143 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'x', 0);
1144 Scheduler::ProcessEventsToIdle();
1145 CPPUNIT_ASSERT(pView
->IsTextEdit());
1147 // Make sure that cursor state is not changed just because we create a second view.
1148 aView1
.m_bCursorVisibleChanged
= false;
1149 SfxLokHelper::createView();
1150 pXImpressDocument
->initializeForTiledRendering(uno::Sequence
<beans::PropertyValue
>());
1151 Scheduler::ProcessEventsToIdle();
1152 CPPUNIT_ASSERT(!aView1
.m_bCursorVisibleChanged
);
1154 // Make sure that typing in the first view causes an invalidation in the
1155 // second view as well, even if the second view was created after begin
1156 // text edit in the first view.
1157 ViewCallback aView2
;
1158 // This failed: the second view didn't get a lock notification, even if the
1159 // first view already started text edit.
1160 CPPUNIT_ASSERT(aView2
.m_bViewLock
);
1161 SfxLokHelper::setView(nView1
);
1162 aView2
.m_bTilesInvalidated
= false;
1163 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'x', 0);
1164 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'x', 0);
1165 Scheduler::ProcessEventsToIdle();
1166 // This failed: the second view was not invalidated when pressing a key in
1168 CPPUNIT_ASSERT(aView2
.m_bTilesInvalidated
);
1171 void SdTiledRenderingTest::testViewLock()
1173 // Load a document that has a shape and create two views.
1174 SdXImpressDocument
* pXImpressDocument
= createDoc("shape.odp");
1175 ViewCallback aView1
;
1176 SfxLokHelper::createView();
1177 pXImpressDocument
->initializeForTiledRendering(uno::Sequence
<beans::PropertyValue
>());
1179 // Begin text edit in the second view and assert that the first gets a lock
1181 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1182 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1183 SdrObject
* pObject
= pActualPage
->GetObj(0);
1184 SdrView
* pView
= pViewShell
->GetView();
1185 aView1
.m_bViewLock
= false;
1186 pView
->SdrBeginTextEdit(pObject
);
1187 CPPUNIT_ASSERT(aView1
.m_bViewLock
);
1189 // End text edit in the second view, and assert that the lock is removed in
1191 pView
->SdrEndTextEdit();
1192 CPPUNIT_ASSERT(!aView1
.m_bViewLock
);
1195 void SdTiledRenderingTest::testUndoLimiting()
1197 // Create the first view.
1198 SdXImpressDocument
* pXImpressDocument
= createDoc("title-shape.odp");
1199 sd::ViewShell
* pViewShell1
= pXImpressDocument
->GetDocShell()->GetViewShell();
1200 int nView1
= SfxLokHelper::getView();
1201 SfxLokHelper::createView();
1202 sd::ViewShell
* pViewShell2
= pXImpressDocument
->GetDocShell()->GetViewShell();
1203 CPPUNIT_ASSERT(pViewShell1
!= pViewShell2
);
1205 // Begin text edit on the only object on the slide.
1206 SfxLokHelper::setView(nView1
);
1207 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
1208 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
1209 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'x', 0);
1210 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'x', 0);
1211 Scheduler::ProcessEventsToIdle();
1212 CPPUNIT_ASSERT(pViewShell1
->GetView()->IsTextEdit());
1214 // Now check view2 cannot undo actions.
1216 SfxRequest
aReq2(SID_UNDO
, SfxCallMode::SLOT
, pXImpressDocument
->GetDocShell()->GetDoc()->GetPool());
1217 aReq2
.AppendItem(SfxUInt16Item(SID_UNDO
, 1));
1218 pViewShell2
->ExecuteSlot(aReq2
);
1219 const SfxUInt32Item
* pUInt32Item
= dynamic_cast<const SfxUInt32Item
*>(aReq2
.GetReturnValue());
1220 CPPUNIT_ASSERT(pUInt32Item
);
1221 CPPUNIT_ASSERT_EQUAL(static_cast< sal_uInt32
>(SID_REPAIRPACKAGE
), pUInt32Item
->GetValue());
1224 // Now check view1 can undo action
1226 SfxRequest
aReq1(SID_UNDO
, SfxCallMode::SLOT
, pXImpressDocument
->GetDocShell()->GetDoc()->GetPool());
1227 aReq1
.AppendItem(SfxUInt16Item(SID_UNDO
, 1));
1228 pViewShell1
->ExecuteSlot(aReq1
);
1229 CPPUNIT_ASSERT(aReq1
.IsDone());
1232 mxComponent
->dispose();
1233 mxComponent
.clear();
1236 void SdTiledRenderingTest::testCreateViewGraphicSelection()
1238 // Load a document and register a callback.
1239 SdXImpressDocument
* pXImpressDocument
= createDoc("shape.odp");
1240 ViewCallback aView1
;
1242 // Select the only shape in the document and assert that the graphic selection is changed.
1243 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1244 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1245 SdrObject
* pObject
= pActualPage
->GetObj(0);
1246 SdrView
* pView
= pViewShell
->GetView();
1247 aView1
.m_bGraphicSelectionInvalidated
= false;
1248 pView
->MarkObj(pObject
, pView
->GetSdrPageView());
1249 CPPUNIT_ASSERT(aView1
.m_bGraphicSelectionInvalidated
);
1251 // Now create a new view.
1252 aView1
.m_bGraphicSelectionInvalidated
= false;
1253 SfxLokHelper::createView();
1254 pXImpressDocument
->initializeForTiledRendering({});
1255 // This failed, creating a new view affected the graphic selection of an
1257 CPPUNIT_ASSERT(!aView1
.m_bGraphicSelectionInvalidated
);
1259 // Check that when the first view has a shape selected and we register a
1260 // callback on the second view, then it gets a "graphic view selection".
1261 ViewCallback aView2
;
1262 // This failed, the created new view had no "view selection" of the first
1263 // view's selected shape.
1264 CPPUNIT_ASSERT(aView2
.m_bGraphicViewSelectionInvalidated
);
1267 void SdTiledRenderingTest::testCreateViewTextCursor()
1269 // Load a document and register a callback.
1270 SdXImpressDocument
* pXImpressDocument
= createDoc("title-shape.odp");
1271 ViewCallback aView1
;
1274 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
1275 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
1276 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'x', 0);
1277 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'x', 0);
1278 Scheduler::ProcessEventsToIdle();
1279 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1280 SdrView
* pSdrView
= pViewShell
->GetView();
1281 CPPUNIT_ASSERT(pSdrView
->IsTextEdit());
1283 // Create an editeng text selection.
1284 EditView
& rEditView
= pSdrView
->GetTextEditOutlinerView()->GetEditView();
1285 // 0th para, 0th char -> 0th para, 1st char.
1286 ESelection
aWordSelection(0, 0, 0, 1);
1287 rEditView
.SetSelection(aWordSelection
);
1289 // Make sure that creating a new view either doesn't affect the previous
1290 // one, or at least the effect is not visible at the end.
1291 aView1
.m_aViewCursorInvalidations
.clear();
1292 aView1
.m_aViewCursorVisibilities
.clear();
1293 SfxLokHelper::createView();
1294 pXImpressDocument
->initializeForTiledRendering({});
1295 ViewCallback aView2
;
1296 bool bFoundCursor
= false;
1297 for (const auto& rInvalidation
: aView1
.m_aViewCursorInvalidations
)
1299 auto itVisibility
= aView1
.m_aViewCursorVisibilities
.find(rInvalidation
.first
);
1300 // For each cursor invalidation: if there is no visibility or the visibility is true, that's a problem.
1301 if (itVisibility
== aView1
.m_aViewCursorVisibilities
.end() || itVisibility
->second
)
1303 bFoundCursor
= true;
1307 // This failed: the second view created an unexpected view cursor in the
1309 CPPUNIT_ASSERT(!bFoundCursor
);
1310 // This failed: the text view selection of the first view wasn't seen by
1312 CPPUNIT_ASSERT(aView2
.m_bViewSelectionSet
);
1315 void SdTiledRenderingTest::testTdf102223()
1317 // Load the document.
1318 SdXImpressDocument
* pXImpressDocument
= createDoc("tdf102223.odp");
1319 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1320 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1321 auto pTableObject
= dynamic_cast<sdr::table::SdrTableObj
*>(pActualPage
->GetObj(2));
1322 CPPUNIT_ASSERT(pTableObject
);
1323 SdrView
* pView
= pViewShell
->GetView();
1325 // select contents of cell
1326 ::tools::Rectangle aRect
= pTableObject
->GetCurrentBoundRect();
1327 pXImpressDocument
->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
1328 convertMm100ToTwip(aRect
.getX() + 2), convertMm100ToTwip(aRect
.getY() + 2),
1330 pXImpressDocument
->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP
,
1331 convertMm100ToTwip(aRect
.getX() + 2), convertMm100ToTwip(aRect
.getY() + 2),
1333 Scheduler::ProcessEventsToIdle();
1334 pView
->SdrBeginTextEdit(pTableObject
);
1335 CPPUNIT_ASSERT(pView
->GetTextEditObject());
1336 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
1337 rEditView
.SetSelection(ESelection(0, 0, 0, 3)); // start para, start char, end para, end char.
1338 CPPUNIT_ASSERT_EQUAL(OUString("Red"), rEditView
.GetSelected());
1339 const SvxFontHeightItem
& rItem
= rEditView
.GetAttribs().Get(EE_CHAR_FONTHEIGHT
);
1340 CPPUNIT_ASSERT_EQUAL(int(1411), static_cast<int>(rItem
.GetHeight()));
1342 // cut contents of cell
1343 uno::Sequence
<beans::PropertyValue
> aArgs
;
1344 comphelper::dispatchCommand(".uno:Cut", aArgs
);
1346 pView
->SdrEndTextEdit(false);
1347 pView
->SdrBeginTextEdit(pTableObject
);
1348 CPPUNIT_ASSERT(pView
->GetTextEditObject());
1349 EditView
& rEditView2
= pView
->GetTextEditOutlinerView()->GetEditView();
1350 rEditView2
.SetSelection(ESelection(0, 0, 0, 1)); // start para, start char, end para, end char.
1351 const SvxFontHeightItem
& rItem2
= rEditView2
.GetAttribs().Get(EE_CHAR_FONTHEIGHT
);
1352 CPPUNIT_ASSERT_EQUAL(int(1411), static_cast<int>(rItem2
.GetHeight()));
1355 void SdTiledRenderingTest::testPostKeyEventInvalidation()
1357 // Load a document and begin text edit on the first slide.
1358 SdXImpressDocument
* pXImpressDocument
= createDoc("2slides.odp");
1359 CPPUNIT_ASSERT_EQUAL(0, pXImpressDocument
->getPart());
1360 ViewCallback aView1
;
1361 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1362 SdrView
* pView
= pViewShell
->GetView();
1363 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1364 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_TAB
);
1365 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_F2
);
1366 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_F2
);
1367 Scheduler::ProcessEventsToIdle();
1368 CPPUNIT_ASSERT(pView
->GetTextEditObject());
1370 // Create a second view and begin text edit there as well, in parallel.
1371 SfxLokHelper::createView();
1372 pXImpressDocument
->initializeForTiledRendering({});
1373 ViewCallback aView2
;
1374 pXImpressDocument
->setPart(1);
1375 sd::ViewShell
* pViewShell2
= pXImpressDocument
->GetDocShell()->GetViewShell();
1376 SdrView
* pView2
= pViewShell2
->GetView();
1377 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_TAB
);
1378 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_TAB
);
1379 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_F2
);
1380 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_F2
);
1381 Scheduler::ProcessEventsToIdle();
1382 CPPUNIT_ASSERT(pView2
->GetTextEditObject());
1384 // Now go left with the cursor in the second view and watch for
1386 aView2
.m_bTilesInvalidated
= false;
1387 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
);
1388 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
);
1389 Scheduler::ProcessEventsToIdle();
1390 // This failed: moving the cursor caused unexpected invalidation.
1391 CPPUNIT_ASSERT(!aView2
.m_bTilesInvalidated
);
1395 * tests a cut/paste bug around bullet items in a list
1397 void SdTiledRenderingTest::testTdf103083()
1399 // Load the document.
1400 SdXImpressDocument
* pXImpressDocument
= createDoc("tdf103083.fodp");
1401 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1402 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1404 SdrObject
* pObject1
= pActualPage
->GetObj(1);
1405 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(OBJ_OUTLINETEXT
), pObject1
->GetObjIdentifier());
1406 SdrTextObj
* pTextObject
= static_cast<SdrTextObj
*>(pObject1
);
1408 SdrView
* pView
= pViewShell
->GetView();
1410 // select contents of bullet item
1411 ::tools::Rectangle aRect
= pTextObject
->GetCurrentBoundRect();
1412 pXImpressDocument
->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
1413 convertMm100ToTwip(aRect
.getX() + 2), convertMm100ToTwip(aRect
.getY() + 2),
1415 pXImpressDocument
->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP
,
1416 convertMm100ToTwip(aRect
.getX() + 2), convertMm100ToTwip(aRect
.getY() + 2),
1418 Scheduler::ProcessEventsToIdle();
1419 pView
->SdrBeginTextEdit(pTextObject
);
1420 CPPUNIT_ASSERT(pView
->GetTextEditObject());
1421 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
1422 rEditView
.SetSelection(ESelection(2, 0, 2, 33)); // start para, start char, end para, end char.
1423 CPPUNIT_ASSERT_EQUAL(OUString("They have all the same formatting"), rEditView
.GetSelected());
1424 SdrOutliner
* pOutliner
= pView
->GetTextEditOutliner();
1425 CPPUNIT_ASSERT_EQUAL(OUString("No-Logo Content~LT~Gliederung 2"),
1426 pOutliner
->GetStyleSheet(2)->GetName());
1427 const SfxItemSet
& rParagraphItemSet1
= pTextObject
->GetOutlinerParaObject()->GetTextObject().GetParaAttribs(2);
1428 CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), rParagraphItemSet1
.Count());
1430 // cut contents of bullet item
1431 comphelper::dispatchCommand(".uno:Cut", uno::Sequence
<beans::PropertyValue
>());
1433 CPPUNIT_ASSERT(pView
->GetTextEditObject());
1434 EditView
& rEditView2
= pView
->GetTextEditOutlinerView()->GetEditView();
1435 rEditView2
.SetSelection(ESelection(2, 0, 2, 10)); // start para, start char, end para, end char.
1436 CPPUNIT_ASSERT_EQUAL(OUString(), rEditView2
.GetSelected());
1438 // paste contents of bullet item
1439 comphelper::dispatchCommand(".uno:Paste", uno::Sequence
<beans::PropertyValue
>());
1441 // send an ESC key to trigger the commit of the edit to the main model
1442 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::ESCAPE
);
1443 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::ESCAPE
);
1444 Scheduler::ProcessEventsToIdle();
1446 pView
->SdrBeginTextEdit(pTextObject
);
1447 CPPUNIT_ASSERT(pView
->GetTextEditObject());
1448 pOutliner
= pView
->GetTextEditOutliner();
1449 EditView
& rEditView3
= pView
->GetTextEditOutlinerView()->GetEditView();
1450 rEditView3
.SetSelection(ESelection(2, 0, 2, 33)); // start para, start char, end para, end char.
1451 CPPUNIT_ASSERT_EQUAL(OUString("They have all the same formatting"), rEditView3
.GetSelected());
1452 CPPUNIT_ASSERT_EQUAL(OUString("No-Logo Content~LT~Gliederung 2"),
1453 pOutliner
->GetStyleSheet(2)->GetName());
1455 const SfxItemSet
& rParagraphItemSet2
= pTextObject
->GetOutlinerParaObject()->GetTextObject().GetParaAttribs(2);
1456 CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), rParagraphItemSet2
.Count());
1460 * tests a clone-formatting bug around table cell attributes
1462 void SdTiledRenderingTest::testTdf104405()
1464 // Load the document.
1465 SdXImpressDocument
* pXImpressDocument
= createDoc("tdf104405.fodp");
1466 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1467 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1468 SdrObject
* pObject
= pActualPage
->GetObj(2);
1469 auto pTableObject
= dynamic_cast<sdr::table::SdrTableObj
*>(pObject
);
1470 CPPUNIT_ASSERT(pTableObject
);
1472 // select the middle cell
1473 SdrView
* pView
= pViewShell
->GetView();
1474 pView
->MarkObj(pTableObject
, pView
->GetSdrPageView());
1475 pTableObject
->setActiveCell(sdr::table::CellPos(2,1));
1476 pView
->SdrBeginTextEdit(pTableObject
);
1477 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
1478 rEditView
.SetSelection(ESelection(0, 0, 0, 3)); // start para, start char, end para, end char.
1480 // trigger the clone-formatting/paintbrush command to copy formatting contents of cell
1481 uno::Sequence
< beans::PropertyValue
> aArgs(1);
1482 aArgs
[0].Name
= "PersistentCopy";
1483 aArgs
[0].Value
<<= true;
1484 comphelper::dispatchCommand(".uno:FormatPaintbrush", aArgs
);
1486 Scheduler::ProcessEventsToIdle();
1488 // now click on the table
1489 pView
->MarkObj(pTableObject
, pView
->GetSdrPageView());
1490 pTableObject
->setActiveCell(sdr::table::CellPos(0,0));
1491 pView
->SdrEndTextEdit(false);
1492 pView
->SdrBeginTextEdit(pTableObject
);
1493 EditView
& rEditView2
= pView
->GetTextEditOutlinerView()->GetEditView();
1494 rEditView2
.SetSelection(ESelection(0, 0, 0, 3)); // start para, start char, end para, end char.
1495 ::tools::Rectangle aRect
= pTableObject
->GetCurrentBoundRect();
1496 pXImpressDocument
->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
1497 convertMm100ToTwip(aRect
.getX()), convertMm100ToTwip(aRect
.getY()),
1499 pXImpressDocument
->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP
,
1500 convertMm100ToTwip(aRect
.getX()), convertMm100ToTwip(aRect
.getY()),
1503 Scheduler::ProcessEventsToIdle();
1505 // check that the first cell has acquired the resulting vertical style
1506 xmlDocPtr pXmlDoc
= parseXmlDump();
1507 OString aPrefix
= "/SdDrawDocument/SdrModel/SdPage/SdrObjList/SdrTableObj/SdrTableObjImpl"
1508 "/TableModel/Cell[1]/DefaultProperties/SfxItemSet/SdrTextVertAdjustItem";
1509 // the following name has a compiler-dependent part
1510 CPPUNIT_ASSERT_EQUAL(OUString("2"), getXPath(pXmlDoc
, aPrefix
, "value"));
1511 xmlFreeDoc(pXmlDoc
);
1514 void SdTiledRenderingTest::testTdf81754()
1516 SdXImpressDocument
* pXImpressDocument
= createDoc("tdf81754.pptx");
1517 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1518 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1519 SdrObject
* pObject
= pActualPage
->GetObj(1);
1521 SdrTextObj
* pTextObj
= static_cast<SdrTextObj
*>(pObject
);
1522 SdrView
* pView
= pViewShell
->GetView();
1523 pView
->MarkObj(pTextObj
, pView
->GetSdrPageView());
1524 SfxStringItem
aInputString(SID_ATTR_CHAR
, "x");
1525 pViewShell
->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR
,
1526 SfxCallMode::SYNCHRON
, { &aInputString
});
1528 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'x', 0);
1529 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'x', 0);
1530 Scheduler::ProcessEventsToIdle();
1532 // now save, reload, and assert that we did not lose the edit
1533 ::sd::DrawDocShellRef xDocShRef
= saveAndReload(pXImpressDocument
->GetDocShell(), PPTX
);
1535 const SdrPage
* pPage
= GetPage(1, xDocShRef
);
1536 SdrTextObj
* pTextObject
= dynamic_cast<SdrTextObj
*>(pPage
->GetObj(1));
1537 CPPUNIT_ASSERT(pTextObject
);
1539 OutlinerParaObject
* pOutlinerParagraphObject
= pTextObject
->GetOutlinerParaObject();
1540 const EditTextObject
& aEdit
= pOutlinerParagraphObject
->GetTextObject();
1542 CPPUNIT_ASSERT_EQUAL(OUString("Somethingxx"), aEdit
.GetText(0));
1544 xDocShRef
->DoClose();
1547 void SdTiledRenderingTest::testTdf105502()
1549 // Load the document.
1550 SdXImpressDocument
* pXImpressDocument
= createDoc("tdf105502.odp");
1551 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1552 sd::Window
* pWindow
= pViewShell
->GetActiveWindow();
1553 CPPUNIT_ASSERT(pWindow
);
1554 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1555 SdrObject
* pObject
= pActualPage
->GetObj(0);
1556 auto pTableObject
= dynamic_cast<sdr::table::SdrTableObj
*>(pObject
);
1557 CPPUNIT_ASSERT(pTableObject
);
1559 // Select the first row.
1560 sd::View
* pView
= pViewShell
->GetView();
1561 pView
->MarkObj(pObject
, pView
->GetSdrPageView());
1562 pView
->SdrBeginTextEdit(pObject
);
1563 rtl::Reference
<sdr::SelectionController
> xSelectionController(pView
->getSelectionController());
1564 CPPUNIT_ASSERT(xSelectionController
.is());
1565 SfxRequest
aRequest(pViewShell
->GetViewFrame(), SID_TABLE_SELECT_ROW
);
1566 xSelectionController
->Execute(aRequest
);
1568 // Assert that the A1:B1 selection succeeded.
1569 CPPUNIT_ASSERT(xSelectionController
->hasSelectedCells());
1570 sdr::table::CellPos aFirstCell
;
1571 sdr::table::CellPos aLastCell
;
1572 xSelectionController
->getSelectedCells(aFirstCell
, aLastCell
);
1573 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), aFirstCell
.mnCol
);
1574 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), aFirstCell
.mnRow
);
1575 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), aLastCell
.mnCol
);
1576 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), aLastCell
.mnRow
);
1578 // Grow font size for the selection.
1579 comphelper::dispatchCommand(".uno:Grow", {});
1580 Scheduler::ProcessEventsToIdle();
1582 // Assert that the selected A1 has now a larger font than the unselected
1584 xmlDocPtr pXmlDoc
= parseXmlDump();
1585 sal_Int32 nA1Height
= getXPath(pXmlDoc
, "//Cell[1]/SdrText/OutlinerParaObject/EditTextObject/ContentInfo/SfxItemSet/SvxFontHeightItem[1]", "height").toInt32();
1586 sal_Int32 nA2Height
= getXPath(pXmlDoc
, "//Cell[3]/SdrText/OutlinerParaObject/EditTextObject/ContentInfo/attribs[1]/SvxFontHeightItem", "height").toInt32();
1587 // This failed when FuText::ChangeFontSize() never did "continue" in the
1588 // text loop, instead of doing so depending on what IsInSelection() returns.
1589 CPPUNIT_ASSERT(nA1Height
> nA2Height
);
1591 // Check that selection remains the same
1592 CPPUNIT_ASSERT(xSelectionController
->hasSelectedCells());
1593 xSelectionController
->getSelectedCells(aFirstCell
, aLastCell
);
1594 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), aFirstCell
.mnCol
);
1595 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), aFirstCell
.mnRow
);
1596 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), aLastCell
.mnCol
);
1597 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0), aLastCell
.mnRow
);
1599 xmlFreeDoc(pXmlDoc
);
1602 void SdTiledRenderingTest::testCommentCallbacks()
1604 // Load the document.
1605 // Set the tiled annotations off
1606 comphelper::LibreOfficeKit::setTiledAnnotations(false);
1608 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp", comphelper::InitPropertySequence(
1610 {".uno:Author", uno::makeAny(OUString("LOK User1"))},
1612 ViewCallback aView1
;
1613 int nView1
= SfxLokHelper::getView();
1615 SfxLokHelper::createView();
1616 uno::Sequence
<beans::PropertyValue
> aArgs(comphelper::InitPropertySequence(
1618 {".uno:Author", uno::makeAny(OUString("LOK User2"))},
1620 pXImpressDocument
->initializeForTiledRendering(aArgs
);
1621 ViewCallback aView2
;
1622 int nView2
= SfxLokHelper::getView();
1624 SfxLokHelper::setView(nView1
);
1626 // Add a new comment
1627 aArgs
= comphelper::InitPropertySequence(
1629 {"Text", uno::makeAny(OUString("Comment"))},
1631 comphelper::dispatchCommand(".uno:InsertAnnotation", aArgs
);
1632 Scheduler::ProcessEventsToIdle();
1634 // We received a LOK_CALLBACK_COMMENT callback with comment 'Add' action
1635 CPPUNIT_ASSERT_EQUAL(std::string("Add"), aView1
.m_aCommentCallbackResult
.get
<std::string
>("action"));
1636 CPPUNIT_ASSERT_EQUAL(std::string("Add"), aView2
.m_aCommentCallbackResult
.get
<std::string
>("action"));
1637 int nComment1
= aView1
.m_aCommentCallbackResult
.get
<int>("id");
1638 CPPUNIT_ASSERT_EQUAL(nComment1
, aView2
.m_aCommentCallbackResult
.get
<int>("id"));
1639 css::util::DateTime aDateTime
;
1640 OUString aDateTimeString
= OUString::createFromAscii(aView1
.m_aCommentCallbackResult
.get
<std::string
>("dateTime").c_str());
1641 CPPUNIT_ASSERT(utl::ISO8601parseDateTime(aDateTimeString
, aDateTime
));
1642 CPPUNIT_ASSERT_EQUAL(std::string("LOK User1"), aView1
.m_aCommentCallbackResult
.get
<std::string
>("author"));
1643 CPPUNIT_ASSERT_EQUAL(std::string("LOK User1"), aView2
.m_aCommentCallbackResult
.get
<std::string
>("author"));
1644 CPPUNIT_ASSERT_EQUAL(std::string("Comment"), aView1
.m_aCommentCallbackResult
.get
<std::string
>("text"));
1645 CPPUNIT_ASSERT_EQUAL(std::string("Comment"), aView2
.m_aCommentCallbackResult
.get
<std::string
>("text"));
1646 CPPUNIT_ASSERT(!aView1
.m_aCommentCallbackResult
.get
<std::string
>("parthash").empty());
1647 CPPUNIT_ASSERT(!aView2
.m_aCommentCallbackResult
.get
<std::string
>("parthash").empty());
1649 // Reply to a just added comment
1650 SfxLokHelper::setView(nView2
);
1651 aArgs
= comphelper::InitPropertySequence(
1653 {"Id", uno::makeAny(OUString::number(nComment1
))},
1654 {"Text", uno::makeAny(OUString("Reply to comment"))},
1656 comphelper::dispatchCommand(".uno:ReplyToAnnotation", aArgs
);
1657 Scheduler::ProcessEventsToIdle();
1659 // We received a LOK_CALLBACK_COMMENT callback with comment 'Modify' action
1660 CPPUNIT_ASSERT_EQUAL(std::string("Modify"), aView1
.m_aCommentCallbackResult
.get
<std::string
>("action"));
1661 CPPUNIT_ASSERT_EQUAL(std::string("Modify"), aView2
.m_aCommentCallbackResult
.get
<std::string
>("action"));
1662 CPPUNIT_ASSERT_EQUAL(nComment1
, aView1
.m_aCommentCallbackResult
.get
<int>("id"));
1663 CPPUNIT_ASSERT_EQUAL(nComment1
, aView2
.m_aCommentCallbackResult
.get
<int>("id"));
1664 CPPUNIT_ASSERT_EQUAL(std::string("LOK User2"), aView1
.m_aCommentCallbackResult
.get
<std::string
>("author"));
1665 CPPUNIT_ASSERT_EQUAL(std::string("LOK User2"), aView2
.m_aCommentCallbackResult
.get
<std::string
>("author"));
1666 OUString aReplyTextView1
= OUString::createFromAscii(aView1
.m_aCommentCallbackResult
.get
<std::string
>("text").c_str());
1667 OUString aReplyTextView2
= OUString::createFromAscii(aView2
.m_aCommentCallbackResult
.get
<std::string
>("text").c_str());
1668 CPPUNIT_ASSERT(aReplyTextView1
.startsWith("Reply to LOK User1"));
1669 CPPUNIT_ASSERT(aReplyTextView1
.endsWith("Reply to comment"));
1670 CPPUNIT_ASSERT(aReplyTextView2
.startsWith("Reply to LOK User1"));
1671 CPPUNIT_ASSERT(aReplyTextView2
.endsWith("Reply to comment"));
1672 CPPUNIT_ASSERT(!aView1
.m_aCommentCallbackResult
.get
<std::string
>("parthash").empty());
1673 CPPUNIT_ASSERT(!aView2
.m_aCommentCallbackResult
.get
<std::string
>("parthash").empty());
1675 // Edit this annotation now
1676 aArgs
= comphelper::InitPropertySequence(
1678 {"Id", uno::makeAny(OUString::number(nComment1
))},
1679 {"Text", uno::makeAny(OUString("Edited comment"))},
1681 comphelper::dispatchCommand(".uno:EditAnnotation", aArgs
);
1682 Scheduler::ProcessEventsToIdle();
1684 // We received a LOK_CALLBACK_COMMENT callback with comment 'Modify' action
1685 CPPUNIT_ASSERT_EQUAL(std::string("Modify"), aView1
.m_aCommentCallbackResult
.get
<std::string
>("action"));
1686 CPPUNIT_ASSERT_EQUAL(std::string("Modify"), aView2
.m_aCommentCallbackResult
.get
<std::string
>("action"));
1687 CPPUNIT_ASSERT_EQUAL(nComment1
, aView1
.m_aCommentCallbackResult
.get
<int>("id"));
1688 CPPUNIT_ASSERT_EQUAL(nComment1
, aView2
.m_aCommentCallbackResult
.get
<int>("id"));
1689 CPPUNIT_ASSERT(!aView1
.m_aCommentCallbackResult
.get
<std::string
>("parthash").empty());
1690 CPPUNIT_ASSERT(!aView2
.m_aCommentCallbackResult
.get
<std::string
>("parthash").empty());
1691 CPPUNIT_ASSERT_EQUAL(std::string("Edited comment"), aView1
.m_aCommentCallbackResult
.get
<std::string
>("text"));
1692 CPPUNIT_ASSERT_EQUAL(std::string("Edited comment"), aView2
.m_aCommentCallbackResult
.get
<std::string
>("text"));
1694 // Delete the comment
1695 aArgs
= comphelper::InitPropertySequence(
1697 {"Id", uno::makeAny(OUString::number(nComment1
))},
1699 comphelper::dispatchCommand(".uno:DeleteAnnotation", aArgs
);
1700 Scheduler::ProcessEventsToIdle();
1702 // We received a LOK_CALLBACK_COMMENT callback with comment 'Remove' action
1703 CPPUNIT_ASSERT_EQUAL(std::string("Remove"), aView1
.m_aCommentCallbackResult
.get
<std::string
>("action"));
1704 CPPUNIT_ASSERT_EQUAL(std::string("Remove"), aView2
.m_aCommentCallbackResult
.get
<std::string
>("action"));
1705 CPPUNIT_ASSERT_EQUAL(nComment1
, aView1
.m_aCommentCallbackResult
.get
<int>("id"));
1706 CPPUNIT_ASSERT_EQUAL(nComment1
, aView2
.m_aCommentCallbackResult
.get
<int>("id"));
1708 comphelper::LibreOfficeKit::setTiledAnnotations(true);
1711 void SdTiledRenderingTest::testMultiViewInsertDeletePage()
1713 // Load the document.
1714 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
1715 ViewCallback aView1
;
1716 int nView1
= SfxLokHelper::getView();
1717 uno::Sequence
<beans::PropertyValue
> aArgs
;
1718 SdDrawDocument
* pDoc
= pXImpressDocument
->GetDocShell()->GetDoc();
1720 // Create second view
1721 SfxLokHelper::createView();
1722 pXImpressDocument
->initializeForTiledRendering(aArgs
);
1723 ViewCallback aView2
;
1724 int nView2
= SfxLokHelper::getView();
1726 // the document has 8 slides
1727 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(8), pDoc
->GetSdPageCount(PageKind::Standard
));
1729 // Switch to 5th page in 2nd view
1730 pXImpressDocument
->setPart(4);
1732 // Insert slide in 1st view
1733 SfxLokHelper::setView(nView1
);
1734 comphelper::dispatchCommand(".uno:InsertPage", aArgs
);
1735 Scheduler::ProcessEventsToIdle();
1737 // See if the current slide number changed in 2nd view too
1738 SfxLokHelper::setView(nView2
);
1739 CPPUNIT_ASSERT_EQUAL(5, pXImpressDocument
->getPart());
1741 // Delete the page in 1st view now
1742 SfxLokHelper::setView(nView1
);
1743 comphelper::dispatchCommand(".uno:DeletePage", aArgs
);
1744 Scheduler::ProcessEventsToIdle();
1746 // See if current slide number changed in 2nd view too
1747 SfxLokHelper::setView(nView2
);
1748 CPPUNIT_ASSERT_EQUAL(4, pXImpressDocument
->getPart());
1751 void SdTiledRenderingTest::testDisableUndoRepair()
1753 // Load the document.
1754 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
1755 SfxViewShell
* pView1
= SfxViewShell::Current();
1756 int nView1
= SfxLokHelper::getView();
1757 SfxLokHelper::createView();
1758 SfxViewShell
* pView2
= SfxViewShell::Current();
1759 int nView2
= SfxLokHelper::getView();
1761 std::unique_ptr
<SfxPoolItem
> pItem1
;
1762 std::unique_ptr
<SfxPoolItem
> pItem2
;
1763 CPPUNIT_ASSERT_EQUAL(SfxItemState::DISABLED
, pView1
->GetViewFrame()->GetBindings().QueryState(SID_UNDO
, pItem1
));
1764 CPPUNIT_ASSERT_EQUAL(SfxItemState::DISABLED
, pView2
->GetViewFrame()->GetBindings().QueryState(SID_UNDO
, pItem2
));
1767 // Insert a character in the first view.
1768 SfxLokHelper::setView(nView1
);
1769 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
1770 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
1771 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'h', 0);
1772 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'h', 0);
1773 Scheduler::ProcessEventsToIdle();
1775 std::unique_ptr
<SfxPoolItem
> xItem1
;
1776 std::unique_ptr
<SfxPoolItem
> xItem2
;
1777 pView1
->GetViewFrame()->GetBindings().QueryState(SID_UNDO
, xItem1
);
1778 pView2
->GetViewFrame()->GetBindings().QueryState(SID_UNDO
, xItem2
);
1779 CPPUNIT_ASSERT(!dynamic_cast< const SfxUInt32Item
* >(xItem1
.get()));
1780 const SfxUInt32Item
* pUInt32Item
= dynamic_cast<const SfxUInt32Item
*>(xItem2
.get());
1781 CPPUNIT_ASSERT(pUInt32Item
);
1782 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32
>(SID_REPAIRPACKAGE
), pUInt32Item
->GetValue());
1785 // Insert a character in the second view.
1786 SfxLokHelper::setView(nView2
);
1787 pXImpressDocument
->setPart(1);
1788 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
1789 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
1790 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'c', 0);
1791 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'c', 0);
1792 Scheduler::ProcessEventsToIdle();
1794 std::unique_ptr
<SfxPoolItem
> xItem1
;
1795 std::unique_ptr
<SfxPoolItem
> xItem2
;
1796 pView1
->GetViewFrame()->GetBindings().QueryState(SID_UNDO
, xItem1
);
1797 pView2
->GetViewFrame()->GetBindings().QueryState(SID_UNDO
, xItem2
);
1798 CPPUNIT_ASSERT(!dynamic_cast< const SfxUInt32Item
* >(xItem2
.get()));
1799 const SfxUInt32Item
* pUInt32Item
= dynamic_cast<const SfxUInt32Item
*>(xItem1
.get());
1800 CPPUNIT_ASSERT(pUInt32Item
);
1801 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32
>(SID_REPAIRPACKAGE
), pUInt32Item
->GetValue());
1805 void SdTiledRenderingTest::testDocumentRepair()
1807 // Create two views.
1808 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
1809 CPPUNIT_ASSERT(pXImpressDocument
);
1812 SfxViewShell
* pView1
= SfxViewShell::Current();
1815 SfxLokHelper::createView();
1816 SfxViewShell
* pView2
= SfxViewShell::Current();
1817 int nView2
= SfxLokHelper::getView();
1818 CPPUNIT_ASSERT(pView1
!= pView2
);
1820 std::unique_ptr
<SfxPoolItem
> xItem1
;
1821 std::unique_ptr
<SfxPoolItem
> xItem2
;
1822 pView1
->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR
, xItem1
);
1823 pView2
->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR
, xItem2
);
1824 const SfxBoolItem
* pItem1
= dynamic_cast<const SfxBoolItem
*>(xItem1
.get());
1825 const SfxBoolItem
* pItem2
= dynamic_cast<const SfxBoolItem
*>(xItem2
.get());
1826 CPPUNIT_ASSERT(pItem1
);
1827 CPPUNIT_ASSERT(pItem2
);
1828 CPPUNIT_ASSERT_EQUAL(false, pItem1
->GetValue());
1829 CPPUNIT_ASSERT_EQUAL(false, pItem2
->GetValue());
1832 // Insert a character in the second view.
1833 SfxLokHelper::setView(nView2
);
1834 pXImpressDocument
->setPart(1);
1835 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
1836 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
1837 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 'c', 0);
1838 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 'c', 0);
1839 Scheduler::ProcessEventsToIdle();
1841 std::unique_ptr
<SfxPoolItem
> xItem1
;
1842 std::unique_ptr
<SfxPoolItem
> xItem2
;
1843 pView1
->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR
, xItem1
);
1844 pView2
->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR
, xItem2
);
1845 const SfxBoolItem
* pItem1
= dynamic_cast<const SfxBoolItem
*>(xItem1
.get());
1846 const SfxBoolItem
* pItem2
= dynamic_cast<const SfxBoolItem
*>(xItem2
.get());
1847 CPPUNIT_ASSERT(pItem1
);
1848 CPPUNIT_ASSERT(pItem2
);
1849 CPPUNIT_ASSERT_EQUAL(true, pItem1
->GetValue());
1850 CPPUNIT_ASSERT_EQUAL(true, pItem2
->GetValue());
1854 void SdTiledRenderingTest::testLanguageStatus()
1856 // Load the document.
1857 createDoc("dummy.odp");
1858 SfxViewShell
* pView1
= SfxViewShell::Current();
1859 SfxLokHelper::createView();
1860 SfxViewShell
* pView2
= SfxViewShell::Current();
1862 std::unique_ptr
<SfxPoolItem
> xItem1
;
1863 std::unique_ptr
<SfxPoolItem
> xItem2
;
1864 pView1
->GetViewFrame()->GetBindings().QueryState(SID_LANGUAGE_STATUS
, xItem1
);
1865 pView2
->GetViewFrame()->GetBindings().QueryState(SID_LANGUAGE_STATUS
, xItem2
);
1866 auto pStringItem
= dynamic_cast<const SfxStringItem
*>(xItem1
.get());
1867 CPPUNIT_ASSERT(pStringItem
);
1869 CPPUNIT_ASSERT_EQUAL(OUString("English (USA);en-US"), pStringItem
->GetValue());
1871 CPPUNIT_ASSERT(dynamic_cast< const SfxStringItem
* >(xItem2
.get()));
1875 void SdTiledRenderingTest::testLanguageAllText()
1877 // Load the document, which has a single shape, with Hungarian text.
1878 createDoc("language-all-text.odp");
1880 // Set the language to English for all text.
1881 uno::Sequence
<beans::PropertyValue
> aArgs
= comphelper::InitPropertySequence({
1882 { "Language", uno::makeAny(OUString("Default_English (USA)")) },
1884 comphelper::dispatchCommand(".uno:LanguageStatus", aArgs
);
1885 Scheduler::ProcessEventsToIdle();
1887 // Assert that the shape text language was changed.
1888 uno::Reference
<drawing::XDrawPagesSupplier
> xDrawPagesSupplier(mxComponent
, uno::UNO_QUERY
);
1889 uno::Reference
<drawing::XDrawPage
> xPage(xDrawPagesSupplier
->getDrawPages()->getByIndex(0),
1891 uno::Reference
<beans::XPropertySet
> xShape(xPage
->getByIndex(0), uno::UNO_QUERY
);
1892 uno::Reference
<beans::XPropertySet
> xRun(
1893 getRunFromParagraph(0, getParagraphFromShape(0, xShape
)), uno::UNO_QUERY
);
1894 lang::Locale aLocale
;
1895 xRun
->getPropertyValue("CharLocale") >>= aLocale
;
1896 // Without the accompanying fix in place, this test would have failed with 'Expected: en;
1897 // Actual: hu', as the shape text language was not set.
1898 CPPUNIT_ASSERT_EQUAL(OUString("en"), aLocale
.Language
);
1901 void SdTiledRenderingTest::testDefaultView()
1903 // Load the document with notes view.
1904 SdXImpressDocument
* pXImpressDocument
= createDoc("notes-view.odp");
1905 sd::ViewShell
* pView
= pXImpressDocument
->GetDocShell()->GetViewShell();
1907 std::unique_ptr
<SfxPoolItem
> xItem1
;
1908 std::unique_ptr
<SfxPoolItem
> xItem2
;
1909 pView
->GetViewFrame()->GetBindings().QueryState(SID_NORMAL_MULTI_PANE_GUI
, xItem1
);
1910 pView
->GetViewFrame()->GetBindings().QueryState(SID_NOTES_MODE
, xItem2
);
1911 const SfxBoolItem
* pImpressView
= dynamic_cast< const SfxBoolItem
* >(xItem1
.get());
1912 const SfxBoolItem
* pNotesView
= dynamic_cast< const SfxBoolItem
* >(xItem2
.get());
1913 CPPUNIT_ASSERT(pImpressView
);
1914 CPPUNIT_ASSERT(pNotesView
);
1915 CPPUNIT_ASSERT_EQUAL(true, pImpressView
->GetValue());
1916 CPPUNIT_ASSERT_EQUAL(false, pNotesView
->GetValue());
1920 void SdTiledRenderingTest::testIMESupport()
1922 // Load the document with notes view.
1923 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
1924 VclPtr
<vcl::Window
> pDocWindow
= pXImpressDocument
->getDocWindow();
1925 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1926 SdrObject
* pObject
= pViewShell
->GetActualPage()->GetObj(0);
1927 SdrTextObj
* pTextObj
= static_cast<SdrTextObj
*>(pObject
);
1928 SdrView
* pView
= pViewShell
->GetView();
1929 pView
->MarkObj(pTextObj
, pView
->GetSdrPageView());
1930 SfxStringItem
aInputString(SID_ATTR_CHAR
, "x");
1931 pViewShell
->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR
,
1932 SfxCallMode::SYNCHRON
, { &aInputString
});
1934 // sequence of chinese IME compositions when 'nihao' is typed in an IME
1935 const std::vector
<OString
> aUtf8Inputs
{ "å¹´", "ä½ ", "ä½ å¥½", "ä½ å“ˆ", "ä½ å¥½", "ä½ å¥½" };
1936 std::vector
<OUString
> aInputs
;
1937 std::transform(aUtf8Inputs
.begin(), aUtf8Inputs
.end(),
1938 std::back_inserter(aInputs
), [](OString aInput
) {
1939 return OUString::fromUtf8(aInput
);
1941 for (const auto& aInput
: aInputs
)
1943 pDocWindow
->PostExtTextInputEvent(VclEventId::ExtTextInput
, aInput
);
1945 pDocWindow
->PostExtTextInputEvent(VclEventId::EndExtTextInput
, "");
1947 // the cursor should be at position 3rd
1948 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
1949 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(3), rEditView
.GetSelection().nStartPos
);
1951 ESelection
aWordSelection(0, 0, 0, 3); // start para, start char, end para, end char.
1952 rEditView
.SetSelection(aWordSelection
);
1953 // content contains only the last IME composition, not all
1954 CPPUNIT_ASSERT_EQUAL(OUString("x").concat(aInputs
[aInputs
.size() - 1]), rEditView
.GetSelected());
1957 void SdTiledRenderingTest::testTdf115783()
1959 // Load the document.
1960 SdXImpressDocument
* pXImpressDocument
= createDoc("tdf115783.fodp");
1961 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
1962 SdPage
* pActualPage
= pViewShell
->GetActualPage();
1963 SdrObject
* pObject
= pActualPage
->GetObj(0);
1964 auto pTableObject
= dynamic_cast<sdr::table::SdrTableObj
*>(pObject
);
1965 CPPUNIT_ASSERT(pTableObject
);
1966 SdrView
* pView
= pViewShell
->GetView();
1967 pView
->MarkObj(pTableObject
, pView
->GetSdrPageView());
1969 // Create a cell selection and set font height.
1970 // Go to the end of the B1 cell.
1971 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
);
1972 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
);
1973 // Create a B1->C1 cell selection.
1974 const int nShiftRight
= KEY_SHIFT
+ KEY_RIGHT
;
1975 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, nShiftRight
);
1976 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, nShiftRight
);
1977 uno::Sequence
<beans::PropertyValue
> aArgs
= comphelper::InitPropertySequence({
1978 { "FontHeight.Height", uno::makeAny(static_cast<float>(12)) },
1980 comphelper::dispatchCommand(".uno:FontHeight", aArgs
);
1981 Scheduler::ProcessEventsToIdle();
1983 // Create a text selection on the B1 cell.
1984 pTableObject
->setActiveCell(sdr::table::CellPos(1, 0));
1985 pView
->SdrBeginTextEdit(pTableObject
);
1986 EditView
& rEditView
= pView
->GetTextEditOutlinerView()->GetEditView();
1987 // Start para, start char, end para, end char.
1988 rEditView
.SetSelection(ESelection(0, 0, 0, 5));
1989 CPPUNIT_ASSERT_EQUAL(OUString("hello"), rEditView
.GetSelected());
1991 // Copy selection, paste at the start of the cell.
1993 comphelper::dispatchCommand(".uno:Copy", aArgs
);
1994 Scheduler::ProcessEventsToIdle();
1995 rEditView
.SetSelection(ESelection(0, 0, 0, 0));
1997 comphelper::dispatchCommand(".uno:Paste", aArgs
);
1998 Scheduler::ProcessEventsToIdle();
1999 pView
->SdrEndTextEdit();
2001 // And now verify that the cell has the correct font size.
2002 uno::Reference
<table::XCellRange
> xTable
= pTableObject
->getTable();
2003 CPPUNIT_ASSERT(xTable
.is());
2004 uno::Reference
<text::XTextRange
> xCell(xTable
->getCellByPosition(1, 0), uno::UNO_QUERY
);
2005 CPPUNIT_ASSERT(xCell
.is());
2006 uno::Reference
<container::XEnumerationAccess
> xText(xCell
->getText(), uno::UNO_QUERY
);
2007 CPPUNIT_ASSERT(xText
.is());
2008 uno::Reference
<container::XEnumerationAccess
> xParagraph(
2009 xText
->createEnumeration()->nextElement(), uno::UNO_QUERY
);
2010 CPPUNIT_ASSERT(xParagraph
.is());
2011 uno::Reference
<text::XTextRange
> xPortion(xParagraph
->createEnumeration()->nextElement(),
2013 CPPUNIT_ASSERT(xPortion
.is());
2014 // This failed, it was only "hello" as the paragraph had 2 portions: a
2015 // "hello" with 12pt size and a "hello" with 18pt.
2016 CPPUNIT_ASSERT_EQUAL(OUString("hellohello"), xPortion
->getString());
2017 uno::Reference
<beans::XPropertySet
> xPropertySet(xPortion
, uno::UNO_QUERY
);
2018 int nHeight
= xPropertySet
->getPropertyValue("CharHeight").get
<float>();
2019 // Make sure that the single font size for the cell is the expected one.
2020 CPPUNIT_ASSERT_EQUAL(12, nHeight
);
2023 void SdTiledRenderingTest::testPasteTextOnSlide()
2025 // Load the document.
2026 SdXImpressDocument
* pXImpressDocument
= createDoc("paste_text_onslide.odp");
2027 CPPUNIT_ASSERT(pXImpressDocument
);
2029 // select second text object
2030 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
2031 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
2032 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
2033 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
2034 Scheduler::ProcessEventsToIdle();
2036 // step into text editing
2037 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, '1', 0);
2038 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, '1', 0);
2039 Scheduler::ProcessEventsToIdle();
2042 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
| KEY_SHIFT
);
2043 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
| KEY_SHIFT
);
2044 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
| KEY_SHIFT
);
2045 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
| KEY_SHIFT
);
2046 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
| KEY_SHIFT
);
2047 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
| KEY_SHIFT
);
2048 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
| KEY_SHIFT
);
2049 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
| KEY_SHIFT
);
2050 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
| KEY_SHIFT
);
2051 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
| KEY_SHIFT
);
2052 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
| KEY_SHIFT
);
2053 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
| KEY_SHIFT
);
2054 Scheduler::ProcessEventsToIdle();
2057 comphelper::dispatchCommand(".uno:Copy", uno::Sequence
<beans::PropertyValue
>());
2058 Scheduler::ProcessEventsToIdle();
2060 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::ESCAPE
);
2061 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::ESCAPE
);
2062 Scheduler::ProcessEventsToIdle();
2064 // Paste onto the slide
2065 comphelper::dispatchCommand(".uno:Paste", uno::Sequence
<beans::PropertyValue
>());
2066 Scheduler::ProcessEventsToIdle();
2068 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::ESCAPE
);
2069 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::ESCAPE
);
2070 Scheduler::ProcessEventsToIdle();
2072 // Check the position of the newly added text shape, created for pasted text
2073 SdPage
* pActualPage
= pXImpressDocument
->GetDocShell()->GetViewShell()->GetActualPage();
2074 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pActualPage
->GetObjCount());
2075 SdrObject
* pObject
= pActualPage
->GetObj(2);
2076 CPPUNIT_ASSERT(pObject
);
2077 SdrTextObj
* pTextObj
= dynamic_cast<SdrTextObj
*>(pObject
);
2078 CPPUNIT_ASSERT(pTextObj
);
2079 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(OBJ_TEXT
), pTextObj
->GetObjIdentifier());
2080 // This test is unreliable: it gives alternating results for the following coordinates.
2081 // As a compromise, instead of disabling it altogether, we allow for both sets of values.
2082 const Point aPos
= pTextObj
->GetLastBoundRect().TopLeft();
2083 if (aPos
.getX() < 10000)
2085 // We get this with 'make CppunitTest_sd_tiledrendering'
2086 CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(6739), aPos
.getX(), 100);
2087 CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(6822), aPos
.getY(), 100);
2091 // We get this with 'make check'
2092 CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(12990), aPos
.getX(), 100);
2093 CPPUNIT_ASSERT_DOUBLES_EQUAL(static_cast<long>(7393), aPos
.getY(), 100);
2097 void SdTiledRenderingTest::testTdf115873()
2099 // Initialize the navigator.
2100 SdXImpressDocument
* pXImpressDocument
= createDoc("tdf115873.fodp");
2101 SfxViewShell
* pViewShell
= SfxViewShell::Current();
2102 CPPUNIT_ASSERT(pViewShell
);
2103 SfxBindings
& rBindings
= pViewShell
->GetViewFrame()->GetBindings();
2104 ScopedVclPtrInstance
<SdNavigatorWin
> pNavigator(nullptr, &rBindings
);
2105 pNavigator
->InitTreeLB(pXImpressDocument
->GetDoc());
2107 VclPtr
<SdPageObjsTLB
> pObjects
= pNavigator
->GetObjects();
2108 pObjects
->Select(pObjects
->GetEntry(0));
2109 sd::ViewShell
* pSdViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
2110 SdrView
* pSdrView
= pSdViewShell
->GetView();
2111 pSdrView
->UnmarkAllObj(pSdrView
->GetSdrPageView());
2113 // Make sure that no shapes are selected.
2114 const SdrMarkList
& rMarkList
= pSdrView
->GetMarkedObjectList();
2115 Scheduler::ProcessEventsToIdle();
2116 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rMarkList
.GetMarkCount());
2118 // Single-click with the mouse.
2119 short nHeight
= pObjects
->GetEntryHeight();
2120 // Position of the center of the 2nd entry (first is the slide, second is
2122 Point
aPoint(pObjects
->GetOutputWidthPixel() / 2, nHeight
* 1.5);
2123 MouseEvent
aMouseEvent(aPoint
, /*nClicks=*/1, MouseEventModifiers::NONE
, MOUSE_LEFT
);
2124 pObjects
->MouseButtonDown(aMouseEvent
);
2125 pObjects
->MouseButtonUp(aMouseEvent
);
2126 Scheduler::ProcessEventsToIdle();
2127 // This failed, single-click did not result in a shape selection (only
2128 // double-click did).
2129 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rMarkList
.GetMarkCount());
2132 void SdTiledRenderingTest::testTdf115873Group()
2134 // Initialize the navigator.
2135 SdXImpressDocument
* pXImpressDocument
= createDoc("tdf115873-group.fodp");
2136 SfxViewShell
* pViewShell
= SfxViewShell::Current();
2137 CPPUNIT_ASSERT(pViewShell
);
2138 SfxBindings
& rBindings
= pViewShell
->GetViewFrame()->GetBindings();
2139 ScopedVclPtrInstance
<SdNavigatorWin
> pNavigator(nullptr, &rBindings
);
2140 pNavigator
->InitTreeLB(pXImpressDocument
->GetDoc());
2141 VclPtr
<SdPageObjsTLB
> pObjects
= pNavigator
->GetObjects();
2142 // This failed, Fill() and IsEqualToDoc() were out of sync for group
2144 CPPUNIT_ASSERT(pObjects
->IsEqualToDoc(pXImpressDocument
->GetDoc()));
2147 void SdTiledRenderingTest::testCutSelectionChange()
2149 // Load the document.
2150 SdXImpressDocument
* pXImpressDocument
= createDoc("cut_selection_change.odp");
2151 CPPUNIT_ASSERT(pXImpressDocument
);
2153 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
2154 pViewShell
->GetViewShellBase().registerLibreOfficeKitViewCallback(&SdTiledRenderingTest::callback
, this);
2155 Scheduler::ProcessEventsToIdle();
2157 // Select first text object
2158 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
2159 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
2160 Scheduler::ProcessEventsToIdle();
2162 // step into text editing
2163 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, '1', 0);
2164 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, '1', 0);
2165 Scheduler::ProcessEventsToIdle();
2168 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
| KEY_SHIFT
);
2169 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
| KEY_SHIFT
);
2170 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_LEFT
| KEY_SHIFT
);
2171 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_LEFT
| KEY_SHIFT
);
2172 Scheduler::ProcessEventsToIdle();
2174 // Check that we have a selection before cutting
2175 CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), m_aSelection
.size());
2177 // Cut the selected text
2178 comphelper::dispatchCommand(".uno:Cut", uno::Sequence
<beans::PropertyValue
>());
2179 Scheduler::ProcessEventsToIdle();
2181 // Selection is removed
2182 CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(0), m_aSelection
.size());
2185 void SdTiledRenderingTest::testRegenerateDiagram()
2187 // Load the document.
2188 SdXImpressDocument
* pXImpressDocument
= createDoc("regenerate-diagram.pptx");
2189 CPPUNIT_ASSERT(pXImpressDocument
);
2191 SdPage
* pActualPage
= pXImpressDocument
->GetDocShell()->GetViewShell()->GetActualPage();
2192 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), pActualPage
->GetObj(0)->GetSubList()->GetObjCount());
2195 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
2196 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
2197 Scheduler::ProcessEventsToIdle();
2200 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::F3
);
2201 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::F3
);
2202 Scheduler::ProcessEventsToIdle();
2204 // select shape and delete
2205 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
2206 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
2207 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
2208 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
2209 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::DELETE
);
2210 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::DELETE
);
2211 Scheduler::ProcessEventsToIdle();
2214 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
2215 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
2216 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, KEY_MOD1
| awt::Key::F3
);
2217 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, KEY_MOD1
| awt::Key::F3
);
2218 Scheduler::ProcessEventsToIdle();
2221 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYINPUT
, 0, awt::Key::TAB
);
2222 pXImpressDocument
->postKeyEvent(LOK_KEYEVENT_KEYUP
, 0, awt::Key::TAB
);
2223 Scheduler::ProcessEventsToIdle();
2225 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pActualPage
->GetObj(0)->GetSubList()->GetObjCount());
2227 // regenerate diagram
2228 comphelper::dispatchCommand(".uno:RegenerateDiagram", uno::Sequence
<beans::PropertyValue
>());
2229 Scheduler::ProcessEventsToIdle();
2231 // diagram content (child shape count) should be the same as in the beginning
2232 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), pActualPage
->GetObj(0)->GetSubList()->GetObjCount());
2235 void SdTiledRenderingTest::testInsertDeletePageInvalidation()
2237 // Load the document.
2238 SdXImpressDocument
* pXImpressDocument
= createDoc("dummy.odp");
2239 ViewCallback aView1
;
2240 CPPUNIT_ASSERT_EQUAL(8, pXImpressDocument
->getParts());
2243 aView1
.m_bTilesInvalidated
= false;
2244 aView1
.m_aInvalidations
.clear();
2245 comphelper::dispatchCommand(".uno:InsertPage", uno::Sequence
<beans::PropertyValue
>());
2246 Scheduler::ProcessEventsToIdle();
2247 CPPUNIT_ASSERT(aView1
.m_bTilesInvalidated
);
2248 CPPUNIT_ASSERT_EQUAL(9, pXImpressDocument
->getParts());
2249 CPPUNIT_ASSERT_EQUAL(size_t(9), aView1
.m_aInvalidations
.size());
2252 aView1
.m_bTilesInvalidated
= false;
2253 aView1
.m_aInvalidations
.clear();
2254 comphelper::dispatchCommand(".uno:DeletePage", uno::Sequence
<beans::PropertyValue
>());
2255 Scheduler::ProcessEventsToIdle();
2256 CPPUNIT_ASSERT(aView1
.m_bTilesInvalidated
);
2257 CPPUNIT_ASSERT_EQUAL(8, pXImpressDocument
->getParts());
2258 CPPUNIT_ASSERT_EQUAL(size_t(8), aView1
.m_aInvalidations
.size());
2261 CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest
);
2263 CPPUNIT_PLUGIN_IMPLEMENT();
2265 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */