tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / sw / qa / extras / uiwriter / uiwriter9.cxx
blob66ef51e47102dca223a0bd419983d37c62fe8252
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 <officecfg/Office/Common.hxx>
12 #include <com/sun/star/document/XEmbeddedObjectSupplier2.hpp>
13 #include <com/sun/star/embed/EmbedStates.hpp>
14 #include <com/sun/star/embed/XEmbeddedObject.hpp>
15 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
16 #include <vcl/scheduler.hxx>
18 #include <com/sun/star/awt/FontWeight.hpp>
19 #include <com/sun/star/awt/FontSlant.hpp>
20 #include <com/sun/star/table/TableBorder2.hpp>
21 #include <com/sun/star/text/XDocumentIndex.hpp>
22 #include <com/sun/star/text/XTextFrame.hpp>
23 #include <com/sun/star/text/XTextTable.hpp>
24 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
25 #include <com/sun/star/text/XPageCursor.hpp>
26 #include <com/sun/star/text/XParagraphCursor.hpp>
27 #include <com/sun/star/view/XSelectionSupplier.hpp>
29 #include <comphelper/lok.hxx>
30 #include <comphelper/propertysequence.hxx>
31 #include <comphelper/propertyvalue.hxx>
32 #include <comphelper/sequence.hxx>
33 #include <comphelper/scopeguard.hxx>
34 #include <comphelper/configuration.hxx>
35 #include <swdtflvr.hxx>
36 #include <o3tl/string_view.hxx>
37 #include <editeng/acorrcfg.hxx>
38 #include <swacorr.hxx>
39 #include <sfx2/linkmgr.hxx>
41 #include <view.hxx>
42 #include <wrtsh.hxx>
43 #include <unotxdoc.hxx>
44 #include <itabenum.hxx>
45 #include <ndtxt.hxx>
46 #include <toxmgr.hxx>
47 #include <IDocumentFieldsAccess.hxx>
48 #include <IDocumentLayoutAccess.hxx>
49 #include <IDocumentRedlineAccess.hxx>
50 #include <IDocumentLinksAdministration.hxx>
51 #include <fmtinfmt.hxx>
52 #include <rootfrm.hxx>
53 #include <svx/svdview.hxx>
54 #include <svx/svdmark.hxx>
56 namespace
58 class SwUiWriterTest9 : public SwModelTestBase
60 public:
61 SwUiWriterTest9()
62 : SwModelTestBase(u"/sw/qa/extras/uiwriter/data/"_ustr)
67 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf158785)
69 // given a document with a hyperlink surrounded by N-dashes (–www.dordt.edu–)
70 createSwDoc("tdf158785_hyperlink.fodt");
71 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
72 CPPUNIT_ASSERT(pWrtShell);
74 // go to the end of the hyperlink
75 pWrtShell->SttEndDoc(/*bStart=*/false);
76 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
77 // get last point that will be part of the hyperlink (current position 1pt wide).
78 Point aLogicL(pWrtShell->GetCharRect().Center());
79 Point aLogicR(aLogicL);
81 // sanity check - we really are right by the hyperlink
82 aLogicL.AdjustX(-1);
83 SwContentAtPos aContentAtPos(IsAttrAtPos::InetAttr);
84 pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
85 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::InetAttr, aContentAtPos.eContentAtPos);
87 // The test: the position of the N-dash should not indicate hyperlink properties
88 // cursor pos would NOT be considered part of the hyperlink, but increase for good measure...
89 aLogicR.AdjustX(1);
90 pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
91 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
94 * tdf#111969: the beginning of the hyperlink should allow the right-click menu to remove it
96 // move cursor (with no selection) to the start of the hyperlink - after the N-dash
97 pWrtShell->SttEndDoc(/*bStart=*/true);
98 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
99 aLogicL = pWrtShell->GetCharRect().Center();
100 aLogicR = aLogicL;
102 // sanity check - we really are right in front of the hyperlink
103 aLogicL.AdjustX(-1);
104 aContentAtPos = IsAttrAtPos::InetAttr;
105 pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
106 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
107 aLogicR.AdjustX(1);
108 aContentAtPos = IsAttrAtPos::InetAttr;
109 pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
110 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::InetAttr, aContentAtPos.eContentAtPos);
112 // Remove the hyperlink
113 dispatchCommand(mxComponent, u".uno:RemoveHyperlink"_ustr, {});
115 // The test: was the hyperlink actually removed?
116 aContentAtPos = IsAttrAtPos::InetAttr;
117 pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
118 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
121 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf111969)
123 // given a document with a field surrounded by N-dashes (–date–)
124 createSwDoc("tdf111969_field.fodt");
125 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
126 CPPUNIT_ASSERT(pWrtShell);
128 // go to the end of the field
129 pWrtShell->SttEndDoc(/*bStart=*/false);
130 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
131 // get last point that will be part of the field (current position 1pt wide).
132 Point aLogicL(pWrtShell->GetCharRect().Center());
133 Point aLogicR(aLogicL);
135 // sanity check - we really are at the right edge of the field
136 aLogicR.AdjustX(1);
137 SwContentAtPos aContentAtPos(IsAttrAtPos::Field);
138 pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
139 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
140 aLogicL.AdjustX(-1);
141 aContentAtPos = IsAttrAtPos::Field;
142 pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
143 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos);
145 // the test: simulate a right-click of a mouse which sets the cursor and then acts on that pos.
146 pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true);
147 CPPUNIT_ASSERT(pWrtShell->GetCurField(true));
150 * An edge case at the start of a field - don't start the field menu on the first N-dash
152 // go to the start of the field
153 pWrtShell->SttEndDoc(/*bStart=*/true);
154 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
155 // get first point that will be part of the field (current position 1pt wide).
156 aLogicL = pWrtShell->GetCharRect().Center();
157 aLogicR = aLogicL;
159 // sanity check - we really are at the left edge of the field
160 aLogicR.AdjustX(1);
161 aContentAtPos = IsAttrAtPos::Field;
162 pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
163 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos);
164 aLogicL.AdjustX(-1);
165 aContentAtPos = IsAttrAtPos::Field;
166 pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
167 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
169 // the test: simulate a right-click of a mouse (at the end-edge of the N-dash)
170 // which sets the cursor and then acts on that pos.
171 pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true);
172 CPPUNIT_ASSERT(!pWrtShell->GetCurField(true));
175 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf111969B)
177 // given a document with a field surrounded by two N-dashes (––date––)
178 createSwDoc("tdf111969_fieldB.fodt");
179 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
180 CPPUNIT_ASSERT(pWrtShell);
182 // go to the start of the field
183 pWrtShell->SttEndDoc(/*bStart=*/true);
184 pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
185 // get first point that will be part of the field (current position 1pt wide).
186 Point aLogicL(pWrtShell->GetCharRect().Center());
187 Point aLogicR(aLogicL);
189 // sanity check - we really are at the left edge of the field
190 aLogicR.AdjustX(1);
191 SwContentAtPos aContentAtPos(IsAttrAtPos::Field);
192 pWrtShell->GetContentAtPos(aLogicR, aContentAtPos);
193 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::Field, aContentAtPos.eContentAtPos);
194 aLogicL.AdjustX(-1);
195 aContentAtPos = IsAttrAtPos::Field;
196 pWrtShell->GetContentAtPos(aLogicL, aContentAtPos);
197 CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos);
199 // the test: simulate a right-click of a mouse (at the end-edge of the second N-dash)
200 // which sets the cursor and then acts on that pos.
201 pWrtShell->SwCursorShell::SetCursor(aLogicL, false, /*Block=*/false, /*FieldInfo=*/true);
202 CPPUNIT_ASSERT(!pWrtShell->GetCurField(true));
205 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159049)
207 // The document contains a shape which has a text with a line break. When copying the text to
208 // clipboard the line break was missing in the RTF flavor of the clipboard.
209 createSwDoc("tdf159049_LineBreakRTFClipboard.fodt");
210 CPPUNIT_ASSERT_EQUAL(1, getShapes());
211 selectShape(1);
213 // Bring shape into text edit mode
214 SwXTextDocument* pTextDoc = getSwTextDoc();
215 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
216 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_RETURN);
217 Scheduler::ProcessEventsToIdle();
218 // Copy text
219 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
220 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
222 // Deactivate text edit mode ...
223 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE);
224 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_ESCAPE);
225 Scheduler::ProcessEventsToIdle();
226 // ... and deselect shape.
227 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE);
228 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_ESCAPE);
229 Scheduler::ProcessEventsToIdle();
231 // Paste special as RTF
232 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
233 { { "SelectedFormat", uno::Any(static_cast<sal_uInt32>(SotClipboardFormatId::RTF)) } }));
234 dispatchCommand(mxComponent, u".uno:ClipboardFormatItems"_ustr, aArgs);
235 // Without fix Actual was "Abreakhere", the line break \n was missing.
236 CPPUNIT_ASSERT_EQUAL(u"Abreak\nhere"_ustr, getParagraph(1)->getString());
239 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf135083)
241 createSwDoc("tdf135083-simple-text-plus-list.fodt");
243 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
244 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
246 // Paste special as RTF
247 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
248 { { u"SelectedFormat"_ustr,
249 uno::Any(static_cast<sal_uInt32>(SotClipboardFormatId::RTF)) } }));
250 dispatchCommand(mxComponent, u".uno:ClipboardFormatItems"_ustr, aArgs);
252 auto xLastPara = getParagraph(3);
253 CPPUNIT_ASSERT_EQUAL(u"dolor"_ustr, xLastPara->getString());
254 // Without the fix in place, the last paragraph would loose its settings. ListId would be empty.
255 CPPUNIT_ASSERT(!getProperty<OUString>(xLastPara, u"ListId"_ustr).isEmpty());
258 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testHiddenSectionsAroundPageBreak)
260 createSwDoc("hiddenSectionsAroundPageBreak.fodt");
262 CPPUNIT_ASSERT_EQUAL(1, getPages());
264 auto xModel(mxComponent.queryThrow<frame::XModel>());
265 auto xTextViewCursorSupplier(
266 xModel->getCurrentController().queryThrow<text::XTextViewCursorSupplier>());
267 auto xCursor(xTextViewCursorSupplier->getViewCursor().queryThrow<text::XPageCursor>());
269 // Make sure that the page style is set correctly
270 xCursor->jumpToFirstPage();
271 CPPUNIT_ASSERT_EQUAL(u"Landscape"_ustr, getProperty<OUString>(xCursor, u"PageStyleName"_ustr));
274 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159565)
276 // Given a document with a hidden section in the beginning, additionally containing a frame
277 createSwDoc("FrameInHiddenSection.fodt");
279 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
281 // Check that the selection covers the whole visible text
282 auto xModel(mxComponent.queryThrow<css::frame::XModel>());
283 auto xSelSupplier(xModel->getCurrentController().queryThrow<css::view::XSelectionSupplier>());
284 auto xSelections(xSelSupplier->getSelection().queryThrow<css::container::XIndexAccess>());
285 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSelections->getCount());
286 auto xSelection(xSelections->getByIndex(0).queryThrow<css::text::XTextRange>());
288 // Without the fix, this would fail - there was no selection
289 CPPUNIT_ASSERT_EQUAL(u"" SAL_NEWLINE_STRING SAL_NEWLINE_STRING "ipsum"_ustr,
290 xSelection->getString());
293 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159816)
295 createSwDoc();
297 SwDoc* pDoc = getSwDoc();
298 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
299 CPPUNIT_ASSERT(pWrtShell);
301 // Add 5 empty paragraphs
302 pWrtShell->SplitNode();
303 pWrtShell->SplitNode();
304 pWrtShell->SplitNode();
305 pWrtShell->SplitNode();
306 pWrtShell->SplitNode();
308 // Add a bookmark at the very end
309 IDocumentMarkAccess& rIDMA(*pDoc->getIDocumentMarkAccess());
310 rIDMA.makeMark(*pWrtShell->GetCursor(), u"Mark"_ustr, IDocumentMarkAccess::MarkType::BOOKMARK,
311 sw::mark::InsertMode::New);
313 // Get coordinates of the end point in the document
314 SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
315 SwFrame* pPage = pLayout->Lower();
316 SwFrame* pBody = pPage->GetLower();
317 SwFrame* pLastPara = pBody->GetLower()->GetNext()->GetNext()->GetNext()->GetNext()->GetNext();
318 Point ptTo = pLastPara->getFrameArea().BottomRight();
320 pWrtShell->SelAll();
322 // Drag-n-drop to its own end
323 rtl::Reference<SwTransferable> xTransfer = new SwTransferable(*pWrtShell);
324 // Without the fix, this would crash: either in CopyFlyInFlyImpl (tdf#159813):
325 // Assertion failed: !pCopiedPaM || pCopiedPaM->End()->GetNode() == rRg.aEnd.GetNode()
326 // or in BigPtrArray::operator[] (tdf#159816):
327 // Assertion failed: idx < m_nSize
328 xTransfer->PrivateDrop(*pWrtShell, ptTo, /*bMove=*/true, /*bXSelection=*/true);
331 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf34804)
333 createSwDoc();
334 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
336 // Simulate a keyboard shortcut to SID_ATTR_CHAR_COLOR2 (which must use the shared button color)
337 dispatchCommand(mxComponent, u".uno:FontColor"_ustr, {});
338 pWrtShell->Insert(u"New World!"_ustr);
340 const uno::Reference<text::XTextRange> xRun = getRun(getParagraph(1, "New World!"), 1);
341 // (This test assumes that nothing in the unit tests has modified the app's recent font color)
342 // COL_DEFAULT_FONT is the default red color for the fontColor button on the toolbar.
343 CPPUNIT_ASSERT_EQUAL(COL_DEFAULT_FONT, getProperty<Color>(xRun, u"CharColor"_ustr));
346 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf139631)
348 // Unit test for tdf#139631
349 // Test to see if preceding space is cut when cutting a word with track changes (redline) on
350 createSwDoc();
351 SwDoc* pDoc = getSwDoc();
352 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
354 pWrtShell->Insert(u"New World!\""_ustr);
355 // Assert that the string, New World!", is inserted correctly into the document
356 CPPUNIT_ASSERT_EQUAL(u"New World!\""_ustr, getParagraph(1)->getString());
358 // Enable redline
359 dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
360 CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
361 // Hide redline changes
362 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
363 CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
365 pWrtShell->Left(SwCursorSkipMode::Chars, false, 2, false);
366 // Select and cut "World" from string
367 pWrtShell->Left(SwCursorSkipMode::Chars, true, 5, false);
368 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
369 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
370 pXmlDoc = parseLayoutDump();
371 // Verifies that the leading space before "World" was also cut
372 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
373 "portion", u"New!\"");
375 // Reset to initial string
376 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
377 pXmlDoc = parseLayoutDump();
378 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
379 "portion", u"New World!\"");
381 pWrtShell->EndPara(false);
382 pWrtShell->Left(SwCursorSkipMode::Chars, false, 1, false);
383 // Replace ! with .
384 pWrtShell->Left(SwCursorSkipMode::Chars, true, 1, false);
385 pWrtShell->Delete();
386 pWrtShell->Insert(u"."_ustr);
387 pXmlDoc = parseLayoutDump();
388 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
389 "portion", u"New World.\"");
391 pWrtShell->Left(SwCursorSkipMode::Chars, false, 1, false);
392 // Select and cut "World" from string
393 pWrtShell->Left(SwCursorSkipMode::Chars, true, 5, false);
394 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
396 pXmlDoc = parseLayoutDump();
397 // Without the test in place, the leading space before "World" is not also cut.
398 // Expected: New."
399 // Actual: New ."
400 assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
401 "portion", u"New.\"");
404 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf151710)
406 createSwDoc();
408 // Check that the particular setting is turned on by default
409 const SwViewOption* pVwOpt = getSwDocShell()->GetWrtShell()->GetViewOptions();
410 CPPUNIT_ASSERT(pVwOpt);
411 CPPUNIT_ASSERT(pVwOpt->IsEncloseWithCharactersOn());
413 // Localized quotation marks
414 SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect();
415 CPPUNIT_ASSERT(pACorr);
416 LanguageType eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
417 OUString sStartSingleQuote{ pACorr->GetQuote('\'', true, eLang) };
418 OUString sEndSingleQuote{ pACorr->GetQuote('\'', false, eLang) };
419 OUString sStartDoubleQuote{ pACorr->GetQuote('\"', true, eLang) };
420 OUString sEndDoubleQuote{ pACorr->GetQuote('\"', false, eLang) };
422 // Insert some text to work with
423 uno::Sequence<beans::PropertyValue> aArgsInsert(
424 comphelper::InitPropertySequence({ { "Text", uno::Any(u"abcd"_ustr) } }));
425 dispatchCommand(mxComponent, u".uno:InsertText"_ustr, aArgsInsert);
426 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
427 CPPUNIT_ASSERT_EQUAL(u"abcd"_ustr, xTextDocument->getText()->getString());
429 // Successfully enclose the text; afterwards the selection should exist with the new
430 // enclosed text
431 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
432 SwXTextDocument* pTextDoc = getSwTextDoc();
433 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '(', 0);
434 Scheduler::ProcessEventsToIdle();
435 CPPUNIT_ASSERT_EQUAL(u"(abcd)"_ustr, xTextDocument->getText()->getString());
437 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '[', 0);
438 Scheduler::ProcessEventsToIdle();
439 CPPUNIT_ASSERT_EQUAL(u"[(abcd)]"_ustr, xTextDocument->getText()->getString());
441 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '{', 0);
442 Scheduler::ProcessEventsToIdle();
443 CPPUNIT_ASSERT_EQUAL(u"{[(abcd)]}"_ustr, xTextDocument->getText()->getString());
445 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '\'', 0);
446 Scheduler::ProcessEventsToIdle();
447 CPPUNIT_ASSERT_EQUAL(OUString(sStartSingleQuote + "{[(abcd)]}" + sEndSingleQuote),
448 xTextDocument->getText()->getString());
450 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '\"', 0);
451 Scheduler::ProcessEventsToIdle();
452 CPPUNIT_ASSERT_EQUAL(OUString(sStartDoubleQuote + sStartSingleQuote + "{[(abcd)]}"
453 + sEndSingleQuote + sEndDoubleQuote),
454 xTextDocument->getText()->getString());
456 // Disable the setting and check that enclosing doesn't happen anymore
457 const_cast<SwViewOption*>(pVwOpt)->SetEncloseWithCharactersOn(false);
458 CPPUNIT_ASSERT(!pVwOpt->IsEncloseWithCharactersOn());
460 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '(', 0);
461 Scheduler::ProcessEventsToIdle();
462 CPPUNIT_ASSERT_EQUAL(u"("_ustr, xTextDocument->getText()->getString());
464 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
465 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '[', 0);
466 Scheduler::ProcessEventsToIdle();
467 CPPUNIT_ASSERT_EQUAL(u"["_ustr, xTextDocument->getText()->getString());
469 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
470 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '{', 0);
471 Scheduler::ProcessEventsToIdle();
472 CPPUNIT_ASSERT_EQUAL(u"{"_ustr, xTextDocument->getText()->getString());
474 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
475 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '\'', 0);
476 Scheduler::ProcessEventsToIdle();
477 CPPUNIT_ASSERT_EQUAL(sStartSingleQuote, xTextDocument->getText()->getString());
479 dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
480 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, '\"', 0);
481 Scheduler::ProcessEventsToIdle();
482 CPPUNIT_ASSERT_EQUAL(sStartDoubleQuote, xTextDocument->getText()->getString());
485 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159054_disableOutlineNumbering)
487 createSwDoc("tdf159054_disableOutlineNumbering.docx");
488 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
490 const uno::Reference<text::XTextRange> xPara1 = getParagraph(1, u"Heading A"_ustr);
491 const uno::Reference<text::XTextRange> xPara2 = getParagraph(2, u"Heading B"_ustr);
492 const uno::Reference<text::XTextRange> xPara3 = getParagraph(3, u"Heading C"_ustr);
494 CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xPara1, u"ListLabelString"_ustr));
495 CPPUNIT_ASSERT_EQUAL(u"B."_ustr, getProperty<OUString>(xPara2, u"ListLabelString"_ustr));
496 CPPUNIT_ASSERT_EQUAL(u"C."_ustr, getProperty<OUString>(xPara3, u"ListLabelString"_ustr));
498 // select (at least parts) of the first two paragraphs
499 pWrtShell->Down(/*bSelect=*/true, /*nCount=*/1, /*bBasicCall=*/true);
501 // on the selection, simulate pressing the toolbar button to toggle OFF numbering
502 dispatchCommand(mxComponent, u".uno:DefaultNumbering"_ustr, {});
504 // the selected paragraphs should definitely have the list label removed
505 CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara1, u"ListLabelString"_ustr));
506 CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara2, u"ListLabelString"_ustr));
507 // the third paragraph must retain the existing numbering format
508 CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xPara3, u"ListLabelString"_ustr));
510 // on the selection, simulate pressing the toolbar button to toggle ON numbering again
511 dispatchCommand(mxComponent, u".uno:DefaultNumbering"_ustr, {});
513 // the outline numbering format must be re-applied to the first two paragraphs
514 CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xPara1, u"ListLabelString"_ustr));
515 CPPUNIT_ASSERT_EQUAL(u"B."_ustr, getProperty<OUString>(xPara2, u"ListLabelString"_ustr));
516 CPPUNIT_ASSERT_EQUAL(u"C."_ustr, getProperty<OUString>(xPara3, u"ListLabelString"_ustr));
518 // on the selection, simulate a right click - list - No list
519 dispatchCommand(mxComponent, u".uno:RemoveBullets"_ustr, {});
521 // the selected paragraphs should definitely have the list label removed
522 CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara1, u"ListLabelString"_ustr));
523 CPPUNIT_ASSERT_EQUAL(u""_ustr, getProperty<OUString>(xPara2, u"ListLabelString"_ustr));
524 CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xPara3, u"ListLabelString"_ustr));
527 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf158375_dde_disable)
529 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
530 comphelper::ConfigurationChanges::create());
531 officecfg::Office::Common::Security::Scripting::DisableActiveContent::set(true, pBatch);
532 pBatch->commit();
533 comphelper::ScopeGuard g([] {
534 std::shared_ptr<comphelper::ConfigurationChanges> _pBatch(
535 comphelper::ConfigurationChanges::create());
536 officecfg::Office::Common::Security::Scripting::DisableActiveContent::set(false, _pBatch);
537 _pBatch->commit();
540 createSwDoc();
541 SwDoc* pDoc = getSwDoc();
543 // force the AppName to enable DDE, it is not there for test runs
544 Application::SetAppName(u"soffice"_ustr);
546 // temp copy for the file that will be used as a reference for DDE link
547 // this file includes a section named "Section1" with text inside
548 createTempCopy(u"tdf158375_dde_reference.fodt");
550 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer
551 = getSwDocShell()->getEmbeddedObjectContainer();
552 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);
554 // create a section with DDE link
555 uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
556 uno::Reference<beans::XPropertySet> xTextSectionProps(
557 xFactory->createInstance(u"com.sun.star.text.TextSection"_ustr), uno::UNO_QUERY);
559 uno::Sequence<OUString> aNames{ u"DDECommandFile"_ustr, u"DDECommandType"_ustr,
560 u"DDECommandElement"_ustr, u"IsAutomaticUpdate"_ustr,
561 u"IsProtected"_ustr };
562 uno::Sequence<uno::Any> aValues{ uno::Any(u"soffice"_ustr), uno::Any(maTempFile.GetURL()),
563 uno::Any(u"Section1"_ustr), uno::Any(true), uno::Any(true) };
564 uno::Reference<beans::XMultiPropertySet> rMultiPropSet(xTextSectionProps, uno::UNO_QUERY);
565 rMultiPropSet->setPropertyValues(aNames, aValues);
567 // insert the TextSection with DDE link
568 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
569 uno::Reference<text::XTextRange> xTextRange = xTextDocument->getText();
570 uno::Reference<text::XText> xText = xTextRange->getText();
571 uno::Reference<text::XParagraphCursor> xCursor(xText->createTextCursor(), uno::UNO_QUERY);
572 xText->insertTextContent(
573 xCursor, uno::Reference<text::XTextContent>(xTextSectionProps, uno::UNO_QUERY), false);
575 CPPUNIT_ASSERT_EQUAL(
576 size_t(1), pDoc->getIDocumentLinksAdministration().GetLinkManager().GetLinks().size());
578 pDoc->getIDocumentLinksAdministration().GetLinkManager().UpdateAllLinks(false, false, nullptr,
579 u""_ustr);
581 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
582 uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(),
583 uno::UNO_QUERY);
584 uno::Reference<text::XTextSection> xSection(xSections->getByIndex(0), uno::UNO_QUERY);
586 // make sure there's no text in the section after UpdateAllLinks, since
587 // DisableActiveContent disables DDE links.
588 CPPUNIT_ASSERT_EQUAL(u""_ustr, xSection->getAnchor()->getString());
591 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf158375_ole_object_disable)
593 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
594 comphelper::ConfigurationChanges::create());
595 officecfg::Office::Common::Security::Scripting::DisableActiveContent::set(true, pBatch);
596 pBatch->commit();
597 comphelper::ScopeGuard g([] {
598 std::shared_ptr<comphelper::ConfigurationChanges> _pBatch(
599 comphelper::ConfigurationChanges::create());
600 officecfg::Office::Common::Security::Scripting::DisableActiveContent::set(false, _pBatch);
601 _pBatch->commit();
604 // Enable LOK mode, otherwise OCommonEmbeddedObject::SwitchStateTo_Impl() will throw when it
605 // finds out that the test runs headless.
606 comphelper::LibreOfficeKit::setActive();
608 // Load a document with a Draw doc in it.
609 createSwDoc("ole-save-while-edit.odt");
610 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
612 selectShape(1);
614 // attempt to edit the OLE object.
615 pWrtShell->LaunchOLEObj();
617 // it shouldn't switch because the current configuration
618 // (DisableActiveContent) prohibits OLE objects changing to states other
619 // then LOADED
620 auto xShape = getShape(1);
621 uno::Reference<document::XEmbeddedObjectSupplier2> xEmbedSupplier(xShape, uno::UNO_QUERY);
622 auto xEmbeddedObj = xEmbedSupplier->getExtendedControlOverEmbeddedObject();
623 CPPUNIT_ASSERT_EQUAL(embed::EmbedStates::LOADED, xEmbeddedObj->getCurrentState());
625 // Dispose the document while LOK is still active to avoid leaks.
626 mxComponent->dispose();
627 mxComponent.clear();
628 comphelper::LibreOfficeKit::setActive(false);
631 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf146190)
633 // Given a document with a number rule at the start of a paragraph and two drawing objects:
634 createSwDoc("tdf146190.odt");
635 SwDocShell* pDocShell = getSwDocShell();
636 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
638 const SdrMarkList& rMrkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
640 // Assert the current cursor position has a number rule and is at the start of a paragraph:
641 pWrtShell->SttEndDoc(/*bStt=*/true);
642 CPPUNIT_ASSERT(pWrtShell->GetNumRuleAtCurrCursorPos());
643 CPPUNIT_ASSERT(pWrtShell->IsSttOfPara());
645 // Then go to "Shape 1" drawing object using the GotoDrawingObject function:
646 pWrtShell->GotoDrawingObject(u"Shape 1");
647 CPPUNIT_ASSERT_EQUAL(u"Shape 1"_ustr, rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
649 // Move to the next drawing object by Tab key press:
650 SwXTextDocument* pTextDoc = getSwTextDoc();
651 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
652 Scheduler::ProcessEventsToIdle();
653 // Without the fix in place, this test would have failed with:
654 // equality assertion failed
655 // - Expected: Shape 2
656 // - Actual : Shape 1
657 // i.e. Tab did not move to the next drawing object
658 CPPUNIT_ASSERT_EQUAL(u"Shape 2"_ustr, rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
660 // Tab key press should now select 'Shape 1':
661 pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
662 Scheduler::ProcessEventsToIdle();
663 CPPUNIT_ASSERT_EQUAL(u"Shape 1"_ustr, rMrkList.GetMark(0)->GetMarkedSdrObj()->GetName());
666 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf160898)
668 // Given a document with a 1-cell table in another 1-cell table:
669 createSwDoc("table-in-table.fodt");
670 SwDocShell* pDocShell = getSwDocShell();
671 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
673 // Move to the normally hidden paragraph inside the outer table cell, following the inner table
674 pWrtShell->Down(false, 2);
675 // Without the fix, this would crash:
676 pWrtShell->SelAll();
679 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf161172)
681 // Given a paragraph manually made a member of a list:
682 createSwDoc("tdf161172.fodt");
683 auto para = getParagraph(1);
685 // Check initial state: the first paragraph has "No_list" para style, "Num_1" numbering style,
686 // numbering level 0, and "Num1_lvl1_1" numbering label.
687 CPPUNIT_ASSERT_EQUAL(u"No_list"_ustr, getProperty<OUString>(para, u"ParaStyleName"_ustr));
688 CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty<OUString>(para, u"NumberingStyleName"_ustr));
689 CPPUNIT_ASSERT_EQUAL(u"Num1_lvl1_1"_ustr, getProperty<OUString>(para, u"ListLabelString"_ustr));
690 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(para, u"NumberingLevel"_ustr));
692 // Assign "Num_1_lvl2" paragraph style to the first paragraph. The style is associated with
693 // "Num_1" numbering style, level 1.
694 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
695 { comphelper::makePropertyValue(u"FamilyName"_ustr, u"ParagraphStyles"_ustr),
696 comphelper::makePropertyValue(u"Style"_ustr, u"Num_1_lvl2"_ustr) });
698 // Check that the respective properties got correctly applied
699 CPPUNIT_ASSERT_EQUAL(u"Num_1_lvl2"_ustr, getProperty<OUString>(para, u"ParaStyleName"_ustr));
700 CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty<OUString>(para, u"NumberingStyleName"_ustr));
701 CPPUNIT_ASSERT_EQUAL(u"Num1_lvl2_1"_ustr, getProperty<OUString>(para, u"ListLabelString"_ustr));
702 CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(para, u"NumberingLevel"_ustr));
704 // Undo
705 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
707 // Check that the numbering properties got correctly restored
708 CPPUNIT_ASSERT_EQUAL(u"No_list"_ustr, getProperty<OUString>(para, u"ParaStyleName"_ustr));
709 CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty<OUString>(para, u"NumberingStyleName"_ustr));
710 // Without the fix, this would fail with
711 // - Expected: Num1_lvl1_1
712 // - Actual : Num1_lvl2_1
713 CPPUNIT_ASSERT_EQUAL(u"Num1_lvl1_1"_ustr, getProperty<OUString>(para, u"ListLabelString"_ustr));
714 // Without the fix, this would fail with
715 // - Expected: 0
716 // - Actual : 1
717 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(para, u"NumberingLevel"_ustr));
720 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf144752)
722 // Undoing/redoing a replacement must select the new text
723 createSwDoc();
724 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
725 CPPUNIT_ASSERT(pWrtShell);
727 emulateTyping(u"Some Text");
728 CPPUNIT_ASSERT(!pWrtShell->HasSelection());
729 // Select "Text", and replace with "Word"
730 pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect*/ true, 4, /*bBasicCall*/ false);
731 pWrtShell->Replace(u"Word"_ustr, false);
732 pWrtShell->EndOfSection();
733 CPPUNIT_ASSERT(!pWrtShell->HasSelection());
735 // Undo and check, that the "Text" is selected
736 dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
737 // Without the fix, this would fail
738 CPPUNIT_ASSERT(pWrtShell->HasSelection());
739 CPPUNIT_ASSERT_EQUAL(u"Text"_ustr, pWrtShell->GetSelText());
741 // Redo and check, that the "Word" is selected
742 dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
743 CPPUNIT_ASSERT(pWrtShell->HasSelection());
744 CPPUNIT_ASSERT_EQUAL(u"Word"_ustr, pWrtShell->GetSelText());
747 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162326_Paragraph)
749 createSwDoc("tdf162326.odt");
750 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
751 CPPUNIT_ASSERT(pWrtShell);
753 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD,
754 getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
755 CPPUNIT_ASSERT_EQUAL(
756 awt::FontSlant_ITALIC,
757 getProperty<awt::FontSlant>(getRun(getParagraph(2), 2), u"CharPosture"_ustr));
758 CPPUNIT_ASSERT_EQUAL(short(1),
759 getProperty<short>(getRun(getParagraph(3), 2), u"CharUnderline"_ustr));
761 pWrtShell->Down(/*bSelect=*/true, 3);
763 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
764 { comphelper::makePropertyValue(u"FamilyName"_ustr, u"ParagraphStyles"_ustr),
765 comphelper::makePropertyValue(u"Style"_ustr, u"Footnote"_ustr),
766 comphelper::makePropertyValue(u"KeyModifier"_ustr, uno::Any(KEY_MOD1)) });
768 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
769 getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
770 CPPUNIT_ASSERT_THROW(getRun(getParagraph(2), 2), css::container::NoSuchElementException);
771 CPPUNIT_ASSERT_THROW(getRun(getParagraph(3), 2), css::container::NoSuchElementException);
774 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162326_Character)
776 createSwDoc("tdf162326.odt");
777 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
778 CPPUNIT_ASSERT(pWrtShell);
780 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD,
781 getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
782 CPPUNIT_ASSERT_EQUAL(
783 awt::FontSlant_ITALIC,
784 getProperty<awt::FontSlant>(getRun(getParagraph(2), 2), u"CharPosture"_ustr));
785 CPPUNIT_ASSERT_EQUAL(short(1),
786 getProperty<short>(getRun(getParagraph(3), 2), u"CharUnderline"_ustr));
788 pWrtShell->Down(/*bSelect=*/true, 3);
790 //add Ctrl/MOD_1
791 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
792 { comphelper::makePropertyValue(u"FamilyName"_ustr, u"CharacterStyles"_ustr),
793 comphelper::makePropertyValue(u"Style"_ustr, u"Definition"_ustr),
794 comphelper::makePropertyValue(u"KeyModifier"_ustr, uno::Any(KEY_MOD1)) });
796 CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
797 getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
798 CPPUNIT_ASSERT_THROW(getRun(getParagraph(2), 2), css::container::NoSuchElementException);
799 //last runs are not changed because the selection ends at the beginning of that paragraph
800 CPPUNIT_ASSERT_EQUAL(short(1),
801 getProperty<short>(getRun(getParagraph(3), 2), u"CharUnderline"_ustr));
804 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162326_List)
806 createSwDoc("tdf162326_list.odt");
807 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
808 uno::Reference<text::XParagraphCursor> xParaCursor(xTextDocument->getText()->createTextCursor(),
809 uno::UNO_QUERY);
811 CPPUNIT_ASSERT_EQUAL(u"A)"_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
813 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
814 { comphelper::makePropertyValue(u"FamilyName"_ustr, u"ParagraphStyles"_ustr),
815 comphelper::makePropertyValue(u"Style"_ustr, u"Footnote"_ustr) });
817 //hard list attribute unchanged
818 CPPUNIT_ASSERT_EQUAL(u"A)"_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
820 dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
821 { comphelper::makePropertyValue(u"FamilyName"_ustr, u"ParagraphStyles"_ustr),
822 comphelper::makePropertyValue(u"Style"_ustr, u"Footnote"_ustr),
823 comphelper::makePropertyValue(u"KeyModifier"_ustr, uno::Any(KEY_MOD1)) });
825 //list replaced by para style list setting
826 CPPUNIT_ASSERT_EQUAL(u"1."_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
829 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf163340)
831 createSwDoc("tdf163340.odt");
832 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
833 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
834 uno::Reference<text::XText> xText = xTextDocument->getText();
835 uno::Reference<view::XSelectionSupplier> xSelSupplier(xModel->getCurrentController(),
836 uno::UNO_QUERY_THROW);
837 uno::Reference<text::XParagraphCursor> xParaCursor(xTextDocument->getText()->createTextCursor(),
838 uno::UNO_QUERY);
840 for (int i = 0; i < 14; i++)
841 xParaCursor->gotoNextParagraph(false);
842 xParaCursor->gotoEndOfParagraph(true);
843 xSelSupplier->select(uno::Any(xParaCursor));
845 CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
846 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
848 xParaCursor = uno::Reference<text::XParagraphCursor>(xText->createTextCursor(), uno::UNO_QUERY);
849 for (int i = 0; i < 3; i++)
850 xParaCursor->gotoNextParagraph(false);
851 xParaCursor->gotoEndOfParagraph(true);
852 CPPUNIT_ASSERT_EQUAL(u"1."_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
853 xSelSupplier->select(uno::Any(xParaCursor));
854 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
855 CPPUNIT_ASSERT_EQUAL(u"A."_ustr, getProperty<OUString>(xParaCursor, u"ListLabelString"_ustr));
858 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159023)
860 createSwDoc();
861 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
863 SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0);
864 pWrtShell->InsertTable(aTableOptions, /*nRows=*/2, /*nCols=*/2);
865 pWrtShell->MoveTable(GotoPrevTable, fnTableStart);
867 dispatchCommand(mxComponent, u".uno:SelectTable"_ustr, {});
868 dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
870 pWrtShell->InsertFootnote(u""_ustr);
871 CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote());
873 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
874 dispatchCommand(mxComponent, u".uno:GoLeft"_ustr, {});
875 dispatchCommand(mxComponent, u".uno:GoLeft"_ustr, {});
877 // Without the fix in place, this test would have crashed here
878 CPPUNIT_ASSERT(pWrtShell->IsCursorInFootnote());
881 CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162195)
883 // Given a document, which has some index entries in a hidden section
884 createSwDoc("IndexElementsInHiddenSections.fodt");
886 auto xIndexSupplier(mxComponent.queryThrow<css::text::XDocumentIndexesSupplier>());
887 auto xIndexes = xIndexSupplier->getDocumentIndexes();
888 CPPUNIT_ASSERT(xIndexes);
889 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexes->getCount()); // A ToC and a table index
891 auto xToC(xIndexes->getByIndex(0).queryThrow<css::text::XDocumentIndex>());
892 xToC->update();
893 // Without the fix, all the elements from the hidden section appeared in the index
894 CPPUNIT_ASSERT_EQUAL(u"Table of Contents" SAL_NEWLINE_STRING "Section Visible\t1"_ustr,
895 xToC->getAnchor()->getString());
897 auto xTables(xIndexes->getByIndex(1).queryThrow<css::text::XDocumentIndex>());
898 xTables->update();
899 // Without the fix, all the elements from the hidden section appeared in the index
900 CPPUNIT_ASSERT_EQUAL(u"Index of Tables" SAL_NEWLINE_STRING "Table1\t1"_ustr,
901 xTables->getAnchor()->getString());
903 // Show the hidden section
904 auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>();
905 auto xSections = xTextSectionsSupplier->getTextSections();
906 CPPUNIT_ASSERT(xSections);
907 auto xSection
908 = xSections->getByName(u"Section Hidden"_ustr).queryThrow<css::beans::XPropertySet>();
909 xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
911 xToC->update();
912 CPPUNIT_ASSERT_EQUAL(u"Table of Contents" SAL_NEWLINE_STRING
913 "Section Visible\t1" SAL_NEWLINE_STRING
914 "Section Hidden\t1" SAL_NEWLINE_STRING "entry\t1" SAL_NEWLINE_STRING
915 "CustomTOCStyle paragraph\t1"_ustr,
916 xToC->getAnchor()->getString());
918 xTables->update();
919 CPPUNIT_ASSERT_EQUAL(u"Index of Tables" SAL_NEWLINE_STRING "Table1\t1" SAL_NEWLINE_STRING
920 "Table2\t1"_ustr,
921 xTables->getAnchor()->getString());
924 } // end of anonymous namespace
925 CPPUNIT_PLUGIN_IMPLEMENT();
927 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */