1
0
Fork 0
libreoffice/sw/qa/core/undo/undo.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

179 lines
6.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <swmodeltestbase.hxx>
#include <unotools/mediadescriptor.hxx>
#include <unotxdoc.hxx>
#include <docsh.hxx>
#include <wrtsh.hxx>
#include <swdtflvr.hxx>
#include <frameformats.hxx>
#include <fmtcntnt.hxx>
/// Covers sw/source/core/undo/ fixes.
class SwCoreUndoTest : public SwModelTestBase
{
public:
SwCoreUndoTest()
: SwModelTestBase(u"/sw/qa/core/undo/data/"_ustr)
{
}
};
CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testTextboxCutSave)
{
// Load the document and select all.
createSwDoc("textbox-cut-save.docx");
SwDocShell* pDocShell = getSwDocShell();
SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
pWrtShell->SelAll();
// Cut.
rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
pTransfer->Cut();
// Undo.
pWrtShell->Undo();
// Save.
uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
utl::MediaDescriptor aMediaDescriptor;
aMediaDescriptor[u"FilterName"_ustr] <<= u"Office Open XML Text"_ustr;
// Without the accompanying fix in place, this test would have failed with:
// void sax_fastparser::FastSaxSerializer::endDocument(): Assertion `mbMarkStackEmpty && maMarkStack.empty()' failed.
// i.e. failed to save because we tried to write not-well-formed XML.
xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
}
CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testTextboxCutUndo)
{
createSwDoc("textbox-cut-undo.docx");
SwDocShell* pDocShell = getSwDocShell();
SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
SwDoc* pDoc = pDocShell->GetDoc();
selectShape(1);
rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
pTransfer->Cut();
auto& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rSpzFrameFormats.size());
pWrtShell->Undo();
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rSpzFrameFormats.size());
const SwNodeIndex* pIndex1 = rSpzFrameFormats[0]->GetContent().GetContentIdx();
const SwNodeIndex* pIndex2 = rSpzFrameFormats[1]->GetContent().GetContentIdx();
// Without the accompanying fix in place, this test would have failed with:
// - Expected: 5
// - Actual : 8
// i.e. the draw frame format had a wrong node index in its content.
CPPUNIT_ASSERT_EQUAL(pIndex1->GetIndex(), pIndex2->GetIndex());
}
CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testTableCopyRedline)
{
// Given a document with two table cells and redlining enabled:
createSwDoc("table-copy-redline.odt");
SwDocShell* pDocShell = getSwDocShell();
SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
// When doing select-all, copy, paste and undo:
pWrtShell->SelAll();
rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
pTransfer->Copy();
TransferableDataHelper aHelper(pTransfer);
SwTransferable::Paste(*pWrtShell, aHelper);
// Without the accompanying fix in place, this test would have crashed.
pWrtShell->Undo();
}
CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testImagePropsCreateUndoAndModifyDoc)
{
createSwDoc("image-as-character.odt");
SwDocShell* pDocShell = getSwDocShell();
SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
SwXTextDocument* pTextDoc = getSwTextDoc();
css::uno::Reference<css::beans::XPropertySet> xImage(
pTextDoc->getGraphicObjects()->getByName(u"Image1"_ustr), css::uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT(pTextDoc->isSetModifiedEnabled());
CPPUNIT_ASSERT(!pTextDoc->isModified());
CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
// Check that modifications of the geometry mark document dirty, and create an undo
xImage->setPropertyValue(u"RelativeWidth"_ustr, css::uno::Any(sal_Int16(80)));
// Without the fix, this would fail
CPPUNIT_ASSERT(pTextDoc->isModified());
CPPUNIT_ASSERT(pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
pWrtShell->Undo();
CPPUNIT_ASSERT(!pTextDoc->isModified());
CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
// Check that modifications of anchor mark document dirty, and create an undo
xImage->setPropertyValue(u"AnchorType"_ustr,
css::uno::Any(css::text::TextContentAnchorType_AT_PARAGRAPH));
CPPUNIT_ASSERT(pTextDoc->isModified());
CPPUNIT_ASSERT(pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
pWrtShell->Undo();
CPPUNIT_ASSERT(!pTextDoc->isModified());
CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
// Check that setting the same values do not make it dirty and do not add undo
xImage->setPropertyValue(u"RelativeWidth"_ustr,
xImage->getPropertyValue(u"RelativeWidth"_ustr));
xImage->setPropertyValue(u"AnchorType"_ustr, xImage->getPropertyValue(u"AnchorType"_ustr));
CPPUNIT_ASSERT(!pTextDoc->isModified());
CPPUNIT_ASSERT(!pWrtShell->GetLastUndoInfo(nullptr, nullptr, nullptr));
}
CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testAnchorTypeChangePosition)
{
// Given a document with a textbox (draw + fly format pair) + an inner image:
createSwDoc("anchor-type-change-position.docx");
selectShape(1);
SwDoc* pDoc = getSwDoc();
const auto& rFormats = *pDoc->GetSpzFrameFormats();
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), rFormats.size());
Point aOldPos;
{
const SwFormatHoriOrient& rHoriOrient = rFormats[0]->GetHoriOrient();
const SwFormatVertOrient& rVertOrient = rFormats[0]->GetVertOrient();
aOldPos = Point(rHoriOrient.GetPos(), rVertOrient.GetPos());
}
// When changing the anchor type + undo:
dispatchCommand(mxComponent, u".uno:SetAnchorToChar"_ustr, {});
dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
// Then make sure the old position is also restored:
const SwFormatHoriOrient& rHoriOrient = rFormats[0]->GetHoriOrient();
const SwFormatVertOrient& rVertOrient = rFormats[0]->GetVertOrient();
Point aNewPos(rHoriOrient.GetPos(), rVertOrient.GetPos());
// Without the accompanying fix in place, this test would have failed with:
// - Expected: 789,213
// - Actual : 1578,3425
// i.e. there was a big, unexpected increase in the vertical position after undo.
CPPUNIT_ASSERT_EQUAL(aOldPos, aNewPos);
}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */