Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/qa/extras/uiwriter/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 111 kB image not shown  

Quelle  uiwriter4.cxx   Sprache: 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/drawing/FillStyle.hpp>
#include <com/sun/star/style/CaseMap.hpp>
#include <swmodeltestbase.hxx>
#include <ndtxt.hxx>
#include <wrtsh.hxx>
#include <drawdoc.hxx>
#include <redline.hxx>
#include <dcontact.hxx>
#include <view.hxx>
#include <IDocumentSettingAccess.hxx>

#include <editeng/brushitem.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdview.hxx>

#include <i18nutil/transliteration.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <UndoManager.hxx>
#include <tblafmt.hxx>

#include <com/sun/star/text/XTextField.hpp>
#include <com/sun/star/linguistic2/XLinguProperties.hpp>
#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
#include <com/sun/star/text/XPageCursor.hpp>
#include <com/sun/star/text/XParagraphAppend.hpp>
#include <o3tl/cppunittraitshelper.hxx>
#include <osl/thread.hxx>
#include <hyp.hxx>
#include <swdtflvr.hxx>
#include <comphelper/propertysequence.hxx>
#include <sfx2/classificationhelper.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <editeng/unolingu.hxx>
#include <vcl/scheduler.hxx>
#include <config_fonts.h>
#include <unotxdoc.hxx>
#include <unotools/transliterationwrapper.hxx>
#include <officecfg/Office/Writer.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 SwUiWriterTest4 : public SwModelTestBase
{
public:
    SwUiWriterTest4()
        : SwModelTestBase(u"/sw/qa/extras/uiwriter/data/"_ustr)
    {
    }

    void mergeDocs(const char* aDestDoc, const char* aInsertDoc);
};

void SwUiWriterTest4::mergeDocs(const char* aDestDoc, const char* aInsertDoc)
{
    createSwDoc(aDestDoc);

    // set a page cursor into the end of the document
    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
        xModel->getCurrentController(), uno::UNO_QUERY);
    uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
                                              uno::UNO_QUERY);
    xCursor->jumpToEndOfPage();

    // insert the same document at current cursor position
    {
        const OUString insertFileid = createFileURL(OUString::createFromAscii(aInsertDoc));
        uno::Sequence<beans::PropertyValue> aPropertyValues(
            comphelper::InitPropertySequence({ { "Name", uno::Any(insertFileid) } }));
        dispatchCommand(mxComponent, u".uno:InsertDoc"_ustr, aPropertyValues);
    }
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf96515)
{
    // Enable hide whitespace mode.
    createSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
    aViewOptions.SetHideWhitespaceMode(true);
    pWrtShell->ApplyViewOptions(aViewOptions);
    CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsWhitespaceHidden());

    // Insert a new paragraph at the end of the document.
    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
    uno::Reference<text::XParagraphAppend> xParagraphAppend(xTextDocument->getText(),
                                                            uno::UNO_QUERY);
    xParagraphAppend->finishParagraph(uno::Sequence<beans::PropertyValue>());
    calcLayout();

    // This was 2, a new page was created for the new paragraph.
    CPPUNIT_ASSERT_EQUAL(1, getPages());
}

static OUString lcl_translitTest(SwDoc& rDoc, const SwPaM& rPaM, TransliterationFlags const nType)
{
    utl::TransliterationWrapper aTrans(::comphelper::getProcessComponentContext(), nType);
    rDoc.getIDocumentContentOperations().TransliterateText(rPaM, aTrans);
    //SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    return rPaM.GetMarkNode().GetTextNode()->GetText();
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf146449)
{
    createSwDoc("tdf146449.odt");

    auto pShell = getSwDocShell()->GetFEShell();
    CPPUNIT_ASSERT(pShell);

    auto xTextBox = getShapeByName(u"Frame1");
    auto pObject = SdrObject::getSdrObjectFromXShape(xTextBox);

    CPPUNIT_ASSERT(pShell->SelectObj(Point(), 0, pObject));

    dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});

    dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});

    uno::Reference<beans::XPropertySet> xShapeProps(xTextBox, uno::UNO_QUERY);
    uno::Reference<beans::XPropertySet> xFrameProps(
        xShapeProps->getPropertyValue(u"TextBoxContent"_ustr), uno::UNO_QUERY);

    const auto nShapeZOrder = pObject->GetOrdNum();
    const auto nFrameZOrder = xFrameProps->getPropertyValue(u"ZOrder"_ustr);

    CPPUNIT_ASSERT_MESSAGE("Wrong Zorder!", nShapeZOrder < nFrameZOrder.get<sal_uInt32>());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf49033)
{
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // Insert the test text at the end of the document.
    pWrtShell->SttEndDoc(/*bStt=*/false);
    pWrtShell->Insert(u"Mary Jones met joe Smith. Time Passed."_ustr);
    pWrtShell->StartOfSection();
    SwShellCursor* pCursor = pWrtShell->getShellCursor(false);

    using TF = TransliterationFlags;

    /* -- Test behavior when there is no selection -- */

    /* Move cursor between the 't' and the ' ' after 'met', nothing should change */
    for (int i = 0; i < 14; i++)
        pCursor->Move(fnMoveForward);

    CPPUNIT_ASSERT_EQUAL(false, pCursor->HasMark());
    CPPUNIT_ASSERT_EQUAL(false, pWrtShell->IsSelection());
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* Move cursor between the 'h' and the '.' after 'Smith', nothing should change */
    for (int i = 0; i < 10; i++)
        pCursor->Move(fnMoveForward);

    CPPUNIT_ASSERT_EQUAL(false, pCursor->HasMark());
    CPPUNIT_ASSERT_EQUAL(false, pWrtShell->IsSelection());
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* Move cursor between the 'm' and the 'e' in 'met' */
    for (int i = 0; i < 12; i++)
        pCursor->Move(fnMoveBackward);

    CPPUNIT_ASSERT_EQUAL(false, pCursor->HasMark());
    CPPUNIT_ASSERT_EQUAL(false, pWrtShell->IsSelection());
    CPPUNIT_ASSERT_EQUAL(u"Mary jones met joe smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));

    /* Undo the sentence case change to reset for the following tests */
    pDoc->GetIDocumentUndoRedo().Undo();

    CPPUNIT_ASSERT_EQUAL(u"Mary Jones Met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones MET joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* -- Test behavior when there is a selection that does not cross a word boundary -- */
    pCursor->Move(fnMoveBackward);
    pWrtShell->SelWrd();
    CPPUNIT_ASSERT_EQUAL(true, pCursor->HasMark());
    CPPUNIT_ASSERT_EQUAL(true, pWrtShell->IsSelection());

    OUString currentSelectedText;
    pWrtShell->GetSelectedText(currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"met"_ustr, currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones Met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones Met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones MET joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* -- Test behavior when there is a selection that does not begin at a word boundary: "et" -- */
    for (int i = 0; i < 2; i++)
        pCursor->Move(fnMoveBackward);
    pCursor->SetMark();
    for (int i = 0; i < 2; i++)
        pCursor->Move(fnMoveForward);
    pWrtShell->GetSelectedText(currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"et"_ustr, currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones mEt joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    pDoc->GetIDocumentUndoRedo().Undo();
    CPPUNIT_ASSERT_EQUAL(u"et"_ustr, currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones mEt joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    pDoc->GetIDocumentUndoRedo().Undo();
    CPPUNIT_ASSERT_EQUAL(u"et"_ustr, currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones mET joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* -- Test behavior when there is a selection that crosses a word boundary -- */
    for (int i = 0; i < 7; i++)
        pCursor->Move(fnMoveBackward);
    pCursor->SetMark();
    for (int i = 0; i < 14; i++)
        pCursor->Move(fnMoveForward);

    pWrtShell->GetSelectedText(currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"nes met joe Sm"_ustr, currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"Mary JoNes met joe smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary JoNes Met Joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary JoNES MET JOE SMith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* Reset the 's' to upper-case for the next test */
    for (int i = 0; i < 2; i++)
        pCursor->Move(fnMoveBackward);
    pCursor->SetMark();
    pCursor->Move(fnMoveForward);
    pDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, OUString('S'), false);

    /* -- Test behavior when there is a selection that crosses a sentence boundary -- */
    for (int i = 0; i < 4; i++)
        pCursor->Move(fnMoveBackward);
    pCursor->SetMark();
    for (int i = 0; i < 22; i++)
        pCursor->Move(fnMoveForward);
    pWrtShell->GetSelectedText(currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"joe Smith. Time Passed"_ustr, currentSelectedText);

    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met Joe smith. Time passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));

    /* Undo the sentence case change to reset for the following tests */
    pDoc->GetIDocumentUndoRedo().Undo();

    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met Joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met JOE SMITH. TIME PASSED."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe smith. time passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* Undo the previous changes to reset for the following tests */
    pDoc->GetIDocumentUndoRedo().Undo();
    pDoc->GetIDocumentUndoRedo().Undo();
    pDoc->GetIDocumentUndoRedo().Undo();

    /* -- Test behavior when there is a selection that does not reach end of sentence -- */
    for (int i = 0; i < 37; i++)
        pCursor->Move(fnMoveBackward);
    pCursor->SetMark();
    for (int i = 0; i < 10; i++)
        pCursor->Move(fnMoveForward);
    pWrtShell->GetSelectedText(currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones"_ustr, currentSelectedText);
    CPPUNIT_ASSERT_EQUAL(u"Mary jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"Mary Jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"MARY JONES met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"mary jones met joe Smith. Time Passed."_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf147196)
{
    using TF = TransliterationFlags;
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // Insert the test text at the end of the document.
    pWrtShell->SttEndDoc(/*bStt=*/false);
    pWrtShell->Insert(
        u"2.2 Publication of information - CAA\nSection 4.2 of a CA\'s Certificate Policy and/or "
        "Certification Practice Statement SHALL state the CA\'s policy or practice on processing "
        "CAA Records for Fully Qualified Domain Names; that policy shall be consistent with these "
        "Requirements. \n\nIt shall clearly specify the set of Issuer Domain Names that the CA "
        "recognises in CAA \"issue\" or \"issuewild\" records as permitting it to issue. The CA "
        "SHALL log all actions taken, if any, consistent with its processing practice."_ustr);

    pWrtShell->StartOfSection();
    SwShellCursor* pCursor = pWrtShell->getShellCursor(false);
    pCursor->SetMark();
    for (int i = 0; i < 510; i++)
    {
        pCursor->Move(fnMoveForward);
    }
    CPPUNIT_ASSERT_EQUAL(
        u"2.2 Publication Of Information - Caa\nSection 4.2 Of A Ca\'s Certificate Policy "
        "And/Or Certification Practice Statement Shall State The Ca\'s Policy Or Practice "
        "On Processing Caa Records For Fully Qualified Domain Names; That Policy Shall Be "
        "Consistent With These Requirements. \n\nIt Shall Clearly Specify The Set Of "
        "Issuer Domain Names That The Ca Recognises In Caa \"Issue\" Or \"Issuewild\" "
        "Records As Permitting It To Issue. The Ca Shall Log All Actions Taken, If Any, "
        "Consistent With Its Processing Practice."_ustr,
        lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf148148)
{
    using TF = TransliterationFlags;
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    pWrtShell->SttEndDoc(/*bStt=*/false);
    pWrtShell->Insert(u" text"_ustr);

    /* Test what happens when node contains text but selection does not contain any text */
    pWrtShell->StartOfSection();
    SwShellCursor* pCursor = pWrtShell->getShellCursor(false);
    pCursor->SetMark();
    for (int i = 0; i < 3; i++)
    {
        pCursor->Move(fnMoveForward);
    }
    CPPUNIT_ASSERT_EQUAL(u" text"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u" text"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u" text"_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u" text"_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* Test what happens when node contains text but selection does not contain any text */
    createSwDoc();
    pDoc = getSwDoc();
    pWrtShell = getSwDocShell()->GetWrtShell();
    pWrtShell->SttEndDoc(/*bStt=*/false);
    pWrtShell->Insert(u"text "_ustr);

    pWrtShell->StartOfSection();
    pCursor = pWrtShell->getShellCursor(false);
    for (int i = 0; i < 4; i++)
    {
        pCursor->Move(fnMoveForward);
    }
    pCursor->SetMark();
    for (int i = 0; i < 2; i++)
    {
        pCursor->Move(fnMoveForward);
    }

    CPPUNIT_ASSERT_EQUAL(u"text "_ustr, lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"text "_ustr, lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"text "_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"text "_ustr,
                         lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* Test what happens when node contains only non-word text but selection does not contain any text */
    createSwDoc();
    pDoc = getSwDoc();
    pWrtShell = getSwDocShell()->GetWrtShell();
    pWrtShell->SttEndDoc(/*bStt=*/false);
    pWrtShell->Insert(u"-1 "_ustr);

    pWrtShell->StartOfSection();
    pCursor = pWrtShell->getShellCursor(false);
    for (int i = 0; i < 2; i++)
    {
        pCursor->Move(fnMoveForward);
    }
    pCursor->SetMark();
    for (int i = 0; i < 2; i++)
    {
        pCursor->Move(fnMoveForward);
    }

    CPPUNIT_ASSERT_EQUAL(u"-1 "_ustr, lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"-1 "_ustr, lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u"-1 "_ustr, lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u"-1 "_ustr, lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    createSwDoc();
    pDoc = getSwDoc();
    pWrtShell = getSwDocShell()->GetWrtShell();
    pWrtShell->SttEndDoc(/*bStt=*/false);
    pWrtShell->Insert(u" -1"_ustr);

    pWrtShell->StartOfSection();
    pCursor = pWrtShell->getShellCursor(false);
    pCursor->SetMark();
    for (int i = 0; i < 2; i++)
    {
        pCursor->Move(fnMoveForward);
    }

    CPPUNIT_ASSERT_EQUAL(u" -1"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u" -1"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u" -1"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u" -1"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));

    /* Test what happens when node and selection contains only non-word text */
    createSwDoc();
    pDoc = getSwDoc();
    pWrtShell = getSwDocShell()->GetWrtShell();
    pWrtShell->SttEndDoc(/*bStt=*/false);
    pWrtShell->Insert(u" -1"_ustr);

    pWrtShell->StartOfSection();
    pCursor = pWrtShell->getShellCursor(false);
    pCursor->SetMark();
    for (int i = 0; i < 5; i++)
    {
        pCursor->Move(fnMoveForward);
    }

    CPPUNIT_ASSERT_EQUAL(u" -1"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::SENTENCE_CASE));
    CPPUNIT_ASSERT_EQUAL(u" -1"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::TITLE_CASE));
    CPPUNIT_ASSERT_EQUAL(u" -1"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::LOWERCASE_UPPERCASE));
    CPPUNIT_ASSERT_EQUAL(u" -1"_ustr, lcl_translitTest(*pDoc, *pCursor, TF::UPPERCASE_LOWERCASE));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf96943)
{
    // Enable hide whitespace mode.
    createSwDoc("tdf96943.odt");
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
    aViewOptions.SetHideWhitespaceMode(true);
    pWrtShell->ApplyViewOptions(aViewOptions);

    // Insert a new character at the end of the document.
    pWrtShell->SttEndDoc(/*bStt=*/false);
    pWrtShell->Insert(u"d"_ustr);

    // This was 2, a new page was created for the new layout line.
    CPPUNIT_ASSERT_EQUAL(1, getPages());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf96536)
{
    // Enable hide whitespace mode.
    createSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
    aViewOptions.SetHideWhitespaceMode(true);
    pWrtShell->ApplyViewOptions(aViewOptions);
    CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsWhitespaceHidden());

    // Insert a page break and go back to the first page.
    pWrtShell->InsertPageBreak();
    pWrtShell->SttEndDoc(/*bStt=*/true);
    calcLayout();
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    sal_Int32 nSingleParaPageHeight
        = getXPath(pXmlDoc, "/root/page[1]/infos/bounds""height").toInt32();

    // Insert a 2nd paragraph at the end of the first page, so the page height grows at least twice...
    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
    uno::Reference<text::XParagraphAppend> xParagraphAppend(xTextDocument->getText(),
                                                            uno::UNO_QUERY);
    const uno::Reference<text::XTextRange> xInsertPos = getRun(getParagraph(1), 1);
    xParagraphAppend->finishParagraphInsert(uno::Sequence<beans::PropertyValue>(), xInsertPos);
    calcLayout();
    pXmlDoc = parseLayoutDump();
    CPPUNIT_ASSERT(getXPath(pXmlDoc, "/root/page[1]/infos/bounds""height").toInt32()
                   >= 2 * nSingleParaPageHeight);

    // ... and then delete the 2nd paragraph, which shrinks the page to the previous size.
    uno::Reference<lang::XComponent> xParagraph(getParagraph(2), uno::UNO_QUERY);
    xParagraph->dispose();
    calcLayout();
    pXmlDoc = parseLayoutDump();
    CPPUNIT_ASSERT_EQUAL(nSingleParaPageHeight,
                         getXPath(pXmlDoc, "/root/page[1]/infos/bounds""height").toInt32());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf96479)
{
    // We want to verify the empty input text field in the bookmark
    static const OUString emptyInputTextField
        = OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + OUStringChar(CH_TXT_ATR_INPUTFIELDEND);

    createSwDoc();
    SwDoc* pDoc = getSwDoc();

    // So we can clean up all references for reload
    {
        // Append bookmark
        SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
        SwPaM aPaM(aIdx);
        IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
        sw::mark::MarkBase* pMark
            = rIDMA.makeMark(aPaM, SwMarkName(u"original"_ustr),
                             IDocumentMarkAccess::MarkType::BOOKMARK, ::sw::mark::InsertMode::New);
        CPPUNIT_ASSERT(!pMark->IsExpanded());
        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());

        // Get helper objects
        uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
        uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);

        // Create cursor from bookmark
        uno::Reference<text::XTextContent> xTextContent(
            xBookmarksSupplier->getBookmarks()->getByName(u"original"_ustr), uno::UNO_QUERY);
        uno::Reference<text::XTextRange> xRange = xTextContent->getAnchor();
        uno::Reference<text::XTextCursor> xCursor
            = xRange->getText()->createTextCursorByRange(xRange);
        CPPUNIT_ASSERT(xCursor->isCollapsed());

        // Remove bookmark
        xRange->getText()->removeTextContent(xTextContent);
        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rIDMA.getBookmarksCount());

        // Insert replacement bookmark
        uno::Reference<text::XTextContent> xBookmarkNew(
            xFactory->createInstance(u"com.sun.star.text.Bookmark"_ustr), uno::UNO_QUERY);
        uno::Reference<container::XNamed> xBookmarkName(xBookmarkNew, uno::UNO_QUERY);
        xBookmarkName->setName(u"replacement"_ustr);
        CPPUNIT_ASSERT(xCursor->isCollapsed());
        // Force bookmark expansion
        xCursor->getText()->insertString(xCursor, u"."_ustr, true);
        xCursor->getText()->insertTextContent(xCursor, xBookmarkNew, true);
        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
        auto mark = *(rIDMA.getBookmarksBegin());
        CPPUNIT_ASSERT(mark->IsExpanded());

        // Create and insert input textfield with some content
        uno::Reference<text::XTextField> xTextField(
            xFactory->createInstance(u"com.sun.star.text.TextField.Input"_ustr), uno::UNO_QUERY);
        uno::Reference<text::XTextCursor> xCursorNew(
            xBookmarkNew->getAnchor()->getText()->createTextCursorByRange(
                xBookmarkNew->getAnchor()));
        CPPUNIT_ASSERT(!xCursorNew->isCollapsed());
        xCursorNew->getText()->insertTextContent(xCursorNew, xTextField, true);
        xBookmarkNew = uno::Reference<text::XTextContent>(
            xBookmarksSupplier->getBookmarks()->getByName(u"replacement"_ustr), uno::UNO_QUERY);
        xCursorNew = xBookmarkNew->getAnchor()->getText()->createTextCursorByRange(
            xBookmarkNew->getAnchor());
        CPPUNIT_ASSERT(!xCursorNew->isCollapsed());

        // Can't check the actual content of the text node via UNO
        mark = *(rIDMA.getBookmarksBegin());
        CPPUNIT_ASSERT(mark->IsExpanded());
        SwPaM pam(mark->GetMarkStart(), mark->GetMarkEnd());
        // Check for the actual bug, which didn't include CH_TXT_ATR_INPUTFIELDEND in the bookmark
        CPPUNIT_ASSERT_EQUAL(emptyInputTextField, pam.GetText());
    }

    {
        // Save and load cycle
        // Actually not needed, but the bug symptom of a missing bookmark
        // occurred because a broken bookmark was saved and loading silently
        // dropped the broken bookmark!
        saveAndReload(u"writer8"_ustr);
        pDoc = getSwDoc();

        // Lookup "replacement" bookmark
        IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
        uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
        CPPUNIT_ASSERT(xBookmarksSupplier->getBookmarks()->hasByName(u"replacement"_ustr));

        uno::Reference<text::XTextContent> xTextContent(
            xBookmarksSupplier->getBookmarks()->getByName(u"replacement"_ustr), uno::UNO_QUERY);
        uno::Reference<text::XTextRange> xRange = xTextContent->getAnchor();
        uno::Reference<text::XTextCursor> xCursor
            = xRange->getText()->createTextCursorByRange(xRange);
        CPPUNIT_ASSERT(!xCursor->isCollapsed());

        // Verify bookmark content via text node / PaM
        auto mark = *(rIDMA.getBookmarksBegin());
        CPPUNIT_ASSERT(mark->IsExpanded());
        SwPaM pam(mark->GetMarkStart(), mark->GetMarkEnd());
        CPPUNIT_ASSERT_EQUAL(emptyInputTextField, pam.GetText());
    }
}

// If you resave original document the bookmark will be changed from
//
//  <text:p text:style-name="Standard">
//      <text:bookmark-start text:name="test"/>
//      <text:bookmark-end text:name="test"/>
//      def
//  </text:p>
//
// to
//
//  <text:p text:style-name="Standard">
//      <text:bookmark text:name="test"/>
//      def
//  </text:p>
//
CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testBookmarkCollapsed)
{
    // load document
    createSwDoc("collapsed_bookmark.odt");

    // save original document
    save(u"writer8"_ustr);

    // load only content.xml from the resaved document
    xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);

    const charconst aPath("/office:document-content/office:body/office:text/text:p");

    const int pos1 = getXPathPosition(pXmlDoc, aPath, "bookmark");
    CPPUNIT_ASSERT_EQUAL(0, pos1); // found, and it is first

    CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc, aPath, "bookmark-start")); // not found
    CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc, aPath, "bookmark-end")); // not found
}

// 1. Open a new writer document
// 2. Enter the text "abcdef"
// 3. Select "abc"
// 4. Insert a bookmark on "abc" using Insert->Bookmark. Name the bookmark "test".
// 5. Open the navigator (F5)
//    Select the bookmark "test" using the navigator.
// 6. Hit Del, thus deleting "abc" (The bookmark "test" is still there).
// 7. Save the document:
//      <text:p text:style-name="Standard">
//          <text:bookmark text:name="test"/>
//          def
//      </text:p>
//
CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testRemoveBookmarkText)
{
    // create document
    {
        // create a text document with "abcdef"
        createSwDoc();
        SwDoc* pDoc = getSwDoc();

        {
            SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
            SwPaM aPaM(aIdx);
            pDoc->getIDocumentContentOperations().InsertString(aPaM, u"abcdef"_ustr);
        }

        // mark "abc" with "testBookmark" bookmark
        {
            SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
            SwPaM aPaM(aIdx);

            lcl_selectCharacters(aPaM, 0, 3);
            IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
            sw::mark::MarkBase* pMark = rIDMA.makeMark(aPaM, SwMarkName(u"testBookmark"_ustr),
                                                       IDocumentMarkAccess::MarkType::BOOKMARK,
                                                       ::sw::mark::InsertMode::New);

            // verify
            CPPUNIT_ASSERT(pMark->IsExpanded());
            CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
        }

        // remove text marked with bookmark
        {
            SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
            SwPaM aPaM(aIdx);

            lcl_selectCharacters(aPaM, 0, 3);
            pDoc->getIDocumentContentOperations().DeleteRange(aPaM);

            // verify: bookmark is still exist
            IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
            CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
        }
    }

    // save document
    save(u"writer8"_ustr);

    // load only content.xml from the resaved document
    xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);

    // Bookmark without text becomes collapsed
    assertXPath(pXmlDoc, "//office:body/office:text/text:p/text:bookmark", 1);
    assertXPath(pXmlDoc, "//office:body/office:text/text:p/text:bookmark-start", 0);
    assertXPath(pXmlDoc, "//office:body/office:text/text:p/text:bookmark-end", 0);
}

// 1. Open a new writer document
// 2. Enter the text "abcdef"
// 3. Select "abc"
// 4. Insert a bookmark on "abc" using Insert->Bookmark. Name the bookmark "test".
// 5. Open the navigator (F5)
//    Select the bookmark "test" using the navigator.
// 6. Hit Del, thus deleting "abc" (The bookmark "test" is still there).
// 7. Call our macro
//
//      Sub Main
//          bookmark = ThisComponent.getBookmarks().getByName("test")
//          bookmark.getAnchor().setString("abc")
//      End Sub
//
//    The text "abc" gets inserted inside the bookmark "test", and the document now contains the string "abcdef".
// 7. Save the document:
//      <text:p text:style-name="Standard">
//          <text:bookmark-start text:name="test"/>
//          abc
//          <text:bookmark-end text:name="test"/>
//          def
//      </text:p>
//
CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testRemoveBookmarkTextAndAddNew)
{
    // create document
    {
        // create a text document with "abcdef"
        createSwDoc();
        SwDoc* pDoc = getSwDoc();
        {
            SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
            SwPaM aPaM(aIdx);
            pDoc->getIDocumentContentOperations().InsertString(aPaM, u"abcdef"_ustr);
        }

        // mark "abc" with "testBookmark" bookmark
        {
            SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
            SwPaM aPaM(aIdx);

            lcl_selectCharacters(aPaM, 0, 3);
            IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
            sw::mark::MarkBase* pMark = rIDMA.makeMark(aPaM, SwMarkName(u"testBookmark"_ustr),
                                                       IDocumentMarkAccess::MarkType::BOOKMARK,
                                                       ::sw::mark::InsertMode::New);

            // verify
            CPPUNIT_ASSERT(pMark->IsExpanded());
            CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
        }

        // remove text marked with bookmark
        {
            SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
            SwPaM aPaM(aIdx);

            lcl_selectCharacters(aPaM, 0, 3);
            pDoc->getIDocumentContentOperations().DeleteRange(aPaM);

            // verify: bookmark is still exist
            IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
            CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
        }

        // write "abc" to area marked with "testBookmark" bookmark
        {
            // Get helper objects
            uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent,
                                                                        uno::UNO_QUERY);

            // Create cursor from bookmark
            uno::Reference<text::XTextContent> xTextContent(
                xBookmarksSupplier->getBookmarks()->getByName(u"testBookmark"_ustr),
                uno::UNO_QUERY);
            uno::Reference<text::XTextRange> xRange = xTextContent->getAnchor();
            CPPUNIT_ASSERT_EQUAL(u""_ustr, xRange->getString());

            // write "abc"
            xRange->setString(u"abc"_ustr);

            // verify: bookmark is still exist
            IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
            CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
        }
    }

    // save document
    save(u"writer8"_ustr);

    // load only content.xml from the resaved document
    xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);

    const charconst aPath("/office:document-content/office:body/office:text/text:p");

    CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc, aPath, "bookmark")); // not found
    const int pos2 = getXPathPosition(pXmlDoc, aPath, "bookmark-start");
    const int pos3 = getXPathPosition(pXmlDoc, aPath, "text");
    const int pos4 = getXPathPosition(pXmlDoc, aPath, "bookmark-end");

    CPPUNIT_ASSERT_EQUAL(0, pos2);
    CPPUNIT_ASSERT_EQUAL(1, pos3);
    CPPUNIT_ASSERT_EQUAL(2, pos4);
}

// 1. Load document:
//  <text:p text:style-name="Standard">
//      <text:bookmark-start text:name="test"/>
//      <text:bookmark-end text:name="test"/>
//      def
//  </text:p>
//
// 2. Call our macro
//
//      Sub Main
//          bookmark = ThisComponent.getBookmarks().getByName("test")
//          bookmark.getAnchor().setString("abc")
//      End Sub
//
//    The text "abc" gets inserted inside the bookmark "test", and the document now contains the string "abcdef".
// 3. Save the document:
//      <text:p text:style-name="Standard">
//          <text:bookmark text:name="test"/>
//          abcdef
//      </text:p>
//
CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testRemoveBookmarkTextAndAddNewAfterReload)
{
    // load document
    createSwDoc("collapsed_bookmark.odt");
    SwDoc* pDoc = getSwDoc();

    // write "abc" to area marked with "testBookmark" bookmark
    {
        // Get helper objects
        uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);

        // Create cursor from bookmark
        uno::Reference<text::XTextContent> xTextContent(
            xBookmarksSupplier->getBookmarks()->getByName(u"test"_ustr), uno::UNO_QUERY);
        uno::Reference<text::XTextRange> xRange = xTextContent->getAnchor();
        CPPUNIT_ASSERT_EQUAL(u""_ustr, xRange->getString());

        // write "abc"
        xRange->setString(u"abc"_ustr);

        // verify: bookmark is still exist
        IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), rIDMA.getBookmarksCount());
    }

    // save original document
    save(u"writer8"_ustr);

    // load only content.xml from the resaved document
    xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
    const charconst aPath("/office:document-content/office:body/office:text/text:p");

    const int pos1 = getXPathPosition(pXmlDoc, aPath, "bookmark");
    const int pos2 = getXPathPosition(pXmlDoc, aPath, "text");

    CPPUNIT_ASSERT_EQUAL(0, pos1);
    CPPUNIT_ASSERT_EQUAL(1, pos2);

    CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc, aPath, "bookmark-start")); // not found
    CPPUNIT_ASSERT_ASSERTION_FAIL(getXPathPosition(pXmlDoc, aPath, "bookmark-end")); // not found
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf96961)
{
    // Insert a page break.
    createSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    pWrtShell->InsertPageBreak();

    // Enable hide whitespace mode.
    SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
    aViewOptions.SetHideWhitespaceMode(true);
    pWrtShell->ApplyViewOptions(aViewOptions);

    calcLayout();

    // Assert that the height of the last page is larger than the height of other pages.
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    sal_Int32 nOther = getXPath(pXmlDoc, "/root/page[1]/infos/bounds""height").toInt32();
    sal_Int32 nLast = getXPath(pXmlDoc, "/root/page[2]/infos/bounds""height").toInt32();
    CPPUNIT_ASSERT(nLast > nOther);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf88453)
{
    createSwDoc("tdf88453.odt");
    calcLayout();
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    // This was 0: the table does not fit the first page, but it wasn't split
    // to continue on the second page.
    assertXPath(pXmlDoc, "/root/page[2]/body/tab", 1);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf88453Table)
{
    createSwDoc("tdf88453-table.odt");
    calcLayout();
    // This was 2: layout could not split the large outer table in the document
    // into 3 pages.
    CPPUNIT_ASSERT_EQUAL(3, getPages());
}

namespace
{
int checkShells(const SwDocShell* pSource, const SwDocShell* pDestination)
{
    return int(SfxClassificationHelper::CheckPaste(pSource->getDocProperties(),
                                                   pDestination->getDocProperties()));
}
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testClassificationPaste)
{
    createSwDoc();
    SwDocShell* pSourceShell = getSwDocShell();
    uno::Reference<lang::XComponent> xSourceComponent = mxComponent;
    mxComponent.clear();

    createSwDoc();
    SwDocShell* pDestinationShell = getSwDocShell();

    // Not classified source, not classified destination.
    CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::None),
                         checkShells(pSourceShell, pDestinationShell));

    // Classified source, not classified destination.
    uno::Sequence<beans::PropertyValue> aInternalOnly
        = comphelper::InitPropertySequence({ { "Name", uno::Any(u"Internal Only"_ustr) } });
    dispatchCommand(xSourceComponent, u".uno:ClassificationApply"_ustr, aInternalOnly);
    CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::TargetDocNotClassified),
                         checkShells(pSourceShell, pDestinationShell));

    // Classified source and classified destination -- internal only has a higher level than confidential.
    uno::Sequence<beans::PropertyValue> aConfidential
        = comphelper::InitPropertySequence({ { "Name", uno::Any(u"Confidential"_ustr) } });
    dispatchCommand(mxComponent, u".uno:ClassificationApply"_ustr, aConfidential);
    CPPUNIT_ASSERT_EQUAL(int(SfxClassificationCheckPasteResult::DocClassificationTooLow),
                         checkShells(pSourceShell, pDestinationShell));

    xSourceComponent->dispose();
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testSmallCaps)
{
    // Create a document, add some characters and select them.
    createSwDoc();
    createSwDoc();
    SwDocShell* pDocShell = getSwDocShell();
    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
    pWrtShell->Insert(u"text"_ustr);
    pWrtShell->SelAll();

    // Dispatch the command to make them formatted small capitals.
    dispatchCommand(mxComponent, u".uno:SmallCaps"_ustr, {});

    // This was css::style::CaseMap::NONE as the shell didn't handle the command.
    CPPUNIT_ASSERT_EQUAL(css::style::CaseMap::SMALLCAPS,
                         getProperty<sal_Int16>(getRun(getParagraph(1), 1), u"CharCaseMap"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf98987)
{
    createSwDoc("tdf98987.docx");
    calcLayout();
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[2]/SdrObject""name",
                u"Rectangle 1");
    sal_Int32 nRectangle1
        = getXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[2]/bounds""top")
              .toInt32();
    assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[1]/SdrObject""name",
                u"Rectangle 2");
    sal_Int32 nRectangle2
        = getXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[1]/bounds""top")
              .toInt32();
    CPPUNIT_ASSERT_GREATER(nRectangle1, nRectangle2);

    assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[3]/SdrObject""name",
                u"Rectangle 3");
    sal_Int32 nRectangle3
        = getXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[3]/bounds""top")
              .toInt32();
    // This failed: the 3rd rectangle had a smaller "top" value than the 2nd one, it even overlapped with the 1st one.
    CPPUNIT_ASSERT_GREATER(nRectangle2, nRectangle3);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf99004)
{
    createSwDoc("tdf99004.docx");
    calcLayout();
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    sal_Int32 nTextbox1Top
        = getXPath(pXmlDoc, "/root/page/body/txt/anchored/fly/infos/bounds""top").toInt32();
    sal_Int32 nTextBox1Height
        = getXPath(pXmlDoc, "/root/page/body/txt/anchored/fly/infos/bounds""height").toInt32();
    sal_Int32 nTextBox1Bottom = nTextbox1Top + nTextBox1Height;

    assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[1]/SdrObject""name",
                u"Rectangle 2");
    sal_Int32 nRectangle2Top
        = getXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject[1]/bounds""top")
              .toInt32();
    // This was 3291 and 2531, should be now around 2472 and 2531, i.e. the two rectangles should not overlap anymore.
    CPPUNIT_ASSERT(nTextBox1Bottom < nRectangle2Top);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf84695)
{
    createSwDoc("tdf84695.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);

    // Now Enter + a key should add some text.
    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN);
    emulateTyping(u"a");

    uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY);
    // This was empty, Enter did not start the fly frame edit mode.
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xShape->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf84695NormalChar)
{
    createSwDoc("tdf84695.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);

    // Now pressing 'a' should add a character.
    emulateTyping(u"a");

    uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY);
    // This was empty, pressing a normal character did not start the fly frame edit mode.
    CPPUNIT_ASSERT_EQUAL(u"a"_ustr, xShape->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf84695Tab)
{
    createSwDoc("tdf84695-tab.odt");
    SwDoc* pDoc = getSwDoc();
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
    SdrObject* pObject = pPage->GetObj(0);
    SwContact* pShape = static_cast<SwContact*>(pObject->GetUserCall());
    // First, make sure that pShape is a draw shape.
    CPPUNIT_ASSERT_EQUAL(sal_uInt16(RES_DRAWFRMFMT), pShape->GetFormat()->Which());

    // Then select it.
    pWrtShell->SelectObj(Point(), 0, pObject);

    // Now pressing 'tab' should jump to the other shape.
    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB);
    Scheduler::ProcessEventsToIdle();

    // And finally make sure the selection has changed.
    const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
    SwContact* pOtherShape
        = static_cast<SwContact*>(rMarkList.GetMark(0)->GetMarkedSdrObj()->GetUserCall());
    // This failed, 'tab' didn't do anything -> the selected shape was the same.
    CPPUNIT_ASSERT(pOtherShape != pShape);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTableStyleUndo)
{
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    sw::UndoManager& rUndoManager = pDoc->GetUndoManager();

    sal_Int32 nStyleCount = pDoc->GetTableStyles().size();
    SwTableAutoFormat* pStyle = pDoc->MakeTableStyle(TableStyleName(u"Test Style"_ustr));
    SvxBrushItem aBackground(COL_LIGHTMAGENTA, RES_BACKGROUND);
    pStyle->GetBoxFormat(0).GetProps().SetBackground(aBackground);

    CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc->GetTableStyles().size()), nStyleCount + 1);
    rUndoManager.Undo();
    CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc->GetTableStyles().size()), nStyleCount);
    rUndoManager.Redo();
    CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc->GetTableStyles().size()), nStyleCount + 1);
    // check if attributes are preserved
    pStyle = pDoc->GetTableStyles().FindAutoFormat(TableStyleName(u"Test Style"_ustr));
    CPPUNIT_ASSERT(pStyle);
    CPPUNIT_ASSERT(bool(pStyle->GetBoxFormat(0).GetProps().GetBackground() == aBackground));

    pDoc->DelTableStyle(TableStyleName(u"Test Style"_ustr));
    CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc->GetTableStyles().size()), nStyleCount);
    rUndoManager.Undo();
    CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc->GetTableStyles().size()), nStyleCount + 1);
    pStyle = pDoc->GetTableStyles().FindAutoFormat(TableStyleName(u"Test Style"_ustr));
    // check if attributes are preserved
    CPPUNIT_ASSERT(pStyle);
    CPPUNIT_ASSERT(bool(pStyle->GetBoxFormat(0).GetProps().GetBackground() == aBackground));
    rUndoManager.Redo();
    CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc->GetTableStyles().size()), nStyleCount);

    // undo delete so we can replace the style
    rUndoManager.Undo();
    CPPUNIT_ASSERT_EQUAL(sal_Int32(pDoc->GetTableStyles().size()), nStyleCount + 1);
    pStyle = pDoc->GetTableStyles().FindAutoFormat(TableStyleName(u"Test Style"_ustr));
    CPPUNIT_ASSERT(pStyle);
    CPPUNIT_ASSERT(bool(pStyle->GetBoxFormat(0).GetProps().GetBackground() == aBackground));

    SwTableAutoFormat aNewStyle(TableStyleName(u"Test Style2"_ustr));
    SvxBrushItem aBackground2(COL_LIGHTGREEN, RES_BACKGROUND);
    aNewStyle.GetBoxFormat(0).GetProps().SetBackground(aBackground2);

    pDoc->ChgTableStyle(TableStyleName(u"Test Style"_ustr), aNewStyle);
    pStyle = pDoc->GetTableStyles().FindAutoFormat(TableStyleName(u"Test Style"_ustr));
    CPPUNIT_ASSERT(pStyle);
    CPPUNIT_ASSERT(bool(pStyle->GetBoxFormat(0).GetProps().GetBackground() == aBackground2));
    rUndoManager.Undo();
    pStyle = pDoc->GetTableStyles().FindAutoFormat(TableStyleName(u"Test Style"_ustr));
    CPPUNIT_ASSERT(pStyle);
    CPPUNIT_ASSERT(bool(pStyle->GetBoxFormat(0).GetProps().GetBackground() == aBackground));
    rUndoManager.Redo();
    pStyle = pDoc->GetTableStyles().FindAutoFormat(TableStyleName(u"Test Style"_ustr));
    CPPUNIT_ASSERT(pStyle);
    CPPUNIT_ASSERT(bool(pStyle->GetBoxFormat(0).GetProps().GetBackground() == aBackground2));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testRedlineCopyPaste)
{
    // regressed in tdf#106746
    createSwDoc();
    SwDoc* pDoc = getSwDoc();

    SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
    SwPaM aPaM(aIdx);

    pDoc->getIDocumentContentOperations().InsertString(aPaM, u"abzdezgh"_ustr);
    SwTextNode* pTextNode = aPaM.GetPointNode().GetTextNode();

    // Turn on track changes, make changes, turn off track changes
    uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY);
    xPropertySet->setPropertyValue(u"RecordChanges"_ustr, uno::Any(true));
    lcl_selectCharacters(aPaM, 2, 3);
    pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, u"c"_ustr, false);
    lcl_selectCharacters(aPaM, 6, 7);
    pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, u"f"_ustr, false);
    xPropertySet->setPropertyValue(u"RecordChanges"_ustr, uno::Any(false));

    // Create the clipboard document.
    SwDoc aClipboard;
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();

    // Select the whole content, copy, delete the original and paste the copied content
    pWrtShell->SelAll();
    pWrtShell->Copy(aClipboard);
    pWrtShell->Delete();
    pWrtShell->Paste(aClipboard);

    // With the bug this is "abzcdefgh", ie. contains the first deleted piece, too
    CPPUNIT_ASSERT_EQUAL(u"abcdefgh"_ustr, pTextNode->GetText());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf135260)
{
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwDocShell* pDocShell = getSwDocShell();
    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
    pWrtShell->Insert(u"test"_ustr);

    // Turn on track changes
    uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY);
    xPropertySet->setPropertyValue(u"RecordChanges"_ustr, uno::Any(true));

    for (int i = 0; i < 4; i++)
    {
        pWrtShell->DelLeft();
    }

    SwEditShell* const pEditShell(pDoc->GetEditShell());
    CPPUNIT_ASSERT(pEditShell);
    // accept all redlines
    while (pEditShell->GetRedlineCount())
        pEditShell->AcceptRedline(0);

    // Without the fix in place, this test would have failed with
    // - Expected:
    // - Actual  : tes
    CPPUNIT_ASSERT_EQUAL(u""_ustr, getParagraph(1)->getString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testRedlineParam)
{
    // Create a document with minimal content.
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwDocShell* pDocShell = getSwDocShell();
    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
    pWrtShell->Insert(u"middle"_ustr);

    // Turn on track changes, and add changes to the start and end of the document.
    uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY);
    xPropertySet->setPropertyValue(u"RecordChanges"_ustr, uno::Any(true));
    pWrtShell->StartOfSection();
    pWrtShell->Insert(u"aaa"_ustr);
    pWrtShell->EndOfSection();
    pWrtShell->Insert(u"zzz"_ustr);

    const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), rTable.size());

    // Select the first redline.
    pWrtShell->StartOfSection();
    uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
        { { "NextTrackedChange", uno::Any(o3tl::narrowing<sal_uInt16>(rTable[0]->GetId())) } }));
    dispatchCommand(mxComponent, u".uno:NextTrackedChange"_ustr, aPropertyValues);
    SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
    // This failed: the parameter wasn't handled so the next change (zzz) was
    // selected, not the first one (aaa).
    CPPUNIT_ASSERT_EQUAL(u"aaa"_ustr, pShellCursor->GetText());

    // Select the second redline.
    pWrtShell->StartOfSection();
    aPropertyValues = comphelper::InitPropertySequence(
        { { "NextTrackedChange", uno::Any(o3tl::narrowing<sal_uInt16>(rTable[1]->GetId())) } });
    dispatchCommand(mxComponent, u".uno:NextTrackedChange"_ustr, aPropertyValues);
    pShellCursor = pWrtShell->getShellCursor(false);
    CPPUNIT_ASSERT_EQUAL(u"zzz"_ustr, pShellCursor->GetText());

    // Move the cursor to the start again, and reject the second change.
    pWrtShell->StartOfSection();
    aPropertyValues = comphelper::InitPropertySequence(
        { { "RejectTrackedChange", uno::Any(o3tl::narrowing<sal_uInt16>(rTable[1]->GetId())) } });
    dispatchCommand(mxComponent, u".uno:RejectTrackedChange"_ustr, aPropertyValues);
    pShellCursor = pWrtShell->getShellCursor(false);

    // This was 'middlezzz', the uno command rejected the redline under the
    // cursor, instead of the requested one.
    CPPUNIT_ASSERT_EQUAL(u"aaamiddle"_ustr,
                         pShellCursor->GetPoint()->GetNode().GetTextNode()->GetText());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testRedlineViewAuthor)
{
    // Test that setting an author at an SwView level has effect.

    // Create a document with minimal content.
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwDocShell* pDocShell = getSwDocShell();
    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
    pWrtShell->Insert(u"middle"_ustr);
    SwView* pView = pDocShell->GetView();
    static constexpr OUString aAuthor(u"A U. Thor"_ustr);
    pView->SetRedlineAuthor(aAuthor);
    pDocShell->SetView(pView);

    // Turn on track changes, and add changes to the start of the document.
    uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY);
    xPropertySet->setPropertyValue(u"RecordChanges"_ustr, uno::Any(true));
    pWrtShell->StartOfSection();
    pWrtShell->Insert(u"aaa"_ustr);

    // Now assert that SwView::SetRedlineAuthor() had an effect.
    const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), rTable.size());
    SwRangeRedline* pRedline = rTable[0];
    // This was 'Unknown Author' instead of 'A U. Thor'.
    CPPUNIT_ASSERT_EQUAL(aAuthor, pRedline->GetAuthorString());

    // Insert a comment and assert that SwView::SetRedlineAuthor() affects this as well.
    dispatchCommand(mxComponent, u".uno:.uno:InsertAnnotation"_ustr, {});
    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<beans::XPropertySet> xField(xFields->nextElement(), uno::UNO_QUERY);
    // This was 'Unknown Author' instead of 'A U. Thor'.
    CPPUNIT_ASSERT_EQUAL(aAuthor, xField->getPropertyValue(u"Author"_ustr).get<OUString>());

    //Reset the redline author after using it, otherwise, it might interfere with other unittests
    pView->SetRedlineAuthor(u"Unknown Author"_ustr);
    pDocShell->SetView(pView);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf91292)
{
    createSwDoc("tdf91292_paraBackground.docx");
    uno::Reference<beans::XPropertySet> xPropertySet(getParagraph(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Solid background color", drawing::FillStyle_SOLID,
                                 getProperty<drawing::FillStyle>(xPropertySet, u"FillStyle"_ustr));
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Background Color", Color(0x5C2D91),
                                 getProperty<Color>(xPropertySet, u"FillColor"_ustr));

    // remove background color
    xPropertySet->setPropertyValue(u"FillStyle"_ustr, uno::Any(drawing::FillStyle_NONE));

    // Save it and load it back.
    saveAndReload(u"Office Open XML Text"_ustr);

    xPropertySet.set(getParagraph(1), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL_MESSAGE("No background color", drawing::FillStyle_NONE,
                                 getProperty<drawing::FillStyle>(xPropertySet, u"FillStyle"_ustr));
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf78727)
{
    createSwDoc("tdf78727.docx");
    SwDoc* pDoc = getSwDoc();
    SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
    // This was 1: make sure we don't loose the TextBox anchored inside the
    // table that is moved inside a text frame.
    CPPUNIT_ASSERT(SwTextBoxHelper::getCount(pPage) > 1);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testRedlineTimestamp)
{
    // Test that a redline timestamp's second is not always 0.

    // Create a document with minimal content.
    createSwDoc();
    SwDoc* pDoc = getSwDoc();
    SwDocShell* pDocShell = getSwDocShell();
    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
    pWrtShell->Insert(u"middle"_ustr);

    // Turn on track changes, and add changes to the start and to the end of
    // the document.
    uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY);
    xPropertySet->setPropertyValue(u"RecordChanges"_ustr, uno::Any(true));
    pWrtShell->StartOfSection();
    pWrtShell->Insert(u"aaa"_ustr);
    osl::Thread::wait(std::chrono::seconds(1));
    pWrtShell->EndOfSection();
    pWrtShell->Insert(u"zzz"_ustr);

    // Inserting additional characters at the start changed the table size to
    // 3, i.e. the first and the second "aaa" wasn't combined.
    pWrtShell->StartOfSection();
    pWrtShell->Insert(u"aaa"_ustr);

    // Now assert that at least one of the seconds are not 0.
    const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
    if (rTable.size() >= 2
        && rTable[0]->GetRedlineData().GetTimeStamp().GetMin()
               != rTable[1]->GetRedlineData().GetTimeStamp().GetMin())
        // The relatively rare case when waiting for a second also changes the minute.
        return;

    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), rTable.size());
    sal_uInt16 nSec1 = rTable[0]->GetRedlineData().GetTimeStamp().GetSec();
    sal_uInt16 nSec2 = rTable[1]->GetRedlineData().GetTimeStamp().GetSec();
    // This failed, seconds was always 0.
    CPPUNIT_ASSERT(nSec1 != 0 || nSec2 != 0);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testCursorWindows)
{
    // Create a new document with one window.
    createSwDoc();
    SwDocShell* pDocShell = getSwDocShell();
    SwWrtShell* pWrtShell1 = pDocShell->GetWrtShell();

    // Create a second view and type something.
    pDocShell->GetViewShell()->GetViewFrame().GetDispatcher()->Execute(
        SID_NEWWINDOW, SfxCallMode::SYNCHRON | SfxCallMode::RECORD);
    SwWrtShell* pWrtShell2 = pDocShell->GetWrtShell();
    OUString aText(u"foo"_ustr);
    pWrtShell2->Insert(aText);

    // Assert that only the cursor of the actual window move, not other cursors.
    SwShellCursor* pShellCursor1 = pWrtShell1->getShellCursor(false);
    SwShellCursor* pShellCursor2 = pWrtShell2->getShellCursor(false);
    // This was 3, not 0 -- cursor of the other window moved.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), pShellCursor1->Start()->GetContentIndex());
    CPPUNIT_ASSERT_EQUAL(aText.getLength(), pShellCursor2->Start()->GetContentIndex());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testLandscape)
{
    // Set page orientation to landscape.
    createSwDoc();
    uno::Sequence<beans::PropertyValue> aPropertyValues(
        comphelper::InitPropertySequence({ { "AttributePage.Landscape", uno::Any(true) } }));
    dispatchCommand(mxComponent, u".uno:AttributePage"_ustr, aPropertyValues);

    // Assert that the document model was modified.
    SwDocShell* pDocShell = getSwDocShell();
    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
    size_t nPageDesc = pWrtShell->GetCurPageDesc();
    // This failed, page was still portrait.
    CPPUNIT_ASSERT(pWrtShell->GetPageDesc(nPageDesc).GetLandscape());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf95699)
{
    // Open the document with single FORMCHECKBOX field, select all and copy to clipboard
    // then check that clipboard contains the FORMCHECKBOX in text body.
    // Previously that failed.
    createSwDoc("tdf95699.odt");
    SwDoc* pDoc = getSwDoc();
    IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
    SwDoc aClipboard;
    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
    pWrtShell->SelAll();
    pWrtShell->Copy(aClipboard);
    pMarkAccess = aClipboard.getIDocumentMarkAccess();
    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
    ::sw::mark::Fieldmark* pFieldMark
        = pMarkAccess->getFieldmarkAfter(SwPosition(aClipboard.GetNodes().GetEndOfExtras()), false);
    CPPUNIT_ASSERT_EQUAL(u"vnd.oasis.opendocument.field.FORMCHECKBOX"_ustr,
                         pFieldMark->GetFieldname());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest4, testTdf151548_tabNavigation2)
{
    // given a form-protected doc with 2 unchecked legacy fieldmark checkboxes, 1 modern
    // checkbox, and a couple of other content controls that are not supposed to
    // have their contents selected upon entry into the control (i.e. no placeholder text).
    createSwDoc("tdf151548_tabNavigation2.docx");
    SwDoc* pDoc = getSwDoc();

    IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMarkAccess->getFieldmarksCount());

    // verify that the checkboxes start off in the unchecked state
    for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it)
    {
        sw::mark::CheckboxFieldmark* pCheckBox = dynamic_cast<::sw::mark::CheckboxFieldmark*>(*it);
        CPPUNIT_ASSERT(!pCheckBox->IsChecked());
    }

    // Toggle on the legacy checkbox
    SwXTextDocument* pTextDoc = getSwTextDoc();
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 32, KEY_SPACE);
    // Tab to the next control - the modern checkbox
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
    // Tab to the next control - the second legacy checkbox, and toggle it on.
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 32, KEY_SPACE);
    // Tab to the next control - a plain text control without placeholder text
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
    // Tab to the next control - a combobox with custom text
    pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
    Scheduler::ProcessEventsToIdle();

    for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it)
    {
        sw::mark::CheckboxFieldmark* pCheckBox = dynamic_cast<::sw::mark::CheckboxFieldmark*>(*it);
        // verify that the legacy checkbox became checked by the first loop.
        CPPUNIT_ASSERT(pCheckBox->IsChecked());

        // This is where it was failing. Tab got stuck moving into the plain text/combobox,
        // so it could never loop around. At this point we are at the end of the loop,
        // so the next tab should take us back to the beginning with the first legacy checkbox.

        // Tab to the legacy checkbox, and toggle it off.
        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 32, KEY_SPACE);
        Scheduler::ProcessEventsToIdle();
        CPPUNIT_ASSERT(!pCheckBox->IsChecked());

        // Tab to the next content control
        pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB);
    }
}

--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=92 H=93 G=92

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.23Bemerkung:  (vorverarbeitet)  ¤

*Bot Zugriff






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.