Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / qa / core / undo / undo.cxx
blob7b68e1b3b25981d9e343798a11e14946566c9401
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>
12 #include <unotools/mediadescriptor.hxx>
14 #include <unotxdoc.hxx>
15 #include <docsh.hxx>
16 #include <wrtsh.hxx>
17 #include <swdtflvr.hxx>
18 #include <frameformats.hxx>
19 #include <fmtcntnt.hxx>
21 /// Covers sw/source/core/undo/ fixes.
22 class SwCoreUndoTest : public SwModelTestBase
24 public:
25 SwCoreUndoTest()
26 : SwModelTestBase("/sw/qa/core/undo/data/")
31 CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testTextboxCutSave)
33 // Load the document and select all.
34 createSwDoc("textbox-cut-save.docx");
35 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
36 SwDocShell* pDocShell = pTextDoc->GetDocShell();
37 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
38 pWrtShell->SelAll();
40 // Cut.
41 rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
42 pTransfer->Cut();
44 // Undo.
45 pWrtShell->Undo();
47 // Save.
48 uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
49 utl::MediaDescriptor aMediaDescriptor;
50 aMediaDescriptor["FilterName"] <<= OUString("Office Open XML Text");
52 // Without the accompanying fix in place, this test would have failed with:
53 // void sax_fastparser::FastSaxSerializer::endDocument(): Assertion `mbMarkStackEmpty && maMarkStack.empty()' failed.
54 // i.e. failed to save because we tried to write not-well-formed XML.
55 xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
58 CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testTextboxCutUndo)
60 createSwDoc("textbox-cut-undo.docx");
61 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
62 SwDocShell* pDocShell = pTextDoc->GetDocShell();
63 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
64 SwDoc* pDoc = pDocShell->GetDoc();
66 selectShape(1);
67 rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
68 pTransfer->Cut();
69 auto& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
70 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rSpzFrameFormats.size());
72 pWrtShell->Undo();
73 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rSpzFrameFormats.size());
75 const SwNodeIndex* pIndex1 = rSpzFrameFormats[0]->GetContent().GetContentIdx();
76 const SwNodeIndex* pIndex2 = rSpzFrameFormats[1]->GetContent().GetContentIdx();
77 // Without the accompanying fix in place, this test would have failed with:
78 // - Expected: 5
79 // - Actual : 8
80 // i.e. the draw frame format had a wrong node index in its content.
81 CPPUNIT_ASSERT_EQUAL(pIndex1->GetIndex(), pIndex2->GetIndex());
84 CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testTableCopyRedline)
86 // Given a document with two table cells and redlining enabled:
87 createSwDoc("table-copy-redline.odt");
88 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
89 SwDocShell* pDocShell = pTextDoc->GetDocShell();
90 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
92 // When doing select-all, copy, paste and undo:
93 pWrtShell->SelAll();
94 rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
95 pTransfer->Copy();
96 TransferableDataHelper aHelper(pTransfer);
97 SwTransferable::Paste(*pWrtShell, aHelper);
99 // Without the accompanying fix in place, this test would have crashed.
100 pWrtShell->Undo();
103 CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testImagePropsCreateUndoAndModifyDoc)
105 createSwDoc("image-as-character.odt");
106 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
107 SwDocShell* pDocShell = pTextDoc->GetDocShell();
108 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
109 css::uno::Reference<css::beans::XPropertySet> xImage(
110 pTextDoc->getGraphicObjects()->getByName("Image1"), css::uno::UNO_QUERY_THROW);
112 CPPUNIT_ASSERT(pTextDoc->isSetModifiedEnabled());
113 CPPUNIT_ASSERT(!pTextDoc->isModified());
114 CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
116 // Check that modifications of the geometry mark document dirty, and create an undo
118 xImage->setPropertyValue("RelativeWidth", css::uno::Any(sal_Int16(80)));
120 // Without the fix, this would fail
121 CPPUNIT_ASSERT(pTextDoc->isModified());
122 CPPUNIT_ASSERT(pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
124 pWrtShell->Undo();
125 CPPUNIT_ASSERT(!pTextDoc->isModified());
126 CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
128 // Check that modifications of anchor mark document dirty, and create an undo
130 xImage->setPropertyValue("AnchorType",
131 css::uno::Any(css::text::TextContentAnchorType_AT_PARAGRAPH));
133 CPPUNIT_ASSERT(pTextDoc->isModified());
134 CPPUNIT_ASSERT(pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
136 pWrtShell->Undo();
137 CPPUNIT_ASSERT(!pTextDoc->isModified());
138 CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
140 // Check that setting the same values do not make it dirty and do not add undo
142 xImage->setPropertyValue("RelativeWidth", xImage->getPropertyValue("RelativeWidth"));
143 xImage->setPropertyValue("AnchorType", xImage->getPropertyValue("AnchorType"));
145 CPPUNIT_ASSERT(!pTextDoc->isModified());
146 CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
149 CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testAnchorTypeChangePosition)
151 // Given a document with a textbox (draw + fly format pair) + an inner image:
152 createSwDoc("anchor-type-change-position.docx");
153 selectShape(1);
154 SwDoc* pDoc = getSwDoc();
155 const auto& rFormats = *pDoc->GetSpzFrameFormats();
156 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), rFormats.size());
157 Point aOldPos;
159 const SwFormatHoriOrient& rHoriOrient = rFormats[0]->GetHoriOrient();
160 const SwFormatVertOrient& rVertOrient = rFormats[0]->GetVertOrient();
161 aOldPos = Point(rHoriOrient.GetPos(), rVertOrient.GetPos());
164 // When changing the anchor type + undo:
165 dispatchCommand(mxComponent, ".uno:SetAnchorToChar", {});
166 dispatchCommand(mxComponent, ".uno:Undo", {});
168 // Then make sure the old position is also restored:
169 const SwFormatHoriOrient& rHoriOrient = rFormats[0]->GetHoriOrient();
170 const SwFormatVertOrient& rVertOrient = rFormats[0]->GetVertOrient();
171 Point aNewPos(rHoriOrient.GetPos(), rVertOrient.GetPos());
172 // Without the accompanying fix in place, this test would have failed with:
173 // - Expected: 789,213
174 // - Actual : 1578,3425
175 // i.e. there was a big, unexpected increase in the vertical position after undo.
176 CPPUNIT_ASSERT_EQUAL(aOldPos, aNewPos);
179 CPPUNIT_PLUGIN_IMPLEMENT();
181 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */