Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / qa / extras / uiwriter / uiwriter8.cxx
bloba669192fdc25b32f18313d296f0bc4c88c545821
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <swmodeltestbase.hxx>
11 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
12 #include <vcl/filter/PDFiumLibrary.hxx>
13 #include <vcl/scheduler.hxx>
14 #include <vcl/TypeSerializer.hxx>
15 #include <com/sun/star/awt/FontWeight.hpp>
16 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
17 #include <IDocumentDrawModelAccess.hxx>
18 #include <com/sun/star/text/XTextTable.hpp>
19 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
20 #include <com/sun/star/text/XPageCursor.hpp>
21 #include <comphelper/propertysequence.hxx>
22 #include <boost/property_tree/json_parser.hpp>
23 #include <frameformats.hxx>
24 #include <tools/json_writer.hxx>
25 #include <unotools/streamwrap.hxx>
26 #include <sfx2/linkmgr.hxx>
28 #include <wrtsh.hxx>
29 #include <unotxdoc.hxx>
30 #include <drawdoc.hxx>
31 #include <dcontact.hxx>
32 #include <svx/svdpage.hxx>
33 #include <ndtxt.hxx>
34 #include <txtfld.hxx>
35 #include <IDocumentFieldsAccess.hxx>
36 #include <IDocumentLinksAdministration.hxx>
37 #include <IDocumentRedlineAccess.hxx>
38 #include <rootfrm.hxx>
39 #include <redline.hxx>
40 #include <itabenum.hxx>
41 #include <officecfg/Office/Common.hxx>
43 /// 8th set of tests asserting the behavior of Writer user interface shells.
44 class SwUiWriterTest8 : public SwModelTestBase
46 public:
47 SwUiWriterTest8()
48 : SwModelTestBase("/sw/qa/extras/uiwriter/data/")
53 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf131684)
55 createSwDoc("tdf131684.docx");
57 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
58 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
59 uno::UNO_QUERY);
60 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
62 //Use selectAll 3 times in a row
63 dispatchCommand(mxComponent, ".uno:SelectAll", {});
64 dispatchCommand(mxComponent, ".uno:SelectAll", {});
65 dispatchCommand(mxComponent, ".uno:SelectAll", {});
67 dispatchCommand(mxComponent, ".uno:Cut", {});
68 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());
70 dispatchCommand(mxComponent, ".uno:Undo", {});
71 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
73 dispatchCommand(mxComponent, ".uno:Paste", {});
74 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
76 // without the fix, it crashes
77 dispatchCommand(mxComponent, ".uno:Undo", {});
78 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
80 // check that the text frame has the correct upper
81 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
82 OUString const sectionId = getXPath(pXmlDoc, "/root/page[1]/body/section[7]", "id");
83 OUString const sectionLower = getXPath(pXmlDoc, "/root/page[1]/body/section[7]", "lower");
84 OUString const textId = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]", "id");
85 OUString const textUpper = getXPath(pXmlDoc, "/root/page[1]/body/section[7]/txt[1]", "upper");
86 CPPUNIT_ASSERT_EQUAL(textId, sectionLower);
87 CPPUNIT_ASSERT_EQUAL(sectionId, textUpper);
90 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132420)
92 createSwDoc("tdf132420.odt");
94 CPPUNIT_ASSERT_EQUAL(12, getShapes());
96 dispatchCommand(mxComponent, ".uno:SelectAll", {});
98 dispatchCommand(mxComponent, ".uno:Cut", {});
99 CPPUNIT_ASSERT_EQUAL(0, getShapes());
101 dispatchCommand(mxComponent, ".uno:Undo", {});
103 //Without the fix in place, 1 frame and 1 image would be gone and getShapes would return 10
104 CPPUNIT_ASSERT_EQUAL(12, getShapes());
107 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132744)
109 createSwDoc("tdf132744.odt");
110 SwDoc* pDoc = getSwDoc();
112 // disable change tracking to cut the table
113 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
114 | RedlineFlags::ShowInsert);
116 CPPUNIT_ASSERT_MESSAGE("redlining should be off",
117 !pDoc->getIDocumentRedlineAccess().IsRedlineOn());
119 CPPUNIT_ASSERT_EQUAL(1, getShapes());
121 dispatchCommand(mxComponent, ".uno:SelectAll", {});
123 dispatchCommand(mxComponent, ".uno:Cut", {});
125 CPPUNIT_ASSERT_EQUAL(0, getShapes());
127 dispatchCommand(mxComponent, ".uno:Paste", {});
129 //Without the fix in place, the image wouldn't be pasted
130 CPPUNIT_ASSERT_EQUAL(1, getShapes());
133 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146622)
135 createSwDoc("TC-table-del-add.docx");
136 SwDoc* pDoc = getSwDoc();
137 CPPUNIT_ASSERT(pDoc);
138 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
139 CPPUNIT_ASSERT(pWrtShell);
141 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
142 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
144 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
145 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
146 uno::UNO_QUERY);
147 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount());
148 uno::Reference<container::XNameAccess> xTableNames = xTablesSupplier->getTextTables();
149 CPPUNIT_ASSERT(xTableNames->hasByName("Table1"));
150 uno::Reference<text::XTextTable> xTable1(xTableNames->getByName("Table1"), uno::UNO_QUERY);
151 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
153 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
155 // This was 3 (deleting the already deleted row with change tracking)
156 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
158 dispatchCommand(mxComponent, ".uno:SelectAll", {});
159 dispatchCommand(mxComponent, ".uno:SelectAll", {});
161 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
162 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
164 dispatchCommand(mxComponent, ".uno:SelectAll", {});
165 dispatchCommand(mxComponent, ".uno:SelectAll", {});
167 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
168 // This was 2 (deleting the already deleted table with change tracking)
169 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount());
170 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getRows()->getCount());
172 // check that the first table was deleted with change tracking
173 dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
174 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
176 // Undo AcceptAllTrackedChanges and DeleteRows
177 dispatchCommand(mxComponent, ".uno:Undo", {});
178 dispatchCommand(mxComponent, ".uno:Undo", {});
180 // now only the second table deleted by AcceptAllTrackedChanges
181 dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
182 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount());
185 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146962)
187 // load a 2-row table, set Hide Changes mode and delete the first row with change tracking
188 createSwDoc("tdf116789.fodt");
189 SwDoc* pDoc = getSwDoc();
190 CPPUNIT_ASSERT(pDoc);
191 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
192 CPPUNIT_ASSERT(pWrtShell);
194 // enable redlining
195 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
196 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
197 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
198 // hide changes
199 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
200 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
202 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
204 // Without the fix in place, the deleted row would be visible
206 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
207 // This was 2
208 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);
210 // check it in Show Changes mode
212 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
213 CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());
215 discardDumpedLayout();
216 pXmlDoc = parseLayoutDump();
217 // 2 rows are visible now
218 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
220 // check it in Hide Changes mode again
222 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
223 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
225 discardDumpedLayout();
226 pXmlDoc = parseLayoutDump();
227 // only a single row is visible again
228 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);
230 // tdf#148227 check Undo of tracked table row deletion
232 dispatchCommand(mxComponent, ".uno:Undo", {});
233 discardDumpedLayout();
234 pXmlDoc = parseLayoutDump();
235 // This was 1
236 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
239 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf147347)
241 // load a 2-row table, set Hide Changes mode and delete the table with change tracking
242 createSwDoc("tdf116789.fodt");
243 SwDoc* pDoc = getSwDoc();
244 CPPUNIT_ASSERT(pDoc);
245 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
246 CPPUNIT_ASSERT(pWrtShell);
248 // enable redlining
249 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
250 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
251 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
252 // hide changes
253 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
254 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
256 dispatchCommand(mxComponent, ".uno:DeleteTable", {});
258 // Without the fix in place, the deleted row would be visible
260 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
261 // This was 1
262 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 0);
264 // check it in Show Changes mode
266 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
267 CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());
269 discardDumpedLayout();
270 pXmlDoc = parseLayoutDump();
271 // 2 rows are visible now
272 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
274 // check it in Hide Changes mode again
276 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
277 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
279 discardDumpedLayout();
280 pXmlDoc = parseLayoutDump();
281 // no visible row again
282 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 0);
284 // tdf#148228 check Undo of tracked table deletion
286 dispatchCommand(mxComponent, ".uno:Undo", {});
287 discardDumpedLayout();
288 pXmlDoc = parseLayoutDump();
289 // This was 0
290 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
293 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf153819)
295 // copy a table before a deleted table in Hide Changes mode
296 createSwDoc("tdf153819.fodt");
297 SwDoc* pDoc = getSwDoc();
298 CPPUNIT_ASSERT(pDoc);
299 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
300 CPPUNIT_ASSERT(pWrtShell);
302 // hide changes
303 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
305 dispatchCommand(mxComponent, ".uno:SelectTable", {});
306 dispatchCommand(mxComponent, ".uno:Copy", {});
307 dispatchCommand(mxComponent, ".uno:GoDown", {});
309 // Without the fix in place, this test would have crashed here
310 dispatchCommand(mxComponent, ".uno:Paste", {});
312 // FIXME: Show Changes, otherwise ~SwTableNode() would have crashed
313 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
316 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148345)
318 // load a 2-row table, set Hide Changes mode and delete the first row with change tracking
319 createSwDoc("tdf116789.fodt");
320 SwDoc* pDoc = getSwDoc();
321 CPPUNIT_ASSERT(pDoc);
322 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
323 CPPUNIT_ASSERT(pWrtShell);
325 // enable redlining
326 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
327 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
328 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
329 // hide changes
330 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
331 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
333 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
335 // Without the fix in place, the deleted row would be visible
337 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
338 // This was 2
339 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);
341 // check it in Show Changes mode
343 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
344 CPPUNIT_ASSERT(!pWrtShell->GetLayout()->IsHideRedlines());
346 discardDumpedLayout();
347 pXmlDoc = parseLayoutDump();
348 // 2 rows are visible now
349 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
351 // check it in Hide Changes mode again
353 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
354 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
356 discardDumpedLayout();
357 pXmlDoc = parseLayoutDump();
358 // only a single row is visible again
359 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 1);
361 // tdf#148227 check Reject All of tracked table row deletion
363 dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
364 discardDumpedLayout();
365 pXmlDoc = parseLayoutDump();
366 // This was 1
367 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
370 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf141391)
372 // table insertion in the first paragraph of the cell
373 // overwrites the row content, instead of inserting a nested table
375 // load a 2-row table
376 createSwDoc("tdf116789.fodt");
377 SwDoc* pDoc = getSwDoc();
378 CPPUNIT_ASSERT(pDoc);
379 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
380 CPPUNIT_ASSERT(pWrtShell);
382 // select the table, and copy it into at paragraph start of cell "A2"
384 dispatchCommand(mxComponent, ".uno:SelectTable", {});
385 dispatchCommand(mxComponent, ".uno:Copy", {});
386 // remove the selection and positionate the cursor at beginning of A2
387 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
388 dispatchCommand(mxComponent, ".uno:Paste", {});
390 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
391 // 3-row, overwriting cells of the second row and inserting a new row
392 // with the 2-row clipboard table content
393 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3);
394 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout",
395 "portion", "hello");
397 // Undo
399 dispatchCommand(mxComponent, ".uno:Undo", {});
400 discardDumpedLayout();
401 pXmlDoc = parseLayoutDump();
402 // 2 rows again, no copied text content
403 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
404 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/SwParaPortion", 0);
406 // insert the 2-row table into the second paragraph of cell "A2" as a nested table
407 // For this it's enough to positionate the text cursor not in the first paragraph
409 // insert some text and an empty paragraph
410 pWrtShell->Insert("Some text...");
411 pWrtShell->SplitNode();
412 Scheduler::ProcessEventsToIdle();
413 discardDumpedLayout();
414 pXmlDoc = parseLayoutDump();
415 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
416 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt", 2);
417 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/SwParaPortion/SwLineLayout",
418 "portion", "Some text...");
419 // the empty paragraph in A2
420 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[2]/SwParaPortion", 0);
422 // insert the table, as a nested one in cell "A2"
423 dispatchCommand(mxComponent, ".uno:Paste", {});
424 discardDumpedLayout();
425 pXmlDoc = parseLayoutDump();
426 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
427 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab", 1);
428 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/tab/row", 2);
430 // Undo
432 dispatchCommand(mxComponent, ".uno:Undo", {});
433 discardDumpedLayout();
434 pXmlDoc = parseLayoutDump();
435 // 2 rows again, no copied text content
436 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 2);
437 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt[1]/SwParaPortion/SwLineLayout",
438 "portion", "Some text...");
440 // copy the 2-row table into the fist paragraph of cell "A2",
441 // but not at paragraph start (changed behaviour)
443 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
444 pWrtShell->Insert("and some text again in the first paragraph to be sure...");
445 dispatchCommand(mxComponent, ".uno:Paste", {});
447 discardDumpedLayout();
448 pXmlDoc = parseLayoutDump();
450 // 3-row, overwriting cells of the second row and inserting a new row
451 // with the 2-row clipboard table content
453 // This was 2 (nested table)
454 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 3);
455 // This was "Some text..." with a nested table
456 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout",
457 "portion", "hello");
460 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148791)
462 // test Paste as Rows Above with centered table alignment
464 // load a 2-row table
465 createSwDoc("tdf116789.fodt");
466 SwDoc* pDoc = getSwDoc();
467 CPPUNIT_ASSERT(pDoc);
468 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
469 CPPUNIT_ASSERT(pWrtShell);
471 // select and copy the table, and Paste As Rows Above
473 dispatchCommand(mxComponent, ".uno:SelectTable", {});
474 dispatchCommand(mxComponent, ".uno:Copy", {});
475 // remove the selection and positionate the cursor at beginning of A2
476 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
477 pWrtShell->Up(/*bSelect=*/false);
478 dispatchCommand(mxComponent, ".uno:PasteRowsBefore", {});
480 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
481 // Paste as Rows Above results 4-row table with default table alignment
482 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 4);
483 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/SwParaPortion/SwLineLayout",
484 "portion", "hello");
485 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/SwParaPortion/SwLineLayout",
486 "portion", "hello");
488 // set table alignment to center, select and copy the table again
489 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
490 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
491 uno::UNO_QUERY);
492 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
494 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
496 // Default table alignment
497 CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::FULL,
498 getProperty<sal_Int16>(xTextTable, "HoriOrient"));
500 //CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xTextTable, "TableTemplateName"));
501 uno::Reference<beans::XPropertySet> xTableProps(xTextTable, uno::UNO_QUERY_THROW);
503 xTableProps->setPropertyValue("HoriOrient", uno::Any(text::HoriOrientation::CENTER));
505 CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER,
506 getProperty<sal_Int16>(xTextTable, "HoriOrient"));
508 dispatchCommand(mxComponent, ".uno:SelectTable", {});
509 dispatchCommand(mxComponent, ".uno:Copy", {});
510 // remove the selection and positionate the cursor at beginning of A2
511 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
512 pWrtShell->Up(/*bSelect=*/false);
513 pWrtShell->Up(/*bSelect=*/false);
514 pWrtShell->Up(/*bSelect=*/false);
515 dispatchCommand(mxComponent, ".uno:PasteRowsBefore", {});
517 discardDumpedLayout();
518 pXmlDoc = parseLayoutDump();
519 // This was 5 (inserting only a single row for the 4-row clipboard content, and
520 // overwriting 3 existing rows)
521 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 8);
522 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[1]/cell[1]/txt/SwParaPortion/SwLineLayout",
523 "portion", "hello");
524 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[3]/cell[1]/txt/SwParaPortion/SwLineLayout",
525 "portion", "hello");
526 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[5]/cell[1]/txt/SwParaPortion/SwLineLayout",
527 "portion", "hello");
528 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row[7]/cell[1]/txt/SwParaPortion/SwLineLayout",
529 "portion", "hello");
531 // tdf#64902 add a test case for nested tables
533 // insert a nested table, and copy as paste as rows above the whole table with it
534 dispatchCommand(mxComponent, ".uno:PasteNestedTable", {});
535 dispatchCommand(mxComponent, ".uno:SelectTable", {});
536 dispatchCommand(mxComponent, ".uno:Copy", {});
537 // remove the selection and positionate the cursor at beginning of A2
538 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
539 // skip 7 table rows plus 4 rows of the nested table
540 for (int i = 0; i < 7 + 4; ++i)
541 pWrtShell->Up(/*bSelect=*/false);
542 dispatchCommand(mxComponent, ".uno:PasteRowsBefore", {});
544 discardDumpedLayout();
545 pXmlDoc = parseLayoutDump();
546 // rows of the nested table doesn't effect row number of the main table
547 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 16);
548 // there are two nested tables after the paste
549 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 2);
551 // tdf#64902 add a test case for repeated table headings
553 xTableProps->setPropertyValue("RepeatHeadline", uno::Any(true));
554 CPPUNIT_ASSERT(getProperty<bool>(xTextTable, "RepeatHeadline"));
556 xTableProps->setPropertyValue("HeaderRowCount", uno::Any(sal_Int32(3)));
557 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), getProperty<sal_Int32>(xTextTable, "HeaderRowCount"));
559 dispatchCommand(mxComponent, ".uno:SelectTable", {});
560 dispatchCommand(mxComponent, ".uno:Copy", {});
561 // remove the selection and positionate the cursor at beginning of A2
562 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
563 // skip 15 table rows plus 4 * 2 rows of the nested tables
564 for (int i = 0; i < 15 + 4 * 2; ++i)
565 pWrtShell->Up(/*bSelect=*/false);
566 dispatchCommand(mxComponent, ".uno:PasteRowsBefore", {});
568 discardDumpedLayout();
569 pXmlDoc = parseLayoutDump();
570 // repeating table header (and its thead/tbody indentation) doesn't effect row number
571 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 32);
572 // there are two nested tables after the paste
573 assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/cell/tab", 4);
576 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf135014)
578 createSwDoc();
580 uno::Sequence<beans::PropertyValue> aArgs(
581 comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(sal_Int32(0)) } }));
583 // Toggle Numbering List
584 dispatchCommand(mxComponent, ".uno:DefaultBullet", aArgs);
586 uno::Sequence<beans::PropertyValue> aArgs2(comphelper::InitPropertySequence(
587 { { "Param", uno::Any(OUString("NewNumberingStyle")) },
588 { "Family", uno::Any(static_cast<sal_Int16>(SfxStyleFamily::Pseudo)) } }));
590 // New Style from selection
591 dispatchCommand(mxComponent, ".uno:StyleNewByExample", aArgs2);
593 // Without the fix in place, this test would have failed here
594 saveAndReload("Office Open XML Text");
596 xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
597 assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='NewNumberingStyle']/w:qFormat", 1);
600 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf130629)
602 createSwDoc();
603 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
605 uno::Sequence<beans::PropertyValue> aArgs(
606 comphelper::InitPropertySequence({ { "KeyModifier", uno::Any(KEY_MOD1) } }));
608 dispatchCommand(mxComponent, ".uno:BasicShapes.diamond", aArgs);
610 CPPUNIT_ASSERT_EQUAL(1, getShapes());
612 // Undo twice
613 dispatchCommand(mxComponent, ".uno:Undo", {});
614 dispatchCommand(mxComponent, ".uno:Undo", {});
616 CPPUNIT_ASSERT_EQUAL(0, getShapes());
618 // Shape toolbar is active, use ESC before inserting a new shape
619 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE);
620 Scheduler::ProcessEventsToIdle();
622 // Without the fix in place, this test would have crashed here
623 dispatchCommand(mxComponent, ".uno:BasicShapes.diamond", aArgs);
625 CPPUNIT_ASSERT_EQUAL(1, getShapes());
628 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf145584)
630 std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
631 if (!pPDFium)
633 return;
635 createSwDoc();
636 SwDoc* const pDoc = getSwDoc();
637 SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
638 CPPUNIT_ASSERT(pWrtSh);
640 pWrtSh->Insert("Hello World");
642 // Select 'World'
643 pWrtSh->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 5, /*bBasicCall=*/false);
645 // Save as PDF.
646 uno::Sequence<beans::PropertyValue> aFilterData(
647 comphelper::InitPropertySequence({ { "Selection", uno::Any(true) } }));
649 uno::Sequence<beans::PropertyValue> aDescriptor(comphelper::InitPropertySequence(
650 { { "FilterName", uno::Any(OUString("writer_pdf_Export")) },
651 { "FilterData", uno::Any(aFilterData) },
652 { "URL", uno::Any(maTempFile.GetURL()) } }));
654 // Without the fix in place, this test would have crashed here
655 dispatchCommand(mxComponent, ".uno:ExportToPDF", aDescriptor);
657 std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
658 CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
659 std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/0);
660 CPPUNIT_ASSERT(pPdfPage);
661 CPPUNIT_ASSERT_EQUAL(1, pPdfPage->getObjectCount());
662 std::unique_ptr<vcl::pdf::PDFiumTextPage> pPdfTextPage = pPdfPage->getTextPage();
663 CPPUNIT_ASSERT(pPdfTextPage);
665 std::unique_ptr<vcl::pdf::PDFiumPageObject> pPageObject = pPdfPage->getObject(0);
666 OUString sText = pPageObject->getText(pPdfTextPage);
667 CPPUNIT_ASSERT_EQUAL(OUString("World"), sText);
670 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf152575)
672 std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get();
673 if (!pPDFium)
674 return;
676 createSwDoc("152575.fodt");
678 // Save as PDF.
679 uno::Sequence<beans::PropertyValue> aFilterData(
680 comphelper::InitPropertySequence({ { "ExportNotesInMargin", uno::Any(true) } }));
682 uno::Sequence<beans::PropertyValue> aDescriptor(comphelper::InitPropertySequence(
683 { { "FilterName", uno::Any(OUString("writer_pdf_Export")) },
684 { "FilterData", uno::Any(aFilterData) },
685 { "URL", uno::Any(maTempFile.GetURL()) } }));
687 // Without the fix in place, this test would have crashed here
688 dispatchCommand(mxComponent, ".uno:ExportToPDF", aDescriptor);
690 std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport();
691 CPPUNIT_ASSERT_EQUAL(3, pPdfDocument->getPageCount());
692 std::unique_ptr<vcl::pdf::PDFiumPage> pPdfPage = pPdfDocument->openPage(/*nIndex=*/1);
693 CPPUNIT_ASSERT(pPdfPage);
694 // Without the fix for tdf#152575 this would be only 42 objects
695 CPPUNIT_ASSERT_EQUAL(51, pPdfPage->getObjectCount());
698 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf140731)
700 createSwDoc();
701 SwDoc* const pDoc = getSwDoc();
702 SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
703 CPPUNIT_ASSERT(pWrtSh);
705 pWrtSh->Insert("Lorem");
707 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
709 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3);
710 Scheduler::ProcessEventsToIdle();
712 // generating a big text with ~60k words and several paragraphs
713 for (sal_Int32 i = 0; i < 8; ++i)
715 dispatchCommand(mxComponent, ".uno:SelectAll", {});
717 dispatchCommand(mxComponent, ".uno:Copy", {});
719 dispatchCommand(mxComponent, ".uno:Paste", {});
721 dispatchCommand(mxComponent, ".uno:Paste", {});
724 dispatchCommand(mxComponent, ".uno:GoToStartOfDoc", {});
726 // Format->Text operations on small selections (which would generate <~500 redlines)
727 // changetracking still working
728 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
730 SwCursorShell* pShell(pDoc->GetEditShell());
732 pShell->SelectTextModel(1, 500);
734 dispatchCommand(mxComponent, ".uno:ChangeCaseToTitleCase", {});
736 SwEditShell* const pEditShell(pDoc->GetEditShell());
737 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(120),
738 pEditShell->GetRedlineCount());
740 //Removing all the redlines.
741 dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
743 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());
745 dispatchCommand(mxComponent, ".uno:SelectAll", {});
747 dispatchCommand(mxComponent, ".uno:ChangeCaseToTitleCase", {});
749 // Without the fix in place, on big selections writer would freeze. Now it ignores change tracking.
750 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());
752 // The patch has no effects on the Format->Text operations
753 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Lorem Ipsum Dolor Sit Amet"));
755 dispatchCommand(mxComponent, ".uno:ChangeCaseToUpper", {});
757 CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("LOREM IPSUM DOLOR SIT AMET"));
760 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf116315)
762 createSwDoc();
763 SwDoc* const pDoc = getSwDoc();
764 SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
765 CPPUNIT_ASSERT(pWrtSh);
767 pWrtSh->Insert("This is a test");
768 pWrtSh->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 4, /*bBasicCall=*/false);
770 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
771 for (sal_Int32 i = 0; i < 5; ++i)
773 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
774 Scheduler::ProcessEventsToIdle();
776 // Title Case
777 CPPUNIT_ASSERT_EQUAL(OUString("This is a Test"), getParagraph(1)->getString());
779 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
780 Scheduler::ProcessEventsToIdle();
782 // Sentence Case
783 // Without the fix in place, this test would have failed with
784 // - Expected: This is a Test
785 // - Actual : This is a TEST
786 CPPUNIT_ASSERT_EQUAL(OUString("This is a Test"), getParagraph(1)->getString());
788 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
789 Scheduler::ProcessEventsToIdle();
791 // Upper Case
792 CPPUNIT_ASSERT_EQUAL(OUString("This is a TEST"), getParagraph(1)->getString());
794 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_F3);
795 Scheduler::ProcessEventsToIdle();
797 // Lower Case
798 CPPUNIT_ASSERT_EQUAL(OUString("This is a test"), getParagraph(1)->getString());
802 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf144364)
804 createSwDoc();
805 SwDoc* const pDoc = getSwDoc();
806 SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
807 CPPUNIT_ASSERT(pWrtSh);
809 // expands autotext (via F3)
810 pWrtSh->Insert("AR");
812 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
813 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3);
814 Scheduler::ProcessEventsToIdle();
816 // was ...'letter of <placeholder:"November 21, 2004":"Click placeholder and overwrite">'
817 CPPUNIT_ASSERT_EQUAL(
818 OUString("We hereby acknowledge the receipt of your letter of <November 21, 2004>."),
819 getParagraph(1)->getString());
822 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146248)
824 createSwDoc("tdf146248.docx");
826 uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
827 uno::UNO_QUERY);
828 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, "HeaderIsOn"));
830 SwDoc* pDoc = getSwDoc();
831 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
833 // Delete the header
834 pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false);
836 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, "HeaderIsOn"));
838 // Without the fix in place, this test would have crashed here
839 dispatchCommand(mxComponent, ".uno:Undo", {});
841 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, "HeaderIsOn"));
844 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf152964)
846 createSwDoc();
848 dispatchCommand(mxComponent, ".uno:TrackChanges", {});
849 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
851 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
852 { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));
854 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
856 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
857 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
858 uno::UNO_QUERY);
859 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
860 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
861 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
862 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
864 SwDoc* pDoc = getSwDoc();
865 SwEditShell* const pEditShell(pDoc->GetEditShell());
866 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
867 dispatchCommand(mxComponent, ".uno:GoDown", {});
868 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
869 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
871 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
873 // Without the fix in place, this test would have crashed here
874 dispatchCommand(mxComponent, ".uno:Undo", {});
876 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
878 dispatchCommand(mxComponent, ".uno:Undo", {});
880 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), pEditShell->GetRedlineCount());
882 dispatchCommand(mxComponent, ".uno:Redo", {});
884 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
885 dispatchCommand(mxComponent, ".uno:Redo", {});
887 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount());
890 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf107427)
892 createSwDoc();
894 dispatchCommand(mxComponent,
895 ".uno:InsertPageHeader?PageStyle:string=Default%20Page%20Style&On:bool=true",
896 {});
897 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
898 { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));
900 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
902 xmlDocUniquePtr pLayout = parseLayoutDump();
903 assertXPath(pLayout, "/root/page[1]/header/tab/row", 2);
905 SwDoc* pDoc = getSwDoc();
906 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
907 // Delete the header
908 pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false);
910 discardDumpedLayout();
911 pLayout = parseLayoutDump();
912 assertXPath(pLayout, "/root/page[1]/header", 0);
914 dispatchCommand(mxComponent, ".uno:Undo", {});
916 discardDumpedLayout();
917 pLayout = parseLayoutDump();
918 assertXPath(pLayout, "/root/page[1]/header/tab/row", 2);
921 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf141613)
923 createSwDoc();
924 SwDoc* const pDoc = getSwDoc();
925 SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
926 CPPUNIT_ASSERT(pWrtSh);
928 pWrtSh->Insert("Test");
930 dispatchCommand(mxComponent,
931 ".uno:InsertPageHeader?PageStyle:string=Default%20Page%20Style&On:bool=true",
932 {});
934 uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
935 uno::UNO_QUERY);
936 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, "HeaderIsOn"));
937 CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString());
939 dispatchCommand(mxComponent, ".uno:Undo", {});
941 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPageStyle, "HeaderIsOn"));
942 CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString());
944 // Without the fix in place, this test would have crashed here
945 dispatchCommand(mxComponent, ".uno:Undo", {});
946 CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString());
949 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf107494)
951 createSwDoc();
953 // Create a graphic object, but don't insert it yet.
954 uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
955 uno::Reference<beans::XPropertySet> xTextGraphic(
956 xFactory->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY);
958 uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY);
960 uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"),
961 uno::UNO_QUERY);
963 xPageStyle->setPropertyValue("HeaderIsOn", uno::Any(true));
965 uno::Reference<text::XText> xHeader(
966 getProperty<uno::Reference<text::XText>>(xPageStyle, "HeaderText"));
967 CPPUNIT_ASSERT(xHeader.is());
968 uno::Reference<text::XTextCursor> xHeaderCursor(xHeader->createTextCursor());
970 xHeader->insertTextContent(xHeaderCursor, xTextContent, false);
972 CPPUNIT_ASSERT_EQUAL(1, getShapes());
974 xPageStyle->setPropertyValue("HeaderIsOn", uno::Any(false));
976 CPPUNIT_ASSERT_EQUAL(0, getShapes());
978 xPageStyle->setPropertyValue("FooterIsOn", uno::Any(true));
980 uno::Reference<text::XText> xFooter(
981 getProperty<uno::Reference<text::XText>>(xPageStyle, "FooterText"));
982 CPPUNIT_ASSERT(xFooter.is());
983 uno::Reference<text::XTextCursor> xFooterCursor(xFooter->createTextCursor());
985 xTextGraphic.set(xFactory->createInstance("com.sun.star.text.TextGraphicObject"),
986 uno::UNO_QUERY);
988 xTextContent.set(xTextGraphic, uno::UNO_QUERY);
990 xFooter->insertTextContent(xFooterCursor, xTextContent, false);
992 CPPUNIT_ASSERT_EQUAL(1, getShapes());
994 xPageStyle->setPropertyValue("FooterIsOn", uno::Any(false));
996 CPPUNIT_ASSERT_EQUAL(0, getShapes());
999 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf133358)
1001 createSwDoc();
1002 SwDoc* const pDoc = getSwDoc();
1003 SwWrtShell* const pWrtSh = pDoc->GetDocShell()->GetWrtShell();
1004 CPPUNIT_ASSERT(pWrtSh);
1006 pWrtSh->Insert("Test");
1008 CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(1)->getString());
1010 uno::Reference<beans::XPropertyState> xParagraph(getParagraph(1), uno::UNO_QUERY);
1012 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
1014 dispatchCommand(mxComponent, ".uno:IncrementIndent", {});
1016 CPPUNIT_ASSERT_EQUAL(sal_Int32(1251), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
1018 dispatchCommand(mxComponent, ".uno:Undo", {});
1020 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
1022 // Without the fix in place, this test would have crashed here
1023 dispatchCommand(mxComponent, ".uno:Redo", {});
1025 CPPUNIT_ASSERT_EQUAL(sal_Int32(1251), getProperty<sal_Int32>(xParagraph, "ParaLeftMargin"));
1028 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf131771)
1030 createSwDoc();
1032 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1033 { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));
1035 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
1037 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1038 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
1039 uno::UNO_QUERY);
1040 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1042 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1044 CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xTextTable, "TableTemplateName"));
1045 uno::Reference<beans::XPropertySet> xTableProps(xTextTable, uno::UNO_QUERY_THROW);
1046 xTableProps->setPropertyValue("TableTemplateName", uno::Any(OUString("Default Style")));
1048 CPPUNIT_ASSERT_EQUAL(OUString("Default Style"),
1049 getProperty<OUString>(xTextTable, "TableTemplateName"));
1051 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1052 dispatchCommand(mxComponent, ".uno:Copy", {});
1053 dispatchCommand(mxComponent, ".uno:GoDown", {});
1054 dispatchCommand(mxComponent, ".uno:Paste", {});
1056 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
1058 CPPUNIT_ASSERT_EQUAL(OUString("Default Style"),
1059 getProperty<OUString>(xTextTable, "TableTemplateName"));
1061 uno::Reference<text::XTextTable> xTextTable2(xIndexAccess->getByIndex(1), uno::UNO_QUERY);
1063 // Without the fix in place, this test would have failed with
1064 // - Expected: Default Style
1065 // - Actual :
1066 CPPUNIT_ASSERT_EQUAL(OUString("Default Style"),
1067 getProperty<OUString>(xTextTable2, "TableTemplateName"));
1070 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf80663)
1072 createSwDoc();
1074 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1075 { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(2)) } }));
1077 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
1079 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1080 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
1081 uno::UNO_QUERY);
1082 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1083 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1084 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
1085 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
1087 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
1089 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1090 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getRows()->getCount());
1091 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
1093 dispatchCommand(mxComponent, ".uno:Undo", {});
1095 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1096 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
1097 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
1100 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf130805)
1102 createSwDoc("tdf130805.odt");
1103 SwDoc* pDoc = getSwDoc();
1105 const auto& rFrmFormats = *pDoc->GetSpzFrameFormats();
1106 CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
1107 auto pShape = rFrmFormats.front();
1108 CPPUNIT_ASSERT(pShape);
1110 SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
1111 auto pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
1112 CPPUNIT_ASSERT(pTxBxFrm);
1114 const SwNode* pTxAnch = pTxBxFrm->GetAnchor().GetAnchorNode();
1115 const SwNode* pShpAnch = pShape->GetAnchor().GetAnchorNode();
1116 CPPUNIT_ASSERT(pTxAnch);
1117 CPPUNIT_ASSERT(pShpAnch);
1119 CPPUNIT_ASSERT_EQUAL_MESSAGE("The textbox got apart!", pTxAnch->GetIndex(),
1120 pShpAnch->GetIndex());
1123 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf107893)
1125 //Open the sample doc
1126 createSwDoc("tdf107893.odt");
1127 SwDoc* pDoc = getSwDoc();
1129 //Get the format of the shape
1130 const auto& rFrmFormats = *pDoc->GetSpzFrameFormats();
1131 CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
1132 auto pShape = rFrmFormats.front();
1133 CPPUNIT_ASSERT(pShape);
1135 //Add a textbox
1136 SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
1137 SwFrameFormat* pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
1138 CPPUNIT_ASSERT(pTxBxFrm);
1140 //Remove the textbox using Undo
1141 dispatchCommand(mxComponent, ".uno:Undo", {});
1143 //Add again
1144 SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
1145 pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
1147 //This was nullptr because of unsuccessful re-adding
1148 CPPUNIT_ASSERT_MESSAGE("Textbox cannot be readd after Undo!", pTxBxFrm);
1151 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf121031)
1153 createSwDoc();
1155 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1156 { { "Rows", uno::Any(sal_Int32(3)) }, { "Columns", uno::Any(sal_Int32(3)) } }));
1158 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
1160 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1161 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
1162 uno::UNO_QUERY);
1163 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1165 dispatchCommand(mxComponent, ".uno:DeleteTable", {});
1166 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());
1168 dispatchCommand(mxComponent, ".uno:Undo", {});
1169 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1171 // Without the fix in place, the table would be hidden
1172 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1173 assertXPath(pXmlDoc, "/root/page[1]/body/tab", 1);
1176 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, TestTextBoxCrashAfterLineDel)
1178 // Open the desired file
1179 createSwDoc("txbx_crash.odt");
1180 SwDoc* pDoc = getSwDoc();
1182 // Get the format of the shape
1183 const auto& rFrmFormats = *pDoc->GetSpzFrameFormats();
1184 CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
1185 auto pShape = rFrmFormats.front();
1186 CPPUNIT_ASSERT(pShape);
1188 // Add a textbox
1189 SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
1190 SwFrameFormat* pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
1191 CPPUNIT_ASSERT(pTxBxFrm);
1193 // remove the last paragraph
1194 auto xCursor = getParagraph(1)->getText()->createTextCursor();
1195 xCursor->gotoEnd(false);
1196 xCursor->goLeft(3, true);
1198 // This caused crash before, now it should pass with the patch.
1199 xCursor->setString(OUString());
1202 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf121546)
1204 createSwDoc("tdf121546.odt");
1206 CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString());
1208 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1210 dispatchCommand(mxComponent, ".uno:Cut", {});
1212 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
1214 // Create a new document
1215 createSwDoc();
1217 dispatchCommand(mxComponent, ".uno:Paste", {});
1219 CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString());
1221 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1223 dispatchCommand(mxComponent, ".uno:Cut", {});
1225 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
1227 dispatchCommand(mxComponent, ".uno:Undo", {});
1229 CPPUNIT_ASSERT_EQUAL(OUString("xxxxxxxxxxxxxxxxxxxx"), getParagraph(2)->getString());
1231 dispatchCommand(mxComponent, ".uno:Undo", {});
1233 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1235 // Without the fix in place, this test would have crashed here
1236 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
1237 Scheduler::ProcessEventsToIdle();
1239 CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
1242 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf145621)
1244 createSwDoc("tdf145621.odt");
1246 CPPUNIT_ASSERT_EQUAL(OUString("AAAAAA"), getParagraph(1)->getString());
1248 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1250 dispatchCommand(mxComponent, ".uno:Cut", {});
1252 CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString());
1254 // Without the fix in place, this test would have crashed
1255 dispatchCommand(mxComponent, ".uno:Paste", {});
1257 CPPUNIT_ASSERT_EQUAL(OUString("AAAAAA"), getParagraph(1)->getString());
1260 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf134626)
1262 createSwDoc("tdf134626.odt");
1263 SwDoc* pDoc = getSwDoc();
1264 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1266 CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString());
1268 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1270 dispatchCommand(mxComponent, ".uno:Copy", {});
1272 // Create a new document
1273 createSwDoc();
1274 pDoc = getSwDoc();
1275 pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1276 CPPUNIT_ASSERT(pWrtShell);
1278 // Without the fix in place, this test would have crashed here
1279 for (sal_Int32 i = 0; i < 5; ++i)
1281 dispatchCommand(mxComponent, ".uno:Paste", {});
1283 CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString());
1285 dispatchCommand(mxComponent, ".uno:Paste", {});
1287 CPPUNIT_ASSERT_EQUAL(OUString("AppleApple"), getParagraph(1)->getString());
1289 dispatchCommand(mxComponent, ".uno:Undo", {});
1291 CPPUNIT_ASSERT_EQUAL(OUString("Apple"), getParagraph(1)->getString());
1293 dispatchCommand(mxComponent, ".uno:Undo", {});
1295 CPPUNIT_ASSERT_EQUAL(OUString(""), getParagraph(1)->getString());
1299 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf139566)
1301 createSwDoc();
1302 SwDoc* pDoc = getSwDoc();
1303 SwWrtShell* pWrtSh = pDoc->GetDocShell()->GetWrtShell();
1305 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1306 { { "Rows", uno::Any(sal_Int32(1)) }, { "Columns", uno::Any(sal_Int32(1)) } }));
1308 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
1310 // Move the cursor outside the table
1311 pWrtSh->Down(/*bSelect=*/false);
1313 pWrtSh->Insert("Test");
1315 CPPUNIT_ASSERT_EQUAL(OUString("Test"), getParagraph(2)->getString());
1317 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1319 uno::Reference<frame::XFrames> xFrames = mxDesktop->getFrames();
1320 sal_Int32 nFrames = xFrames->getCount();
1322 // Create a second window so the first window looses focus
1323 dispatchCommand(mxComponent, ".uno:NewWindow", {});
1325 CPPUNIT_ASSERT_EQUAL(nFrames + 1, xFrames->getCount());
1327 dispatchCommand(mxComponent, ".uno:CloseWin", {});
1329 CPPUNIT_ASSERT_EQUAL(nFrames, xFrames->getCount());
1331 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
1332 uno::Reference<container::XIndexAccess> xSelections(xModel->getCurrentSelection(),
1333 uno::UNO_QUERY);
1335 // Without the fix in place, this test would have failed here
1336 CPPUNIT_ASSERT(xSelections.is());
1339 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf96067)
1341 createSwDoc();
1343 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1344 { { "Rows", uno::Any(sal_Int32(3)) }, { "Columns", uno::Any(sal_Int32(3)) } }));
1346 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
1348 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1349 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
1350 uno::UNO_QUERY);
1351 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1352 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1353 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getRows()->getCount());
1354 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());
1356 dispatchCommand(mxComponent, ".uno:SelectTable", {});
1357 dispatchCommand(mxComponent, ".uno:InsertRowsBefore", {});
1359 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1360 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getRows()->getCount());
1361 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());
1363 dispatchCommand(mxComponent, ".uno:Undo", {});
1365 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1366 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getRows()->getCount());
1367 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());
1370 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf87199)
1372 createSwDoc();
1374 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1375 { { "Rows", uno::Any(sal_Int32(2)) }, { "Columns", uno::Any(sal_Int32(1)) } }));
1377 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
1379 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1380 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
1381 uno::UNO_QUERY);
1382 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1383 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1384 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
1385 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());
1387 uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
1388 xCellA1->setString("test1");
1390 uno::Reference<text::XTextRange> xCellA2(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
1391 xCellA2->setString("test2");
1393 dispatchCommand(mxComponent, ".uno:EntireColumn", {});
1394 dispatchCommand(mxComponent, ".uno:MergeCells", {});
1396 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1397 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getRows()->getCount());
1398 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());
1400 CPPUNIT_ASSERT(xCellA1->getString().endsWith("test2"));
1402 dispatchCommand(mxComponent, ".uno:Undo", {});
1404 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1405 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
1406 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());
1408 xCellA1.set(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
1410 CPPUNIT_ASSERT(xCellA1->getString().endsWith("test1"));
1413 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf39828)
1415 createSwDoc("tdf39828.fodt");
1416 SwDoc* pDoc = getSwDoc();
1418 // show changes
1419 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
1420 | RedlineFlags::ShowInsert);
1421 CPPUNIT_ASSERT_MESSAGE("redlining should be off",
1422 !pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1423 CPPUNIT_ASSERT_MESSAGE(
1424 "redlines should be visible",
1425 IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
1427 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1428 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
1429 uno::UNO_QUERY);
1430 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1432 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());
1434 uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
1435 // deleted "1", inserted "2"
1436 CPPUNIT_ASSERT_EQUAL(OUString("12"), xCellA1->getString());
1437 uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
1438 // This was 14 (bad sum: 2 + A1, where A1 was 12 instead of the correct 2)
1439 CPPUNIT_ASSERT_EQUAL(OUString("4"), xCellA3->getString());
1440 uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
1441 // This was 28 (bad sum: 2 + A1 + A3, where A1 was 12 and A3 was 14)
1442 CPPUNIT_ASSERT_EQUAL(OUString("8"), xCellA4->getString());
1445 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf146573)
1447 createSwDoc("tdf39828.fodt");
1448 SwDoc* pDoc = getSwDoc();
1449 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1451 // remove redlines, add a footnote, and change the value
1452 // of the cell with the footnote
1453 dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
1454 pWrtShell->Right(SwCursorSkipMode::Cells, /*bSelect=*/false, /*nCount=*/1,
1455 /*bBasicCall=*/false);
1456 dispatchCommand(mxComponent, ".uno:InsertFootnote", {});
1457 dispatchCommand(mxComponent, ".uno:PageUp", {}); // leave footnote
1458 pWrtShell->Left(SwCursorSkipMode::Cells, /*bSelect=*/false, /*nCount=*/1, /*bBasicCall=*/false);
1459 pWrtShell->Left(SwCursorSkipMode::Cells, /*bSelect=*/true, /*nCount=*/1, /*bBasicCall=*/false);
1460 pWrtShell->Insert("100");
1462 // trigger recalculation by leaving the cell
1463 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
1465 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1466 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
1467 uno::UNO_QUERY);
1468 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1470 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());
1472 uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
1473 // value "100" and footnote index "1"
1474 CPPUNIT_ASSERT_EQUAL(OUString("1001"), xCellA1->getString());
1475 uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
1476 // This was 4 (missing recalculation)
1477 CPPUNIT_ASSERT_EQUAL(OUString("102"), xCellA3->getString());
1478 uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
1479 // This was 8 (missing recalculation)
1480 CPPUNIT_ASSERT_EQUAL(OUString("204"), xCellA4->getString());
1483 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf157132)
1485 createSwDoc("tdf157132.odt");
1487 SwDoc* pDoc = getSwDoc();
1488 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1490 // Go to cell A2
1491 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
1493 // Select A2 and A3 and copy
1494 pWrtShell->Down(/*bSelect=*/true, /*nCount=*/1);
1496 dispatchCommand(mxComponent, ".uno:Copy", {});
1498 // Go to A4 and paste
1499 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
1501 dispatchCommand(mxComponent, ".uno:Paste", {});
1503 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1504 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
1505 uno::UNO_QUERY);
1507 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
1509 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1511 uno::Reference<text::XTextRange> xCellA2(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
1512 CPPUNIT_ASSERT_EQUAL(OUString("2"), xCellA2->getString());
1513 uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
1514 CPPUNIT_ASSERT_EQUAL(OUString("3"), xCellA3->getString());
1515 uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
1517 // Without the fix in place, this test would have failed with
1518 // - Expected: 6
1519 // - Actual : 2
1520 CPPUNIT_ASSERT_EQUAL(OUString("6"), xCellA4->getString());
1521 uno::Reference<text::XTextRange> xCellA5(xTextTable->getCellByName("A5"), uno::UNO_QUERY);
1522 CPPUNIT_ASSERT_EQUAL(OUString("7"), xCellA5->getString());
1525 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf147938)
1527 createSwDoc("tdf147938.fodt");
1529 SwDoc* pDoc = getSwDoc();
1530 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1532 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
1533 CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
1534 pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
1536 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
1537 pWrtShell->TableToText('\t');
1539 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
1540 CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
1541 pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
1543 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1544 SwInsertTableOptions const opts(SwInsertTableFlags::NONE, 0);
1545 pWrtShell->TextToTable(opts, '\t', nullptr);
1547 pWrtShell->Undo();
1549 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
1550 CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
1551 pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
1553 pWrtShell->Undo();
1555 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
1556 CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
1557 pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
1559 pWrtShell->Redo();
1561 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
1562 CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
1563 pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
1565 pWrtShell->Redo();
1567 pWrtShell->Undo();
1569 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
1570 CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
1571 pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
1573 pWrtShell->Undo();
1575 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->getIDocumentRedlineAccess().GetRedlineTable().size());
1576 CPPUNIT_ASSERT_EQUAL(OUString("Bar\nbaz "),
1577 pDoc->getIDocumentRedlineAccess().GetRedlineTable()[0]->GetText());
1580 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148799)
1582 // load a document with table formulas with comma delimiter,
1583 // but with a document language with default point delimiter
1584 createSwDoc("tdf148799.docx");
1585 SwDoc* pDoc = getSwDoc();
1586 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1588 // check formula update
1590 // put cursor in the first table row
1591 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
1593 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1594 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
1595 uno::UNO_QUERY);
1597 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
1599 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1601 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTextTable->getRows()->getCount());
1603 // These were "** Expression is faulty **"
1605 uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName("D3"), uno::UNO_QUERY);
1606 CPPUNIT_ASSERT_EQUAL(OUString("2.3"), xCellA1->getString());
1607 uno::Reference<text::XTextRange> xCellA3(xTextTable->getCellByName("D4"), uno::UNO_QUERY);
1608 CPPUNIT_ASSERT_EQUAL(OUString("2345"), xCellA3->getString());
1609 uno::Reference<text::XTextRange> xCellA4(xTextTable->getCellByName("D5"), uno::UNO_QUERY);
1610 CPPUNIT_ASSERT_EQUAL(OUString("23684.5"), xCellA4->getString());
1613 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151993)
1615 // load a document with table formulas with comma delimiter
1616 // (with a document language with default comma delimiter)
1617 createSwDoc("tdf151993.docx");
1618 SwDoc* pDoc = getSwDoc();
1619 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1621 // check formula update
1623 // put cursor in the first table row
1624 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
1626 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1627 uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(),
1628 uno::UNO_QUERY);
1630 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
1632 uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
1634 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
1636 // This was 0
1637 uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
1638 CPPUNIT_ASSERT_EQUAL(OUString("30"), xCellA1->getString());
1641 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf148849)
1643 // load a document with a table and an empty paragraph before the table
1644 createSwDoc("tdf148849.fodt");
1645 SwDoc* pDoc = getSwDoc();
1646 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1648 // record changes
1649 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1650 | RedlineFlags::ShowInsert);
1651 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1652 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1653 // hide changes
1654 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
1655 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
1657 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1658 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1659 uno::UNO_QUERY);
1660 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
1662 // put cursor in the first table row
1663 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
1665 // delete a table row
1666 pWrtShell->DeleteRow();
1668 // check cursor position
1670 // This was "", because the text cursor jumped to the start of the document
1671 // after deleting a table row instead of remaining in the next table row
1672 SwNode& rNode = pWrtShell->GetCursor()->GetPoint()->GetNode();
1673 CPPUNIT_ASSERT_EQUAL(OUString("Row 2"), rNode.GetTextNode()->GetText());
1676 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf150576)
1678 // load a document with a table and an empty paragraph before the table
1679 createSwDoc("tdf148849.fodt");
1680 SwDoc* pDoc = getSwDoc();
1681 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1683 // record changes
1684 pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
1685 | RedlineFlags::ShowInsert);
1686 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1687 pDoc->getIDocumentRedlineAccess().IsRedlineOn());
1688 // hide changes
1689 dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
1690 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
1692 uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1693 uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
1694 uno::UNO_QUERY);
1695 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
1697 // Check deletion of the first row, if the second row deleted already
1699 // put cursor in the second table row
1700 pWrtShell->Down(/*bSelect=*/false, /*nCount=*/2);
1701 SwNode& rNode = pWrtShell->GetCursor()->GetPoint()->GetNode();
1702 CPPUNIT_ASSERT_EQUAL(OUString("Row 2"), rNode.GetTextNode()->GetText());
1704 // delete the second table row
1705 pWrtShell->DeleteRow();
1707 // check cursor position (row 3)
1708 SwNode& rNode2 = pWrtShell->GetCursor()->GetPoint()->GetNode();
1709 CPPUNIT_ASSERT_EQUAL(OUString("Row 3"), rNode2.GetTextNode()->GetText());
1711 // put cursor in the first row
1712 pWrtShell->Up(/*bSelect=*/false, /*nCount=*/1);
1713 SwNode& rNode3 = pWrtShell->GetCursor()->GetPoint()->GetNode();
1714 CPPUNIT_ASSERT_EQUAL(OUString("12"), rNode3.GetTextNode()->GetText());
1716 // delete the first row
1717 pWrtShell->DeleteRow();
1719 // This was empty (cursor jumped in the start of the document instead of
1720 // the next not deleted row)
1721 SwNode& rNode4 = pWrtShell->GetCursor()->GetPoint()->GetNode();
1722 CPPUNIT_ASSERT_EQUAL(OUString("Row 3"), rNode4.GetTextNode()->GetText());
1724 // Check skipping previous lines
1726 // restore deleted rows
1727 dispatchCommand(mxComponent, ".uno:Undo", {});
1728 dispatchCommand(mxComponent, ".uno:Undo", {});
1729 SwNode& rNode5 = pWrtShell->GetCursor()->GetPoint()->GetNode();
1730 CPPUNIT_ASSERT_EQUAL(OUString("Row 2"), rNode5.GetTextNode()->GetText());
1732 // delete the second row
1733 pWrtShell->DeleteRow();
1734 SwNode& rNode7 = pWrtShell->GetCursor()->GetPoint()->GetNode();
1735 CPPUNIT_ASSERT_EQUAL(OUString("Row 3"), rNode7.GetTextNode()->GetText());
1737 // delete the third, i.e. last row
1738 pWrtShell->DeleteRow();
1739 SwNode& rNode8 = pWrtShell->GetCursor()->GetPoint()->GetNode();
1741 // This was empty (cursor jumped in the start of the document instead of
1742 // the previous not deleted row)
1743 CPPUNIT_ASSERT_EQUAL(OUString("12"), rNode8.GetTextNode()->GetText());
1746 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132603)
1748 createSwDoc();
1749 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1751 uno::Sequence<beans::PropertyValue> aPropertyValues
1752 = comphelper::InitPropertySequence({ { "Text", uno::Any(OUString("Comment")) } });
1754 dispatchCommand(mxComponent, ".uno:InsertAnnotation", aPropertyValues);
1756 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1758 // Without the fix in place, it would crash here
1759 dispatchCommand(mxComponent, ".uno:Copy", {});
1761 tools::JsonWriter aJsonWriter;
1762 pTextDoc->getPostIts(aJsonWriter);
1763 OString pChar = aJsonWriter.finishAndGetAsOString();
1764 std::stringstream aStream((std::string(pChar)));
1765 boost::property_tree::ptree aTree;
1766 boost::property_tree::read_json(aStream, aTree);
1767 for (const boost::property_tree::ptree::value_type& rValue : aTree.get_child("comments"))
1769 const boost::property_tree::ptree& rComment = rValue.second;
1771 OString aText(rComment.get<std::string>("text"));
1772 CPPUNIT_ASSERT_EQUAL(OString("Comment"), aText);
1776 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf117601)
1778 createSwDoc();
1779 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1781 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1782 { { "Rows", uno::Any(sal_Int32(5)) }, { "Columns", uno::Any(sal_Int32(3)) } }));
1784 dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
1786 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
1787 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
1788 uno::UNO_QUERY);
1789 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1790 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1791 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTextTable->getRows()->getCount());
1792 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());
1794 uno::Reference<text::XTextRange> xCellB1(xTextTable->getCellByName("B1"), uno::UNO_QUERY);
1795 xCellB1->setString("test1");
1797 uno::Reference<text::XTextRange> xCellB2(xTextTable->getCellByName("B2"), uno::UNO_QUERY);
1798 xCellB2->setString("test2");
1800 //go to middle row
1801 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_UP);
1802 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RIGHT);
1803 Scheduler::ProcessEventsToIdle();
1805 dispatchCommand(mxComponent, ".uno:EntireColumn", {});
1806 dispatchCommand(mxComponent, ".uno:MergeCells", {});
1808 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1809 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTextTable->getRows()->getCount());
1810 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());
1812 CPPUNIT_ASSERT(xCellB1->getString().endsWith("test2"));
1814 dispatchCommand(mxComponent, ".uno:Undo", {});
1816 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
1817 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xTextTable->getRows()->getCount());
1818 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTextTable->getColumns()->getCount());
1820 CPPUNIT_ASSERT(xCellB1->getString().endsWith("test1"));
1823 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf138130)
1825 createSwDoc("tdf138130.docx");
1827 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1828 uno::Reference<drawing::XShape> xShape = getShape(1);
1830 awt::Point aPos = xShape->getPosition();
1832 //select shape and change the anchor
1833 selectShape(1);
1835 // Without the fix in place, this test would have crashed here
1836 dispatchCommand(mxComponent, ".uno:SetAnchorToPage", {});
1838 //position has changed
1839 CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X);
1840 CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y);
1842 dispatchCommand(mxComponent, ".uno:Undo", {});
1844 CPPUNIT_ASSERT_EQUAL(aPos.X, xShape->getPosition().X);
1845 CPPUNIT_ASSERT_EQUAL(aPos.Y, xShape->getPosition().Y);
1848 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136385)
1850 createSwDoc("tdf136385.odt");
1852 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1853 uno::Reference<drawing::XShape> xShape = getShape(1);
1855 awt::Point aPos = xShape->getPosition();
1857 //select shape and change the anchor
1858 selectShape(1);
1860 dispatchCommand(mxComponent, ".uno:SetAnchorToPage", {});
1862 //position has changed
1863 CPPUNIT_ASSERT(aPos.X < xShape->getPosition().X);
1864 CPPUNIT_ASSERT(aPos.Y < xShape->getPosition().Y);
1866 dispatchCommand(mxComponent, ".uno:Undo", {});
1868 //Without the fix in place, this test would have failed with
1869 //- Expected: 2447
1870 //- Actual : 446
1871 CPPUNIT_ASSERT_EQUAL(aPos.X, xShape->getPosition().X);
1872 CPPUNIT_ASSERT_EQUAL(aPos.Y, xShape->getPosition().Y);
1875 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf145207)
1877 createSwDoc("tdf145207.odt");
1878 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1880 CPPUNIT_ASSERT_EQUAL(1, getPages());
1881 CPPUNIT_ASSERT_EQUAL(3, getShapes());
1883 //select one shape and use the TAB key to iterate over the different shapes
1884 selectShape(1);
1886 for (sal_Int32 i = 0; i < 10; ++i)
1888 // Without the fix in place, this test would have crashed here
1889 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
1890 Scheduler::ProcessEventsToIdle();
1894 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf128782)
1896 createSwDoc("tdf128782.odt");
1897 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1899 CPPUNIT_ASSERT_EQUAL(2, getShapes());
1900 uno::Reference<drawing::XShape> xShape1 = getShape(1);
1901 uno::Reference<drawing::XShape> xShape2 = getShape(2);
1903 awt::Point aPos[2];
1904 aPos[0] = xShape1->getPosition();
1905 aPos[1] = xShape2->getPosition();
1907 //select shape 2 and move it down
1908 selectShape(2);
1910 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_DOWN);
1911 Scheduler::ProcessEventsToIdle();
1913 CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
1914 CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
1915 CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
1916 //Y position in shape 2 has changed
1917 CPPUNIT_ASSERT(aPos[1].Y < xShape2->getPosition().Y);
1919 dispatchCommand(mxComponent, ".uno:Undo", {});
1921 CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
1922 CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
1923 CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
1924 // Shape2 has come back to the original position
1925 // without the fix in place, it would have failed
1926 CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
1929 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf135623)
1931 createSwDoc("tdf135623.docx");
1932 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1934 CPPUNIT_ASSERT_EQUAL(2, getShapes());
1935 CPPUNIT_ASSERT_EQUAL(2, getPages());
1937 uno::Reference<drawing::XShape> xShape1 = getShape(1);
1938 uno::Reference<drawing::XShape> xShape2 = getShape(2);
1940 awt::Point aPos[2];
1941 aPos[0] = xShape1->getPosition();
1942 aPos[1] = xShape2->getPosition();
1944 //select shape 1 and move it down
1945 selectShape(1);
1947 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_DOWN);
1948 Scheduler::ProcessEventsToIdle();
1950 CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
1951 //Y position in shape 1 has changed
1952 CPPUNIT_ASSERT(aPos[0].Y < xShape1->getPosition().Y);
1953 CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
1954 CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
1956 dispatchCommand(mxComponent, ".uno:Undo", {});
1958 CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
1959 CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
1960 CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
1962 // Without the fix in place, this test would have failed here
1963 // - Expected: 1351
1964 // - Actual : 2233
1965 CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
1967 CPPUNIT_ASSERT_EQUAL(2, getPages());
1970 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf133490)
1972 createSwDoc("tdf133490.odt");
1973 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
1975 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1977 dispatchCommand(mxComponent, ".uno:SelectAll", {});
1979 dispatchCommand(mxComponent, ".uno:Cut", {});
1981 CPPUNIT_ASSERT_EQUAL(0, getShapes());
1983 dispatchCommand(mxComponent, ".uno:Paste", {});
1985 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1987 dispatchCommand(mxComponent, ".uno:Paste", {});
1989 CPPUNIT_ASSERT_EQUAL(2, getShapes());
1991 uno::Reference<drawing::XShape> xShape1 = getShape(1);
1992 uno::Reference<drawing::XShape> xShape2 = getShape(2);
1994 awt::Point aPos[2];
1995 aPos[0] = xShape1->getPosition();
1996 aPos[1] = xShape2->getPosition();
1998 //select shape 2 and move it to the right
1999 selectShape(2);
2001 for (sal_Int32 i = 0; i < 5; ++i)
2003 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RIGHT);
2004 Scheduler::ProcessEventsToIdle();
2007 CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
2008 CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
2009 //X position in shape 2 has changed
2010 CPPUNIT_ASSERT(aPos[1].X < xShape2->getPosition().X);
2011 CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
2013 for (sal_Int32 i = 0; i < 4; ++i)
2015 dispatchCommand(mxComponent, ".uno:Undo", {});
2017 // Without the fix in place, undo action would have changed shape1's position
2018 // and this test would have failed with
2019 // - Expected: -139
2020 // - Actual : 1194
2021 CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
2022 CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
2023 CPPUNIT_ASSERT(aPos[1].X < xShape2->getPosition().X);
2024 CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
2027 dispatchCommand(mxComponent, ".uno:Undo", {});
2029 CPPUNIT_ASSERT_EQUAL(aPos[0].X, xShape1->getPosition().X);
2030 CPPUNIT_ASSERT_EQUAL(aPos[0].Y, xShape1->getPosition().Y);
2031 // Shape 2 has come back to the original position
2032 CPPUNIT_ASSERT_EQUAL(aPos[1].X, xShape2->getPosition().X);
2033 CPPUNIT_ASSERT_EQUAL(aPos[1].Y, xShape2->getPosition().Y);
2035 dispatchCommand(mxComponent, ".uno:Undo", {});
2037 CPPUNIT_ASSERT_EQUAL(1, getShapes());
2039 dispatchCommand(mxComponent, ".uno:Undo", {});
2041 CPPUNIT_ASSERT_EQUAL(0, getShapes());
2043 dispatchCommand(mxComponent, ".uno:Undo", {});
2045 CPPUNIT_ASSERT_EQUAL(1, getShapes());
2048 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf132637_protectTrackChanges)
2050 createSwDoc("tdf132637_protectTrackChanges.doc");
2051 SwDoc* pDoc = getSwDoc();
2053 // The password should only prevent turning off track changes, not open as read-only
2054 CPPUNIT_ASSERT(!pDoc->GetDocShell()->IsReadOnly());
2057 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf127652)
2059 createSwDoc("tdf127652.odt");
2060 SwDoc* pDoc = getSwDoc();
2061 SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2063 // get a page cursor
2064 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
2065 uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
2066 xModel->getCurrentController(), uno::UNO_QUERY);
2067 uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
2068 uno::UNO_QUERY);
2070 // go to the start of page 4
2071 xCursor->jumpToPage(4);
2072 xCursor->jumpToStartOfPage();
2074 // mark a section that overlaps multiple pages
2075 pWrtShell->Down(false, 2);
2076 pWrtShell->Up(true, 5);
2078 // delete the marked section
2079 pWrtShell->DelRight();
2081 // go to the start of page 4
2082 xCursor->jumpToPage(4);
2083 xCursor->jumpToStartOfPage();
2085 // move up to page 3
2086 pWrtShell->Up(false, 5);
2088 // check that we are on the third page
2089 // in the bug one issue was that the cursor was placed incorrectly, so
2090 // moving up to the previous page would not work any more
2091 sal_uInt16 assertPage = 3;
2092 SwCursorShell* pShell(pDoc->GetEditShell());
2093 sal_uInt16 currentPage = pShell->GetPageNumSeqNonEmpty();
2094 CPPUNIT_ASSERT_EQUAL_MESSAGE("We are on the wrong page!", assertPage, currentPage);
2097 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, AtPageTextBoxCrash)
2099 // Load sample file
2100 createSwDoc("AtPageTextBoxCrash.odt");
2101 SwDoc* pDoc = getSwDoc();
2103 // Get the format of the shape
2104 const auto& rFrmFormats = *pDoc->GetSpzFrameFormats();
2105 CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
2106 auto pShape = rFrmFormats.front();
2107 CPPUNIT_ASSERT(pShape);
2109 // Add a textbox to the shape
2110 SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject());
2111 auto pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
2112 CPPUNIT_ASSERT(pTxBxFrm);
2114 // Change its anchor to page
2115 uno::Reference<beans::XPropertySet> xShpProps(getShape(1), uno::UNO_QUERY_THROW);
2116 xShpProps->setPropertyValue(
2117 "AnchorType", uno::Any(text::TextContentAnchorType::TextContentAnchorType_AT_PAGE));
2119 // The page anchored objects must not have content anchor
2120 // unless this will lead to crash later, for example on
2121 // removing the paragraph where it is anchored to...
2122 CPPUNIT_ASSERT_EQUAL(RndStdIds::FLY_AT_PAGE, pTxBxFrm->GetAnchor().GetAnchorId());
2123 CPPUNIT_ASSERT(!pTxBxFrm->GetAnchor().GetAnchorNode());
2125 // Remove the paragraph where the textframe should be anchored
2126 // before. Now with the patch it must not crash...
2127 auto xPara = getParagraph(1);
2128 xPara->getText()->setString(OUString());
2131 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf135661)
2133 createSwDoc("tdf135661.odt");
2135 CPPUNIT_ASSERT_EQUAL(1, getShapes());
2136 uno::Reference<drawing::XShape> xShape(getShape(1), uno::UNO_QUERY);
2137 CPPUNIT_ASSERT_EQUAL(sal_Int32(3424), xShape->getPosition().X);
2138 CPPUNIT_ASSERT_EQUAL(sal_Int32(1545), xShape->getPosition().Y);
2140 dispatchCommand(mxComponent, ".uno:SelectAll", {});
2141 dispatchCommand(mxComponent, ".uno:Cut", {});
2143 CPPUNIT_ASSERT_EQUAL(0, getShapes());
2145 dispatchCommand(mxComponent, ".uno:Undo", {});
2147 CPPUNIT_ASSERT_EQUAL(1, getShapes());
2149 xShape.set(getShape(1), uno::UNO_QUERY);
2151 //Without the fix in place, the shape position would have been 0,0
2152 CPPUNIT_ASSERT_EQUAL(sal_Int32(3424), xShape->getPosition().X);
2153 CPPUNIT_ASSERT_EQUAL(sal_Int32(1545), xShape->getPosition().Y);
2156 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf133477)
2158 if (getDefaultDeviceBitCount() < 24)
2159 return;
2160 createSwDoc("tdf133477.fodt");
2162 // Save the shape to a BMP.
2163 uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter
2164 = drawing::GraphicExportFilter::create(mxComponentContext);
2165 uno::Reference<lang::XComponent> xSourceDoc(getShape(1), uno::UNO_QUERY);
2166 xGraphicExporter->setSourceDocument(xSourceDoc);
2168 SvMemoryStream aStream;
2169 uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
2170 uno::Sequence<beans::PropertyValue> aDescriptor(
2171 comphelper::InitPropertySequence({ { "OutputStream", uno::Any(xOutputStream) },
2172 { "FilterName", uno::Any(OUString("BMP")) } }));
2173 xGraphicExporter->filter(aDescriptor);
2174 aStream.Seek(STREAM_SEEK_TO_BEGIN);
2176 // Read it back and check the color of the first pixel.
2177 // (Actually check at one-pixel offset, because imprecise shape positioning may
2178 // result in blending with background for the first pixel).
2179 Graphic aGraphic;
2180 TypeSerializer aSerializer(aStream);
2181 aSerializer.readGraphic(aGraphic);
2183 BitmapEx aBitmap = aGraphic.GetBitmapEx();
2184 CPPUNIT_ASSERT_EQUAL(Color(0, 102, 204), aBitmap.GetPixelColor(1, 1));
2187 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf137964)
2189 createSwDoc("tdf137964.odt");
2190 SwDoc* pDoc = getSwDoc();
2191 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2192 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
2194 CPPUNIT_ASSERT_EQUAL(1, getShapes());
2195 uno::Reference<drawing::XShape> xShape(getShape(1), uno::UNO_QUERY);
2196 CPPUNIT_ASSERT_EQUAL(sal_Int32(3579), xShape->getPosition().X);
2197 CPPUNIT_ASSERT_EQUAL(sal_Int32(4090), xShape->getPosition().Y);
2199 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
2200 SdrObject* pObject = pPage->GetObj(1);
2201 SwContact* pTextBox = static_cast<SwContact*>(pObject->GetUserCall());
2202 CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_FLYFRMFMT), pTextBox->GetFormat()->Which());
2204 pWrtShell->SelectObj(Point(), 0, pObject);
2206 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_UP);
2207 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_SHIFT | KEY_LEFT);
2208 Scheduler::ProcessEventsToIdle();
2210 // Without the fix in place, the shape would have stayed where it was
2211 CPPUNIT_ASSERT_EQUAL(sal_Int32(2579), xShape->getPosition().X);
2212 CPPUNIT_ASSERT_EQUAL(sal_Int32(3090), xShape->getPosition().Y);
2215 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf143244)
2217 createSwDoc("tdf143244.odt");
2219 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
2220 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
2221 uno::UNO_QUERY);
2222 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
2223 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
2224 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getRows()->getCount());
2225 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
2227 uno::Reference<text::XTextRange> xCell(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
2228 CPPUNIT_ASSERT_EQUAL(Color(0x009353), getProperty<Color>(xCell, "BackColor"));
2230 xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
2231 CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
2233 xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
2234 CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
2236 xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
2237 CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
2239 xCell.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY);
2240 CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
2242 xCell.set(xTextTable->getCellByName("A6"), uno::UNO_QUERY);
2243 CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty<Color>(xCell, "BackColor"));
2245 dispatchCommand(mxComponent, ".uno:SelectAll", {});
2246 dispatchCommand(mxComponent, ".uno:Cut", {});
2248 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndexAccess->getCount());
2250 dispatchCommand(mxComponent, ".uno:Paste", {});
2252 xTextTable.set(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
2253 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getRows()->getCount());
2254 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
2256 dispatchCommand(mxComponent, ".uno:GoUp", {});
2258 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
2259 for (sal_Int32 i = 0; i < 6; ++i)
2261 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
2262 Scheduler::ProcessEventsToIdle();
2265 for (sal_Int32 i = 0; i < 5; ++i)
2267 dispatchCommand(mxComponent, ".uno:Undo", {});
2270 xTextTable.set(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
2271 CPPUNIT_ASSERT_EQUAL(sal_Int32(6), xTextTable->getRows()->getCount());
2272 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
2274 for (sal_Int32 i = 0; i < 5; ++i)
2276 dispatchCommand(mxComponent, ".uno:Redo", {});
2279 xTextTable.set(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
2280 CPPUNIT_ASSERT_EQUAL(sal_Int32(9), xTextTable->getRows()->getCount());
2281 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getColumns()->getCount());
2283 xCell.set(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
2284 CPPUNIT_ASSERT_EQUAL(Color(0x009353), getProperty<Color>(xCell, "BackColor"));
2286 xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
2287 CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
2289 xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
2290 CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
2292 xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
2293 CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
2295 xCell.set(xTextTable->getCellByName("A5"), uno::UNO_QUERY);
2296 CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
2298 xCell.set(xTextTable->getCellByName("A6"), uno::UNO_QUERY);
2300 // Without the fix in place, this test would have failed with
2301 // - Expected: Color: R:255 G:255 B:255 A:255
2302 // - Actual : Color: R:190 G:227 B:211 A:0
2303 CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
2305 xCell.set(xTextTable->getCellByName("A7"), uno::UNO_QUERY);
2306 CPPUNIT_ASSERT_EQUAL(Color(0xdddddd), getProperty<Color>(xCell, "BackColor"));
2308 xCell.set(xTextTable->getCellByName("A8"), uno::UNO_QUERY);
2309 CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xCell, "BackColor"));
2311 xCell.set(xTextTable->getCellByName("A9"), uno::UNO_QUERY);
2312 CPPUNIT_ASSERT_EQUAL(Color(0xbee3d3), getProperty<Color>(xCell, "BackColor"));
2315 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136715)
2317 createSwDoc("tdf136715.odt");
2319 uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
2320 uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(),
2321 uno::UNO_QUERY);
2322 uno::Reference<text::XTextTable> xTextTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
2323 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
2324 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());
2325 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());
2327 uno::Reference<text::XTextRange> xCell(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
2328 uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
2329 uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
2330 uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
2331 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, "CharWeight"));
2333 xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
2334 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2335 xParaEnum.set(xParaEnumAccess->createEnumeration());
2336 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2337 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, "CharWeight"));
2339 xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
2340 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2341 xParaEnum.set(xParaEnumAccess->createEnumeration());
2342 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2343 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, "CharWeight"));
2345 xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
2346 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2347 xParaEnum.set(xParaEnumAccess->createEnumeration());
2348 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2349 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, "CharWeight"));
2351 dispatchCommand(mxComponent, ".uno:GoDown", {});
2352 dispatchCommand(mxComponent, ".uno:GoDown", {});
2353 dispatchCommand(mxComponent, ".uno:LineDownSel", {});
2354 dispatchCommand(mxComponent, ".uno:DeleteRows", {});
2356 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
2357 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());
2359 xCell.set(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
2360 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2361 xParaEnum.set(xParaEnumAccess->createEnumeration());
2362 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2363 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, "CharWeight"));
2365 xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
2366 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2367 xParaEnum.set(xParaEnumAccess->createEnumeration());
2368 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2369 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, "CharWeight"));
2371 dispatchCommand(mxComponent, ".uno:Undo", {});
2373 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTextTable->getRows()->getCount());
2374 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTextTable->getColumns()->getCount());
2376 xCell.set(xTextTable->getCellByName("A1"), uno::UNO_QUERY);
2377 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2378 xParaEnum.set(xParaEnumAccess->createEnumeration());
2379 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2380 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, "CharWeight"));
2382 xCell.set(xTextTable->getCellByName("A2"), uno::UNO_QUERY);
2383 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2384 xParaEnum.set(xParaEnumAccess->createEnumeration());
2385 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2387 // Without the fix in place, this test would have failed with
2388 // - Expected: 100
2389 // - Actual : 150
2390 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, "CharWeight"));
2392 xCell.set(xTextTable->getCellByName("A3"), uno::UNO_QUERY);
2393 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2394 xParaEnum.set(xParaEnumAccess->createEnumeration());
2395 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2396 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xPara, "CharWeight"));
2398 xCell.set(xTextTable->getCellByName("A4"), uno::UNO_QUERY);
2399 xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
2400 xParaEnum.set(xParaEnumAccess->createEnumeration());
2401 xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
2402 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xPara, "CharWeight"));
2405 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf138897)
2407 createSwDoc("tdf100018-1.odt");
2409 dispatchCommand(mxComponent, ".uno:SelectAll", {});
2410 dispatchCommand(mxComponent, ".uno:Cut", {});
2411 dispatchCommand(mxComponent, ".uno:Paste", {});
2412 // this was crashing
2413 dispatchCommand(mxComponent, ".uno:Undo", {});
2414 dispatchCommand(mxComponent, ".uno:Redo", {});
2415 dispatchCommand(mxComponent, ".uno:Undo", {});
2416 dispatchCommand(mxComponent, ".uno:Redo", {});
2419 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf136740)
2421 createSwDoc();
2422 css::uno::Reference<css::lang::XMultiServiceFactory> xFact(mxComponent,
2423 css::uno::UNO_QUERY_THROW);
2424 css::uno::Reference<css::beans::XPropertySet> xTextDefaults(
2425 xFact->createInstance("com.sun.star.text.Defaults"), css::uno::UNO_QUERY_THROW);
2426 const css::uno::Any aOrig = xTextDefaults->getPropertyValue("TabStopDistance");
2427 sal_Int32 nDefTab = aOrig.get<sal_Int32>();
2428 CPPUNIT_ASSERT(nDefTab != 0);
2430 css::uno::Reference<css::text::XTextRange> const xParagraph(getParagraphOrTable(1),
2431 css::uno::UNO_QUERY_THROW);
2432 xParagraph->setString("Foo");
2434 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
2435 CPPUNIT_ASSERT_EQUAL(OUString("Foo"), xParagraph->getString());
2437 dispatchCommand(mxComponent, ".uno:SelectAll", {});
2438 dispatchCommand(mxComponent, ".uno:Copy", {});
2439 dispatchCommand(mxComponent, ".uno:GoToEndOfDoc", {});
2441 const css::uno::Any aNew(nDefTab * 2);
2442 xTextDefaults->setPropertyValue("TabStopDistance", aNew);
2443 // it may become slightly different because of conversions, so get the actual value
2444 const css::uno::Any aNewCorrected = xTextDefaults->getPropertyValue("TabStopDistance");
2445 CPPUNIT_ASSERT_DOUBLES_EQUAL(nDefTab * 2, aNewCorrected.get<sal_Int32>(), 1);
2447 // Paste special as RTF
2448 const auto aPropertyValues = comphelper::InitPropertySequence(
2449 { { "SelectedFormat",
2450 css::uno::Any(static_cast<sal_uInt32>(SotClipboardFormatId::RTF)) } });
2451 dispatchCommand(mxComponent, ".uno:ClipboardFormatItems", aPropertyValues);
2453 CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
2454 CPPUNIT_ASSERT_EQUAL(OUString("FooFoo"), xParagraph->getString());
2456 // Without the fix in place, this would fail with
2457 // equality assertion failed
2458 // - Expected: <Any: (long) 2501>
2459 // - Actual : <Any: (long) 1251>
2460 // i.e., pasting RTF would reset the modified default tab stop distance to hardcoded default
2461 CPPUNIT_ASSERT_EQUAL(aNewCorrected, xTextDefaults->getPropertyValue("TabStopDistance"));
2464 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf128106)
2466 createSwDoc("cross_reference_demo_bmk.odt");
2468 const auto aPropertyValues
2469 = comphelper::InitPropertySequence({ { "FileName", css::uno::Any(maTempFile.GetURL()) } });
2470 dispatchCommand(mxComponent, ".uno:NewGlobalDoc", aPropertyValues);
2472 mxComponent = loadFromDesktop(maTempFile.GetURL());
2474 SwWrtShell* pWrtShell = getSwDoc()->GetDocShell()->GetWrtShell();
2475 SwDoc* const pMasterDoc(pWrtShell->GetDoc());
2476 CPPUNIT_ASSERT_EQUAL(
2477 size_t(2),
2478 pMasterDoc->getIDocumentLinksAdministration().GetLinkManager().GetLinks().size());
2479 // no way to set SwDocShell::m_nUpdateDocMode away from NO_UPDATE ?
2480 // pMasterDoc->getIDocumentLinksAdministration().UpdateLinks();
2481 pMasterDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks(false, false,
2482 nullptr);
2483 // note: this has called SwGetRefFieldType::UpdateGetReferences()
2484 SwFieldType const* const pType(
2485 pMasterDoc->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetRef));
2486 std::vector<SwFormatField*> fields;
2487 pType->GatherFields(fields);
2488 CPPUNIT_ASSERT_EQUAL(size_t(6), fields.size());
2489 std::sort(fields.begin(), fields.end(), [](auto const* const pA, auto const* const pB) {
2490 SwTextField const* const pHintA(pA->GetTextField());
2491 SwTextField const* const pHintB(pB->GetTextField());
2492 // in this document: only 1 field per node
2493 CPPUNIT_ASSERT(pA == pB || &pHintA->GetTextNode() != &pHintB->GetTextNode());
2494 return pHintA->GetTextNode().GetIndex() < pHintB->GetTextNode().GetIndex();
2496 CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[0]->GetField()->GetSubType());
2497 CPPUNIT_ASSERT_EQUAL(OUString("bookmarkchapter1_text"),
2498 static_cast<SwGetRefField const*>(fields[0]->GetField())->GetSetRefName());
2499 CPPUNIT_ASSERT_EQUAL(OUString("Text"),
2500 static_cast<SwGetRefField const*>(fields[0]->GetField())
2501 ->GetExpandedTextOfReferencedTextNode(*pWrtShell->GetLayout()));
2502 CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[1]->GetField()->GetSubType());
2503 CPPUNIT_ASSERT(
2504 static_cast<SwGetRefField const*>(fields[1]->GetField())->IsRefToHeadingCrossRefBookmark());
2505 CPPUNIT_ASSERT_EQUAL(OUString("Chapter 2"),
2506 static_cast<SwGetRefField const*>(fields[1]->GetField())->GetPar2());
2507 CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[2]->GetField()->GetSubType());
2508 CPPUNIT_ASSERT_EQUAL(OUString("Bookmarkchapter1"),
2509 static_cast<SwGetRefField const*>(fields[2]->GetField())->GetSetRefName());
2510 CPPUNIT_ASSERT_EQUAL(OUString("Chapter 1"),
2511 static_cast<SwGetRefField const*>(fields[2]->GetField())->GetPar2());
2512 CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[3]->GetField()->GetSubType());
2513 CPPUNIT_ASSERT_EQUAL(OUString("bookmarkchapter1_text"),
2514 static_cast<SwGetRefField const*>(fields[3]->GetField())->GetSetRefName());
2515 CPPUNIT_ASSERT_EQUAL(OUString("Text"),
2516 static_cast<SwGetRefField const*>(fields[3]->GetField())->GetPar2());
2517 CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[4]->GetField()->GetSubType());
2518 CPPUNIT_ASSERT(
2519 static_cast<SwGetRefField const*>(fields[4]->GetField())->IsRefToHeadingCrossRefBookmark());
2520 CPPUNIT_ASSERT_EQUAL(OUString("Chapter 1.1"),
2521 static_cast<SwGetRefField const*>(fields[4]->GetField())->GetPar2());
2522 CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), fields[5]->GetField()->GetSubType());
2523 CPPUNIT_ASSERT(
2524 static_cast<SwGetRefField const*>(fields[5]->GetField())->IsRefToHeadingCrossRefBookmark());
2525 CPPUNIT_ASSERT_EQUAL(OUString("Chapter 2"),
2526 static_cast<SwGetRefField const*>(fields[5]->GetField())->GetPar2());
2529 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf103612)
2531 createSwGlobalDoc("DUMMY.odm");
2532 SwDoc* pGlobalDoc = getSwDoc();
2533 CPPUNIT_ASSERT_EQUAL(
2534 size_t(1),
2535 pGlobalDoc->getIDocumentLinksAdministration().GetLinkManager().GetLinks().size());
2536 pGlobalDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks(false, false,
2537 nullptr);
2539 xmlDocUniquePtr pLayout = parseLayoutDump();
2541 assertXPath(pLayout, "/root/page[1]/body/section[1]/txt[1]/SwParaPortion/SwLineLayout[1]",
2542 "portion", "Text before section");
2543 // the inner section and its content was hidden
2544 assertXPath(pLayout, "/root/page[1]/body/section[2]/txt[1]/SwParaPortion/SwLineLayout[1]",
2545 "portion", "Text inside section before ToC");
2546 assertXPath(pLayout, "/root/page[1]/body/section[3]/txt[1]/SwParaPortion/SwLineLayout[1]",
2547 "portion", "Table of Contents");
2548 assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[1]/SwParaPortion/SwLineLayout[1]",
2549 "portion", "First header*1");
2550 assertXPath(pLayout, "/root/page[1]/body/section[4]/txt[2]/SwParaPortion/SwLineLayout[1]",
2551 "portion", "Second header*1");
2552 assertXPath(pLayout, "/root/page[1]/body/section[5]/txt[2]/SwParaPortion/SwLineLayout[1]",
2553 "portion", "Text inside section after ToC");
2554 assertXPath(pLayout, "/root/page[1]/body/section[6]/txt[1]/SwParaPortion/SwLineLayout[1]",
2555 "portion", "Text after section");
2558 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf97899)
2560 createSwDoc();
2561 SwDoc* pDoc = getSwDoc();
2562 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2563 SwPaM* pCursor = pDoc->GetEditShell()->GetCursor();
2564 IDocumentContentOperations& rIDCO(pDoc->getIDocumentContentOperations());
2566 // Create an Ordered List
2567 rIDCO.InsertString(*pCursor, "\ta");
2568 pWrtShell->SplitNode();
2569 rIDCO.InsertString(*pCursor, " b");
2570 pWrtShell->SplitNode();
2571 rIDCO.InsertString(*pCursor, " \t c");
2573 dispatchCommand(mxComponent, ".uno:SelectAll", {});
2574 dispatchCommand(mxComponent, ".uno:DefaultNumbering", {});
2576 // tdf#109285: RemoveLeadingWhiteSpace from all numbered paragraphs
2577 getParagraph(1, "a");
2578 getParagraph(2, "b");
2579 getParagraph(3, "c");
2581 // Save it as DOCX & load it again
2582 saveAndReload("Office Open XML Text");
2583 uno::Reference<container::XIndexAccess> xNumberingRules
2584 = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules");
2585 CPPUNIT_ASSERT(xNumberingRules->getCount());
2586 uno::Sequence<beans::PropertyValue> aNumbering;
2587 xNumberingRules->getByIndex(0) >>= aNumbering;
2588 OUString sCharStyleName;
2589 for (const auto& prop : aNumbering)
2591 if (prop.Name == "CharStyleName")
2593 prop.Value >>= sCharStyleName;
2594 break;
2597 CPPUNIT_ASSERT(!sCharStyleName.isEmpty());
2600 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf40142)
2602 createSwDoc("tdf40142.odt");
2603 dispatchCommand(mxComponent, ".uno:UpdateAllIndexes", {});
2605 xmlDocUniquePtr pLayout = parseLayoutDump();
2606 // Without the fix in place, this test would have failed with
2607 // - Expected: 2
2608 // - Actual : 4
2609 assertXPath(pLayout, "/root/page[1]/body/section[2]/txt", 2);
2612 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151462)
2614 createSwDoc("tdf151462.odt");
2615 dispatchCommand(mxComponent, ".uno:UpdateAllIndexes", {});
2617 xmlDocUniquePtr pLayout = parseLayoutDump();
2618 // Without the fix in place, there would be just the first index entry
2619 assertXPath(pLayout,
2620 "/root/page[1]/body/txt[2]/anchored/fly/section/txt[1]/SwParaPortion/"
2621 "SwLineLayout[1]/SwLinePortion[1]",
2622 "portion", "sub one");
2623 assertXPath(pLayout,
2624 "/root/page[1]/body/txt[2]/anchored/fly/section/txt[2]/SwParaPortion/"
2625 "SwLineLayout[1]/SwLinePortion[1]",
2626 "portion", "sub two");
2627 assertXPath(pLayout,
2628 "/root/page[1]/body/txt[2]/anchored/fly/section/txt[3]/SwParaPortion/"
2629 "SwLineLayout[1]/SwLinePortion[1]",
2630 "portion", "sub three");
2632 // Without the fix in place, there would be just the first index entry
2633 assertXPath(pLayout,
2634 "/root/page[1]/body/txt[6]/anchored/fly/section/txt[1]/SwParaPortion/"
2635 "SwLineLayout[1]/SwLinePortion[1]",
2636 "portion", "another sub one");
2637 assertXPath(pLayout,
2638 "/root/page[1]/body/txt[6]/anchored/fly/section/txt[2]/SwParaPortion/"
2639 "SwLineLayout[1]/SwLinePortion[1]",
2640 "portion", "another sub two");
2641 assertXPath(pLayout,
2642 "/root/page[1]/body/txt[6]/anchored/fly/section/txt[3]/SwParaPortion/"
2643 "SwLineLayout[1]/SwLinePortion[1]",
2644 "portion", "another sub three");
2647 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf151801)
2649 Resetter resetter([]() {
2650 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
2651 comphelper::ConfigurationChanges::create());
2652 officecfg::Office::Common::AutoCorrect::SingleQuoteAtStart::set(0, pBatch);
2653 officecfg::Office::Common::AutoCorrect::SingleQuoteAtEnd::set(0, pBatch);
2654 return pBatch->commit();
2656 // Set Single Quotes › and ‹
2657 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
2658 comphelper::ConfigurationChanges::create());
2659 officecfg::Office::Common::AutoCorrect::SingleQuoteAtStart::set(8250, pBatch);
2660 officecfg::Office::Common::AutoCorrect::SingleQuoteAtEnd::set(8249, pBatch);
2661 pBatch->commit();
2663 createSwDoc("tdf151801.fodt");
2664 SwDoc* pDoc = getSwDoc();
2665 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2666 CPPUNIT_ASSERT(pWrtShell);
2667 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
2668 // Single starting quote: 'word -> ›word
2669 emulateTyping(*pTextDoc, u"'word");
2670 OUString sReplaced(u"\u203Aword");
2671 CPPUNIT_ASSERT_EQUAL(sReplaced, getParagraph(1)->getString());
2672 // Single ending quote: ›word' -> ›word‹
2673 emulateTyping(*pTextDoc, u"'");
2674 sReplaced += u"\u2039";
2675 CPPUNIT_ASSERT_EQUAL(sReplaced, getParagraph(1)->getString());
2676 // Use apostrophe without preceding starting quote: word' -> word’
2677 emulateTyping(*pTextDoc, u" word'");
2678 sReplaced += u" word\u2019";
2679 CPPUNIT_ASSERT_EQUAL(sReplaced, getParagraph(1)->getString());
2682 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testCursorPositionAfterUndo)
2684 createSwDoc("cursor_position_after_undo.odt");
2685 SwDoc* pDoc = getSwDoc();
2686 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2688 // switch on "Outline Folding" mode
2689 dispatchCommand(mxComponent, ".uno:ShowOutlineContentVisibilityButton", {});
2690 CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton());
2692 // move the cursor to the beginning of the 3rd word in the 3rd paragraph, "tincidunt"
2693 pWrtShell->FwdPara();
2694 pWrtShell->FwdPara();
2695 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 16, /*bBasicCall=*/false);
2697 // select the word
2698 dispatchCommand(mxComponent, ".uno:SelectWord", {});
2700 // check the word is select
2701 SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
2702 CPPUNIT_ASSERT_EQUAL(OUString("tincidunt"), pShellCursor->GetText());
2704 // remember the cursor position for comparison
2705 SwPosition aCursorPos(*pWrtShell->GetCursor()->GetPoint());
2707 // delete the selected word
2708 pWrtShell->Delete();
2710 // undo delete
2711 dispatchCommand(mxComponent, ".uno:Undo", {});
2713 // without the fix in place, the cursor would have been set to the start of the outline node
2714 // - Expected: SwPosition (node 11, offset 25)
2715 // - Actual : SwPosition (node 9, offset 0)
2716 CPPUNIT_ASSERT_EQUAL(aCursorPos, *pWrtShell->GetCursor()->GetPoint());
2718 // switch off "Outline Folding" mode
2719 dispatchCommand(mxComponent, ".uno:ShowOutlineContentVisibilityButton", {});
2720 CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton());
2723 CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf73483)
2725 // Given a document with a first paragraph having a manually set page break with page style
2726 createSwDoc("pageBreakWithPageStyle.fodt");
2727 SwDoc* pDoc = getSwDoc();
2728 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
2730 CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), pWrtShell->GetCurPageStyle());
2732 dispatchCommand(mxComponent, ".uno:ResetAttributes", {}); // Ctrl+M "Clear Direct Formatting"
2733 // Make sure that clearing direct formatting doesn't clear the page style
2734 CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), pWrtShell->GetCurPageStyle());
2736 // Make sure that the page break with page style survives ODF save-and-reload
2737 saveAndReload("writer8");
2739 xmlDocUniquePtr pXml = parseExport("content.xml");
2740 CPPUNIT_ASSERT(pXml);
2741 OUString para_style_name
2742 = getXPath(pXml, "/office:document-content/office:body/office:text/text:p", "style-name");
2743 // Without the fix in place, this would fail
2744 CPPUNIT_ASSERT(!para_style_name.equalsIgnoreAsciiCase("Standard"));
2746 OString para_style_path
2747 = "/office:document-content/office:automatic-styles/style:style[@style:name='"
2748 + para_style_name.toUtf8() + "']";
2749 assertXPath(pXml, para_style_path, "family", "paragraph");
2750 // Without the fix in place, the autostyle had no parent
2751 assertXPath(pXml, para_style_path, "parent-style-name", "Standard");
2752 assertXPath(pXml, para_style_path, "master-page-name", "Right_20_Page");
2755 CPPUNIT_PLUGIN_IMPLEMENT();
2757 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */