1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include "../sdmodeltestbase.hxx"
11 
12 #include "CallbackRecorder.hxx"
13 
14 #include <test/bootstrapfixture.hxx>
15 #include <test/helper/transferable.hxx>
16 #include <test/xmltesttools.hxx>
17 
18 #include <comphelper/dispatchcommand.hxx>
19 #include <comphelper/processfactory.hxx>
20 #include <comphelper/propertysequence.hxx>
21 #include <comphelper/lok.hxx>
22 #include <svl/srchitem.hxx>
23 #include <vcl/scheduler.hxx>
24 #include <ViewShellBase.hxx>
25 #include <ViewShell.hxx>
26 #include <unomodel.hxx>
27 
28 #include <sdpage.hxx>
29 #include <svx/svdograf.hxx>
30 #include <vcl/filter/PDFiumLibrary.hxx>
31 
32 #include <com/sun/star/frame/Desktop.hpp>
33 
34 using namespace css;
35 
36 class LOKitSearchTest : public SdModelTestBase, public XmlTestTools
37 {
38 private:
39     static constexpr OUStringLiteral DATA_DIRECTORY = u"/sd/qa/unit/tiledrendering/data/";
40 
41 public:
42     LOKitSearchTest() = default;
43 
44     virtual void setUp() override;
45     virtual void tearDown() override;
46 
47     void testSearch();
48     void testSearchAll();
49     void testSearchAllSelections();
50     void testSearchAllNotifications();
51     void testSearchAllFollowedBySearch();
52     void testDontSearchInMasterPages();
53     void testSearchInPDFNonExisting();
54     void testSearchInPDF();
55     void testSearchInPDFOnePDFObject();
56     void testSearchInPDFInMultiplePages();
57     void testSearchInPDFInMultiplePagesBackwards();
58     void testSearchIn2MixedObjects();
59     void testSearchIn6MixedObjects();
60     void testReplace();
61     void testReplaceAll();
62     void testReplaceCombined();
63 
64     CPPUNIT_TEST_SUITE(LOKitSearchTest);
65     CPPUNIT_TEST(testSearch);
66     CPPUNIT_TEST(testSearchAll);
67     CPPUNIT_TEST(testSearchAllSelections);
68     CPPUNIT_TEST(testSearchAllNotifications);
69     CPPUNIT_TEST(testSearchAllFollowedBySearch);
70     CPPUNIT_TEST(testDontSearchInMasterPages);
71     CPPUNIT_TEST(testSearchInPDFNonExisting);
72     CPPUNIT_TEST(testSearchInPDF);
73     CPPUNIT_TEST(testSearchInPDFOnePDFObject);
74     CPPUNIT_TEST(testSearchInPDFInMultiplePages);
75     CPPUNIT_TEST(testSearchInPDFInMultiplePagesBackwards);
76     CPPUNIT_TEST(testSearchIn2MixedObjects);
77     CPPUNIT_TEST(testSearchIn6MixedObjects);
78     CPPUNIT_TEST(testReplace);
79     CPPUNIT_TEST(testReplaceAll);
80     CPPUNIT_TEST(testReplaceCombined);
81     CPPUNIT_TEST_SUITE_END();
82 
83 private:
84     SdXImpressDocument* createDoc(const char* pName,
85                                   const uno::Sequence<beans::PropertyValue>& rArguments
86                                   = uno::Sequence<beans::PropertyValue>());
87 
88     uno::Reference<lang::XComponent> mxComponent;
89     std::unique_ptr<CallbackRecorder> mpCallbackRecorder;
90 };
91 
setUp()92 void LOKitSearchTest::setUp()
93 {
94     test::BootstrapFixture::setUp();
95 
96     // prevent showing warning message box
97     setenv("OOX_NO_SMARTART_WARNING", "1", 1);
98     comphelper::LibreOfficeKit::setActive(true);
99 
100     mxDesktop.set(
101         css::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())));
102     mpCallbackRecorder = std::make_unique<CallbackRecorder>();
103 }
104 
tearDown()105 void LOKitSearchTest::tearDown()
106 {
107     if (mxComponent.is())
108         mxComponent->dispose();
109 
110     comphelper::LibreOfficeKit::setActive(false);
111 
112     test::BootstrapFixture::tearDown();
113 }
114 
115 SdXImpressDocument*
createDoc(const char * pName,const uno::Sequence<beans::PropertyValue> & rArguments)116 LOKitSearchTest::createDoc(const char* pName, const uno::Sequence<beans::PropertyValue>& rArguments)
117 {
118     if (mxComponent.is())
119         mxComponent->dispose();
120 
121     mxComponent = loadFromDesktop(m_directories.getURLFromSrc(DATA_DIRECTORY)
122                                   + OUString::createFromAscii(pName));
123 
124     CPPUNIT_ASSERT(mxComponent.is());
125     SdXImpressDocument* pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
126     CPPUNIT_ASSERT(pImpressDocument);
127     pImpressDocument->initializeForTiledRendering(rArguments);
128     return pImpressDocument;
129 }
130 
131 namespace
132 {
lcl_search(const OUString & rKey,bool bFindAll=false,bool bBackwards=false)133 void lcl_search(const OUString& rKey, bool bFindAll = false, bool bBackwards = false)
134 {
135     Scheduler::ProcessEventsToIdle();
136     SvxSearchCmd eSearch = bFindAll ? SvxSearchCmd::FIND_ALL : SvxSearchCmd::FIND;
137 
138     uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({
139         { "SearchItem.SearchString", uno::makeAny(rKey) },
140         { "SearchItem.Backward", uno::makeAny(bBackwards) },
141         { "SearchItem.Command", uno::makeAny(sal_uInt16(eSearch)) },
142     }));
143 
144     comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues);
145     Scheduler::ProcessEventsToIdle();
146 }
147 
lcl_replace(const OUString & rKey,const OUString & rReplace,bool bAll=false)148 void lcl_replace(const OUString& rKey, const OUString& rReplace, bool bAll = false)
149 {
150     Scheduler::ProcessEventsToIdle();
151 
152     SvxSearchCmd eSearch = bAll ? SvxSearchCmd::REPLACE_ALL : SvxSearchCmd::REPLACE;
153 
154     uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({
155         { "SearchItem.SearchString", uno::makeAny(rKey) },
156         { "SearchItem.ReplaceString", uno::makeAny(rReplace) },
157         { "SearchItem.Command", uno::makeAny(sal_uInt16(eSearch)) },
158     }));
159 
160     comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues);
161     Scheduler::ProcessEventsToIdle();
162 }
163 
lclGetSelectedObject(sd::ViewShell * pViewShell)164 SdrObject* lclGetSelectedObject(sd::ViewShell* pViewShell)
165 {
166     SdrView* pSdrView = pViewShell->GetView();
167     const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
168     CPPUNIT_ASSERT_EQUAL(size_t(1), rMarkList.GetMarkCount());
169     SdrObject* pObject = rMarkList.GetMark(0)->GetMarkedSdrObj();
170     return pObject;
171 }
172 
173 } // end anonymous namespace
174 
testSearch()175 void LOKitSearchTest::testSearch()
176 {
177     SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
178     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
179     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
180     uno::Reference<container::XIndexAccess> xDrawPage(
181         pXImpressDocument->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
182     uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
183     xShape->setString("Aaa bbb.");
184 
185     lcl_search("bbb");
186 
187     SdrView* pView = pViewShell->GetView();
188     EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
189     // Did we indeed manage to select the second word?
190     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), rEditView.GetSelected());
191 
192     // Did the selection callback fire?
193     CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), mpCallbackRecorder->m_aSelection.size());
194 
195     // Search for something on the second slide, and make sure that the set-part callback fired.
196     lcl_search("bbb");
197     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), mpCallbackRecorder->m_nPart);
198     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
199     // This was 0; should be 1 match for "find".
200     CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1),
201                          mpCallbackRecorder->m_aSearchResultSelection.size());
202     // Result is on the second slide.
203     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_aSearchResultPart[0]);
204 
205     // This should trigger the not-found callback.
206     lcl_search("ccc");
207     CPPUNIT_ASSERT_EQUAL(false, mpCallbackRecorder->m_bFound);
208 }
209 
testSearchAll()210 void LOKitSearchTest::testSearchAll()
211 {
212     SdXImpressDocument* pXImpressDocument = createDoc("search-all.odp");
213     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
214     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
215 
216     lcl_search("match", /*bFindAll=*/true);
217 
218     // This was empty: find-all did not highlight the first match.
219     CPPUNIT_ASSERT_EQUAL(OString("match"),
220                          apitest::helper::transferable::getTextSelection(
221                              pXImpressDocument->getSelection(), "text/plain;charset=utf-8"));
222 
223     // We're on the first slide, search for something on the second slide and make sure we get a SET_PART.
224     mpCallbackRecorder->m_nPart = 0;
225     lcl_search("second", /*bFindAll=*/true);
226     // This was 0: no SET_PART was emitted.
227     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), mpCallbackRecorder->m_nPart);
228 }
229 
testSearchAllSelections()230 void LOKitSearchTest::testSearchAllSelections()
231 {
232     SdXImpressDocument* pXImpressDocument = createDoc("search-all.odp");
233     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
234     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
235 
236     lcl_search("third", /*bFindAll=*/true);
237     // Make sure this is found on the 3rd slide.
238     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), mpCallbackRecorder->m_nPart);
239 
240     CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), mpCallbackRecorder->m_aSelection.size());
241 }
242 
testSearchAllNotifications()243 void LOKitSearchTest::testSearchAllNotifications()
244 {
245     SdXImpressDocument* pXImpressDocument = createDoc("search-all.odp");
246     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
247     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
248 
249     lcl_search("third", /*bFindAll=*/true);
250     // Make sure that we get no notifications about selection changes during search.
251     CPPUNIT_ASSERT_EQUAL(0, mpCallbackRecorder->m_nSelectionBeforeSearchResult);
252     // But we do get the selection of the first hit.
253     CPPUNIT_ASSERT(mpCallbackRecorder->m_nSelectionAfterSearchResult > 0);
254 }
255 
testSearchAllFollowedBySearch()256 void LOKitSearchTest::testSearchAllFollowedBySearch()
257 {
258     SdXImpressDocument* pXImpressDocument = createDoc("search-all.odp");
259     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
260     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
261 
262     lcl_search("third", /*bFindAll=*/true);
263     lcl_search("match" /*,bFindAll=false*/);
264 
265     // This used to give wrong result: 'search' after 'search all' still
266     // returned 'third'
267     CPPUNIT_ASSERT_EQUAL(OString("match"),
268                          apitest::helper::transferable::getTextSelection(
269                              pXImpressDocument->getSelection(), "text/plain;charset=utf-8"));
270 }
271 
testDontSearchInMasterPages()272 void LOKitSearchTest::testDontSearchInMasterPages()
273 {
274     SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
275     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
276     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
277 
278     // This should trigger the not-found callback ("date" is present only on
279     // the master page)
280     lcl_search("date");
281     CPPUNIT_ASSERT_EQUAL(false, mpCallbackRecorder->m_bFound);
282 }
283 
testSearchInPDFNonExisting()284 void LOKitSearchTest::testSearchInPDFNonExisting()
285 {
286     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
287     if (!pPdfium)
288     {
289         return;
290     }
291 
292     SdXImpressDocument* pXImpressDocument = createDoc("PDFSearch.pdf");
293     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
294     CPPUNIT_ASSERT(pViewShell);
295     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
296 
297     SdPage* pPage = pViewShell->GetActualPage();
298     CPPUNIT_ASSERT(pPage);
299 
300     SdrObject* pObject = pPage->GetObj(0);
301     CPPUNIT_ASSERT(pObject);
302 
303     SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
304     CPPUNIT_ASSERT(pGraphicObject);
305 
306     Graphic aGraphic = pGraphicObject->GetGraphic();
307     auto const& pVectorGraphicData = aGraphic.getVectorGraphicData();
308     CPPUNIT_ASSERT(pVectorGraphicData);
309     CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType());
310 
311     lcl_search("NonExisting");
312 
313     CPPUNIT_ASSERT_EQUAL(false, mpCallbackRecorder->m_bFound);
314 }
315 
testSearchInPDF()316 void LOKitSearchTest::testSearchInPDF()
317 {
318     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
319     if (!pPdfium)
320     {
321         return;
322     }
323 
324     SdXImpressDocument* pXImpressDocument = createDoc("PDFSearch.pdf");
325     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
326     CPPUNIT_ASSERT(pViewShell);
327     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
328 
329     SdPage* pPage = pViewShell->GetActualPage();
330     CPPUNIT_ASSERT(pPage);
331 
332     SdrObject* pObject = pPage->GetObj(0);
333     CPPUNIT_ASSERT(pObject);
334 
335     SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
336     CPPUNIT_ASSERT(pGraphicObject);
337 
338     Graphic aGraphic = pGraphicObject->GetGraphic();
339     auto const& pVectorGraphicData = aGraphic.getVectorGraphicData();
340     CPPUNIT_ASSERT(pVectorGraphicData);
341     CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType());
342 
343     // Search
344     lcl_search("ABC");
345 
346     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
347     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_nSearchResultCount);
348 
349     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
350     CPPUNIT_ASSERT_EQUAL(OString("3763, 1331, 1432, 483"),
351                          mpCallbackRecorder->m_aSearchResultSelection[0]);
352     CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(3763, 1331), Size(1433, 484)),
353                          mpCallbackRecorder->m_aSelection[0]);
354 
355     // Search again - same result
356     lcl_search("ABC");
357 
358     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
359     CPPUNIT_ASSERT_EQUAL(2, mpCallbackRecorder->m_nSearchResultCount);
360 
361     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
362     CPPUNIT_ASSERT_EQUAL(OString("3763, 1331, 1432, 483"),
363                          mpCallbackRecorder->m_aSearchResultSelection[0]);
364     CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(3763, 1331), Size(1433, 484)),
365                          mpCallbackRecorder->m_aSelection[0]);
366 }
367 
testSearchInPDFOnePDFObject()368 void LOKitSearchTest::testSearchInPDFOnePDFObject()
369 {
370     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
371     if (!pPdfium)
372     {
373         return;
374     }
375 
376     SdXImpressDocument* pXImpressDocument = createDoc("OnePDFObject.odg");
377     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
378     CPPUNIT_ASSERT(pViewShell);
379     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
380 
381     SdPage* pPage = pViewShell->GetActualPage();
382     CPPUNIT_ASSERT(pPage);
383 
384     SdrObject* pObject = pPage->GetObj(0);
385     CPPUNIT_ASSERT(pObject);
386 
387     SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
388     CPPUNIT_ASSERT(pGraphicObject);
389 
390     Graphic aGraphic = pGraphicObject->GetGraphic();
391     auto const& pVectorGraphicData = aGraphic.getVectorGraphicData();
392     CPPUNIT_ASSERT(pVectorGraphicData);
393     CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType());
394 
395     // Search down
396     lcl_search("ABC", false, false);
397 
398     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
399     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_nSearchResultCount);
400 
401     // Search up
402     lcl_search("ABC", false, true); // This caused a crash
403 
404     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
405     CPPUNIT_ASSERT_EQUAL(2, mpCallbackRecorder->m_nSearchResultCount);
406 }
407 
testSearchInPDFInMultiplePages()408 void LOKitSearchTest::testSearchInPDFInMultiplePages()
409 {
410     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
411     if (!pPdfium)
412     {
413         return;
414     }
415 
416     SdXImpressDocument* pXImpressDocument = createDoc("PDFSearch.pdf");
417     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
418     CPPUNIT_ASSERT(pViewShell);
419     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
420 
421     SdPage* pPage = pViewShell->GetActualPage();
422     CPPUNIT_ASSERT(pPage);
423 
424     {
425         SdrObject* pObject = pPage->GetObj(0);
426         CPPUNIT_ASSERT(pObject);
427 
428         SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
429         CPPUNIT_ASSERT(pGraphicObject);
430 
431         Graphic aGraphic = pGraphicObject->GetGraphic();
432         auto const& pVectorGraphicData = aGraphic.getVectorGraphicData();
433         CPPUNIT_ASSERT(pVectorGraphicData);
434         CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType());
435     }
436 
437     // Search for "him"
438     lcl_search("him");
439 
440     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
441     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_nSearchResultCount);
442 
443     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
444     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
445 
446     CPPUNIT_ASSERT_EQUAL(0, mpCallbackRecorder->m_aSearchResultPart[0]);
447     CPPUNIT_ASSERT_EQUAL(OString("9463, 3382, 1099, 499"),
448                          mpCallbackRecorder->m_aSearchResultSelection[0]);
449 
450     // Search for "him"
451     lcl_search("him");
452 
453     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
454     CPPUNIT_ASSERT_EQUAL(2, mpCallbackRecorder->m_nSearchResultCount);
455 
456     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
457     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
458 
459     CPPUNIT_ASSERT_EQUAL(0, mpCallbackRecorder->m_aSearchResultPart[0]);
460     CPPUNIT_ASSERT_EQUAL(OString("5592, 5038, 1100, 499"),
461                          mpCallbackRecorder->m_aSearchResultSelection[0]);
462 
463     // Search for "him"
464     lcl_search("him");
465 
466     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
467     CPPUNIT_ASSERT_EQUAL(3, mpCallbackRecorder->m_nSearchResultCount);
468 
469     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
470     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
471 
472     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_aSearchResultPart[0]);
473     CPPUNIT_ASSERT_EQUAL(OString("9463, 1308, 1099, 499"),
474                          mpCallbackRecorder->m_aSearchResultSelection[0]);
475 
476     // Search for "him"
477     lcl_search("him");
478 
479     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
480     CPPUNIT_ASSERT_EQUAL(4, mpCallbackRecorder->m_nSearchResultCount);
481 
482     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
483     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
484 
485     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_aSearchResultPart[0]);
486     CPPUNIT_ASSERT_EQUAL(OString("5592, 2964, 1100, 499"),
487                          mpCallbackRecorder->m_aSearchResultSelection[0]);
488 
489     // Search for "him" - back to start
490     lcl_search("him");
491 
492     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
493     CPPUNIT_ASSERT_EQUAL(5, mpCallbackRecorder->m_nSearchResultCount);
494 
495     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
496     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
497 
498     CPPUNIT_ASSERT_EQUAL(0, mpCallbackRecorder->m_aSearchResultPart[0]);
499     CPPUNIT_ASSERT_EQUAL(OString("9463, 3382, 1099, 499"),
500                          mpCallbackRecorder->m_aSearchResultSelection[0]);
501 }
502 
testSearchInPDFInMultiplePagesBackwards()503 void LOKitSearchTest::testSearchInPDFInMultiplePagesBackwards()
504 {
505     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
506     if (!pPdfium)
507     {
508         return;
509     }
510 
511     SdXImpressDocument* pXImpressDocument = createDoc("PDFSearch.pdf");
512     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
513     CPPUNIT_ASSERT(pViewShell);
514     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
515 
516     SdPage* pPage = pViewShell->GetActualPage();
517     CPPUNIT_ASSERT(pPage);
518 
519     {
520         SdrObject* pObject = pPage->GetObj(0);
521         CPPUNIT_ASSERT(pObject);
522 
523         SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
524         CPPUNIT_ASSERT(pGraphicObject);
525 
526         Graphic aGraphic = pGraphicObject->GetGraphic();
527         auto const& pVectorGraphicData = aGraphic.getVectorGraphicData();
528         CPPUNIT_ASSERT(pVectorGraphicData);
529         CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType());
530     }
531 
532     // Expected for backwards search is:
533     // - Start with Page 1
534     //   + search backwards through objects
535     //   + inside objects search backwards through text
536     // - Switch to Page 2
537     //   + search backwards through objects
538     //   + inside objects search backwards through text
539 
540     // Search for "him"
541     lcl_search("him", /*FindAll*/ false, /*Backwards*/ true);
542 
543     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
544     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_nSearchResultCount);
545 
546     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
547     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
548 
549     CPPUNIT_ASSERT_EQUAL(0, mpCallbackRecorder->m_aSearchResultPart[0]);
550     CPPUNIT_ASSERT_EQUAL(OString("5592, 5038, 1100, 499"),
551                          mpCallbackRecorder->m_aSearchResultSelection[0]);
552 
553     // Search for "him"
554     lcl_search("him", /*FindAll*/ false, /*Backwards*/ true);
555 
556     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
557     CPPUNIT_ASSERT_EQUAL(2, mpCallbackRecorder->m_nSearchResultCount);
558 
559     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
560     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
561 
562     CPPUNIT_ASSERT_EQUAL(0, mpCallbackRecorder->m_aSearchResultPart[0]);
563     CPPUNIT_ASSERT_EQUAL(OString("9463, 3382, 1099, 499"),
564                          mpCallbackRecorder->m_aSearchResultSelection[0]);
565 
566     // Search for "him"
567     lcl_search("him", /*FindAll*/ false, /*Backwards*/ true);
568 
569     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
570     CPPUNIT_ASSERT_EQUAL(3, mpCallbackRecorder->m_nSearchResultCount);
571 
572     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
573     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
574 
575     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_aSearchResultPart[0]);
576     CPPUNIT_ASSERT_EQUAL(OString("5592, 2964, 1100, 499"),
577                          mpCallbackRecorder->m_aSearchResultSelection[0]);
578 
579     // Search for "him"
580     lcl_search("him", /*FindAll*/ false, /*Backwards*/ true);
581 
582     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
583     CPPUNIT_ASSERT_EQUAL(4, mpCallbackRecorder->m_nSearchResultCount);
584 
585     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
586     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
587 
588     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_aSearchResultPart[0]);
589     CPPUNIT_ASSERT_EQUAL(OString("9463, 1308, 1099, 499"),
590                          mpCallbackRecorder->m_aSearchResultSelection[0]);
591 
592     // Search for "him" - back to start
593     lcl_search("him", /*FindAll*/ false, /*Backwards*/ true);
594 
595     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
596     CPPUNIT_ASSERT_EQUAL(5, mpCallbackRecorder->m_nSearchResultCount);
597 
598     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
599     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
600 
601     CPPUNIT_ASSERT_EQUAL(0, mpCallbackRecorder->m_aSearchResultPart[0]);
602     CPPUNIT_ASSERT_EQUAL(OString("5592, 5038, 1100, 499"),
603                          mpCallbackRecorder->m_aSearchResultSelection[0]);
604 }
605 
606 // Test searching in document with mixed objects.
607 // We have 2 objects: 1. Text Object, 2. Graphic Object with PDF
testSearchIn2MixedObjects()608 void LOKitSearchTest::testSearchIn2MixedObjects()
609 {
610     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
611     if (!pPdfium)
612     {
613         return;
614     }
615 
616     SdXImpressDocument* pXImpressDocument = createDoc("MixedTest1.odg");
617     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
618     CPPUNIT_ASSERT(pViewShell);
619     SdDrawDocument* pDocument = pXImpressDocument->GetDocShell()->GetDoc();
620     CPPUNIT_ASSERT(pDocument);
621     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
622 
623     // Check we have one page
624     CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pDocument->GetSdPageCount(PageKind::Standard));
625 
626     SdPage* pPage = pViewShell->GetActualPage();
627     CPPUNIT_ASSERT(pPage);
628 
629     // Check page has 2 objects only
630     CPPUNIT_ASSERT_EQUAL(size_t(2), pPage->GetObjCount());
631 
632     // Check Object 1
633     {
634         SdrObject* pObject = pPage->GetObj(0);
635         CPPUNIT_ASSERT(pObject);
636 
637         CPPUNIT_ASSERT_EQUAL(OBJ_TEXT, pObject->GetObjIdentifier());
638     }
639 
640     // Check Object 2
641     {
642         SdrObject* pObject = pPage->GetObj(1);
643         CPPUNIT_ASSERT(pObject);
644 
645         CPPUNIT_ASSERT_EQUAL(OBJ_GRAF, pObject->GetObjIdentifier());
646 
647         SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
648         CPPUNIT_ASSERT(pGraphicObject);
649 
650         Graphic aGraphic = pGraphicObject->GetGraphic();
651         auto const& pVectorGraphicData = aGraphic.getVectorGraphicData();
652         CPPUNIT_ASSERT(pVectorGraphicData);
653 
654         CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType());
655     }
656 
657     // Let's try to search now
658 
659     lcl_search("ABC");
660 
661     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
662     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_nSearchResultCount);
663 
664     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
665     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
666 
667     CPPUNIT_ASSERT_EQUAL(OString("3546, 3174, 738, 402"),
668                          mpCallbackRecorder->m_aSearchResultSelection[0]);
669 
670     // Search next
671 
672     lcl_search("ABC");
673 
674     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
675     CPPUNIT_ASSERT_EQUAL(2, mpCallbackRecorder->m_nSearchResultCount);
676 
677     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
678     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
679 
680     CPPUNIT_ASSERT_EQUAL(OString("8412, 6385, 519, 174"),
681                          mpCallbackRecorder->m_aSearchResultSelection[0]);
682 
683     // Search next again - we should get the first object again
684 
685     lcl_search("ABC");
686 
687     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
688     CPPUNIT_ASSERT_EQUAL(3, mpCallbackRecorder->m_nSearchResultCount);
689 
690     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
691     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
692 
693     CPPUNIT_ASSERT_EQUAL(OString("3546, 3174, 738, 402"),
694                          mpCallbackRecorder->m_aSearchResultSelection[0]);
695 }
696 
697 // Test searching in document with mixed objects. We have 6 objects.
testSearchIn6MixedObjects()698 void LOKitSearchTest::testSearchIn6MixedObjects()
699 {
700     auto pPdfium = vcl::pdf::PDFiumLibrary::get();
701     if (!pPdfium)
702     {
703         return;
704     }
705 
706     SdXImpressDocument* pXImpressDocument = createDoc("MixedTest2.odg");
707     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
708     CPPUNIT_ASSERT(pViewShell);
709     SdDrawDocument* pDocument = pXImpressDocument->GetDocShell()->GetDoc();
710     CPPUNIT_ASSERT(pDocument);
711     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
712 
713     // Check we have one page
714     CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pDocument->GetSdPageCount(PageKind::Standard));
715 
716     SdPage* pPage = pViewShell->GetActualPage();
717     CPPUNIT_ASSERT(pPage);
718 
719     // Check page has 6 objects only
720     CPPUNIT_ASSERT_EQUAL(size_t(6), pPage->GetObjCount());
721 
722     // Check we have the right objects that we expect
723 
724     // Check Object 1
725     {
726         SdrObject* pObject = pPage->GetObj(0);
727         CPPUNIT_ASSERT(pObject);
728         CPPUNIT_ASSERT_EQUAL(OBJ_TEXT, pObject->GetObjIdentifier());
729     }
730 
731     // Check Object 2
732     {
733         SdrObject* pObject = pPage->GetObj(1);
734         CPPUNIT_ASSERT(pObject);
735         CPPUNIT_ASSERT_EQUAL(OBJ_GRAF, pObject->GetObjIdentifier());
736         SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
737         CPPUNIT_ASSERT(pGraphicObject);
738         auto const& pVectorGraphicData = pGraphicObject->GetGraphic().getVectorGraphicData();
739         CPPUNIT_ASSERT(pVectorGraphicData);
740         CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType());
741     }
742 
743     // Check Object 3
744     {
745         SdrObject* pObject = pPage->GetObj(2);
746         CPPUNIT_ASSERT(pObject);
747         CPPUNIT_ASSERT_EQUAL(OBJ_CUSTOMSHAPE, pObject->GetObjIdentifier());
748     }
749 
750     // Check Object 4
751     {
752         SdrObject* pObject = pPage->GetObj(3);
753         CPPUNIT_ASSERT(pObject);
754         CPPUNIT_ASSERT_EQUAL(OBJ_CUSTOMSHAPE, pObject->GetObjIdentifier());
755     }
756 
757     // Check Object 5
758     {
759         SdrObject* pObject = pPage->GetObj(4);
760         CPPUNIT_ASSERT(pObject);
761         CPPUNIT_ASSERT_EQUAL(OBJ_GRAF, pObject->GetObjIdentifier());
762         SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
763         CPPUNIT_ASSERT(pGraphicObject);
764         auto const& pVectorGraphicData = pGraphicObject->GetGraphic().getVectorGraphicData();
765         CPPUNIT_ASSERT(pVectorGraphicData);
766         CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Svg, pVectorGraphicData->getType());
767     }
768 
769     // Check Object 6
770     {
771         SdrObject* pObject = pPage->GetObj(5);
772         CPPUNIT_ASSERT(pObject);
773         CPPUNIT_ASSERT_EQUAL(OBJ_GRAF, pObject->GetObjIdentifier());
774         SdrGrafObj* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
775         CPPUNIT_ASSERT(pGraphicObject);
776         auto const& pVectorGraphicData = pGraphicObject->GetGraphic().getVectorGraphicData();
777         CPPUNIT_ASSERT(pVectorGraphicData);
778         CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType());
779     }
780 
781     // Search "ABC" which is in all objects (2 times in Object 3)
782 
783     // Object 1
784     lcl_search("ABC");
785 
786     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
787     CPPUNIT_ASSERT_EQUAL(1, mpCallbackRecorder->m_nSearchResultCount);
788 
789     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
790     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
791     CPPUNIT_ASSERT_EQUAL(pPage->GetObj(0), lclGetSelectedObject(pViewShell));
792 
793     // Object 2
794     lcl_search("ABC");
795 
796     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
797     CPPUNIT_ASSERT_EQUAL(2, mpCallbackRecorder->m_nSearchResultCount);
798 
799     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
800     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
801     CPPUNIT_ASSERT_EQUAL(pPage->GetObj(1), lclGetSelectedObject(pViewShell));
802 
803     // Object 3
804     lcl_search("ABC");
805 
806     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
807     CPPUNIT_ASSERT_EQUAL(3, mpCallbackRecorder->m_nSearchResultCount);
808 
809     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
810     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
811     CPPUNIT_ASSERT_EQUAL(pPage->GetObj(2), lclGetSelectedObject(pViewShell));
812 
813     // Object 3 again
814     lcl_search("ABC");
815 
816     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
817     CPPUNIT_ASSERT_EQUAL(4, mpCallbackRecorder->m_nSearchResultCount);
818 
819     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
820     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
821     CPPUNIT_ASSERT_EQUAL(pPage->GetObj(2), lclGetSelectedObject(pViewShell));
822 
823     // Object 4
824     lcl_search("ABC");
825 
826     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
827     CPPUNIT_ASSERT_EQUAL(5, mpCallbackRecorder->m_nSearchResultCount);
828 
829     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
830     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
831     CPPUNIT_ASSERT_EQUAL(pPage->GetObj(3), lclGetSelectedObject(pViewShell));
832 
833     // Object 5
834     lcl_search("ABC");
835 
836     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
837     CPPUNIT_ASSERT_EQUAL(6, mpCallbackRecorder->m_nSearchResultCount);
838 
839     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
840     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
841     CPPUNIT_ASSERT_EQUAL(pPage->GetObj(4), lclGetSelectedObject(pViewShell));
842 
843     // Object 6
844     lcl_search("ABC");
845 
846     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
847     CPPUNIT_ASSERT_EQUAL(7, mpCallbackRecorder->m_nSearchResultCount);
848 
849     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
850     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
851     CPPUNIT_ASSERT_EQUAL(pPage->GetObj(5), lclGetSelectedObject(pViewShell));
852 
853     // Loop to Object 1 again
854     lcl_search("ABC");
855 
856     CPPUNIT_ASSERT_EQUAL(true, mpCallbackRecorder->m_bFound);
857     CPPUNIT_ASSERT_EQUAL(8, mpCallbackRecorder->m_nSearchResultCount);
858 
859     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultSelection.size());
860     CPPUNIT_ASSERT_EQUAL(size_t(1), mpCallbackRecorder->m_aSearchResultPart.size());
861     CPPUNIT_ASSERT_EQUAL(pPage->GetObj(0), lclGetSelectedObject(pViewShell));
862 }
863 namespace
864 {
getShapeText(SdXImpressDocument * pXImpressDocument,sal_uInt32 nPage,sal_uInt32 nShape)865 OUString getShapeText(SdXImpressDocument* pXImpressDocument, sal_uInt32 nPage, sal_uInt32 nShape)
866 {
867     uno::Reference<container::XIndexAccess> xDrawPage;
868     xDrawPage.set(pXImpressDocument->getDrawPages()->getByIndex(nPage), uno::UNO_QUERY);
869 
870     uno::Reference<text::XTextRange> xShape(xDrawPage->getByIndex(nShape), uno::UNO_QUERY);
871     return xShape->getString();
872 }
873 }
874 
testReplace()875 void LOKitSearchTest::testReplace()
876 {
877     SdXImpressDocument* pXImpressDocument = createDoc("ReplaceTest.odp");
878     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
879     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
880 
881     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 0, 0));
882     CPPUNIT_ASSERT_EQUAL(OUString("Bbb bbb bbb bbb"), getShapeText(pXImpressDocument, 1, 0));
883     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 2, 0));
884     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 3, 0));
885     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 4, 0));
886 
887     lcl_replace("bbb", "aaa", false); // select
888 
889     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 0, 0));
890     CPPUNIT_ASSERT_EQUAL(OUString("Bbb bbb bbb bbb"), getShapeText(pXImpressDocument, 1, 0));
891     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 2, 0));
892     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 3, 0));
893     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 4, 0));
894 
895     lcl_replace("bbb", "aaa", false); // replace
896 
897     CPPUNIT_ASSERT_EQUAL(OUString("aaa"), getShapeText(pXImpressDocument, 0, 0));
898     CPPUNIT_ASSERT_EQUAL(OUString("Bbb bbb bbb bbb"), getShapeText(pXImpressDocument, 1, 0));
899     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 2, 0));
900     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 3, 0));
901     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 4, 0));
902 }
903 
testReplaceAll()904 void LOKitSearchTest::testReplaceAll()
905 {
906     SdXImpressDocument* pXImpressDocument = createDoc("ReplaceTest.odp");
907     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
908     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
909 
910     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 0, 0));
911     CPPUNIT_ASSERT_EQUAL(OUString("Bbb bbb bbb bbb"), getShapeText(pXImpressDocument, 1, 0));
912     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 2, 0));
913     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 3, 0));
914     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 4, 0));
915 
916     lcl_replace("bbb", "ccc", true);
917 
918     CPPUNIT_ASSERT_EQUAL(OUString("ccc"), getShapeText(pXImpressDocument, 0, 0));
919     CPPUNIT_ASSERT_EQUAL(OUString("ccc ccc ccc ccc"), getShapeText(pXImpressDocument, 1, 0));
920     CPPUNIT_ASSERT_EQUAL(OUString("ccc"), getShapeText(pXImpressDocument, 2, 0));
921     CPPUNIT_ASSERT_EQUAL(OUString("ccc"), getShapeText(pXImpressDocument, 3, 0));
922     CPPUNIT_ASSERT_EQUAL(OUString("ccc"), getShapeText(pXImpressDocument, 4, 0));
923 
924     lcl_replace("ccc", "bbb", true);
925 
926     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 0, 0));
927     CPPUNIT_ASSERT_EQUAL(OUString("bbb bbb bbb bbb"), getShapeText(pXImpressDocument, 1, 0));
928     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 2, 0));
929     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 3, 0));
930     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 4, 0));
931 }
932 
testReplaceCombined()933 void LOKitSearchTest::testReplaceCombined()
934 {
935     SdXImpressDocument* pXImpressDocument = createDoc("ReplaceTest.odp");
936     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
937     mpCallbackRecorder->registerCallbacksFor(pViewShell->GetViewShellBase());
938 
939     lcl_replace("bbb", "aaa", false); // select
940     lcl_replace("bbb", "aaa", false); // replace
941 
942     CPPUNIT_ASSERT_EQUAL(OUString("aaa"), getShapeText(pXImpressDocument, 0, 0));
943     CPPUNIT_ASSERT_EQUAL(OUString("Bbb bbb bbb bbb"), getShapeText(pXImpressDocument, 1, 0));
944     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 2, 0));
945     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 3, 0));
946     CPPUNIT_ASSERT_EQUAL(OUString("bbb"), getShapeText(pXImpressDocument, 4, 0));
947 
948     lcl_replace("bbb", "ccc", true);
949 
950     CPPUNIT_ASSERT_EQUAL(OUString("aaa"), getShapeText(pXImpressDocument, 0, 0));
951     CPPUNIT_ASSERT_EQUAL(OUString("ccc ccc ccc ccc"), getShapeText(pXImpressDocument, 1, 0));
952     CPPUNIT_ASSERT_EQUAL(OUString("ccc"), getShapeText(pXImpressDocument, 2, 0));
953     CPPUNIT_ASSERT_EQUAL(OUString("ccc"), getShapeText(pXImpressDocument, 3, 0));
954     CPPUNIT_ASSERT_EQUAL(OUString("ccc"), getShapeText(pXImpressDocument, 4, 0));
955 }
956 
957 CPPUNIT_TEST_SUITE_REGISTRATION(LOKitSearchTest);
958 
959 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
960