tdf#152872 sw: conditionally hide paragraph breaks

Add a 3rd kind of hiding to SwRootFrame and CheckParaRedlineMerge().

This is quite simple as only consecutive paragraphs are merged.

There is an existing similar feature described in
http://www.openoffice.org/specs/writer/hidden_text/hidden_text.sxw
which results in 0-height text frames if all text is hidden
- but that is unconditional, while Word shows the paragraph when
control chars are shown, and hides it otherwise *iff* its paragraph
marker is hidden (and there's no page break on it).

Change-Id: I8290962ea58278e17b8f84bf6b2ca4bb2325aa8f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145162
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 8412f1a..dd2973f 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -142,6 +142,7 @@ namespace sw::mark { class MarkManager; }
namespace sw {
    enum class RedlineMode;
    enum class FieldmarkMode;
    enum class ParagraphBreakMode;
    class MetaFieldManager;
    class UndoManager;
    class IShellCursorSupplier;
@@ -1339,7 +1340,7 @@ public:

    // insert section (the ODF kind of section, not the nodesarray kind)
    SwSection * InsertSwSection(SwPaM const& rRange, SwSectionData &,
            std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode> const* pTOXBase,
            std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode, sw::ParagraphBreakMode> const* pTOXBase,
            SfxItemSet const*const pAttr, bool const bUpdate = true);
    static sal_uInt16 IsInsRegionAvailable( const SwPaM& rRange,
                                const SwNode** ppSttNd = nullptr );
diff --git a/sw/qa/extras/layout/data/hidden-para-separator.docx b/sw/qa/extras/layout/data/hidden-para-separator.docx
new file mode 100644
index 0000000..1d5d260
--- /dev/null
+++ b/sw/qa/extras/layout/data/hidden-para-separator.docx
Binary files differ
diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx
index b8ba46b..c5b4bbe 100644
--- a/sw/qa/extras/layout/layout2.cxx
+++ b/sw/qa/extras/layout/layout2.cxx
@@ -636,6 +636,43 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf149711_importDOCXMoveToParagraphMar
    assertXPath(pXmlDoc, "/root/page[1]/body/txt", 5);
}

CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
{
    createSwDoc("hidden-para-separator.docx");
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();

    assertXPath(pXmlDoc, "/root/page[1]/body/txt", 2);
    assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout", "portion", "C DE");
    assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion", 0); // 5 is empty
    assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds", "height", "379");

    dispatchCommand(mxComponent, ".uno:ControlCodes", {});

    discardDumpedLayout();
    pXmlDoc = parseLayoutDump();

    assertXPath(pXmlDoc, "/root/page[1]/body/txt", 5);
    assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout", "portion", "C ");
    assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout", "portion", "D");
    // 3 is an empty paragraph with RES_CHRATR_HIDDEN which results in 0-height
    // frame; ideally it should only be hidden when control codes are hidden
    // and be a full-height frame now, but that needs more work...
    assertXPath(pXmlDoc, "/root/page/body/txt[3]/infos/bounds", "height", "0");
    assertXPath(pXmlDoc, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout", "portion", "E");
    assertXPath(pXmlDoc, "/root/page/body/txt[5]/SwParaPortion", 0); // 5 is empty
    assertXPath(pXmlDoc, "/root/page/body/txt[5]/infos/bounds", "height", "379");

    dispatchCommand(mxComponent, ".uno:ControlCodes", {});

    discardDumpedLayout();
    pXmlDoc = parseLayoutDump();

    assertXPath(pXmlDoc, "/root/page[1]/body/txt", 2);
    assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout", "portion", "C DE");
    assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion", 0); // 5 is empty
    assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds", "height", "379");
}

CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf151954)
{
    createSwDoc("tdf151954.docx");
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index 5578a50..5f54e53 100644
--- a/sw/source/core/doc/doctxm.cxx
+++ b/sw/source/core/doc/doctxm.cxx
@@ -363,12 +363,13 @@ SwTOXBaseSection* SwDoc::InsertTableOf( const SwPaM& aPam,
    OUString sSectNm = GetUniqueTOXBaseName( *rTOX.GetTOXType(), rTOX.GetTOXName() );
    SwSectionData aSectionData( SectionType::ToxContent, sSectNm );

    std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode> const tmp(
    std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode, sw::ParagraphBreakMode> const tmp(
        &rTOX,
        pLayout && pLayout->IsHideRedlines()
            ? sw::RedlineMode::Hidden
            : sw::RedlineMode::Shown,
        pLayout ? pLayout->GetFieldmarkMode() : sw::FieldmarkMode::ShowBoth);
        pLayout ? pLayout->GetFieldmarkMode() : sw::FieldmarkMode::ShowBoth,
        pLayout ? pLayout->GetParagraphBreakMode() : sw::ParagraphBreakMode::Shown);
    SwTOXBaseSection *const pNewSection = dynamic_cast<SwTOXBaseSection *>(
        InsertSwSection(aPam, aSectionData, & tmp, pSet, false));
    if (pNewSection)
diff --git a/sw/source/core/docnode/ndsect.cxx b/sw/source/core/docnode/ndsect.cxx
index 8a53f83..f4fe9b9 100644
--- a/sw/source/core/docnode/ndsect.cxx
+++ b/sw/source/core/docnode/ndsect.cxx
@@ -152,7 +152,7 @@ static void lcl_CheckEmptyLayFrame( SwNodes const & rNds, SwSectionData& rSectio

SwSection *
SwDoc::InsertSwSection(SwPaM const& rRange, SwSectionData & rNewData,
       std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode> const*const pTOXBaseAndMode,
       std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode, sw::ParagraphBreakMode> const*const pTOXBaseAndMode,
                       SfxItemSet const*const pAttr, bool const bUpdate)
{
    const SwNode* pPrvNd = nullptr;
diff --git a/sw/source/core/inc/UndoSection.hxx b/sw/source/core/inc/UndoSection.hxx
index 85b15a8..5be018a 100644
--- a/sw/source/core/inc/UndoSection.hxx
+++ b/sw/source/core/inc/UndoSection.hxx
@@ -35,13 +35,14 @@ class SwTOXBase;
namespace sw {
    enum class RedlineMode;
    enum class FieldmarkMode;
    enum class ParagraphBreakMode;
};

class SwUndoInsSection final : public SwUndo, private SwUndRng
{
private:
    const std::unique_ptr<SwSectionData> m_pSectionData;
    std::optional<std::tuple<std::unique_ptr<SwTOXBase>, sw::RedlineMode, sw::FieldmarkMode>> m_xTOXBase; /// set iff section is TOX
    std::optional<std::tuple<std::unique_ptr<SwTOXBase>, sw::RedlineMode, sw::FieldmarkMode, sw::ParagraphBreakMode>> m_xTOXBase; /// set iff section is TOX
    const std::unique_ptr<SfxItemSet> m_pAttrSet;
    std::unique_ptr<SwHistory> m_pHistory;
    std::unique_ptr<SwRedlineData> m_pRedlData;
@@ -56,7 +57,7 @@ private:
public:
    SwUndoInsSection(SwPaM const&, SwSectionData const&,
        SfxItemSet const* pSet,
        std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode> const* pTOXBase);
        std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode, sw::ParagraphBreakMode> const* pTOXBase);

    virtual ~SwUndoInsSection() override;

diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx
index 3d00fe1..32344bf0 100644
--- a/sw/source/core/inc/rootfrm.hxx
+++ b/sw/source/core/inc/rootfrm.hxx
@@ -47,6 +47,7 @@ namespace sw {
    };

    enum class FieldmarkMode { ShowCommand = 1, ShowResult = 2, ShowBoth = 3 };
    enum class ParagraphBreakMode { Shown, Hidden };
};

enum class SwInvalidateFlags
@@ -121,6 +122,7 @@ class SW_DLLPUBLIC SwRootFrame final : public SwLayoutFrame
    bool    mbLayoutFreezed;
    bool    mbHideRedlines;
    sw::FieldmarkMode m_FieldmarkMode;
    sw::ParagraphBreakMode m_ParagraphBreakMode;

    /**
     * For BrowseMode
@@ -421,10 +423,9 @@ public:
    bool IsHideRedlines() const { return mbHideRedlines; }
    void SetHideRedlines(bool);
    sw::FieldmarkMode GetFieldmarkMode() const { return m_FieldmarkMode; }
    void SetFieldmarkMode(sw::FieldmarkMode);
    bool HasMergedParas() const {
        return IsHideRedlines() || GetFieldmarkMode() != sw::FieldmarkMode::ShowBoth;
    }
    void SetFieldmarkMode(sw::FieldmarkMode, sw::ParagraphBreakMode);
    sw::ParagraphBreakMode GetParagraphBreakMode() const { return m_ParagraphBreakMode; }
    bool HasMergedParas() const;
};

inline tools::Long SwRootFrame::GetBrowseWidth() const
diff --git a/sw/source/core/layout/newfrm.cxx b/sw/source/core/layout/newfrm.cxx
index c09c557..5ca11e3 100644
--- a/sw/source/core/layout/newfrm.cxx
+++ b/sw/source/core/layout/newfrm.cxx
@@ -418,6 +418,9 @@ SwRootFrame::SwRootFrame( SwFrameFormat *pFormat, SwViewShell * pSh ) :
    m_FieldmarkMode(pSh->GetViewOptions()->IsFieldName()
            ? sw::FieldmarkMode::ShowCommand
            : sw::FieldmarkMode::ShowResult),
    m_ParagraphBreakMode(pSh->GetViewOptions()->IsParagraph()
            ? sw::ParagraphBreakMode::Shown
            : sw::ParagraphBreakMode::Hidden),
    mnBrowseWidth(MIN_BROWSE_WIDTH),
    mpTurbo( nullptr ),
    mpLastPage( nullptr ),
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 2d59a1c..f753a99 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4706,23 +4706,26 @@ void SwRootFrame::SetHideRedlines(bool const bHideRedlines)
    }
    // TODO: remove temporary ShowBoth
    sw::FieldmarkMode const eMode(m_FieldmarkMode);
    sw::ParagraphBreakMode const ePBMode(m_ParagraphBreakMode);
    if (HasMergedParas())
    {
        m_FieldmarkMode = sw::FieldmarkMode::ShowBoth;
        m_ParagraphBreakMode = sw::ParagraphBreakMode::Shown;
        mbHideRedlines = false;
        UnHide(*this);
    }
    if (bHideRedlines || eMode != m_FieldmarkMode)
    if (bHideRedlines || eMode != m_FieldmarkMode || ePBMode != m_ParagraphBreakMode)
    {
        m_FieldmarkMode = eMode;
        m_ParagraphBreakMode = ePBMode;
        mbHideRedlines = bHideRedlines;
        UnHide(*this);
    }
}

void SwRootFrame::SetFieldmarkMode(sw::FieldmarkMode const eMode)
void SwRootFrame::SetFieldmarkMode(sw::FieldmarkMode const eFMMode, sw::ParagraphBreakMode const ePBMode)
{
    if (eMode == m_FieldmarkMode)
    if (eFMMode == m_FieldmarkMode && ePBMode == m_ParagraphBreakMode)
    {
        return;
    }
@@ -4732,14 +4735,23 @@ void SwRootFrame::SetFieldmarkMode(sw::FieldmarkMode const eMode)
    {
        mbHideRedlines = false;
        m_FieldmarkMode = sw::FieldmarkMode::ShowBoth;
        m_ParagraphBreakMode = sw::ParagraphBreakMode::Shown;
        UnHide(*this);
    }
    if (eMode != sw::FieldmarkMode::ShowBoth || isHideRedlines)
    if (isHideRedlines || eFMMode != sw::FieldmarkMode::ShowBoth || ePBMode == sw::ParagraphBreakMode::Hidden)
    {
        mbHideRedlines = isHideRedlines;
        m_FieldmarkMode = eMode;
        m_FieldmarkMode = eFMMode;
        m_ParagraphBreakMode = ePBMode;
        UnHide(*this);
    }
}

bool SwRootFrame::HasMergedParas() const
{
    return IsHideRedlines()
        || GetFieldmarkMode() != sw::FieldmarkMode::ShowBoth
        || GetParagraphBreakMode() == sw::ParagraphBreakMode::Hidden;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index 2b77d86..acf8355 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -47,8 +47,11 @@
#include <vcl/svapp.hxx>
#include "redlnitr.hxx"
#include <extinput.hxx>
#include <fmtpdsc.hxx>
#include <editeng/charhiddenitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/crossedoutitem.hxx>
#include <editeng/formatbreakitem.hxx>
#include <editeng/udlnitem.hxx>

using namespace ::com::sun::star;
@@ -62,12 +65,15 @@ private:
    IDocumentMarkAccess const& m_rIDMA;
    bool const m_isHideRedlines;
    sw::FieldmarkMode const m_eFieldmarkMode;
    bool const m_isHideParagraphBreaks;
    SwPosition const m_Start;
    /// next redline
    SwRedlineTable::size_type m_RedlineIndex;
    /// next fieldmark
    std::pair<sw::mark::IFieldmark const*, std::optional<SwPosition>> m_Fieldmark;
    std::optional<SwPosition> m_oNextFieldmarkHide;
    /// previous paragraph break - because m_pStartPos/EndPos are non-owning
    std::optional<std::pair<SwPosition, SwPosition>> m_oParagraphBreak;
    /// current start/end pair
    SwPosition const* m_pStartPos;
    SwPosition const* m_pEndPos;
@@ -77,11 +83,13 @@ public:
    SwPosition const* GetEndPos() const { return m_pEndPos; }

    HideIterator(SwTextNode & rTextNode,
            bool const isHideRedlines, sw::FieldmarkMode const eMode)
            bool const isHideRedlines, sw::FieldmarkMode const eMode,
            sw::ParagraphBreakMode const ePBMode)
        : m_rIDRA(rTextNode.getIDocumentRedlineAccess())
        , m_rIDMA(*rTextNode.getIDocumentMarkAccess())
        , m_isHideRedlines(isHideRedlines)
        , m_eFieldmarkMode(eMode)
        , m_isHideParagraphBreaks(ePBMode == sw::ParagraphBreakMode::Hidden)
        , m_Start(rTextNode, 0)
        , m_RedlineIndex(isHideRedlines ? m_rIDRA.GetRedlinePos(rTextNode, RedlineType::Any) : SwRedlineTable::npos)
        , m_pStartPos(nullptr)
@@ -188,12 +196,65 @@ public:
            m_pEndPos = &*m_Fieldmark.second;
            return true;
        }
        else // nothing
        else
        {
            assert(!pNextRedlineHide && !m_oNextFieldmarkHide);
            m_pStartPos = nullptr;
            m_pEndPos = nullptr;
            return false;
            auto const hasHiddenItem = [](auto const& rNode) {
                auto const& rpSet(rNode.GetAttr(RES_PARATR_LIST_AUTOFMT).GetStyleHandle());
                return rpSet ? rpSet->Get(RES_CHRATR_HIDDEN).GetValue() : false;
            };
            auto const hasBreakBefore = [](SwTextNode const& rNode) {
                if (rNode.GetAttr(RES_PAGEDESC).GetPageDesc())
                {
                    return true;
                }
                switch (rNode.GetAttr(RES_BREAK).GetBreak())
                {
                    case SvxBreak::ColumnBefore:
                    case SvxBreak::ColumnBoth:
                    case SvxBreak::PageBefore:
                    case SvxBreak::PageBoth:
                        return true;
                    default:
                        break;
                }
                return false;
            };
            auto const hasBreakAfter = [](SwTextNode const& rNode) {
                switch (rNode.GetAttr(RES_BREAK).GetBreak())
                {
                    case SvxBreak::ColumnAfter:
                    case SvxBreak::ColumnBoth:
                    case SvxBreak::PageAfter:
                    case SvxBreak::PageBoth:
                        return true;
                    default:
                        break;
                }
                return false;
            };
            if (m_isHideParagraphBreaks
                // only merge if next node is also text node
                && m_pEndPos->GetNodes()[m_pEndPos->GetNodeIndex()+1]->IsTextNode()
                && hasHiddenItem(*m_pEndPos->GetNode().GetTextNode())
                // no merge if there's a page break on any node
                && !hasBreakBefore(*m_pEndPos->GetNodes()[m_pEndPos->GetNodeIndex()+1]->GetTextNode())
                // first node, see SwTextFrame::GetBreak()
                && !hasBreakAfter(*m_Start.GetNode().GetTextNode()))
            {
                m_oParagraphBreak.emplace(
                    SwPosition(*m_pEndPos->GetNode().GetTextNode(), m_pEndPos->GetNode().GetTextNode()->Len()),
                    SwPosition(*m_pEndPos->GetNodes()[m_pEndPos->GetNodeIndex()+1]->GetTextNode(), 0));
                m_pStartPos = &m_oParagraphBreak->first;
                m_pEndPos = &m_oParagraphBreak->second;
                return true;
            }
            else // nothing
            {
                m_pStartPos = nullptr;
                m_pEndPos = nullptr;
                return false;
            }
        }
    }
};
@@ -221,7 +282,9 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode,
    sal_Int32 nLastEnd(0);
    for (auto iter = HideIterator(rTextNode,
                rFrame.getRootFrame()->IsHideRedlines(),
                rFrame.getRootFrame()->GetFieldmarkMode()); iter.Next(); )
                rFrame.getRootFrame()->GetFieldmarkMode(),
                rFrame.getRootFrame()->GetParagraphBreakMode());
            iter.Next(); )
    {
        SwPosition const*const pStart(iter.GetStartPos());
        SwPosition const*const pEnd(iter.GetEndPos());
diff --git a/sw/source/core/undo/unsect.cxx b/sw/source/core/undo/unsect.cxx
index b812821..4e75aa9 100644
--- a/sw/source/core/undo/unsect.cxx
+++ b/sw/source/core/undo/unsect.cxx
@@ -77,7 +77,7 @@ static std::optional<SfxItemSet> lcl_GetAttrSet( const SwSection& rSect )
SwUndoInsSection::SwUndoInsSection(
        SwPaM const& rPam, SwSectionData const& rNewData,
        SfxItemSet const*const pSet,
        std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode> const*const pTOXBase)
        std::tuple<SwTOXBase const*, sw::RedlineMode, sw::FieldmarkMode, sw::ParagraphBreakMode> const*const pTOXBase)
    : SwUndo( SwUndoId::INSSECTION, &rPam.GetDoc() ), SwUndRng( rPam )
    , m_pSectionData(new SwSectionData(rNewData))
    , m_pAttrSet( (pSet && pSet->Count()) ? new SfxItemSet( *pSet ) : nullptr )
@@ -90,7 +90,8 @@ SwUndoInsSection::SwUndoInsSection(
        m_xTOXBase.emplace(
            std::make_unique<SwTOXBase>(*std::get<0>(*pTOXBase)),
            std::get<1>(*pTOXBase),
            std::get<2>(*pTOXBase));
            std::get<2>(*pTOXBase),
            std::get<3>(*pTOXBase));

    SwDoc& rDoc = rPam.GetDoc();
    if( rDoc.getIDocumentRedlineAccess().IsRedlineOn() )
@@ -187,18 +188,20 @@ void SwUndoInsSection::RedoImpl(::sw::UndoRedoContext & rContext)
        SwRootFrame const* pLayout(nullptr);
        SwRootFrame * pLayoutToReset(nullptr);
        sw::FieldmarkMode eFieldmarkMode{};
        sw::ParagraphBreakMode eParagraphBreakMode{};
        comphelper::ScopeGuard g([&]() {
                if (pLayoutToReset)
                {
                    pLayoutToReset->SetHideRedlines(std::get<1>(*m_xTOXBase) == sw::RedlineMode::Shown);
                    pLayoutToReset->SetFieldmarkMode(eFieldmarkMode);
                    pLayoutToReset->SetFieldmarkMode(eFieldmarkMode, eParagraphBreakMode);
                }
            });
        o3tl::sorted_vector<SwRootFrame *> layouts(rDoc.GetAllLayouts());
        for (SwRootFrame const*const p : layouts)
        {
            if ((std::get<1>(*m_xTOXBase) == sw::RedlineMode::Hidden) == p->IsHideRedlines()
                && std::get<2>(*m_xTOXBase) == p->GetFieldmarkMode())
                && std::get<2>(*m_xTOXBase) == p->GetFieldmarkMode()
                && std::get<3>(*m_xTOXBase) == p->GetParagraphBreakMode())
            {
                pLayout = p;
                break;
@@ -209,8 +212,9 @@ void SwUndoInsSection::RedoImpl(::sw::UndoRedoContext & rContext)
            assert(!layouts.empty()); // must have one layout
            pLayoutToReset = *layouts.begin();
            eFieldmarkMode = pLayoutToReset->GetFieldmarkMode();
            eParagraphBreakMode = pLayoutToReset->GetParagraphBreakMode();
            pLayoutToReset->SetHideRedlines(std::get<1>(*m_xTOXBase) == sw::RedlineMode::Hidden);
            pLayoutToReset->SetFieldmarkMode(std::get<2>(*m_xTOXBase));
            pLayoutToReset->SetFieldmarkMode(std::get<2>(*m_xTOXBase), std::get<3>(*m_xTOXBase));
            pLayout = pLayoutToReset;
        }
        pUpdateTOX = rDoc.InsertTableOf( *rPam.GetPoint(),
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 402f4f2..a1ea83c 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -2322,11 +2322,15 @@ void SwViewShell::ImplApplyViewOptions( const SwViewOption &rOpt )
    // - Of course, the screen is something completely different than the printer ...
    bool const isToggleFieldNames(mpOpt->IsFieldName() != rOpt.IsFieldName());

    if (mpOpt->IsFieldName() != rOpt.IsFieldName())
    if (mpOpt->IsFieldName() != rOpt.IsFieldName()
        || mpOpt->IsParagraph() != rOpt.IsParagraph())
    {
        GetLayout()->SetFieldmarkMode( rOpt.IsFieldName()
                    ? sw::FieldmarkMode::ShowCommand
                    : sw::FieldmarkMode::ShowResult );
                    : sw::FieldmarkMode::ShowResult,
                rOpt.IsParagraph()
                    ? sw::ParagraphBreakMode::Shown
                    : sw::ParagraphBreakMode::Hidden);
        bReformat = true;
    }