Files
libreoffice/sw/qa/extras/uiwriter/uiwriter.cxx
Varun 9d9fbbdc1e Add test for tdf#75137 crsr movement b/w footnote
Change-Id: Ifd0ec1e7922c54fb3509824de13bb8f0b1c79279
Reviewed-on: https://gerrit.libreoffice.org/16391
Reviewed-by: Michael Stahl <mstahl@redhat.com>
Tested-by: Michael Stahl <mstahl@redhat.com>
2015-06-22 11:07:38 +00:00

1165 lines
48 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/drawing/GraphicExportFilter.hpp>
#include <com/sun/star/i18n/TextConversionOption.hpp>
#include <swmodeltestbase.hxx>
#include <ndtxt.hxx>
#include <wrtsh.hxx>
#include <crsskip.hxx>
#include <shellio.hxx>
#include <expfld.hxx>
#include <drawdoc.hxx>
#include <docary.hxx>
#include <redline.hxx>
#include <section.hxx>
#include <fmtclds.hxx>
#include <dcontact.hxx>
#include <textboxhelper.hxx>
#include <view.hxx>
#include <hhcwrp.hxx>
#include <swacorr.hxx>
#include <swmodule.hxx>
#include <modcfg.hxx>
#include <charatr.hxx>
#include <editeng/acorrcfg.hxx>
#include <unotools/streamwrap.hxx>
#include <test/mtfxmldump.hxx>
#include <unocrsr.hxx>
#include <unocrsrhelper.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdview.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/scripttypeitem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/wghtitem.hxx>
#include "UndoManager.hxx"
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/util/SearchOptions.hpp>
#include <com/sun/star/util/SearchFlags.hpp>
#include "com/sun/star/util/SearchAlgorithms.hpp"
#include "com/sun/star/i18n/TransliterationModulesExtra.hpp"
#include "com/sun/star/sdbcx/XTablesSupplier.hpp"
#include <osl/file.hxx>
static const char* DATA_DIRECTORY = "/sw/qa/extras/uiwriter/data/";
class SwUiWriterTest : public SwModelTestBase
{
public:
void testReplaceForward();
//Regression test of fdo#70143
//EDITING: undo search&replace corrupt text when searching backward
void testReplaceBackward();
void testFdo69893();
void testFdo70807();
void testImportRTF();
void testExportRTF();
void testFdo75110();
void testFdo75898();
void testFdo74981();
void testShapeTextboxSelect();
void testShapeTextboxDelete();
void testCp1000071();
void testShapeTextboxVertadjust();
void testShapeTextboxAutosize();
void testFdo82191();
void testCommentedWord();
void testChineseConversionBlank();
void testChineseConversionNonChineseText();
void testChineseConversionTraditionalToSimplified();
void testChineseConversionSimplifiedToTraditional();
void testFdo85554();
void testAutoCorr();
void testMergeDoc();
void testCreatePortions();
void testBookmarkUndo();
void testFdo85876();
void testFdo87448();
void testTdf68183();
void testCp1000115();
void testTdf90003();
void testdelofTableRedlines();
void testExportToPicture();
void testSearchWithTransliterate();
void testTdf75137();
void testTableBackgroundColor();
void testTdf90362();
void testUndoCharAttribute();
void testTdf86639();
void testTdf90883TableBoxGetCoordinates();
void testEmbeddedDataSource();
void testUnoCursorPointer();
CPPUNIT_TEST_SUITE(SwUiWriterTest);
CPPUNIT_TEST(testReplaceForward);
CPPUNIT_TEST(testReplaceBackward);
CPPUNIT_TEST(testFdo69893);
CPPUNIT_TEST(testFdo70807);
CPPUNIT_TEST(testImportRTF);
CPPUNIT_TEST(testExportRTF);
CPPUNIT_TEST(testFdo75110);
CPPUNIT_TEST(testFdo75898);
CPPUNIT_TEST(testFdo74981);
CPPUNIT_TEST(testShapeTextboxSelect);
CPPUNIT_TEST(testShapeTextboxDelete);
CPPUNIT_TEST(testCp1000071);
CPPUNIT_TEST(testShapeTextboxVertadjust);
CPPUNIT_TEST(testShapeTextboxAutosize);
CPPUNIT_TEST(testFdo82191);
CPPUNIT_TEST(testCommentedWord);
CPPUNIT_TEST(testChineseConversionBlank);
CPPUNIT_TEST(testChineseConversionNonChineseText);
CPPUNIT_TEST(testChineseConversionTraditionalToSimplified);
CPPUNIT_TEST(testChineseConversionSimplifiedToTraditional);
CPPUNIT_TEST(testFdo85554);
CPPUNIT_TEST(testAutoCorr);
CPPUNIT_TEST(testMergeDoc);
CPPUNIT_TEST(testCreatePortions);
CPPUNIT_TEST(testBookmarkUndo);
CPPUNIT_TEST(testFdo85876);
CPPUNIT_TEST(testFdo87448);
CPPUNIT_TEST(testTdf68183);
CPPUNIT_TEST(testCp1000115);
CPPUNIT_TEST(testTdf90003);
CPPUNIT_TEST(testdelofTableRedlines);
CPPUNIT_TEST(testExportToPicture);
CPPUNIT_TEST(testSearchWithTransliterate);
CPPUNIT_TEST(testTdf75137);
CPPUNIT_TEST(testTableBackgroundColor);
CPPUNIT_TEST(testTdf90362);
CPPUNIT_TEST(testUndoCharAttribute);
CPPUNIT_TEST(testTdf86639);
CPPUNIT_TEST(testTdf90883TableBoxGetCoordinates);
CPPUNIT_TEST(testEmbeddedDataSource);
CPPUNIT_TEST(testUnoCursorPointer);
CPPUNIT_TEST_SUITE_END();
private:
SwDoc* createDoc(const char* pName = 0);
};
SwDoc* SwUiWriterTest::createDoc(const char* pName)
{
if (!pName)
pName = "empty.odt";
load(DATA_DIRECTORY, pName);
SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
CPPUNIT_ASSERT(pTextDoc);
return pTextDoc->GetDocShell()->GetDoc();
}
//Replacement tests
static void lcl_selectCharacters(SwPaM& rPaM, sal_Int32 first, sal_Int32 end)
{
rPaM.GetPoint()->nContent.Assign(rPaM.GetContentNode(), first);
rPaM.SetMark();
rPaM.GetPoint()->nContent.Assign(rPaM.GetContentNode(), end);
}
static const OUString ORIGINAL_REPLACE_CONTENT("toto titi tutu");
static const OUString EXPECTED_REPLACE_CONTENT("toto toto tutu");
void SwUiWriterTest::testReplaceForward()
{
SwDoc* pDoc = createDoc();
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
SwPaM aPaM(aIdx);
pDoc->getIDocumentContentOperations().InsertString(aPaM, ORIGINAL_REPLACE_CONTENT);
SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
lcl_selectCharacters(aPaM, 5, 9);
pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, OUString("toto"), false);
CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTextNode->GetText());
rUndoManager.Undo();
CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
}
void SwUiWriterTest::testFdo75110()
{
SwDoc* pDoc = createDoc("fdo75110.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->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();
}
void SwUiWriterTest::testFdo75898()
{
SwDoc* pDoc = createDoc("fdo75898.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
pWrtShell->SelAll();
pWrtShell->InsertRow(1, true);
pWrtShell->InsertRow(1, true);
// Now check if the table has 3 lines.
SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(false);
SwTableNode* pTableNode = pShellCrsr->Start()->nNode.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());
}
void SwUiWriterTest::testReplaceBackward()
{
SwDoc* pDoc = createDoc();
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
SwPaM aPaM(aIdx);
pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("toto titi tutu"));
SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
lcl_selectCharacters(aPaM, 9, 5);
pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, OUString("toto"), false);
CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTextNode->GetText());
rUndoManager.Undo();
CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
}
void SwUiWriterTest::testFdo69893()
{
SwDoc* pDoc = createDoc("fdo69893.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
pWrtShell->SelAll(); // A1 is empty -> selects the whole table.
pWrtShell->SelAll(); // Selects the whole document.
SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(false);
SwTextNode& rEnd = dynamic_cast<SwTextNode&>(pShellCrsr->End()->nNode.GetNode());
// Selection did not include the para after table, this was "B1".
CPPUNIT_ASSERT_EQUAL(OUString("Para after table."), rEnd.GetText());
}
void SwUiWriterTest::testFdo70807()
{
load(DATA_DIRECTORY, "fdo70807.odt");
uno::Reference<container::XIndexAccess> stylesIter(getStyles("PageStyles"), uno::UNO_QUERY);
for (sal_Int32 i = 0; i < stylesIter->getCount(); ++i)
{
uno::Reference<style::XStyle> xStyle(stylesIter->getByIndex(i), uno::UNO_QUERY);
uno::Reference<container::XNamed> xName(xStyle, uno::UNO_QUERY);
bool expectedUsedStyle = false;
bool expectedUserDefined = false;
OUString styleName(xName->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()));
}
}
void SwUiWriterTest::testImportRTF()
{
// Insert "foobar" and position the cursor between "foo" and "bar".
SwDoc* pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
pWrtShell->Insert("foobar");
pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 3, /*bBasicCall=*/false);
// Insert the RTF at the cursor position.
OString aData = "{\\rtf1 Hello world!\\par}";
SvMemoryStream aStream(const_cast<sal_Char*>(aData.getStr()), aData.getLength(), StreamMode::READ);
SwReader aReader(aStream, OUString(), OUString(), *pWrtShell->GetCrsr());
Reader* pRTFReader = SwReaderWriter::GetReader(READER_WRITER_RTF);
CPPUNIT_ASSERT(pRTFReader != 0);
CPPUNIT_ASSERT_EQUAL(sal_uLong(0), aReader.Read(*pRTFReader));
sal_uLong nIndex = pWrtShell->GetCrsr()->GetNode().GetIndex();
CPPUNIT_ASSERT_EQUAL(OUString("fooHello world!"), pDoc->GetNodes()[nIndex - 1]->GetTextNode()->GetText());
CPPUNIT_ASSERT_EQUAL(OUString("bar"), pDoc->GetNodes()[nIndex]->GetTextNode()->GetText());
}
void SwUiWriterTest::testExportRTF()
{
// Insert "aaabbbccc" and select "bbb".
SwDoc* pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
pWrtShell->Insert("aaabbbccc");
pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 3, /*bBasicCall=*/false);
pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/true, 3, /*bBasicCall=*/false);
// Create the clipboard document.
boost::shared_ptr<SwDoc> pClpDoc(new SwDoc());
pClpDoc->SetClipBoard(true);
pWrtShell->Copy(pClpDoc.get());
// And finally export it as RTF.
WriterRef xWrt;
SwReaderWriter::GetWriter("RTF", OUString(), xWrt);
SvMemoryStream aStream;
SwWriter aWrt(aStream, *pClpDoc);
aWrt.Write(xWrt);
OString aData(static_cast<const sal_Char*>(aStream.GetBuffer()), 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"));
}
void SwUiWriterTest::testFdo74981()
{
// create a document with an input field
SwDoc* pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
SwInputField aField(static_cast<SwInputFieldType*>(pWrtShell->GetFieldType(0, RES_INPUTFLD)), OUString("foo"), OUString("bar"), 0, 0);
pWrtShell->Insert(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(CRSR_SKIP_CHARS, false, 100, false);
pWrtShell->SplitNode();
// expect only the second paragraph to have hints
aIdx = SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1);
pTextNode = aIdx.GetNode().GetTextNode();
CPPUNIT_ASSERT(pTextNode->HasHints());
--aIdx;
pTextNode = aIdx.GetNode().GetTextNode();
CPPUNIT_ASSERT(!pTextNode->HasHints());
}
void SwUiWriterTest::testShapeTextboxSelect()
{
SwDoc* pDoc = createDoc("shape-textbox.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->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(RES_FLYFRMFMT, static_cast<RES_FMT>(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(RES_DRAWFRMFMT, static_cast<RES_FMT>(pShape->GetFormat()->Which()));
}
void SwUiWriterTest::testShapeTextboxDelete()
{
SwDoc* pDoc = createDoc("shape-textbox.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->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);
}
void SwUiWriterTest::testCp1000071()
{
SwDoc* pDoc = createDoc("cp1000071.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
CPPUNIT_ASSERT_EQUAL( size_t( 2 ), rTable.size());
sal_uLong redlineStart0NodeIndex = rTable[ 0 ]->Start()->nNode.GetIndex();
sal_Int32 redlineStart0Index = rTable[ 0 ]->Start()->nContent.GetIndex();
sal_uLong redlineEnd0NodeIndex = rTable[ 0 ]->End()->nNode.GetIndex();
sal_Int32 redlineEnd0Index = rTable[ 0 ]->End()->nContent.GetIndex();
sal_uLong redlineStart1NodeIndex = rTable[ 1 ]->Start()->nNode.GetIndex();
sal_Int32 redlineStart1Index = rTable[ 1 ]->Start()->nContent.GetIndex();
sal_uLong redlineEnd1NodeIndex = rTable[ 1 ]->End()->nNode.GetIndex();
sal_Int32 redlineEnd1Index = rTable[ 1 ]->End()->nContent.GetIndex();
// Change the document layout to be 2 columns, and then undo.
pWrtShell->SelAll();
SwSectionData section(CONTENT_SECTION, pWrtShell->GetUniqueSectionName());
SfxItemSet set( pDoc->GetDocShell()->GetPool(), RES_COL, RES_COL, 0 );
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( size_t( 2 ), rTable.size());
CPPUNIT_ASSERT_EQUAL( redlineStart0NodeIndex, rTable[ 0 ]->Start()->nNode.GetIndex());
CPPUNIT_ASSERT_EQUAL( redlineStart0Index, rTable[ 0 ]->Start()->nContent.GetIndex());
CPPUNIT_ASSERT_EQUAL( redlineEnd0NodeIndex, rTable[ 0 ]->End()->nNode.GetIndex());
CPPUNIT_ASSERT_EQUAL( redlineEnd0Index, rTable[ 0 ]->End()->nContent.GetIndex());
CPPUNIT_ASSERT_EQUAL( redlineStart1NodeIndex, rTable[ 1 ]->Start()->nNode.GetIndex());
CPPUNIT_ASSERT_EQUAL( redlineStart1Index, rTable[ 1 ]->Start()->nContent.GetIndex());
CPPUNIT_ASSERT_EQUAL( redlineEnd1NodeIndex, rTable[ 1 ]->End()->nNode.GetIndex());
CPPUNIT_ASSERT_EQUAL( redlineEnd1Index, rTable[ 1 ]->End()->nContent.GetIndex());
}
void SwUiWriterTest::testShapeTextboxVertadjust()
{
SwDoc* pDoc = createDoc("shape-textbox-vertadjust.odt");
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());
}
void SwUiWriterTest::testShapeTextboxAutosize()
{
SwDoc* pDoc = createDoc("shape-textbox-autosize.odt");
SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
SdrObject* pFirst = pPage->GetObj(0);
CPPUNIT_ASSERT_EQUAL(OUString("1st"), pFirst->GetName());
SdrObject* pSecond = pPage->GetObj(1);
CPPUNIT_ASSERT_EQUAL(OUString("2nd"), 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().getHeight() < pSecond->GetSnapRect().getHeight());
}
void SwUiWriterTest::testFdo82191()
{
SwDoc* pDoc = createDoc("fdo82191.odt");
SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
// Make sure we have a single draw shape.
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage, aTextBoxes));
SwDoc aClipboard;
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
SdrObject* pObject = pPage->GetObj(0);
// Select it, then copy and paste.
pWrtShell->SelectObj(Point(), 0, pObject);
pWrtShell->Copy(&aClipboard);
pWrtShell->Paste(&aClipboard);
aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
// This was one: the textbox of the shape wasn't copied.
CPPUNIT_ASSERT_EQUAL(size_t(2), aTextBoxes.size());
}
void SwUiWriterTest::testCommentedWord()
{
// This word is commented. <- string in document
// 123456789 <- character positions
SwDoc* pDoc = createDoc("commented-word.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
// Move the cursor into the second word.
pWrtShell->Right(CRSR_SKIP_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.
SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(false);
// This was 9, only "word", not "word<anchor character>" was selected.
CPPUNIT_ASSERT_EQUAL(sal_Int32(10), pShellCrsr->End()->nContent.GetIndex());
// 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(OUString("word"), xField->getAnchor()->getString());
}
// Chinese conversion tests
static const OUString CHINESE_TRADITIONAL_CONTENT(sal_Unicode(0x9F8D));
static const OUString CHINESE_SIMPLIFIED_CONTENT(sal_Unicode(0x9F99));
static const OUString NON_CHINESE_CONTENT ("Hippopotamus");
// Tests that a blank document is still blank after conversion
void SwUiWriterTest::testChineseConversionBlank()
{
// Given
SwDoc* pDoc = createDoc();
SwView* pView = pDoc->GetDocShell()->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, NULL,
i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
true, false, false );
aWrap.Convert();
// Then
SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
CPPUNIT_ASSERT_EQUAL(OUString(), pTextNode->GetText());
}
// Tests that non Chinese text is unchanged after conversion
void SwUiWriterTest::testChineseConversionNonChineseText()
{
// Given
SwDoc* pDoc = createDoc();
SwView* pView = pDoc->GetDocShell()->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, NULL,
i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
true, false, false );
aWrap.Convert();
// Then
SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
CPPUNIT_ASSERT_EQUAL(NON_CHINESE_CONTENT, pTextNode->GetText());
}
// Tests conversion of traditional Chinese characters to simplified Chinese
void SwUiWriterTest::testChineseConversionTraditionalToSimplified()
{
// Given
SwDoc* pDoc = createDoc();
SwView* pView = pDoc->GetDocShell()->GetView();
const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
SwPaM aPaM(aIdx);
pDoc->getIDocumentContentOperations().InsertString(aPaM, CHINESE_TRADITIONAL_CONTENT);
// When
SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, NULL,
i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
true, false, false );
aWrap.Convert();
// Then
SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
CPPUNIT_ASSERT_EQUAL(CHINESE_SIMPLIFIED_CONTENT, pTextNode->GetText());
}
// Tests conversion of simplified Chinese characters to traditional Chinese
void SwUiWriterTest::testChineseConversionSimplifiedToTraditional()
{
// Given
SwDoc* pDoc = createDoc();
SwView* pView = pDoc->GetDocShell()->GetView();
const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
SwPaM aPaM(aIdx);
pDoc->getIDocumentContentOperations().InsertString(aPaM, CHINESE_SIMPLIFIED_CONTENT);
// When
SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_TRADITIONAL, NULL,
i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
true, false, false );
aWrap.Convert();
// Then
SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
CPPUNIT_ASSERT_EQUAL(CHINESE_TRADITIONAL_CONTENT, pTextNode->GetText());
}
void SwUiWriterTest::testFdo85554()
{
// Load the document, it contains one shape with a textbox.
load("/sw/qa/extras/uiwriter/data/", "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("com.sun.star.drawing.RectangleShape"), 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.
reload("writer8", "fdo85554.odt");
xDrawPageSupplier.set(mxComponent, uno::UNO_QUERY);
xDrawPage = xDrawPageSupplier->getDrawPage();
// This was 1, we lost a shape on export.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xDrawPage->getCount());
}
void SwUiWriterTest::testAutoCorr()
{
SwDoc* pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
const sal_Unicode cIns = ' ';
//Normal AutoCorrect
pWrtShell->Insert("tset");
pWrtShell->AutoCorrect(corr, cIns);
sal_uLong nIndex = pWrtShell->GetCrsr()->GetNode().GetIndex();
CPPUNIT_ASSERT_EQUAL(OUString("Test "), static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText());
//AutoCorrect with change style to bolt
pWrtShell->Insert("Bolt");
pWrtShell->AutoCorrect(corr, cIns);
nIndex = pWrtShell->GetCrsr()->GetNode().GetIndex();
const uno::Reference< text::XTextRange > xRun = getRun(getParagraph(1), 2);
CPPUNIT_ASSERT_EQUAL(OUString("Bolt"), xRun->getString());
CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty<OUString>(xRun, "CharFontName"));
//AutoCorrect inserts Table with 2 rows and 3 columns
pWrtShell->Insert("4xx");
pWrtShell->AutoCorrect(corr, cIns);
const uno::Reference< text::XTextTable > xTable(getParagraphOrTable(2), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable->getRows()->getCount());
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
}
void SwUiWriterTest::testMergeDoc()
{
SwDoc* const pDoc1(createDoc("merge-change1.odt"));
auto xDoc2Component(loadFromDesktop(
getURLFromSrc(DATA_DIRECTORY) + "merge-change2.odt",
"com.sun.star.text.TextDocument"));
auto pxDoc2Document(
dynamic_cast<SwXTextDocument *>(xDoc2Component.get()));
CPPUNIT_ASSERT(pxDoc2Document);
SwDoc* const pDoc2(pxDoc2Document->GetDocShell()->GetDoc());
SwEditShell* const pEditShell(pDoc1->GetEditShell());
pEditShell->MergeDoc(*pDoc2);
// accept all redlines
while(pEditShell->GetRedlineCount())
pEditShell->AcceptRedline(0);
CPPUNIT_ASSERT_EQUAL(7, getParagraphs());
getParagraph(1, "Para One: Two Three Four Five");
getParagraph(2, "Para Two: One Three Four Five");
getParagraph(3, "Para Three: One Two Four Five");
getParagraph(4, "Para Four: One Two Three Four Five");
getParagraph(5, "Para Six: One Three Four Five");
getParagraph(6, "");
getParagraph(7, "");
}
void SwUiWriterTest::testCreatePortions()
{
createDoc("uno-cycle.odt");
uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<text::XTextContent> xText(xBookmarksSupplier->getBookmarks()->getByName("Mark"), 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();
}
void SwUiWriterTest::testBookmarkUndo()
{
SwDoc* pDoc = createDoc();
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
pMarkAccess->makeMark(aPaM, OUString("Mark"), IDocumentMarkAccess::MarkType::BOOKMARK);
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());
IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark("Mark");
CPPUNIT_ASSERT(ppBkmk != pMarkAccess->getAllMarksEnd());
pMarkAccess->renameMark(ppBkmk->get(), "Mark_");
CPPUNIT_ASSERT(pMarkAccess->findMark("Mark") == pMarkAccess->getAllMarksEnd());
CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") != pMarkAccess->getAllMarksEnd());
rUndoManager.Undo();
CPPUNIT_ASSERT(pMarkAccess->findMark("Mark") != pMarkAccess->getAllMarksEnd());
CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") == pMarkAccess->getAllMarksEnd());
rUndoManager.Redo();
CPPUNIT_ASSERT(pMarkAccess->findMark("Mark") == pMarkAccess->getAllMarksEnd());
CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") != pMarkAccess->getAllMarksEnd());
pMarkAccess->deleteMark( pMarkAccess->findMark("Mark_") );
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());
}
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());
}
void SwUiWriterTest::testFdo85876()
{
SwDoc* const pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
lcl_setWeight(pWrtShell, WEIGHT_BOLD);
pWrtShell->Insert("test");
lcl_setWeight(pWrtShell, WEIGHT_NORMAL);
pWrtShell->SplitNode();
pWrtShell->SplitNode();
pWrtShell->Up(false);
pWrtShell->Insert("test");
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, "CharWeight"));
}
{
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, "CharWeight"));
}
}
void SwUiWriterTest::testFdo87448()
{
createDoc("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 =
{
beans::PropertyValue("OutputStream", sal_Int32(0), uno::makeAny(xOutputStream), beans::PropertyState_DIRECT_VALUE),
beans::PropertyValue("FilterName", sal_Int32(0), uno::makeAny(OUString("SVM")), beans::PropertyState_DIRECT_VALUE)
};
xGraphicExporter->filter(aDescriptor);
aStream.Seek(STREAM_SEEK_TO_BEGIN);
// Read it back and dump it as an XML file.
Graphic aGraphic;
ReadGraphic(aStream, aGraphic);
const GDIMetaFile& rMetaFile = aGraphic.GetGDIMetaFile();
MetafileXmlDump dumper;
xmlDocPtr pXmlDoc = dumper.dumpAndParse(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, "/metafile/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, "/metafile/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);
}
void SwUiWriterTest::testTdf68183()
{
// First disable RSID and check if indeed no such attribute is inserted.
SwDoc* pDoc = createDoc();
SW_MOD()->GetModuleConfig()->SetStoreRsid(false);
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
pWrtShell->Insert2("X");
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
SwPaM aPaM(aIdx);
SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
CPPUNIT_ASSERT_EQUAL(false, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
// Then enable storing of RSID and make sure that the attribute is inserted.
SW_MOD()->GetModuleConfig()->SetStoreRsid(true);
pWrtShell->DelToStartOfLine();
pWrtShell->Insert2("X");
CPPUNIT_ASSERT_EQUAL(true, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
}
void SwUiWriterTest::testCp1000115()
{
createDoc("cp1000115.fodt");
xmlDocPtr pXmlDoc = parseLayoutDump();
xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "/root/page[2]/body/tab/row/cell[2]/txt");
xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
// 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.
CPPUNIT_ASSERT_EQUAL(2, xmlXPathNodeSetGetLength(pXmlNodes));
xmlXPathFreeObject(pXmlObj);
}
void SwUiWriterTest::testTdf90003()
{
createDoc("tdf90003.odt");
xmlDocPtr 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, "//Special[@nType='POR_FLY']", 0);
}
void SwUiWriterTest::testdelofTableRedlines()
{
SwDoc* pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
SwInsertTableOptions TableOpt(tabopts::DEFAULT_BORDER, 0);
const SwTable& tbl = 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*>(tbl.GetTableBox(OUString("A1")))), OUString("TableCellInsert"), aDescriptor);
SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(tbl.GetTableBox(OUString("B1")))), OUString("TableCellInsert"), aDescriptor);
SwUnoCursorHelper::makeTableCellRedline((*const_cast<SwTableBox*>(tbl.GetTableBox(OUString("C1")))), OUString("TableCellInsert"), aDescriptor);
IDocumentRedlineAccess& pDocRed = pDoc->getIDocumentRedlineAccess();
SwExtraRedlineTable& redtbl = pDocRed.GetExtraRedlineTable();
redtbl.DeleteAllTableRedlines(pDoc, tbl, false, sal_uInt16(USHRT_MAX));
CPPUNIT_ASSERT(redtbl.IsEmpty());
}
void SwUiWriterTest::testExportToPicture()
{
createDoc();
uno::Sequence<beans::PropertyValue> aFilterData =
{
beans::PropertyValue("PixelWidth", sal_Int32(0), uno::makeAny(sal_Int32(610)), beans::PropertyState_DIRECT_VALUE),
beans::PropertyValue("PixelHeight", sal_Int32(0), uno::makeAny(sal_Int32(610)), beans::PropertyState_DIRECT_VALUE)
};
uno::Sequence<beans::PropertyValue> aDescriptor =
{
beans::PropertyValue("FilterName", sal_Int32(0), uno::makeAny(OUString("writer_png_Export")), beans::PropertyState_DIRECT_VALUE),
beans::PropertyValue("FilterData", sal_Int32(0), uno::makeAny(aFilterData), beans::PropertyState_DIRECT_VALUE)
};
utl::TempFile aTempFile;
uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
xStorable->storeToURL(aTempFile.GetURL(), aDescriptor);
bool extchk = aTempFile.IsValid();
CPPUNIT_ASSERT_EQUAL(true, extchk);
osl::File tmpFile(aTempFile.GetURL());
tmpFile.open(sal_uInt32(osl_File_OpenFlag_Read));
sal_uInt64 val;
CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, tmpFile.getSize(val));
CPPUNIT_ASSERT(val > 100);
aTempFile.EnableKillingFile();
}
void SwUiWriterTest::testSearchWithTransliterate()
{
SwDoc* pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
SwPaM aPaM(aIdx);
pDoc->getIDocumentContentOperations().InsertString(aPaM,"This is paragraph one");
pWrtShell->SplitNode();
aIdx = SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1);
aPaM = SwPaM(aIdx);
pDoc->getIDocumentContentOperations().InsertString(aPaM,"This is Other PARAGRAPH");
com::sun::star::util::SearchOptions SearchOpt;
SearchOpt.algorithmType = com::sun::star::util::SearchAlgorithms_ABSOLUTE;
SearchOpt.searchFlag = 0x00000001;
SearchOpt.searchString = "other";
SearchOpt.replaceString.clear();
SearchOpt.changedChars = 0;
SearchOpt.deletedChars = 0;
SearchOpt.insertedChars = 0;
SearchOpt.transliterateFlags = com::sun::star::i18n::TransliterationModulesExtra::IGNORE_DIACRITICS_CTL;
//transliteration option set so that at least one of the search strings is not found
sal_uLong case1 = pWrtShell->SearchPattern(SearchOpt,true,DOCPOS_START,DOCPOS_END,FND_IN_BODY,false);
SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(true);
CPPUNIT_ASSERT_EQUAL(OUString(""),pShellCrsr->GetText());
CPPUNIT_ASSERT_EQUAL(0,(int)case1);
SearchOpt.searchString = "paragraph";
SearchOpt.transliterateFlags = com::sun::star::i18n::TransliterationModulesExtra::IGNORE_KASHIDA_CTL;
//transliteration option set so that all search strings are found
sal_uLong case2 = pWrtShell->SearchPattern(SearchOpt,true,DOCPOS_START,DOCPOS_END,FND_IN_BODY,false);
pShellCrsr = pWrtShell->getShellCrsr(true);
CPPUNIT_ASSERT_EQUAL(OUString("paragraph"),pShellCrsr->GetText());
CPPUNIT_ASSERT_EQUAL(1,(int)case2);
}
void SwUiWriterTest::testTdf75137()
{
SwDoc* pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(true);
pWrtShell->InsertFootnote(OUString("This is first footnote"));
sal_uLong firstIndex = pShellCrsr->GetNode().GetIndex();
pShellCrsr->GotoFootnoteAnchor();
pWrtShell->InsertFootnote(OUString("This is second footnote"));
pWrtShell->Up(false, 1, false);
sal_uLong secondIndex = pShellCrsr->GetNode().GetIndex();
pWrtShell->Down(false, 1, false);
sal_uLong thirdIndex = pShellCrsr->GetNode().GetIndex();
CPPUNIT_ASSERT_EQUAL(firstIndex, thirdIndex);
CPPUNIT_ASSERT(firstIndex != secondIndex);
}
void SwUiWriterTest::testTableBackgroundColor()
{
SwDoc* pDoc = createDoc();
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
SwInsertTableOptions TableOpt(tabopts::DEFAULT_BORDER, 0);
pWrtShell->InsertTable(TableOpt, 3, 3); //Inserting Table
//Checking Rows and Columns of Inserted Table
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());
pWrtShell->SttDoc();
pWrtShell->SelTableRow(); //Selecting First Row
pWrtShell->ClearMark();
//Modifying the color of Table Box
Color colour = sal_Int32(0xFF00FF);
pWrtShell->SetBoxBackground(SvxBrushItem(colour, sal_Int16(RES_BACKGROUND)));
//Checking cells for background color only A1 should be modified
uno::Reference<table::XCell> xCell;
xCell = xTable->getCellByName("A1");
CPPUNIT_ASSERT_EQUAL(sal_Int32(0xFF00FF), getProperty<sal_Int32>(xCell, "BackColor"));
xCell = xTable->getCellByName("A2");
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
xCell = xTable->getCellByName("A3");
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
xCell = xTable->getCellByName("B1");
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
xCell = xTable->getCellByName("B2");
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
xCell = xTable->getCellByName("B3");
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
xCell = xTable->getCellByName("C1");
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
xCell = xTable->getCellByName("C2");
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
xCell = xTable->getCellByName("C3");
CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
}
void SwUiWriterTest::testTdf90362()
{
// First check if the end of the second paragraph is indeed protected.
SwDoc* pDoc = createDoc("tdf90362.fodt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
pWrtShell->EndPara();
pWrtShell->Down(/*bSelect=*/false);
CPPUNIT_ASSERT_EQUAL(true, pWrtShell->HasReadonlySel());
// Then enable ignoring of protected areas and make sure that this time the cursor is read-write.
pWrtShell->Up(/*bSelect=*/false);
SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
aViewOptions.SetIgnoreProtectedArea(true);
pWrtShell->ApplyViewOptions(aViewOptions);
pWrtShell->Down(/*bSelect=*/false);
CPPUNIT_ASSERT_EQUAL(false, pWrtShell->HasReadonlySel());
}
void SwUiWriterTest::testUndoCharAttribute()
{
// Create a new empty Writer document
SwDoc* pDoc = createDoc();
SwPaM* pCrsr = pDoc->GetEditShell()->GetCrsr();
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
IDocumentContentOperations & rIDCO(pDoc->getIDocumentContentOperations());
// Insert some text
rIDCO.InsertString(*pCrsr, "This will be bolded");
// Position of word 9876543210
// Use cursor to select part of text
pCrsr->SetMark();
for (int i = 0; i < 9; i++) {
pCrsr->Move(fnMoveBackward);
}
// Check that correct text was selected
CPPUNIT_ASSERT_EQUAL(OUString("be bolded"), pCrsr->GetText());
// Apply a "Bold" attribute to selection
SvxWeightItem aWeightItem(WEIGHT_BOLD, RES_CHRATR_WEIGHT);
rIDCO.InsertPoolItem(*pCrsr, aWeightItem);
SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT);
// Adds selected text's attributes to aSet
pCrsr->GetNode().GetTextNode()->GetAttr(aSet, 10, 19);
SfxPoolItem const * aPoolItem = aSet.GetItem(RES_CHRATR_WEIGHT);
SfxPoolItem& ampPoolItem = aWeightItem;
// Check that bold is active on the selection; checks if it's in aSet
CPPUNIT_ASSERT_EQUAL((*aPoolItem == ampPoolItem), true);
// Invoke Undo
rUndoManager.Undo();
// Check that bold is no longer active
aSet.ClearItem(RES_CHRATR_WEIGHT);
pCrsr->GetNode().GetTextNode()->GetAttr(aSet, 10, 19);
aPoolItem = aSet.GetItem(RES_CHRATR_WEIGHT);
CPPUNIT_ASSERT_EQUAL((*aPoolItem == ampPoolItem), false);
}
void SwUiWriterTest::testTdf86639()
{
SwDoc* pDoc = createDoc("tdf86639.rtf");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
SwTextFormatColl* pColl = pDoc->FindTextFormatCollByName("Heading");
pWrtShell->SetTextFormatColl(pColl);
OUString aExpected = pColl->GetAttrSet().GetFont().GetFamilyName();
// This was Calibri, should be Liberation Sans.
CPPUNIT_ASSERT_EQUAL(aExpected, getProperty<OUString>(getRun(getParagraph(1), 1), "CharFontName"));
}
void SwUiWriterTest::testTdf90883TableBoxGetCoordinates()
{
SwDoc* pDoc = createDoc("tdf90883.odt");
SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
pWrtShell->Down(true);
SwSelBoxes aBoxes;
::GetTableSel( *pWrtShell, aBoxes );
CPPUNIT_ASSERT_EQUAL( 2, (int)aBoxes.size() );
Point pos ( aBoxes[0]->GetCoordinates() );
CPPUNIT_ASSERT_EQUAL( 1, (int)pos.X() );
CPPUNIT_ASSERT_EQUAL( 1, (int)pos.Y() );
pos = aBoxes[1]->GetCoordinates();
CPPUNIT_ASSERT_EQUAL( 1, (int)pos.X() );
CPPUNIT_ASSERT_EQUAL( 2, (int)pos.Y() );
}
void SwUiWriterTest::testEmbeddedDataSource()
{
// Initially no data source.
uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
uno::Reference<sdb::XDatabaseContext> xDatabaseContext = sdb::DatabaseContext::create(xComponentContext);
CPPUNIT_ASSERT(!xDatabaseContext->hasByName("calc-data-source"));
// Load: should have a component and a data source, too.
load(DATA_DIRECTORY, "embedded-data-source.odt");
CPPUNIT_ASSERT(mxComponent.is());
CPPUNIT_ASSERT(xDatabaseContext->hasByName("calc-data-source"));
// Data source has a table named Sheet1.
uno::Reference<sdbc::XDataSource> xDataSource(xDatabaseContext->getByName("calc-data-source"), uno::UNO_QUERY);
CPPUNIT_ASSERT(xDataSource.is());
uno::Reference<sdbcx::XTablesSupplier> xConnection(xDataSource->getConnection("", ""), uno::UNO_QUERY);
uno::Reference<container::XNameAccess> xTables(xConnection->getTables(), uno::UNO_QUERY);
CPPUNIT_ASSERT(xTables.is());
CPPUNIT_ASSERT(xTables->hasByName("Sheet1"));
// Reload: should still have a component and a data source, too.
reload("writer8", "embedded-data-source.odt");
CPPUNIT_ASSERT(mxComponent.is());
CPPUNIT_ASSERT(xDatabaseContext->hasByName("calc-data-source"));
// Data source has a table named Sheet1 after saving to a different directory.
xDataSource.set(xDatabaseContext->getByName("calc-data-source"), uno::UNO_QUERY);
CPPUNIT_ASSERT(xDataSource.is());
xConnection.set(xDataSource->getConnection("", ""), uno::UNO_QUERY);
xTables.set(xConnection->getTables(), uno::UNO_QUERY);
CPPUNIT_ASSERT(xTables.is());
CPPUNIT_ASSERT(xTables->hasByName("Sheet1"));
// Close: should not have a data source anymore.
mxComponent->dispose();
mxComponent.clear();
CPPUNIT_ASSERT(!xDatabaseContext->hasByName("calc-data-source"));
// Now open again the saved result, and instead of 'save as', just 'save'.
mxComponent = loadFromDesktop(maTempFile.GetURL(), "com.sun.star.text.TextDocument");
uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
xStorable->store();
}
void SwUiWriterTest::testUnoCursorPointer()
{
auto xDocComponent(loadFromDesktop(
getURLFromSrc(DATA_DIRECTORY) + "empty.odt",
"com.sun.star.text.TextDocument"));
auto pxDocDocument(
dynamic_cast<SwXTextDocument *>(xDocComponent.get()));
CPPUNIT_ASSERT(pxDocDocument);
SwDoc* const pDoc(pxDocDocument->GetDocShell()->GetDoc());
std::unique_ptr<SwNodeIndex> xIdx(new SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1));
std::unique_ptr<SwPosition> xPos(new SwPosition(*xIdx));
sw::UnoCursorPointer pCursor(pDoc->CreateUnoCrsr(*xPos));
CPPUNIT_ASSERT(static_cast<bool>(pCursor));
xPos.reset(); // we need to kill the SwPosition before disposing
xIdx.reset(); // we need to kill the SwNodeIndex before disposing
xDocComponent->dispose();
CPPUNIT_ASSERT(!static_cast<bool>(pCursor));
}
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */