2132 lines
94 KiB
C++
2132 lines
94 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 <com/sun/star/awt/FontWeight.hpp>
|
|
#include <com/sun/star/document/XDocumentInsertable.hpp>
|
|
#include <com/sun/star/drawing/GraphicExportFilter.hpp>
|
|
#include <com/sun/star/i18n/TextConversionOption.hpp>
|
|
#include <swmodeltestbase.hxx>
|
|
#include <ndtxt.hxx>
|
|
#include <wrtsh.hxx>
|
|
#include <shellio.hxx>
|
|
#include <expfld.hxx>
|
|
#include <drawdoc.hxx>
|
|
#include <redline.hxx>
|
|
#include <fmtclds.hxx>
|
|
#include <dcontact.hxx>
|
|
#include <view.hxx>
|
|
#include <hhcwrp.hxx>
|
|
#include <swacorr.hxx>
|
|
#include <swmodule.hxx>
|
|
#include <modcfg.hxx>
|
|
#include <editeng/acorrcfg.hxx>
|
|
#include <unotools/streamwrap.hxx>
|
|
#include <unocrsrhelper.hxx>
|
|
#include <com/sun/star/text/VertOrientation.hpp>
|
|
#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
|
|
#include <com/sun/star/text/XTextTable.hpp>
|
|
#include <vcl/TypeSerializer.hxx>
|
|
|
|
#include <svx/svdpage.hxx>
|
|
#include <svx/svdview.hxx>
|
|
#include <svx/svxids.hrc>
|
|
|
|
#include <editeng/eeitem.hxx>
|
|
#include <editeng/scripttypeitem.hxx>
|
|
#include <editeng/wghtitem.hxx>
|
|
#include <IDocumentDrawModelAccess.hxx>
|
|
#include <IDocumentRedlineAccess.hxx>
|
|
#include <UndoManager.hxx>
|
|
#include <frmatr.hxx>
|
|
|
|
#include <com/sun/star/text/TextMarkupType.hpp>
|
|
#include <osl/file.hxx>
|
|
#include <comphelper/propertysequence.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <vcl/scheduler.hxx>
|
|
#include <sfx2/watermarkitem.hxx>
|
|
#include <sfx2/docfile.hxx>
|
|
#include <fmthdft.hxx>
|
|
#include <iodetect.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <unotxdoc.hxx>
|
|
#include <swdtflvr.hxx>
|
|
#include <sortedobjs.hxx>
|
|
#include <rootfrm.hxx>
|
|
#include <txtfrm.hxx>
|
|
|
|
namespace
|
|
{
|
|
void lcl_selectCharacters(SwPaM& rPaM, sal_Int32 first, sal_Int32 end)
|
|
{
|
|
rPaM.GetPoint()->nContent.Assign(rPaM.GetPointContentNode(), first);
|
|
rPaM.SetMark();
|
|
rPaM.GetPoint()->nContent.Assign(rPaM.GetPointContentNode(), end);
|
|
}
|
|
} //namespace
|
|
|
|
class SwUiWriterTest : public SwModelTestBase
|
|
{
|
|
public:
|
|
SwUiWriterTest() :
|
|
SwModelTestBase(u"/sw/qa/extras/uiwriter/data/"_ustr)
|
|
{}
|
|
|
|
std::unique_ptr<SwTextBlocks> readDOCXAutotext(
|
|
std::u16string_view sFileName, bool bEmpty = false);
|
|
void testRedlineFrame(char const*const file);
|
|
};
|
|
|
|
std::unique_ptr<SwTextBlocks> SwUiWriterTest::readDOCXAutotext(std::u16string_view sFileName, bool bEmpty)
|
|
{
|
|
createTempCopy(sFileName);
|
|
|
|
SfxMedium aSrcMed(maTempFile.GetURL(), StreamMode::STD_READ);
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
|
|
SwReader aReader(aSrcMed, maTempFile.GetURL(), pDoc);
|
|
Reader* pDOCXReader = SwReaderWriter::GetDOCXReader();
|
|
auto pGlossary = std::make_unique<SwTextBlocks>(maTempFile.GetURL());
|
|
|
|
CPPUNIT_ASSERT(pDOCXReader != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(!bEmpty, aReader.ReadGlossaries(*pDOCXReader, *pGlossary, false));
|
|
|
|
return pGlossary;
|
|
}
|
|
|
|
void SwUiWriterTest::testRedlineFrame(char const*const file)
|
|
{
|
|
createSwDoc(file);
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
// there is exactly one frame
|
|
CPPUNIT_ASSERT_EQUAL(1, getShapes());
|
|
|
|
RedlineFlags nMode = pWrtShell->GetRedlineFlags();
|
|
CPPUNIT_ASSERT(nMode & RedlineFlags::ShowDelete);
|
|
|
|
// hide delete redlines
|
|
pWrtShell->SetRedlineFlags(nMode & ~RedlineFlags::ShowDelete);
|
|
|
|
// there is still exactly one frame
|
|
CPPUNIT_ASSERT_EQUAL(1, getShapes());
|
|
|
|
pWrtShell->SetRedlineFlags(nMode); // show again
|
|
|
|
// there is still exactly one frame
|
|
CPPUNIT_ASSERT_EQUAL(1, getShapes());
|
|
}
|
|
|
|
//Replacement tests
|
|
|
|
constexpr OUString ORIGINAL_REPLACE_CONTENT(u"toto titi tutu"_ustr);
|
|
constexpr OUString EXPECTED_REPLACE_CONTENT(u"toto toto tutu"_ustr);
|
|
|
|
// Chinese conversion tests
|
|
|
|
const sal_Unicode CHINESE_TRADITIONAL_CONTENT(0x9F8D);
|
|
const sal_Unicode CHINESE_SIMPLIFIED_CONTENT(0x9F99);
|
|
constexpr OUString NON_CHINESE_CONTENT(u"Hippopotamus"_ustr);
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testReplaceForward)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwPaM aPaM(aIdx);
|
|
|
|
pDoc->getIDocumentContentOperations().InsertString(aPaM, ORIGINAL_REPLACE_CONTENT);
|
|
|
|
SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
|
|
lcl_selectCharacters(aPaM, 5, 9);
|
|
pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, u"toto"_ustr, false);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTextNode->GetText());
|
|
|
|
rUndoManager.Undo();
|
|
|
|
CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
|
|
}
|
|
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartOutside0)
|
|
{
|
|
testRedlineFrame("redlineFrame.fodt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartOutside)
|
|
{
|
|
testRedlineFrame("redlineFrame_at_char_start_outside.fodt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtCharStartInside)
|
|
{
|
|
testRedlineFrame("redlineFrame_at_char_start_inside.fodt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaStartOutside)
|
|
{
|
|
testRedlineFrame("redline_fly_duplication_at_para_start_outside.fodt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaEndInside)
|
|
{
|
|
testRedlineFrame("redline_fly_duplication_at_para_end_inside.fodt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtParaOneParagraph)
|
|
{
|
|
// test ALLFLYS flag: oddly enough it didn't fail as fodt but failed as odt...
|
|
testRedlineFrame("redline_fly_at_para_one_paragraph.odt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testRedlineFrameAtPara2ndParagraph)
|
|
{
|
|
// lost via the buggy increment in Copy
|
|
testRedlineFrame("redline_fly_duplication_at_para_2nd_paragraph.fodt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testThreadedException)
|
|
{
|
|
SvFileStream aFileStream(createFileURL(u"threadedException.fodt"), StreamMode::READ);
|
|
|
|
//threaded reading only kicks in if there is sufficient buffer to make it worthwhile, so read
|
|
//from a SvFileStream to ensure that
|
|
bool bRes = TestImportFODT(aFileStream);
|
|
|
|
CPPUNIT_ASSERT(!bRes);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf149595)
|
|
{
|
|
createSwDoc("demo91.fodt");
|
|
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
// all 4 shapes are on the 2nd paragraph
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
|
|
|
|
{
|
|
pWrtShell->Down(false);
|
|
pWrtShell->EndPara(/*bSelect=*/true);
|
|
dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
|
|
|
|
// one shape is anchored in the middle, others at the start/end/at-para
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
|
|
|
|
pWrtShell->Up(false);
|
|
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
|
|
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs()->size());
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
|
|
|
|
pWrtShell->Undo();
|
|
pWrtShell->Undo();
|
|
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
|
|
}
|
|
|
|
// now try the same with redlining enabled - should be the same result
|
|
dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
|
|
dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
|
|
{
|
|
pWrtShell->Down(false);
|
|
pWrtShell->SttPara(/*bSelect=*/false);
|
|
pWrtShell->EndPara(/*bSelect=*/true);
|
|
dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
|
|
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
|
|
// problem was that this deleted all at-char flys, even at the start/end
|
|
CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
|
|
|
|
pWrtShell->Up(false);
|
|
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
|
|
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs()->size());
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(size_t(3), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
|
|
|
|
pWrtShell->Undo();
|
|
pWrtShell->Undo();
|
|
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetDrawObjs() == nullptr);
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs() != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(size_t(4), pWrtShell->GetLayout()->GetLower()->GetLower()->GetLower()->GetNext()->GetDrawObjs()->size());
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf149548)
|
|
{
|
|
createSwDoc("forum-mso-en-13192-min.docx");
|
|
SwDoc* pDoc = getSwDoc();
|
|
|
|
for (SwRangeRedline const*const pRedline : pDoc->getIDocumentRedlineAccess().GetRedlineTable())
|
|
{
|
|
if (pRedline->GetType() == RedlineType::Delete)
|
|
{
|
|
int nLevel(0);
|
|
for (SwNodeIndex index = pRedline->Start()->nNode; index <= pRedline->End()->nNode; ++index)
|
|
{
|
|
switch (index.GetNode().GetNodeType())
|
|
{
|
|
case SwNodeType::Start:
|
|
case SwNodeType::Table:
|
|
case SwNodeType::Section:
|
|
++nLevel;
|
|
break;
|
|
case SwNodeType::End:
|
|
CPPUNIT_ASSERT_MESSAGE("bad overlapping redline", nLevel != 0);
|
|
--nLevel;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
CPPUNIT_ASSERT_EQUAL_MESSAGE("bad overlapping redline", int(0), nLevel);
|
|
}
|
|
}
|
|
|
|
dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {});
|
|
|
|
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
|
|
|
|
// this was a use-after-free on nodes deleted by Copy
|
|
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testPasteTableAtFlyAnchor)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
|
|
anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
|
|
SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
|
|
flySet.Put(anchor);
|
|
SwFlyFrameFormat const* pFly = dynamic_cast<SwFlyFrameFormat const*>(
|
|
pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true));
|
|
CPPUNIT_ASSERT(pFly != nullptr);
|
|
CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
|
|
pWrtShell->SelFlyGrabCursor();
|
|
pWrtShell->GetDrawView()->UnmarkAll();
|
|
CPPUNIT_ASSERT(pWrtShell->GetCurrFlyFrame() != nullptr);
|
|
|
|
// insert table in fly
|
|
SwInsertTableOptions tableOpt(SwInsertTableFlags::DefaultBorder, 0);
|
|
pWrtShell->InsertTable(tableOpt, 2, 2);
|
|
|
|
// select table
|
|
pWrtShell->SelAll();
|
|
|
|
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
|
|
|
|
// move cursor back to body
|
|
pWrtShell->ClearMark();
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
CPPUNIT_ASSERT(!pWrtShell->GetCurrFlyFrame());
|
|
|
|
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
|
|
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
CPPUNIT_ASSERT(pWrtShell->IsCursorInTable());
|
|
CPPUNIT_ASSERT(!pFly->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
|
|
|
|
pWrtShell->Undo();
|
|
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
|
|
CPPUNIT_ASSERT(!pFly->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
|
|
|
|
// the problem was that Redo moved the fly anchor into the first table cell
|
|
pWrtShell->Redo();
|
|
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
CPPUNIT_ASSERT(pWrtShell->IsCursorInTable());
|
|
CPPUNIT_ASSERT(!pFly->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
|
|
|
|
pWrtShell->Undo();
|
|
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
|
|
CPPUNIT_ASSERT(!pFly->GetAnchor().GetContentAnchor()->GetNode().FindTableNode());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCopyPastePageBreak)
|
|
{
|
|
createSwDoc("pagebreak-source.fodt");
|
|
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
|
|
|
|
pWrtShell->SelAll();
|
|
dispatchCommand(mxComponent, u".uno:Copy"_ustr, {});
|
|
|
|
createSwDoc("pagebreak-target.fodt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
|
|
CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
|
|
CPPUNIT_ASSERT_EQUAL(u"TargetSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
|
|
// page style WithMargin is used
|
|
CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
|
|
|
|
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
|
|
|
|
CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
|
|
CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
|
|
CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetSections().size());
|
|
CPPUNIT_ASSERT_EQUAL(u"SourceSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
|
|
// the problem was that there was a page break now
|
|
CPPUNIT_ASSERT_EQUAL(1, getPages());
|
|
// page style WithMargin is used
|
|
CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
|
|
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
|
|
CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
|
|
CPPUNIT_ASSERT_EQUAL(u"TargetSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
|
|
CPPUNIT_ASSERT_EQUAL(1, getPages());
|
|
// page style WithMargin is used
|
|
CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
|
|
|
|
pWrtShell->Redo();
|
|
CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
|
|
CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
|
|
CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetSections().size());
|
|
CPPUNIT_ASSERT_EQUAL(u"SourceSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
|
|
CPPUNIT_ASSERT_EQUAL(1, getPages());
|
|
// page style WithMargin is used
|
|
CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
|
|
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(1, getParagraphs());
|
|
CPPUNIT_ASSERT_EQUAL(u"WithMargin"_ustr, getProperty<OUString>(getParagraph(1), u"PageDescName"_ustr));
|
|
CPPUNIT_ASSERT_EQUAL(u"TargetSection"_ustr, pWrtShell->GetCurrSection()->GetSectionName());
|
|
CPPUNIT_ASSERT_EQUAL(1, getPages());
|
|
// page style WithMargin is used
|
|
CPPUNIT_ASSERT_EQUAL(tools::Long(5669), pWrtShell->GetLayout()->GetLower()->getFramePrintArea().Top());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testBookmarkCopy)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
|
|
// add text and bookmark
|
|
IDocumentMarkAccess & rIDMA(*pDoc->getIDocumentMarkAccess());
|
|
IDocumentContentOperations & rIDCO(pDoc->getIDocumentContentOperations());
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwCursor aPaM(SwPosition(aIdx), nullptr);
|
|
rIDCO.InsertString(aPaM, u"foo"_ustr);
|
|
rIDCO.SplitNode(*aPaM.GetPoint(), false);
|
|
rIDCO.InsertString(aPaM, u"bar"_ustr);
|
|
aPaM.SetMark();
|
|
aPaM.MovePara(GoCurrPara, fnParaStart);
|
|
rIDMA.makeMark(aPaM, u"Mark"_ustr, IDocumentMarkAccess::MarkType::BOOKMARK,
|
|
::sw::mark::InsertMode::New);
|
|
aPaM.Exchange();
|
|
aPaM.DeleteMark();
|
|
rIDCO.SplitNode(*aPaM.GetPoint(), false);
|
|
rIDCO.InsertString(aPaM, u"baz"_ustr);
|
|
|
|
// copy range
|
|
rIDCO.SplitNode(*aPaM.GetPoint(), false);
|
|
SwPosition target(*aPaM.GetPoint());
|
|
aPaM.Move(fnMoveBackward, GoInContent);
|
|
aPaM.SetMark();
|
|
aPaM.SttEndDoc(true/*start*/);
|
|
aPaM.Move(fnMoveForward, GoInContent); // partially select 1st para
|
|
|
|
rIDCO.CopyRange(aPaM, target, SwCopyFlags::CheckPosInFly);
|
|
|
|
// check bookmark was copied to correct position
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), rIDMA.getBookmarksCount());
|
|
for (auto it(rIDMA.getBookmarksBegin()); it != rIDMA.getBookmarksEnd(); ++it)
|
|
{
|
|
OUString markText(SwPaM((*it)->GetMarkPos(), (*it)->GetOtherMarkPos()).GetText());
|
|
CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, markText);
|
|
}
|
|
|
|
// copy 2nd time, such that bCanMoveBack is false in CopyImpl
|
|
SwPaM aCopyPaM(*aPaM.GetMark(), *aPaM.GetPoint());
|
|
aPaM.SttEndDoc(true/*start*/);
|
|
rIDCO.SplitNode(*aPaM.GetPoint(), false);
|
|
aPaM.SttEndDoc(true/*start*/);
|
|
|
|
rIDCO.CopyRange(aCopyPaM, *aPaM.GetPoint(), SwCopyFlags::CheckPosInFly);
|
|
|
|
// check bookmark was copied to correct position
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), rIDMA.getBookmarksCount());
|
|
for (auto it(rIDMA.getBookmarksBegin()); it != rIDMA.getBookmarksEnd(); ++it)
|
|
{
|
|
OUString markText(SwPaM((*it)->GetMarkPos(), (*it)->GetOtherMarkPos()).GetText());
|
|
CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, markText);
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFormulaNumberWithGroupSeparator)
|
|
{
|
|
createSwDoc("tdf125154.odt");
|
|
dispatchCommand(mxComponent, u".uno:UpdateAll"_ustr, {});
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->SttEndDoc(true);
|
|
SwField const* pField;
|
|
|
|
pField = pWrtShell->GetCurField();
|
|
CPPUNIT_ASSERT_EQUAL(u"1000"_ustr, pField->GetFormula());
|
|
CPPUNIT_ASSERT_EQUAL(u"1.000"_ustr, pField->ExpandField(true, nullptr));
|
|
pWrtShell->GoNextCell();
|
|
CPPUNIT_ASSERT_EQUAL(u"10000"_ustr, pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
|
|
pWrtShell->GoNextCell();
|
|
pField = pWrtShell->GetCurField();
|
|
CPPUNIT_ASSERT_EQUAL(u"test"_ustr, pField->GetFormula());
|
|
CPPUNIT_ASSERT_EQUAL(u"1.000"_ustr, pField->ExpandField(true, nullptr));
|
|
pWrtShell->GoNextCell();
|
|
// the problem was that this was 0
|
|
CPPUNIT_ASSERT_EQUAL(u"10000"_ustr, pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
|
|
pWrtShell->Down(false);
|
|
pWrtShell->SttPara(false);
|
|
pField = pWrtShell->GetCurField();
|
|
CPPUNIT_ASSERT_EQUAL(u"1000*10%"_ustr, pField->GetFormula());
|
|
CPPUNIT_ASSERT_EQUAL(u"100"_ustr, pField->ExpandField(true, nullptr));
|
|
pWrtShell->Down(false);
|
|
pField = pWrtShell->GetCurField();
|
|
CPPUNIT_ASSERT_EQUAL(u"5.000*10%"_ustr, pField->GetFormula());
|
|
// the problem was that this was 0
|
|
CPPUNIT_ASSERT_EQUAL(u"500"_ustr, pField->ExpandField(true, nullptr));
|
|
pWrtShell->Down(false);
|
|
pField = pWrtShell->GetCurField();
|
|
CPPUNIT_ASSERT_EQUAL(u"5.000*10%"_ustr, pField->GetFormula());
|
|
// the problem was that this was
|
|
CPPUNIT_ASSERT_EQUAL(u"500"_ustr, pField->ExpandField(true, nullptr));
|
|
pWrtShell->Down(false);
|
|
pField = pWrtShell->GetCurField();
|
|
CPPUNIT_ASSERT_EQUAL(u"5000*10%"_ustr, pField->GetFormula());
|
|
CPPUNIT_ASSERT_EQUAL(u"500"_ustr, pField->ExpandField(true, nullptr));
|
|
pWrtShell->Down(false);
|
|
CPPUNIT_ASSERT_EQUAL(u"-100,00 €"_ustr, pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
|
|
pWrtShell->GoNextCell();
|
|
// tdf#42518 the problem was that this was 1.900,00 €
|
|
CPPUNIT_ASSERT_EQUAL(u"** Expression is faulty **"_ustr, pWrtShell->GetCursor()->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testInsertFileInInputFieldException)
|
|
{
|
|
createSwDoc();
|
|
uno::Reference<text::XTextDocument> const xTextDoc(mxComponent, uno::UNO_QUERY);
|
|
uno::Reference<text::XText> const xBody(xTextDoc->getText());
|
|
uno::Reference<lang::XMultiServiceFactory> const xFactory(mxComponent, uno::UNO_QUERY);
|
|
uno::Reference<text::XTextCursor> const xCursor(xBody->createTextCursor());
|
|
uno::Reference<document::XDocumentInsertable> const xInsertable(xCursor, uno::UNO_QUERY);
|
|
uno::Reference<text::XTextContent> const xContent(
|
|
xFactory->createInstance(u"com.sun.star.text.textfield.Input"_ustr), uno::UNO_QUERY);
|
|
xBody->insertTextContent(xCursor, xContent, false);
|
|
xCursor->goLeft(1, false);
|
|
// try to insert some random file
|
|
// inserting even asserts in debug builds - document model goes invalid with input field split across 2 nodes
|
|
CPPUNIT_ASSERT_THROW(xInsertable->insertDocumentFromURL(createFileURL(u"fdo75110.odt"), {}), uno::RuntimeException);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf67238)
|
|
{
|
|
//create a new writer document
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
//insert a 3X3 table in the newly created document
|
|
SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
|
|
const SwTable& rTable = pWrtShell->InsertTable(TableOpt, 3, 3);
|
|
//checking for the rows and columns
|
|
uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRows()->getCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
|
|
//selecting the table
|
|
pWrtShell->StartOfSection();
|
|
pWrtShell->SelTable();
|
|
//making the table protected
|
|
pWrtShell->ProtectCells();
|
|
//checking each cell's protection, it should be protected
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
//undo the changes, make cells [un]protected
|
|
rUndoManager.Undo();
|
|
//checking each cell's protection, it should be [un]protected
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
//redo the changes, make cells protected
|
|
rUndoManager.Redo();
|
|
//checking each cell's protection, it should be protected
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
//moving the cursor to the starting of the document
|
|
pWrtShell->StartOfSection();
|
|
//making the table [un]protected
|
|
pWrtShell->SelTable();
|
|
pWrtShell->UnProtectCells();
|
|
//checking each cell's protection, it should be [un]protected
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
//undo the changes, make cells protected
|
|
rUndoManager.Undo();
|
|
//checking each cell's protection, it should be protected
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
//redo the changes, make cells [un]protected
|
|
rUndoManager.Redo();
|
|
//checking each cell's protection, it should be [un]protected
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"A3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"B3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C1"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C2"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
CPPUNIT_ASSERT(!((rTable.GetTableBox(u"C3"_ustr))->GetFrameFormat()->GetProtect()).IsContentProtected());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf155685)
|
|
{
|
|
createSwDoc("table-at-end-of-cell.fodt");
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->GoNextCell();
|
|
pWrtShell->GoNextCell();
|
|
pWrtShell->GoNextCell();
|
|
pWrtShell->SelAll();
|
|
pWrtShell->Delete();
|
|
// this crashed
|
|
pWrtShell->Undo();
|
|
pWrtShell->Undo();
|
|
pWrtShell->Redo();
|
|
// this crashed
|
|
pWrtShell->Redo();
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf147220)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
pWrtShell->Insert(u"él"_ustr);
|
|
|
|
// hide and enable
|
|
dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
|
|
dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
|
|
CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
|
|
CPPUNIT_ASSERT(
|
|
IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
|
|
|
|
pWrtShell->GoStartSentence();
|
|
pWrtShell->SetMark();
|
|
pWrtShell->GoEndSentence();
|
|
|
|
// this did not remove the original text from the layout
|
|
pWrtShell->Replace(u"Él"_ustr, false);
|
|
|
|
// currently the deleted text is before the replacement text, not sure if
|
|
// that is really required
|
|
CPPUNIT_ASSERT_EQUAL(u"élÉl"_ustr,
|
|
pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->GetText());
|
|
CPPUNIT_ASSERT_EQUAL(u"Él"_ustr,
|
|
static_cast<SwTextFrame const*>(pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode()->getLayoutFrame(nullptr))->GetText());
|
|
|
|
SwRedlineTable const& rRedlines(pDoc->getIDocumentRedlineAccess().GetRedlineTable());
|
|
CPPUNIT_ASSERT_EQUAL(SwRedlineTable::size_type(2), rRedlines.size());
|
|
CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlines[0]->GetType());
|
|
CPPUNIT_ASSERT_EQUAL(u"él"_ustr, rRedlines[0]->GetText());
|
|
CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rRedlines[1]->GetType());
|
|
CPPUNIT_ASSERT_EQUAL(u"Él"_ustr, rRedlines[1]->GetText());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf135978)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
pWrtShell->Insert(u"foobar"_ustr);
|
|
pWrtShell->SplitNode();
|
|
pWrtShell->Insert(u"bazquux"_ustr);
|
|
|
|
CPPUNIT_ASSERT(pWrtShell->IsEndOfDoc());
|
|
|
|
SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR);
|
|
anchor.SetAnchor(pWrtShell->GetCursor()->GetPoint());
|
|
SfxItemSet flySet(pDoc->GetAttrPool(), svl::Items<RES_ANCHOR, RES_ANCHOR>);
|
|
flySet.Put(anchor);
|
|
SwFlyFrameFormat const* pFly = dynamic_cast<SwFlyFrameFormat const*>(
|
|
pWrtShell->NewFlyFrame(flySet, /*bAnchValid=*/true));
|
|
CPPUNIT_ASSERT(pFly != nullptr);
|
|
CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
|
|
// move cursor back to body
|
|
pWrtShell->SttEndDoc(/*bStt=*/false);
|
|
|
|
// hide and enable
|
|
dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
|
|
dispatchCommand(mxComponent, u".uno:TrackChanges"_ustr, {});
|
|
|
|
CPPUNIT_ASSERT(pDoc->getIDocumentRedlineAccess().IsRedlineOn());
|
|
CPPUNIT_ASSERT(
|
|
IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
|
|
CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
|
|
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 6, /*bBasicCall=*/false);
|
|
pWrtShell->Delete();
|
|
|
|
// now split
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
pWrtShell->SplitNode();
|
|
CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
|
|
|
|
// the problem was that undo removed the fly frame from the layout
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
|
|
|
|
pWrtShell->Redo();
|
|
CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
|
|
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT(pFly->GetFrame() != nullptr);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo75110)
|
|
{
|
|
createSwDoc("fdo75110.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
pWrtShell->SelAll();
|
|
// The problem was that SwEditShell::DeleteSel() what this Delete() invokes took the wrong selection...
|
|
pWrtShell->Delete();
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
// ... so this Undo() call resulted in a crash.
|
|
rUndoManager.Undo();
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo75898)
|
|
{
|
|
createSwDoc("fdo75898.odt");
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->SelAll();
|
|
pWrtShell->InsertRow(1, true);
|
|
pWrtShell->InsertRow(1, true);
|
|
|
|
// Now check if the table has 3 lines.
|
|
SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
|
|
SwTableNode* pTableNode = pShellCursor->Start()->GetNode().FindTableNode();
|
|
// This was 1, when doing the same using the UI, Writer even crashed.
|
|
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pTableNode->GetTable().GetTabLines().size());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testReplaceBackward)
|
|
{
|
|
//Regression test of fdo#70143
|
|
//EDITING: undo search&replace corrupt text when searching backward
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwPaM aPaM(aIdx);
|
|
|
|
pDoc->getIDocumentContentOperations().InsertString(aPaM, u"toto titi tutu"_ustr);
|
|
SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
|
|
lcl_selectCharacters(aPaM, 9, 5);
|
|
|
|
pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, u"toto"_ustr, false);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTextNode->GetText());
|
|
|
|
rUndoManager.Undo();
|
|
|
|
CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo69893)
|
|
{
|
|
createSwDoc("fdo69893.odt");
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
pWrtShell->SelAll(); // A1 is empty -> selects the whole table.
|
|
pWrtShell->SelAll(); // Selects the whole document.
|
|
|
|
SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
|
|
SwTextNode& rEnd = dynamic_cast<SwTextNode&>(pShellCursor->End()->GetNode());
|
|
// Selection did not include the para after table, this was "B1".
|
|
CPPUNIT_ASSERT_EQUAL(u"Para after table."_ustr, rEnd.GetText());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo70807)
|
|
{
|
|
createSwDoc("fdo70807.odt");
|
|
|
|
uno::Reference<container::XIndexAccess> xStylesIter(getStyles(u"PageStyles"_ustr), uno::UNO_QUERY);
|
|
|
|
for (sal_Int32 i = 0; i < xStylesIter->getCount(); ++i)
|
|
{
|
|
uno::Reference<style::XStyle> xStyle(xStylesIter->getByIndex(i), uno::UNO_QUERY);
|
|
|
|
bool expectedUsedStyle = false;
|
|
bool expectedUserDefined = false;
|
|
|
|
OUString styleName(xStyle->getName());
|
|
|
|
// just these styles are user defined styles
|
|
if (styleName == "pagestyle1" || styleName == "pagestyle2")
|
|
expectedUserDefined = true;
|
|
|
|
// just these styles are used in the document
|
|
if (styleName == "Right Page" || styleName == "pagestyle1" || styleName == "pagestyle2")
|
|
expectedUsedStyle = true;
|
|
|
|
CPPUNIT_ASSERT_EQUAL(expectedUserDefined, bool(xStyle->isUserDefined()));
|
|
CPPUNIT_ASSERT_EQUAL(expectedUsedStyle, bool(xStyle->isInUse()));
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testImportRTF)
|
|
{
|
|
// Insert "foobar" and position the cursor between "foo" and "bar".
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->Insert(u"foobar"_ustr);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 3, /*bBasicCall=*/false);
|
|
|
|
// Insert the RTF at the cursor position.
|
|
OString aData = "{\\rtf1 Hello world!\\par}"_ostr;
|
|
SvMemoryStream aStream(const_cast<char*>(aData.getStr()), aData.getLength(), StreamMode::READ);
|
|
SwReader aReader(aStream, OUString(), OUString(), *pWrtShell->GetCursor());
|
|
Reader* pRTFReader = SwReaderWriter::GetRtfReader();
|
|
CPPUNIT_ASSERT(pRTFReader != nullptr);
|
|
CPPUNIT_ASSERT_EQUAL(ERRCODE_NONE, aReader.Read(*pRTFReader).GetCode());
|
|
|
|
SwNodeOffset nIndex = pWrtShell->GetCursor()->GetPointNode().GetIndex();
|
|
CPPUNIT_ASSERT_EQUAL(u"fooHello world!"_ustr, pDoc->GetNodes()[nIndex - 1]->GetTextNode()->GetText());
|
|
CPPUNIT_ASSERT_EQUAL(u"bar"_ustr, pDoc->GetNodes()[nIndex]->GetTextNode()->GetText());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testExportRTF)
|
|
{
|
|
// Insert "aaabbbccc" and select "bbb".
|
|
createSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->Insert(u"aaabbbccc"_ustr);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 3, /*bBasicCall=*/false);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
|
|
|
|
// Create the clipboard document.
|
|
rtl::Reference<SwDoc> xClpDoc(new SwDoc());
|
|
xClpDoc->SetClipBoard(true);
|
|
pWrtShell->Copy(*xClpDoc);
|
|
|
|
// And finally export it as RTF.
|
|
WriterRef xWrt;
|
|
SwReaderWriter::GetWriter(u"RTF", OUString(), xWrt);
|
|
SvMemoryStream aStream;
|
|
SwWriter aWrt(aStream, *xClpDoc);
|
|
aWrt.Write(xWrt);
|
|
|
|
OString aData(static_cast<const char*>(aStream.GetData()), aStream.GetSize());
|
|
|
|
//Amusingly eventually there was a commit id with "ccc" in it, and so the rtf contained
|
|
//{\*\generator LibreOfficeDev/4.4.0.0.alpha0$Linux_X86_64 LibreOffice_project/f70664ccc6837f2cc21a29bb4f44e41e100efe6b}
|
|
//so the test fell over. so strip the generator tag
|
|
sal_Int32 nGeneratorStart = aData.indexOf("{\\*\\generator ");
|
|
CPPUNIT_ASSERT(nGeneratorStart != -1);
|
|
sal_Int32 nGeneratorEnd = aData.indexOf('}', nGeneratorStart + 1);
|
|
CPPUNIT_ASSERT(nGeneratorEnd != -1);
|
|
aData = aData.replaceAt(nGeneratorStart, nGeneratorEnd-nGeneratorStart+1, "");
|
|
|
|
CPPUNIT_ASSERT(aData.startsWith("{\\rtf1"));
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aData.indexOf("aaa"));
|
|
CPPUNIT_ASSERT(aData.indexOf("bbb") != -1);
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aData.indexOf("ccc"));
|
|
// Ensure there's no extra newline
|
|
CPPUNIT_ASSERT(aData.endsWith("bbb}" SAL_NEWLINE_STRING "}"));
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextEmpty)
|
|
{
|
|
// file contains normal content but no AutoText
|
|
std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-empty.dotx", true);
|
|
CPPUNIT_ASSERT(pGlossary != nullptr);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextMultiple)
|
|
{
|
|
// file contains three AutoText entries
|
|
std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-multiple.dotx");
|
|
|
|
// check entries count
|
|
CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), pGlossary->GetCount());
|
|
|
|
// check names of entries, sorted order
|
|
CPPUNIT_ASSERT_EQUAL(u"Anothercomplex"_ustr, pGlossary->GetLongName(0));
|
|
CPPUNIT_ASSERT_EQUAL(u"Multiple"_ustr, pGlossary->GetLongName(1));
|
|
CPPUNIT_ASSERT_EQUAL(u"Second Autotext"_ustr, pGlossary->GetLongName(2));
|
|
|
|
// check if previously loaded content is correct (eg. doesn't contain title)
|
|
SwDoc* pDoc = pGlossary->GetDoc();
|
|
CPPUNIT_ASSERT(pDoc != nullptr);
|
|
|
|
SwNodeIndex aDocEnd(pDoc->GetNodes().GetEndOfContent());
|
|
SwNodeIndex aStart(*aDocEnd.GetNode().StartOfSectionNode(), 1);
|
|
|
|
CPPUNIT_ASSERT(aStart < aDocEnd);
|
|
|
|
// first line
|
|
SwNode& rNode = aStart.GetNode();
|
|
CPPUNIT_ASSERT(rNode.IsTextNode());
|
|
SwTextNode& rTextNode = *rNode.GetTextNode();
|
|
CPPUNIT_ASSERT_EQUAL(u"Another "_ustr, rTextNode.GetText());
|
|
|
|
// Make sure that autotext does not set a custom page style, leading to an unexpected page break
|
|
// on insertion.
|
|
// Without the accompanying fix in place, this test would have failed: the text node had an
|
|
// attribute set containing a page style item.
|
|
CPPUNIT_ASSERT(!rTextNode.HasSwAttrSet() || !rTextNode.GetSwAttrSet().HasItem(RES_PAGEDESC));
|
|
|
|
// last line
|
|
SwNodeIndex aLast(*aDocEnd.GetNode().EndOfSectionNode(), -1);
|
|
SwNode& rLastNode = aLast.GetNode();
|
|
CPPUNIT_ASSERT_EQUAL(u"complex"_ustr, rLastNode.GetTextNode()->GetText());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOTMAutoText)
|
|
{
|
|
// this is dotm file difference is that in the dotm
|
|
// there are no empty paragraphs at the end of each entry
|
|
std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-dotm.dotm");
|
|
|
|
SwDoc* pDoc = pGlossary->GetDoc();
|
|
CPPUNIT_ASSERT(pDoc != nullptr);
|
|
|
|
// check if content is correct
|
|
SwNodeIndex aDocEnd(pDoc->GetNodes().GetEndOfContent());
|
|
SwNodeIndex aStart(*aDocEnd.GetNode().StartOfSectionNode(), 1);
|
|
SwNode& rNode = aStart.GetNode();
|
|
CPPUNIT_ASSERT_EQUAL(u"paragraph"_ustr, rNode.GetTextNode()->GetText());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDOCXAutoTextGallery)
|
|
{
|
|
// this file contains one AutoText entry and other
|
|
// entries which are not AutoText (have different "gallery" value)
|
|
std::unique_ptr<SwTextBlocks> pGlossary = readDOCXAutotext(u"autotext-gallery.dotx");
|
|
|
|
SwDoc* pDoc = pGlossary->GetDoc();
|
|
CPPUNIT_ASSERT(pDoc != nullptr);
|
|
|
|
// check entries count
|
|
CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pGlossary->GetCount());
|
|
|
|
// check entry name (if not contains gallery type)
|
|
CPPUNIT_ASSERT_EQUAL(u"Multiple"_ustr, pGlossary->GetLongName(0));
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testWatermarkDOCX)
|
|
{
|
|
createSwDoc("watermark.docx");
|
|
SwDocShell* pDocShell = getSwDocShell();
|
|
SfxPoolItemHolder aResult;
|
|
SfxItemState eState = pDocShell->GetViewShell()->GetViewFrame().GetDispatcher()->QueryState(SID_WATERMARK, aResult);
|
|
const SfxWatermarkItem* pWatermark(static_cast<const SfxWatermarkItem*>(aResult.getItem()));
|
|
|
|
CPPUNIT_ASSERT(eState >= SfxItemState::DEFAULT);
|
|
CPPUNIT_ASSERT(pWatermark);
|
|
CPPUNIT_ASSERT_EQUAL(static_cast<unsigned short>(SID_WATERMARK), pWatermark->Which());
|
|
|
|
CPPUNIT_ASSERT_EQUAL(u"CustomWatermark"_ustr, pWatermark->GetText());
|
|
CPPUNIT_ASSERT_EQUAL(u"DejaVu Sans Light"_ustr, pWatermark->GetFont());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int16(45), pWatermark->GetAngle());
|
|
CPPUNIT_ASSERT_EQUAL(Color(0x548dd4), pWatermark->GetColor());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int16(50), pWatermark->GetTransparency());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testWatermarkPosition)
|
|
{
|
|
// tdf#108494 Watermark inserted in the document with page break was outside the first page
|
|
const int aPagesInDocument = 2;
|
|
const int aAdditionalPagesCount[] = { 0, 0, 1, 1, 5, 5, 20, 20 };
|
|
const bool aChangeHeader[] = { true, false, true, false, true, false, true, false };
|
|
|
|
for (tools::ULong i = 0; i < sizeof(aAdditionalPagesCount) / sizeof(int); ++i)
|
|
{
|
|
int aPages = aPagesInDocument + aAdditionalPagesCount[i];
|
|
|
|
// Empty document with one Page Break
|
|
createSwDoc("watermark-position.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwEditShell* pEditShell = pDoc->GetEditShell();
|
|
CPPUNIT_ASSERT(pEditShell);
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
|
|
uno::UNO_QUERY);
|
|
uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
|
|
|
|
// 1. Add additional page breaks
|
|
for (int j = 0; j < aAdditionalPagesCount[i]; ++j)
|
|
pWrtShell->InsertPageBreak();
|
|
|
|
// 2. Change header state (On, Off, On)
|
|
if (aChangeHeader[i])
|
|
{
|
|
SwPageDesc aDesc(pDoc->GetPageDesc(0));
|
|
SwFrameFormat& rMaster = aDesc.GetMaster();
|
|
rMaster.SetFormatAttr(SwFormatHeader(true));
|
|
pDoc->ChgPageDesc(0, aDesc);
|
|
|
|
aDesc = pDoc->GetPageDesc(0);
|
|
SwFrameFormat& rMaster2 = aDesc.GetMaster();
|
|
rMaster2.SetFormatAttr(SwFormatHeader(false));
|
|
pDoc->ChgPageDesc(0, aDesc);
|
|
|
|
aDesc = pDoc->GetPageDesc(0);
|
|
SwFrameFormat& rMaster3 = aDesc.GetMaster();
|
|
rMaster3.SetFormatAttr(SwFormatHeader(true));
|
|
pDoc->ChgPageDesc(0, aDesc);
|
|
}
|
|
|
|
// 3. Insert Watermark
|
|
SfxWatermarkItem aWatermark;
|
|
aWatermark.SetText(u"Watermark"_ustr);
|
|
aWatermark.SetFont(u"DejaVu Sans"_ustr);
|
|
|
|
pEditShell->SetWatermark(aWatermark);
|
|
|
|
uno::Reference<css::drawing::XShape> xShape = getShape(1);
|
|
CPPUNIT_ASSERT(xShape.is());
|
|
|
|
SdrPage* pPage = pWrtShell->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
|
|
|
|
// Get Watermark object
|
|
SdrObject* pObject = pPage->GetObj(0);
|
|
pObject->RecalcBoundRect();
|
|
const tools::Rectangle& rRect = pObject->GetSnapRect();
|
|
Size rSize = pPage->GetSize();
|
|
|
|
// Page break, calculate height of a page
|
|
const int nPageHeight = rSize.getHeight() / aPages;
|
|
|
|
std::stringstream aMessage;
|
|
aMessage << "Case: " << i << ", nPageHeight = " << nPageHeight << ", rRect.Bottom = " << rRect.Bottom();
|
|
|
|
// Check if Watermark is inside a page
|
|
CPPUNIT_ASSERT_MESSAGE(aMessage.str(), nPageHeight >= rRect.Bottom());
|
|
|
|
// Check if Watermark is centered
|
|
CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, getProperty<sal_Int16>(xShape, u"HoriOrient"_ustr));
|
|
CPPUNIT_ASSERT_EQUAL(text::VertOrientation::CENTER, getProperty<sal_Int16>(xShape, u"VertOrient"_ustr));
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo74981)
|
|
{
|
|
// create a document with an input field
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
SwInputField aField(static_cast<SwInputFieldType*>(pWrtShell->GetFieldType(0, SwFieldIds::Input)), u"foo"_ustr, u"bar"_ustr, 0, 0);
|
|
pWrtShell->InsertField2(aField);
|
|
|
|
{
|
|
// expect hints
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
|
|
CPPUNIT_ASSERT(pTextNode->HasHints());
|
|
}
|
|
|
|
// go to the begin of the paragraph and split this node
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, false, 100, false);
|
|
pWrtShell->SplitNode();
|
|
|
|
{
|
|
// expect only the second paragraph to have hints
|
|
SwNodeIndex aIdx(SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1));
|
|
SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
|
|
CPPUNIT_ASSERT(pTextNode->HasHints());
|
|
--aIdx;
|
|
pTextNode = aIdx.GetNode().GetTextNode();
|
|
CPPUNIT_ASSERT(!pTextNode->HasHints());
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf98512)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
SwInputFieldType *const pType(static_cast<SwInputFieldType*>(
|
|
pWrtShell->GetFieldType(0, SwFieldIds::Input)));
|
|
SwInputField aField1(pType, u"foo"_ustr, u"bar"_ustr, INP_TXT, 0);
|
|
pWrtShell->InsertField2(aField1);
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
SwInputField aField2(pType, u"baz"_ustr, u"quux"_ustr, INP_TXT, 0);
|
|
pWrtShell->InsertField2(aField2);
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
pWrtShell->SetMark();
|
|
pWrtShell->SttEndDoc(/*bStt=*/false);
|
|
OUString const expected1(
|
|
OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + "foo" + OUStringChar(CH_TXT_ATR_INPUTFIELDEND));
|
|
OUString const expected2(
|
|
OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + "baz" + OUStringChar(CH_TXT_ATR_INPUTFIELDEND)
|
|
+ expected1);
|
|
CPPUNIT_ASSERT_EQUAL(expected2, pWrtShell->getShellCursor(false)->GetText());
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
rUndoManager.Undo();
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
pWrtShell->SetMark();
|
|
pWrtShell->SttEndDoc(/*bStt=*/false);
|
|
CPPUNIT_ASSERT_EQUAL(expected1, pWrtShell->getShellCursor(false)->GetText());
|
|
rUndoManager.Redo();
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
pWrtShell->SetMark();
|
|
pWrtShell->SttEndDoc(/*bStt=*/false);
|
|
CPPUNIT_ASSERT_EQUAL(expected2, pWrtShell->getShellCursor(false)->GetText());
|
|
rUndoManager.Undo();
|
|
pWrtShell->SttEndDoc(/*bStt=*/true);
|
|
pWrtShell->SetMark();
|
|
pWrtShell->SttEndDoc(/*bStt=*/false);
|
|
CPPUNIT_ASSERT_EQUAL(expected1, pWrtShell->getShellCursor(false)->GetText());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxSelect)
|
|
{
|
|
createSwDoc("shape-textbox.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
|
|
SdrObject* pObject = pPage->GetObj(1);
|
|
SwContact* pTextBox = static_cast<SwContact*>(pObject->GetUserCall());
|
|
// First, make sure that pTextBox is a fly frame (textbox of a shape).
|
|
CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_FLYFRMFMT), pTextBox->GetFormat()->Which());
|
|
|
|
// Then select it.
|
|
pWrtShell->SelectObj(Point(), 0, pObject);
|
|
const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
|
|
SwDrawContact* pShape = static_cast<SwDrawContact*>(rMarkList.GetMark(0)->GetMarkedSdrObj()->GetUserCall());
|
|
// And finally make sure the shape got selected, not just the textbox itself.
|
|
CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_DRAWFRMFMT), pShape->GetFormat()->Which());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxDelete)
|
|
{
|
|
createSwDoc("shape-textbox.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
|
|
SdrObject* pObject = pPage->GetObj(0);
|
|
pWrtShell->SelectObj(Point(), 0, pObject);
|
|
size_t nActual = pPage->GetObjCount();
|
|
// Two objects on the draw page: the shape and its textbox.
|
|
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), nActual);
|
|
|
|
pWrtShell->DelSelectedObj();
|
|
nActual = pPage->GetObjCount();
|
|
// Both (not only the shape) should be removed by now (the textbox wasn't removed, so this was 1).
|
|
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), nActual);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testAnchorChangeSelection)
|
|
{
|
|
createSwDoc("test_anchor_as_character.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
|
|
SdrObject* pObject = pPage->GetObj(0);
|
|
CPPUNIT_ASSERT(pObject);
|
|
|
|
// Then select it.
|
|
pWrtShell->SelectObj(Point(), 0, pObject);
|
|
const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
|
|
CPPUNIT_ASSERT_EQUAL(pObject, rMarkList.GetMark(0)->GetMarkedSdrObj());
|
|
|
|
pWrtShell->ChgAnchor(RndStdIds::FLY_AS_CHAR);
|
|
|
|
// tdf#125039 shape must still be selected, extensions depend on that
|
|
CPPUNIT_ASSERT_EQUAL(pObject, rMarkList.GetMark(0)->GetMarkedSdrObj());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCp1000071)
|
|
{
|
|
createSwDoc("cp1000071.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
|
|
CPPUNIT_ASSERT_EQUAL( SwRedlineTable::size_type( 2 ), rTable.size());
|
|
SwNodeOffset redlineStart0NodeIndex = rTable[ 0 ]->Start()->GetNodeIndex();
|
|
sal_Int32 redlineStart0Index = rTable[ 0 ]->Start()->GetContentIndex();
|
|
SwNodeOffset redlineEnd0NodeIndex = rTable[ 0 ]->End()->GetNodeIndex();
|
|
sal_Int32 redlineEnd0Index = rTable[ 0 ]->End()->GetContentIndex();
|
|
SwNodeOffset redlineStart1NodeIndex = rTable[ 1 ]->Start()->GetNodeIndex();
|
|
sal_Int32 redlineStart1Index = rTable[ 1 ]->Start()->GetContentIndex();
|
|
SwNodeOffset redlineEnd1NodeIndex = rTable[ 1 ]->End()->GetNodeIndex();
|
|
sal_Int32 redlineEnd1Index = rTable[ 1 ]->End()->GetContentIndex();
|
|
|
|
// Change the document layout to be 2 columns, and then undo.
|
|
pWrtShell->SelAll();
|
|
SwSectionData section(SectionType::Content, pWrtShell->GetUniqueSectionName());
|
|
SfxItemSet set( getSwDocShell()->GetPool(), svl::Items<RES_COL, RES_COL> );
|
|
SwFormatCol col;
|
|
col.Init( 2, 0, 10000 );
|
|
set.Put( col );
|
|
pWrtShell->InsertSection( section, &set );
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
rUndoManager.Undo();
|
|
|
|
// Check that redlines are the same like at the beginning.
|
|
CPPUNIT_ASSERT_EQUAL( SwRedlineTable::size_type( 2 ), rTable.size());
|
|
CPPUNIT_ASSERT_EQUAL( redlineStart0NodeIndex, rTable[ 0 ]->Start()->GetNodeIndex());
|
|
CPPUNIT_ASSERT_EQUAL( redlineStart0Index, rTable[ 0 ]->Start()->GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL( redlineEnd0NodeIndex, rTable[ 0 ]->End()->GetNodeIndex());
|
|
CPPUNIT_ASSERT_EQUAL( redlineEnd0Index, rTable[ 0 ]->End()->GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL( redlineStart1NodeIndex, rTable[ 1 ]->Start()->GetNodeIndex());
|
|
CPPUNIT_ASSERT_EQUAL( redlineStart1Index, rTable[ 1 ]->Start()->GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL( redlineEnd1NodeIndex, rTable[ 1 ]->End()->GetNodeIndex());
|
|
CPPUNIT_ASSERT_EQUAL( redlineEnd1Index, rTable[ 1 ]->End()->GetContentIndex());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxVertadjust)
|
|
{
|
|
createSwDoc("shape-textbox-vertadjust.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
|
|
SdrObject* pObject = pPage->GetObj(1);
|
|
SwFrameFormat* pFormat = static_cast<SwContact*>(pObject->GetUserCall())->GetFormat();
|
|
// This was SDRTEXTVERTADJUST_TOP.
|
|
CPPUNIT_ASSERT_EQUAL(SDRTEXTVERTADJUST_CENTER, pFormat->GetTextVertAdjust().GetValue());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testShapeTextboxAutosize)
|
|
{
|
|
createSwDoc("shape-textbox-autosize.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
|
|
// 0-1 is the first UI-visible shape+textbox.
|
|
SdrObject* pFirst = pPage->GetObj(0);
|
|
CPPUNIT_ASSERT_EQUAL(u"1st"_ustr, pFirst->GetName());
|
|
|
|
// 2-3 is the second UI-visible shape+textbox.
|
|
SdrObject* pSecond = pPage->GetObj(2);
|
|
CPPUNIT_ASSERT_EQUAL(u"2nd"_ustr, pSecond->GetName());
|
|
|
|
// Shape -> textbox synchronization was missing, the second shape had the
|
|
// same height as the first, even though the first contained 1 paragraph
|
|
// and the other 2 ones.
|
|
CPPUNIT_ASSERT(pFirst->GetSnapRect().getOpenHeight() < pSecond->GetSnapRect().getOpenHeight());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo82191)
|
|
{
|
|
createSwDoc("fdo82191.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
|
|
// Make sure we have a single draw shape.
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage));
|
|
|
|
SwDoc aClipboard;
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
SdrObject* pObject = pPage->GetObj(0);
|
|
// Select it, then copy and paste.
|
|
pWrtShell->SelectObj(Point(), 0, pObject);
|
|
pWrtShell->Copy(aClipboard);
|
|
pWrtShell->Paste(aClipboard);
|
|
|
|
// This was one: the textbox of the shape wasn't copied.
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), SwTextBoxHelper::getCount(*pDoc));
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCommentedWord)
|
|
{
|
|
// This word is commented. <- string in document
|
|
// 123456789 <- character positions
|
|
createSwDoc("commented-word.odt");
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
// Move the cursor into the second word.
|
|
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 5, /*bBasicCall=*/false);
|
|
// Select the word.
|
|
pWrtShell->SelWrd();
|
|
|
|
// Make sure that not only the word, but its comment anchor is also selected.
|
|
SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
|
|
// This was 9, only "word", not "word<anchor character>" was selected.
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(10), pShellCursor->End()->GetContentIndex());
|
|
|
|
// Test that getAnchor() points to "word", not to an empty string.
|
|
uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
|
|
uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
|
|
uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
|
|
uno::Reference<text::XTextContent> xField(xFields->nextElement(), uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT_EQUAL(u"word"_ustr, xField->getAnchor()->getString());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTextFieldGetAnchorGetTextInFooter)
|
|
{
|
|
createSwDoc("textfield-getanchor-gettext-in-footer.odt");
|
|
|
|
uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
|
|
uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
|
|
uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
|
|
uno::Reference<text::XTextContent> xField(xFields->nextElement(), uno::UNO_QUERY);
|
|
|
|
OUString value = xField->getAnchor()->getText()->getString();
|
|
CPPUNIT_ASSERT_EQUAL(u"userfield_in_footer"_ustr, value );
|
|
}
|
|
|
|
// Tests that a blank document is still blank after conversion
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionBlank)
|
|
{
|
|
|
|
// Given
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwView* pView = getSwDocShell()->GetView();
|
|
const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwPaM aPaM(aIdx);
|
|
|
|
// When
|
|
SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
|
|
i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
|
|
true, false, false );
|
|
aWrap.Convert();
|
|
|
|
// Then
|
|
SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
|
|
CPPUNIT_ASSERT_EQUAL(OUString(), pTextNode->GetText());
|
|
|
|
}
|
|
|
|
// Tests that non Chinese text is unchanged after conversion
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionNonChineseText)
|
|
{
|
|
|
|
// Given
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwView* pView = getSwDocShell()->GetView();
|
|
const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwPaM aPaM(aIdx);
|
|
pDoc->getIDocumentContentOperations().InsertString(aPaM, NON_CHINESE_CONTENT);
|
|
|
|
// When
|
|
SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
|
|
i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
|
|
true, false, false );
|
|
aWrap.Convert();
|
|
|
|
// Then
|
|
SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
|
|
CPPUNIT_ASSERT_EQUAL(NON_CHINESE_CONTENT, pTextNode->GetText());
|
|
|
|
}
|
|
|
|
// Tests conversion of traditional Chinese characters to simplified Chinese
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionTraditionalToSimplified)
|
|
{
|
|
|
|
// Given
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwView* pView = getSwDocShell()->GetView();
|
|
const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwPaM aPaM(aIdx);
|
|
pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(CHINESE_TRADITIONAL_CONTENT));
|
|
|
|
// When
|
|
SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, nullptr,
|
|
i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
|
|
true, false, false );
|
|
aWrap.Convert();
|
|
|
|
// Then
|
|
SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
|
|
CPPUNIT_ASSERT_EQUAL(OUString(CHINESE_SIMPLIFIED_CONTENT), pTextNode->GetText());
|
|
|
|
}
|
|
|
|
// Tests conversion of simplified Chinese characters to traditional Chinese
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testChineseConversionSimplifiedToTraditional)
|
|
{
|
|
|
|
// Given
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwView* pView = getSwDocShell()->GetView();
|
|
const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwPaM aPaM(aIdx);
|
|
pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString(CHINESE_SIMPLIFIED_CONTENT));
|
|
|
|
// When
|
|
SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_TRADITIONAL, nullptr,
|
|
i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
|
|
true, false, false );
|
|
aWrap.Convert();
|
|
|
|
// Then
|
|
SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
|
|
CPPUNIT_ASSERT_EQUAL(OUString(CHINESE_TRADITIONAL_CONTENT), pTextNode->GetText());
|
|
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo85554)
|
|
{
|
|
// Load the document, it contains one shape with a textbox.
|
|
createSwDoc("fdo85554.odt");
|
|
|
|
// Add a second shape to the document.
|
|
uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
|
|
uno::Reference<drawing::XShape> xShape(xFactory->createInstance(u"com.sun.star.drawing.RectangleShape"_ustr), uno::UNO_QUERY);
|
|
xShape->setSize(awt::Size(10000, 10000));
|
|
xShape->setPosition(awt::Point(1000, 1000));
|
|
uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
|
|
uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
|
|
xDrawPage->add(xShape);
|
|
|
|
// Save it and load it back.
|
|
saveAndReload(u"writer8"_ustr);
|
|
|
|
// This was 1, we lost a shape on export.
|
|
CPPUNIT_ASSERT_EQUAL(2, getShapes());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testMergeDoc)
|
|
{
|
|
createSwDoc("merge-change1.odt");
|
|
SwDoc* pDoc = getSwDoc();
|
|
|
|
mxComponent2 = loadFromDesktop(
|
|
createFileURL(u"merge-change2.odt"),
|
|
u"com.sun.star.text.TextDocument"_ustr);
|
|
auto pxDoc2Document(
|
|
dynamic_cast<SwXTextDocument *>(mxComponent2.get()));
|
|
CPPUNIT_ASSERT(pxDoc2Document);
|
|
SwDoc* const pDoc2(pxDoc2Document->GetDocShell()->GetDoc());
|
|
|
|
SwEditShell* const pEditShell(pDoc->GetEditShell());
|
|
CPPUNIT_ASSERT(pEditShell);
|
|
pEditShell->MergeDoc(*pDoc2);
|
|
|
|
// accept all redlines
|
|
while(pEditShell->GetRedlineCount())
|
|
pEditShell->AcceptRedline(0);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(7, getParagraphs());
|
|
getParagraph(1, u"Para One: Two Three Four Five"_ustr);
|
|
getParagraph(2, u"Para Two: One Three Four Five"_ustr);
|
|
getParagraph(3, u"Para Three: One Two Four Five"_ustr);
|
|
getParagraph(4, u"Para Four: One Two Three Four Five"_ustr);
|
|
getParagraph(5, u"Para Six: One Three Four Five"_ustr);
|
|
getParagraph(6, u""_ustr);
|
|
getParagraph(7, u""_ustr);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCreatePortions)
|
|
{
|
|
createSwDoc("uno-cycle.odt");
|
|
uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
|
|
uno::Reference<text::XTextContent> xText(xBookmarksSupplier->getBookmarks()->getByName(u"Mark"_ustr), uno::UNO_QUERY);
|
|
uno::Reference<container::XEnumerationAccess> xTextCursor(xText->getAnchor(), uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT(xTextCursor.is());
|
|
|
|
uno::Reference<container::XEnumerationAccess> xParagraph(
|
|
xTextCursor->createEnumeration()->nextElement(), uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT(xParagraph.is());
|
|
// This looped forever in lcl_CreatePortions
|
|
xParagraph->createEnumeration();
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testBookmarkUndo)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
|
|
SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
|
|
|
|
pMarkAccess->makeMark(aPaM, u"Mark"_ustr, IDocumentMarkAccess::MarkType::BOOKMARK,
|
|
::sw::mark::InsertMode::New);
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
rUndoManager.Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
|
|
rUndoManager.Redo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
|
|
auto ppBkmk = pMarkAccess->findMark(u"Mark"_ustr);
|
|
CPPUNIT_ASSERT(ppBkmk != pMarkAccess->getAllMarksEnd());
|
|
|
|
pMarkAccess->renameMark(*ppBkmk, u"Mark_"_ustr);
|
|
CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark"_ustr) == pMarkAccess->getAllMarksEnd()));
|
|
CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark_"_ustr) != pMarkAccess->getAllMarksEnd());
|
|
rUndoManager.Undo();
|
|
CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark"_ustr) != pMarkAccess->getAllMarksEnd());
|
|
CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark_"_ustr) == pMarkAccess->getAllMarksEnd()));
|
|
rUndoManager.Redo();
|
|
CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark"_ustr) == pMarkAccess->getAllMarksEnd()));
|
|
CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark_"_ustr) != pMarkAccess->getAllMarksEnd());
|
|
|
|
pMarkAccess->deleteMark(pMarkAccess->findMark(u"Mark_"_ustr), false);
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
|
|
rUndoManager.Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
rUndoManager.Redo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf148389_Left)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
CPPUNIT_ASSERT(pWrtShell);
|
|
pWrtShell->Insert(u"foo bar baz"_ustr);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
|
|
IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
|
|
|
|
auto pMark = pMarkAccess->makeMark(*pWrtShell->GetCursor(), u"Mark"_ustr,
|
|
IDocumentMarkAccess::MarkType::BOOKMARK, ::sw::mark::InsertMode::New);
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
|
|
pWrtShell->DelLeft();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->DelLeft();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->DelLeft();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->DelLeft();
|
|
// historically it wasn't deleted if empty, not sure if it should be
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
// the problem was that the end position was not restored
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
// this undo is no longer grouped, to prevent Redo deleting bookmark
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Redo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Redo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf148389_Right)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
CPPUNIT_ASSERT(pWrtShell);
|
|
pWrtShell->Insert(u"foo bar baz"_ustr);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
|
|
IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
|
|
|
|
auto pMark = pMarkAccess->makeMark(*pWrtShell->GetCursor(), u"Mark"_ustr,
|
|
IDocumentMarkAccess::MarkType::BOOKMARK, ::sw::mark::InsertMode::New);
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, /*bBasicCall=*/false);
|
|
pWrtShell->DelRight();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->DelRight();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->DelRight();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->DelRight();
|
|
// historically it wasn't deleted if empty, not sure if it should be
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
// the problem was that the start position was not restored
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
// this undo is no longer grouped, to prevent Redo deleting bookmark
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
// this undo is no longer grouped, to prevent Redo deleting bookmark
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Redo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Redo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Redo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pMark->GetOtherMarkPos().GetContentIndex());
|
|
pWrtShell->Undo();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
// Undo re-creates the mark...
|
|
pMark = *pMarkAccess->getAllMarksBegin();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pMark->GetMarkPos().GetContentIndex());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pMark->GetOtherMarkPos().GetContentIndex());
|
|
}
|
|
|
|
static void lcl_setWeight(SwWrtShell* pWrtShell, FontWeight aWeight)
|
|
{
|
|
SvxWeightItem aWeightItem(aWeight, EE_CHAR_WEIGHT);
|
|
SvxScriptSetItem aScriptSetItem(SID_ATTR_CHAR_WEIGHT, pWrtShell->GetAttrPool());
|
|
aScriptSetItem.PutItemForScriptType(SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX, aWeightItem);
|
|
pWrtShell->SetAttrSet(aScriptSetItem.GetItemSet());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo85876)
|
|
{
|
|
createSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
lcl_setWeight(pWrtShell, WEIGHT_BOLD);
|
|
pWrtShell->Insert(u"test"_ustr);
|
|
lcl_setWeight(pWrtShell, WEIGHT_NORMAL);
|
|
pWrtShell->SplitNode();
|
|
pWrtShell->SplitNode();
|
|
pWrtShell->Up(false);
|
|
pWrtShell->Insert(u"test"_ustr);
|
|
auto xText = getParagraph(1)->getText();
|
|
CPPUNIT_ASSERT(xText.is());
|
|
{
|
|
auto xCursor(xText->createTextCursorByRange(getParagraph(1)));
|
|
CPPUNIT_ASSERT(xCursor.is());
|
|
xCursor->collapseToStart();
|
|
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, u"CharWeight"_ustr));
|
|
}
|
|
{
|
|
auto xCursor(xText->createTextCursorByRange(getParagraph(2)));
|
|
CPPUNIT_ASSERT(xCursor.is());
|
|
xCursor->collapseToStart();
|
|
// this used to be BOLD too with fdo#85876
|
|
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, u"CharWeight"_ustr));
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCaretPositionMovingUp)
|
|
{
|
|
createSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->Insert(u"after"_ustr);
|
|
pWrtShell->InsertLineBreak();
|
|
pWrtShell->Up(false);
|
|
pWrtShell->Insert(u"before"_ustr);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(OUString(u"beforeAfter" + OUStringChar(CH_TXTATR_NEWLINE)), getParagraph(1)->getString());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf93441)
|
|
{
|
|
createSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->Insert(u"Hello"_ustr);
|
|
pWrtShell->InsertLineBreak();
|
|
pWrtShell->Insert(u"Hello World"_ustr);
|
|
pWrtShell->Up(false);
|
|
pWrtShell->Insert(u" World"_ustr);
|
|
|
|
// Without the fix in place, this test would have failed with
|
|
// - Expected: Hello World\nHello World
|
|
// - Actual : WorldHello\nHello World
|
|
CPPUNIT_ASSERT_EQUAL(OUString(u"Hello World" + OUStringChar(CH_TXTATR_NEWLINE) + u"Hello World"), getParagraph(1)->getString());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf81226)
|
|
{
|
|
createSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->Insert(u"before"_ustr);
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
|
|
pWrtShell->Down(false);
|
|
pWrtShell->Insert(u"after"_ustr);
|
|
|
|
// Without the fix in place, this test would have failed with
|
|
// - Expected: beforeafter
|
|
// - Actual : beafterfore
|
|
CPPUNIT_ASSERT_EQUAL(u"beforeafter"_ustr, getParagraph(1)->getString());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf137532)
|
|
{
|
|
createSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->Insert(u"test"_ustr);
|
|
|
|
//Select the word and change it to bold
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 4, /*bBasicCall=*/false);
|
|
lcl_setWeight(pWrtShell, WEIGHT_BOLD);
|
|
|
|
// Select first character and replace it
|
|
pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
|
|
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
|
|
pWrtShell->Insert(u"x"_ustr);
|
|
|
|
auto xText = getParagraph(1)->getText();
|
|
CPPUNIT_ASSERT(xText.is());
|
|
auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
|
|
|
|
CPPUNIT_ASSERT(xCursor.is());
|
|
CPPUNIT_ASSERT_EQUAL(u"xest"_ustr, xCursor->getString());
|
|
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, u"CharWeight"_ustr));
|
|
|
|
dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
|
|
|
|
xCursor.set(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
|
|
CPPUNIT_ASSERT(xCursor.is());
|
|
CPPUNIT_ASSERT_EQUAL(u"test"_ustr, xCursor->getString());
|
|
|
|
// Without the fix in place, this test would have failed in
|
|
// - Expected: 150
|
|
// - Actual : 100
|
|
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, u"CharWeight"_ustr));
|
|
|
|
dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
|
|
|
|
xCursor.set(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
|
|
CPPUNIT_ASSERT(xCursor.is());
|
|
CPPUNIT_ASSERT_EQUAL(u"test"_ustr, xCursor->getString());
|
|
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, u"CharWeight"_ustr));
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testFdo87448)
|
|
{
|
|
createSwDoc("fdo87448.odt");
|
|
|
|
// Save the first shape to a metafile.
|
|
uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter = drawing::GraphicExportFilter::create(comphelper::getProcessComponentContext());
|
|
uno::Reference<lang::XComponent> xSourceDoc(getShape(1), uno::UNO_QUERY);
|
|
xGraphicExporter->setSourceDocument(xSourceDoc);
|
|
|
|
SvMemoryStream aStream;
|
|
uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
|
|
uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
|
|
{ "OutputStream", uno::Any(xOutputStream) },
|
|
{ "FilterName", uno::Any(u"SVM"_ustr) }
|
|
}));
|
|
xGraphicExporter->filter(aDescriptor);
|
|
aStream.Seek(STREAM_SEEK_TO_BEGIN);
|
|
|
|
// Read it back and dump it as an XML file.
|
|
Graphic aGraphic;
|
|
TypeSerializer aSerializer(aStream);
|
|
aSerializer.readGraphic(aGraphic);
|
|
const GDIMetaFile& rMetaFile = aGraphic.GetGDIMetaFile();
|
|
MetafileXmlDump dumper;
|
|
xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, rMetaFile);
|
|
|
|
// The first polyline in the document has a number of points to draw arcs,
|
|
// the last one jumps back to the start, so we call "end" the last but one.
|
|
sal_Int32 nFirstEnd = getXPath(pXmlDoc, "(//polyline)[1]/point[last()-1]", "x").toInt32();
|
|
// The second polyline has a different start point, but the arc it draws
|
|
// should end at the ~same position as the first polyline.
|
|
sal_Int32 nSecondEnd = getXPath(pXmlDoc, "(//polyline)[2]/point[last()]", "x").toInt32();
|
|
|
|
// nFirstEnd was 6023 and nSecondEnd was 6648, now they should be much closer, e.g. nFirstEnd = 6550, nSecondEnd = 6548
|
|
OString aMsg = "nFirstEnd is " + OString::number(nFirstEnd) + ", nSecondEnd is " + OString::number(nSecondEnd);
|
|
// Assert that the difference is less than half point.
|
|
CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), abs(nFirstEnd - nSecondEnd) < 10);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTextCursorInvalidation)
|
|
{
|
|
createSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
uno::Reference<beans::XPropertySet> xPageStyle(getStyles(u"PageStyles"_ustr)->getByName(u"Standard"_ustr), uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT(xPageStyle.is());
|
|
xPageStyle->setPropertyValue(u"HeaderIsOn"_ustr, uno::Any(true));
|
|
uno::Reference<text::XText> xHeader(getProperty<uno::Reference<text::XText>>(xPageStyle, u"HeaderText"_ustr));
|
|
CPPUNIT_ASSERT(xHeader.is());
|
|
// create cursor inside the header text
|
|
uno::Reference<text::XTextCursor> xCursor(xHeader->createTextCursor());
|
|
// can't go right in empty header
|
|
CPPUNIT_ASSERT(!xCursor->goRight(1, false));
|
|
// this does not actually delete the header: xPageStyle->setPropertyValue("HeaderIsOn", uno::makeAny(false));
|
|
pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false);
|
|
// must be disposed after deleting header
|
|
// cursor ends up in body
|
|
// UPDATE: this behaviour has been corrected as a side effect of the fix to tdf#46561:
|
|
//CPPUNIT_ASSERT_THROW(xCursor->goRight(1, false), uno::RuntimeException);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf68183)
|
|
{
|
|
// First disable RSID and check if indeed no such attribute is inserted.
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwModule* mod = SwModule::get();
|
|
mod->GetModuleConfig()->SetStoreRsid(false);
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
pWrtShell->Insert2(u"X"_ustr);
|
|
|
|
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
|
|
SwPaM aPaM(aIdx);
|
|
SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();
|
|
CPPUNIT_ASSERT_EQUAL(false, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
|
|
|
|
// Then enable storing of RSID and make sure that the attribute is inserted.
|
|
mod->GetModuleConfig()->SetStoreRsid(true);
|
|
|
|
pWrtShell->DelToStartOfLine();
|
|
pWrtShell->Insert2(u"X"_ustr);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(true, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testCp1000115)
|
|
{
|
|
createSwDoc("cp1000115.fodt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
// This was 1: the long paragraph in the B1 cell did flow over to the
|
|
// second page, so there was only one paragraph in the second cell of the
|
|
// second page.
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell[2]/txt", 2);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf63214)
|
|
{
|
|
//This is a crash test
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
pWrtShell->Insert(u"V"_ustr);
|
|
{ //limiting the lifetime of SwPaM with a nested scope
|
|
//the shell cursor are automatically adjusted when nodes are deleted, but the shell doesn't know about an SwPaM on the stack
|
|
IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
|
|
SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
|
|
aPaM.SetMark();
|
|
aPaM.Move(fnMoveForward, GoInContent);
|
|
//Inserting a crossRefBookmark
|
|
pMarkAccess->makeMark(aPaM, u"Bookmark"_ustr,
|
|
IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK,
|
|
::sw::mark::InsertMode::New);
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
}
|
|
//moving cursor to the end of paragraph
|
|
pWrtShell->EndPara();
|
|
//inserting paragraph break
|
|
pWrtShell->SplitNode();
|
|
rUndoManager.Undo();
|
|
rUndoManager.Redo();
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf90003)
|
|
{
|
|
createSwDoc("tdf90003.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
CPPUNIT_ASSERT(pXmlDoc);
|
|
// This was 1: an unexpected fly portion was created, resulting in too
|
|
// large x position for the empty paragraph marker.
|
|
assertXPath(pXmlDoc, "//SwFixPortion[@type='PortionType::Fly']", 0);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf51741)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
|
|
IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
|
|
SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
|
|
//Modification 1
|
|
pMarkAccess->makeMark(aPaM, u"Mark"_ustr, IDocumentMarkAccess::MarkType::BOOKMARK,
|
|
::sw::mark::InsertMode::New);
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
//Modification 2
|
|
rUndoManager.Undo();
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
|
|
//Modification 3
|
|
rUndoManager.Redo();
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
auto ppBkmk = pMarkAccess->findMark(u"Mark"_ustr);
|
|
CPPUNIT_ASSERT(ppBkmk != pMarkAccess->getAllMarksEnd());
|
|
//Modification 4
|
|
pMarkAccess->renameMark(*ppBkmk, u"Mark_"_ustr);
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark"_ustr) == pMarkAccess->getAllMarksEnd()));
|
|
CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark_"_ustr) != pMarkAccess->getAllMarksEnd());
|
|
//Modification 5
|
|
rUndoManager.Undo();
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark"_ustr) != pMarkAccess->getAllMarksEnd());
|
|
CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark_"_ustr) == pMarkAccess->getAllMarksEnd()));
|
|
//Modification 6
|
|
rUndoManager.Redo();
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT(bool(pMarkAccess->findMark(u"Mark"_ustr) == pMarkAccess->getAllMarksEnd()));
|
|
CPPUNIT_ASSERT(pMarkAccess->findMark(u"Mark_"_ustr) != pMarkAccess->getAllMarksEnd());
|
|
//Modification 7
|
|
pMarkAccess->deleteMark(pMarkAccess->findMark(u"Mark_"_ustr), false);
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
|
|
//Modification 8
|
|
rUndoManager.Undo();
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
|
|
//Modification 9
|
|
rUndoManager.Redo();
|
|
CPPUNIT_ASSERT(pWrtShell->IsModified());
|
|
pWrtShell->ResetModified();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDefaultsOfOutlineNumbering)
|
|
{
|
|
uno::Reference<text::XDefaultNumberingProvider> xDefNum(m_xSFactory->createInstance(u"com.sun.star.text.DefaultNumberingProvider"_ustr), uno::UNO_QUERY);
|
|
css::lang::Locale alocale;
|
|
alocale.Language = "en";
|
|
alocale.Country = "US";
|
|
const uno::Sequence<beans::PropertyValues> aPropVal(xDefNum->getDefaultContinuousNumberingLevels(alocale));
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aPropVal.getLength());
|
|
for(const auto& rPropValues : aPropVal)
|
|
{
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(5), rPropValues.getLength());
|
|
for(const auto& rPropVal : rPropValues)
|
|
{
|
|
uno::Any aAny = rPropVal.Value;
|
|
if(rPropVal.Name == "Prefix" || rPropVal.Name == "Suffix" || rPropVal.Name == "Transliteration")
|
|
CPPUNIT_ASSERT_EQUAL(u"string"_ustr, aAny.getValueTypeName());
|
|
else if(rPropVal.Name == "NumberingType")
|
|
CPPUNIT_ASSERT_EQUAL(u"short"_ustr, aAny.getValueTypeName());
|
|
else if(rPropVal.Name == "NatNum")
|
|
CPPUNIT_ASSERT_EQUAL(u"short"_ustr, aAny.getValueTypeName());
|
|
//It is expected to be long but right now its short !error!
|
|
else
|
|
CPPUNIT_FAIL("Property Name not matched");
|
|
}
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testDeleteTableRedlines)
|
|
{
|
|
createSwDoc();
|
|
SwDoc* pDoc = getSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
|
|
const SwTable& rTable = pWrtShell->InsertTable(TableOpt, 1, 3);
|
|
uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRows()->getCount());
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
|
|
uno::Sequence<beans::PropertyValue> aDescriptor;
|
|
SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox(u"A1"_ustr))), u"TableCellInsert", aDescriptor);
|
|
SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox(u"B1"_ustr))), u"TableCellInsert", aDescriptor);
|
|
SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(rTable.GetTableBox(u"C1"_ustr))), u"TableCellInsert", aDescriptor);
|
|
IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
|
|
SwExtraRedlineTable& rExtras = rIDRA.GetExtraRedlineTable();
|
|
rExtras.DeleteAllTableRedlines(*pDoc, rTable, false, RedlineType::Any);
|
|
CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(0), rExtras.GetSize());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testXFlatParagraph)
|
|
{
|
|
createSwDoc();
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
//Inserting some text in the document
|
|
pWrtShell->Insert(u"This is sample text"_ustr);
|
|
pWrtShell->SplitNode();
|
|
pWrtShell->Insert(u"This is another sample text"_ustr);
|
|
pWrtShell->SplitNode();
|
|
pWrtShell->Insert(u"This is yet another sample text"_ustr);
|
|
//retrieving the XFlatParagraphs
|
|
uno::Reference<text::XFlatParagraphIteratorProvider> xFPIP(mxComponent, uno::UNO_QUERY);
|
|
uno::Reference<text::XFlatParagraphIterator> xFPIterator(xFPIP->getFlatParagraphIterator(sal_Int32(text::TextMarkupType::SPELLCHECK), true));
|
|
uno::Reference<text::XFlatParagraph> xFlatPara(xFPIterator->getFirstPara());
|
|
CPPUNIT_ASSERT_EQUAL(u"This is sample text"_ustr, xFlatPara->getText());
|
|
//checking modified status
|
|
CPPUNIT_ASSERT(!xFlatPara->isModified());
|
|
//checking "checked" status, modifying it and asserting the changes
|
|
CPPUNIT_ASSERT(!xFlatPara->isChecked(sal_Int32(text::TextMarkupType::SPELLCHECK)));
|
|
xFlatPara->setChecked((sal_Int32(text::TextMarkupType::SPELLCHECK)), true);
|
|
CPPUNIT_ASSERT(xFlatPara->isChecked(sal_Int32(text::TextMarkupType::SPELLCHECK)));
|
|
//getting other XFlatParagraphs and asserting their contents
|
|
uno::Reference<text::XFlatParagraph> xFlatPara2(xFPIterator->getParaAfter(xFlatPara));
|
|
CPPUNIT_ASSERT_EQUAL(u"This is another sample text"_ustr, xFlatPara2->getText());
|
|
uno::Reference<text::XFlatParagraph> xFlatPara3(xFPIterator->getParaAfter(xFlatPara2));
|
|
CPPUNIT_ASSERT_EQUAL(u"This is yet another sample text"_ustr, xFlatPara3->getText());
|
|
uno::Reference<text::XFlatParagraph> xFlatPara4(xFPIterator->getParaBefore(xFlatPara3));
|
|
CPPUNIT_ASSERT_EQUAL(xFlatPara2->getText(), xFlatPara4->getText());
|
|
//changing the attributes of last para
|
|
uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
|
|
{ "CharWeight", uno::Any(float(css::awt::FontWeight::BOLD)) }
|
|
}));
|
|
xFlatPara3->changeAttributes(sal_Int32(0), sal_Int32(5), aDescriptor);
|
|
//checking Language Portions
|
|
uno::Sequence<::sal_Int32> aLangPortions(xFlatPara4->getLanguagePortions());
|
|
CPPUNIT_ASSERT(!aLangPortions.hasElements());
|
|
//examining Language of text
|
|
css::lang::Locale alocale = xFlatPara4->getLanguageOfText(sal_Int32(0), sal_Int32(4));
|
|
CPPUNIT_ASSERT_EQUAL(u"en"_ustr, alocale.Language);
|
|
CPPUNIT_ASSERT_EQUAL(u"US"_ustr, alocale.Country);
|
|
//examining Primary Language of text
|
|
css::lang::Locale aprimarylocale = xFlatPara4->getPrimaryLanguageOfText(sal_Int32(0), sal_Int32(20));
|
|
CPPUNIT_ASSERT_EQUAL(u"en"_ustr, aprimarylocale.Language);
|
|
CPPUNIT_ASSERT_EQUAL(u"US"_ustr, aprimarylocale.Country);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf81995)
|
|
{
|
|
uno::Reference<text::XDefaultNumberingProvider> xDefNum(m_xSFactory->createInstance(u"com.sun.star.text.DefaultNumberingProvider"_ustr), uno::UNO_QUERY);
|
|
css::lang::Locale alocale;
|
|
alocale.Language = "en";
|
|
alocale.Country = "US";
|
|
const uno::Sequence<uno::Reference<container::XIndexAccess>> aIndexAccess(xDefNum->getDefaultOutlineNumberings(alocale));
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aIndexAccess.getLength());
|
|
for(const auto& rIndexAccess : aIndexAccess)
|
|
{
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(6), rIndexAccess->getCount());
|
|
for(int j=0;j<rIndexAccess->getCount();j++)
|
|
{
|
|
uno::Sequence<beans::PropertyValue> aProps;
|
|
rIndexAccess->getByIndex(j) >>= aProps;
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(12), aProps.getLength());
|
|
for (const beans::PropertyValue& rProp : aProps)
|
|
{
|
|
uno::Any aAny = rProp.Value;
|
|
if(rProp.Name == "Prefix" || rProp.Name == "Suffix" || rProp.Name == "BulletChar" || rProp.Name == "BulletFontName" || rProp.Name == "Transliteration")
|
|
CPPUNIT_ASSERT_EQUAL(u"string"_ustr, aAny.getValueTypeName());
|
|
else if(rProp.Name == "NumberingType" || rProp.Name == "ParentNumbering" || rProp.Name == "Adjust")
|
|
CPPUNIT_ASSERT_EQUAL(u"short"_ustr, aAny.getValueTypeName());
|
|
else if(rProp.Name == "LeftMargin" || rProp.Name == "SymbolTextDistance" || rProp.Name == "FirstLineOffset" || rProp.Name == "NatNum")
|
|
CPPUNIT_ASSERT_EQUAL(u"long"_ustr, aAny.getValueTypeName());
|
|
else
|
|
CPPUNIT_FAIL("Property Name not matched");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CPPUNIT_PLUGIN_IMPLEMENT();
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|