1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <swmodeltestbase.hxx>
12 #include <unotools/mediadescriptor.hxx>
14 #include <unotxdoc.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
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();
41 rtl::Reference
<SwTransferable
> pTransfer
= new SwTransferable(*pWrtShell
);
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();
67 rtl::Reference
<SwTransferable
> pTransfer
= new SwTransferable(*pWrtShell
);
69 auto& rSpzFrameFormats
= *pDoc
->GetSpzFrameFormats();
70 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rSpzFrameFormats
.size());
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:
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:
94 rtl::Reference
<SwTransferable
> pTransfer
= new SwTransferable(*pWrtShell
);
96 TransferableDataHelper
aHelper(pTransfer
);
97 SwTransferable::Paste(*pWrtShell
, aHelper
);
99 // Without the accompanying fix in place, this test would have crashed.
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));
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));
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");
154 SwDoc
* pDoc
= getSwDoc();
155 const auto& rFormats
= *pDoc
->GetSpzFrameFormats();
156 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), rFormats
.size());
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: */