[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide_3' - 4 commits - sw/inc sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Nov 14 13:07:07 UTC 2018


Rebased ref, commits from common ancestor:
commit ca6eba2bda7513027ee599e2a938f4185b3f6ce3
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Nov 9 16:04:17 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Nov 14 14:00:20 2018 +0100

    sw_redlinehide_3: update fields on redline ops
    
    Can't tell which chapter/reference fields will be affected by a redline,
    so we have to either update all of them, or rely on the
    IDocumentSettingAccess::getFieldUpdateFlags() which lets the SwIdle
    update the fields, at some later time...
    
    Change-Id: I3b9cfd17bd227a18f64dac193f0cc912768810c1

diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 0d4448a79079..a5b60561abdf 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -22,6 +22,7 @@
 #include <txtfrm.hxx>
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
+#include <IDocumentFieldsAccess.hxx>
 #include <IDocumentState.hxx>
 #include <redline.hxx>
 #include <UndoRedline.hxx>
@@ -29,6 +30,7 @@
 #include <ndtxt.hxx>
 #include <unocrsr.hxx>
 #include <ftnidx.hxx>
+#include <authfld.hxx>
 #include <strings.hrc>
 #include <swmodule.hxx>
 #include <editsh.hxx>
@@ -119,6 +121,20 @@ using namespace com::sun::star;
 
 namespace sw {
 
+static void UpdateFieldsForRedline(IDocumentFieldsAccess & rIDFA)
+{
+    auto const pAuthType(static_cast<SwAuthorityFieldType*>(rIDFA.GetFieldType(
+        SwFieldIds::TableOfAuthorities, OUString(), false)));
+    if (pAuthType) // created on demand...
+    {
+        pAuthType->DelSequenceArray();
+    }
+    rIDFA.GetFieldType(SwFieldIds::RefPageGet, OUString(), false)->UpdateFields();
+    rIDFA.GetSysFieldType(SwFieldIds::Chapter)->UpdateFields();
+    rIDFA.UpdateExpFields(nullptr, false);
+    rIDFA.UpdateRefFields();
+}
+
 void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
 {
     // no need to call UpdateFootnoteNums for FTNNUM_PAGE:
@@ -148,6 +164,8 @@ void UpdateFramesForAddDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
         // node of the merged frame, there could be another redline nearby
         sw::AddRemoveFlysAnchoredToFrameStartingAtNode(*pFrame, *pStartNode, nullptr);
     }
+    // fields last - SwGetRefField::UpdateField requires up-to-date frames
+    UpdateFieldsForRedline(rDoc.getIDocumentFieldsAccess()); // after footnotes
 }
 
 void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
@@ -205,6 +223,8 @@ void UpdateFramesForRemoveDeleteRedline(SwDoc & rDoc, SwPaM const& rPam)
             AppendAllObjs(rDoc.GetSpzFrameFormats(), pLayout);
         }
     }
+    // fields last - SwGetRefField::UpdateField requires up-to-date frames
+    UpdateFieldsForRedline(rDoc.getIDocumentFieldsAccess()); // after footnotes
 }
 
 } // namespace sw
commit 7a30f56b66b6921e90e2614a9f27299ea66dea23
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Nov 9 12:50:04 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Nov 14 14:00:20 2018 +0100

    sw_redlinehide_3: update fields in UnHideRedlines
    
    Repainting is not enough, values require up-to-date outline visibility
    etc.
    
    Change-Id: I85d99fc65a071279c2d4656a52ff82ed3b2db7d8

diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index eb8a0fa12368..914df003d2b1 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4504,6 +4504,19 @@ void SwRootFrame::SetHideRedlines(bool const bHideRedlines)
             pFootnote->InvalidateNumberInLayout();
         }
     }
+    // update various fields to re-expand them with the new layout
+    IDocumentFieldsAccess & rIDFA(rDoc.getIDocumentFieldsAccess());
+    auto const pAuthType(rIDFA.GetFieldType(
+        SwFieldIds::TableOfAuthorities, OUString(), false));
+    if (pAuthType) // created on demand...
+    {   // calling DelSequenceArray() should be unnecessary here since the
+        // sequence doesn't depend on frames
+        pAuthType->UpdateFields();
+    }
+    rIDFA.GetFieldType(SwFieldIds::RefPageGet, OUString(), false)->UpdateFields();
+    rIDFA.GetSysFieldType(SwFieldIds::Chapter)->UpdateFields();
+    rIDFA.UpdateExpFields(nullptr, false);
+    rIDFA.UpdateRefFields();
 
 //    InvalidateAllContent(SwInvalidateFlags::Size); // ??? TODO what to invalidate?  this is the big hammer
 }
commit d895cf0fb968fd7ed9554e498772cd384bb77e3e
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Nov 14 12:41:23 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Nov 14 14:00:20 2018 +0100

    sw_redlinehide_3: add second result to SwRefPageGetField
    
    With the old Hide implementation this actually would take the last
    set-field in the redline nodes array section to set the value at the
    start of the document, because there was no check for that; surely that
    was wrong...
    
    Change-Id: I63fb89ccf0067f1fe375226d6d04cafb6485c5d6

diff --git a/sw/inc/docufld.hxx b/sw/inc/docufld.hxx
index 03f2a1deebb9..f9ba0d6344b0 100644
--- a/sw/inc/docufld.hxx
+++ b/sw/inc/docufld.hxx
@@ -600,14 +600,16 @@ class SwRefPageGetFieldType : public SwFieldType
     SwDoc*          m_pDoc;
     sal_Int16       m_nNumberingType;
 
-    void UpdateField( SwTextField const * pTextField, SetGetExpFields const & rSetList );
+    void UpdateField(SwTextField const * pTextField,
+            SetGetExpFields const & rSetList, SwRootFrame const* pLayout);
+
 protected:
     /// overwritten to update all RefPageGet fields
     virtual void Modify( const SfxPoolItem*, const SfxPoolItem * ) override;
 public:
     SwRefPageGetFieldType( SwDoc* pDoc );
     virtual SwFieldType*    Copy() const override;
-    bool MakeSetList( SetGetExpFields& rTmpLst );
+    bool MakeSetList(SetGetExpFields& rTmpLst, SwRootFrame const* pLayout);
     SwDoc*  GetDoc() const                  { return m_pDoc; }
 };
 
@@ -615,15 +617,17 @@ public:
 class SwRefPageGetField : public SwField
 {
     OUString m_sText;
+    OUString m_sTextRLHidden; ///< hidden redlines
+
 public:
     SwRefPageGetField( SwRefPageGetFieldType*, sal_uInt32 nFormat );
 
     virtual OUString    ExpandImpl(SwRootFrame const* pLayout) const override;
     virtual std::unique_ptr<SwField> Copy() const override;
 
-    void SetText( const OUString& rText )      { m_sText = rText; }
+    void SetText(const OUString& rText, SwRootFrame const* pLayout);
 
-    void ChangeExpansion( const SwFrame* pFrame, const SwTextField* pField );
+    void ChangeExpansion(const SwFrame& rFrame, const SwTextField* pField);
     virtual bool        QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich ) const override;
     virtual bool        PutValue( const css::uno::Any& rVal, sal_uInt16 nWhich ) override;
 };
diff --git a/sw/source/core/fields/docufld.cxx b/sw/source/core/fields/docufld.cxx
index 2f997bed40fe..859c5d4ddc02 100644
--- a/sw/source/core/fields/docufld.cxx
+++ b/sw/source/core/fields/docufld.cxx
@@ -2157,18 +2157,42 @@ SwFieldType* SwRefPageGetFieldType::Copy() const
 
 void SwRefPageGetFieldType::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
 {
-    // update all GetReference fields
-    if( !pNew && !pOld && HasWriterListeners() )
+    auto const ModifyImpl = [this](SwRootFrame const*const pLayout)
     {
         // first collect all SetPageRefFields
         SetGetExpFields aTmpLst;
-        if( MakeSetList( aTmpLst ) )
+        if (MakeSetList(aTmpLst, pLayout))
         {
             SwIterator<SwFormatField,SwFieldType> aIter( *this );
             for ( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
+            {
                     // update only the GetRef fields
                     if( pFormatField->GetTextField() )
-                        UpdateField( pFormatField->GetTextField(), aTmpLst );
+                        UpdateField(pFormatField->GetTextField(), aTmpLst, pLayout);
+            }
+        }
+    };
+
+    // update all GetReference fields
+    if( !pNew && !pOld && HasWriterListeners() )
+    {
+        SwRootFrame const* pLayout(nullptr);
+        SwRootFrame const* pLayoutRLHidden(nullptr);
+        for (SwRootFrame const*const pLay : m_pDoc->GetAllLayouts())
+        {
+            if (pLay->IsHideRedlines())
+            {
+                pLayoutRLHidden = pLay;
+            }
+            else
+            {
+                pLayout = pLay;
+            }
+        }
+        ModifyImpl(pLayout);
+        if (pLayoutRLHidden)
+        {
+            ModifyImpl(pLayoutRLHidden);
         }
     }
 
@@ -2176,14 +2200,19 @@ void SwRefPageGetFieldType::Modify( const SfxPoolItem* pOld, const SfxPoolItem*
     NotifyClients( pOld, pNew );
 }
 
-bool SwRefPageGetFieldType::MakeSetList( SetGetExpFields& rTmpLst )
+bool SwRefPageGetFieldType::MakeSetList(SetGetExpFields& rTmpLst,
+        SwRootFrame const*const pLayout)
 {
+    IDocumentRedlineAccess const& rIDRA(m_pDoc->getIDocumentRedlineAccess());
     SwIterator<SwFormatField,SwFieldType> aIter(*m_pDoc->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::RefPageSet));
     for ( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
     {
-            // update only the GetRef fields
-            const SwTextField* pTField = pFormatField->GetTextField();
-            if( pTField )
+        // update only the GetRef fields
+        const SwTextField* pTField = pFormatField->GetTextField();
+        if( pTField )
+        {
+            if (!pLayout || !pLayout->IsHideRedlines()
+                || !sw::IsFieldDeletedInModel(rIDRA, *pTField))
             {
                 const SwTextNode& rTextNd = pTField->GetTextNode();
 
@@ -2191,8 +2220,7 @@ bool SwRefPageGetFieldType::MakeSetList( SetGetExpFields& rTmpLst )
                 Point aPt;
                 std::pair<Point, bool> const tmp(aPt, false);
                 const SwContentFrame *const pFrame = rTextNd.getLayoutFrame(
-                    rTextNd.GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(),
-                    nullptr, &tmp);
+                    pLayout, nullptr, &tmp);
 
                 std::unique_ptr<SetGetExpField> pNew;
 
@@ -2218,16 +2246,18 @@ bool SwRefPageGetFieldType::MakeSetList( SetGetExpFields& rTmpLst )
 
                 rTmpLst.insert( std::move(pNew) );
             }
+        }
     }
 
     return !rTmpLst.empty();
 }
 
 void SwRefPageGetFieldType::UpdateField( SwTextField const * pTextField,
-                                        SetGetExpFields const & rSetList )
+                                        SetGetExpFields const & rSetList,
+                                        SwRootFrame const*const pLayout)
 {
     SwRefPageGetField* pGetField = const_cast<SwRefPageGetField*>(static_cast<const SwRefPageGetField*>(pTextField->GetFormatField().GetField()));
-    pGetField->SetText( OUString() );
+    pGetField->SetText( OUString(), pLayout );
 
     // then search the correct RefPageSet field
     SwTextNode* pTextNode = &pTextField->GetTextNode();
@@ -2251,10 +2281,9 @@ void SwRefPageGetFieldType::UpdateField( SwTextField const * pTextField,
                 Point aPt;
                 std::pair<Point, bool> const tmp(aPt, false);
                 const SwContentFrame *const pFrame = pTextNode->getLayoutFrame(
-                    pTextNode->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp);
+                    pLayout, nullptr, &tmp);
                 const SwContentFrame *const pRefFrame = pRefTextField->GetTextNode().getLayoutFrame(
-                    pRefTextField->GetTextNode().GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(),
-                    nullptr, &tmp);
+                    pLayout, nullptr, &tmp);
                 const SwPageFrame* pPgFrame = nullptr;
                 const short nDiff = ( pFrame && pRefFrame )
                         ?   (pPgFrame = pFrame->FindPageFrame())->GetPhyPageNum() -
@@ -2267,7 +2296,7 @@ void SwRefPageGetFieldType::UpdateField( SwTextField const * pTextField,
                                 : pPgFrame->GetPageDesc()->GetNumType().GetNumberingType() )
                         : static_cast<SvxNumType>(pGetField->GetFormat());
                 const short nPageNum = std::max<short>(0, pSetField->GetOffset() + nDiff);
-                pGetField->SetText( FormatNumber( nPageNum, nTmpFormat ) );
+                pGetField->SetText(FormatNumber(nPageNum, nTmpFormat), pLayout);
             }
         }
     }
@@ -2283,20 +2312,34 @@ SwRefPageGetField::SwRefPageGetField( SwRefPageGetFieldType* pTyp,
 {
 }
 
-OUString SwRefPageGetField::ExpandImpl(SwRootFrame const*const) const
+void SwRefPageGetField::SetText(const OUString& rText,
+        SwRootFrame const*const pLayout)
 {
-    return m_sText;
+    if (!pLayout || !pLayout->IsHideRedlines())
+    {
+        m_sText = rText;
+    }
+    if (!pLayout || pLayout->IsHideRedlines())
+    {
+        m_sTextRLHidden = rText;
+    }
+}
+
+OUString SwRefPageGetField::ExpandImpl(SwRootFrame const*const pLayout) const
+{
+    return pLayout && pLayout->IsHideRedlines() ? m_sTextRLHidden : m_sText;
 }
 
 std::unique_ptr<SwField> SwRefPageGetField::Copy() const
 {
     std::unique_ptr<SwRefPageGetField> pCpy(new SwRefPageGetField(
                         static_cast<SwRefPageGetFieldType*>(GetTyp()), GetFormat() ));
-    pCpy->SetText( m_sText );
+    pCpy->m_sText = m_sText;
+    pCpy->m_sTextRLHidden = m_sTextRLHidden;
     return std::unique_ptr<SwField>(pCpy.release());
 }
 
-void SwRefPageGetField::ChangeExpansion( const SwFrame* pFrame,
+void SwRefPageGetField::ChangeExpansion(const SwFrame& rFrame,
                                         const SwTextField* pField )
 {
     // only fields in Footer, Header, FootNote, Flys
@@ -2306,18 +2349,20 @@ void SwRefPageGetField::ChangeExpansion( const SwFrame* pFrame,
         pDoc->GetNodes().GetEndOfExtras().GetIndex() )
         return;
 
-    m_sText.clear();
+    SwRootFrame const& rLayout(*rFrame.getRootFrame());
+    OUString & rText(rLayout.IsHideRedlines() ? m_sTextRLHidden : m_sText);
+    rText.clear();
 
-    OSL_ENSURE( !pFrame->IsInDocBody(), "Flag incorrect, frame is in DocBody" );
+    OSL_ENSURE(!rFrame.IsInDocBody(), "Flag incorrect, frame is in DocBody");
 
     // collect all SetPageRefFields
     SetGetExpFields aTmpLst;
-    if( !pGetType->MakeSetList( aTmpLst ) )
+    if (!pGetType->MakeSetList(aTmpLst, &rLayout))
         return ;
 
     //  create index for determination of the TextNode
     SwPosition aPos( SwNodeIndex( pDoc->GetNodes() ) );
-    SwTextNode* pTextNode = const_cast<SwTextNode*>(GetBodyTextNode( *pDoc, aPos, *pFrame ));
+    SwTextNode* pTextNode = const_cast<SwTextNode*>(GetBodyTextNode(*pDoc, aPos, rFrame));
 
     // If no layout exists, ChangeExpansion is called for header and
     // footer lines via layout formatting without existing TextNode.
@@ -2338,11 +2383,11 @@ void SwRefPageGetField::ChangeExpansion( const SwFrame* pFrame,
     Point aPt;
     std::pair<Point, bool> const tmp(aPt, false);
     const SwContentFrame *const pRefFrame = pRefTextField->GetTextNode().getLayoutFrame(
-            pFrame->getRootFrame(), nullptr, &tmp);
+            &rLayout, nullptr, &tmp);
     if( pSetField->IsOn() && pRefFrame )
     {
         // determine the correct offset
-        const SwPageFrame* pPgFrame = pFrame->FindPageFrame();
+        const SwPageFrame* pPgFrame = rFrame.FindPageFrame();
         const short nDiff = pPgFrame->GetPhyPageNum() -
                             pRefFrame->FindPageFrame()->GetPhyPageNum() + 1;
 
@@ -2351,7 +2396,7 @@ void SwRefPageGetField::ChangeExpansion( const SwFrame* pFrame,
                             ? pPgFrame->GetPageDesc()->GetNumType().GetNumberingType()
                             : static_cast<SvxNumType>(pGetField->GetFormat());
         const short nPageNum = std::max<short>(0, pSetField->GetOffset() + nDiff);
-        pGetField->SetText( FormatNumber( nPageNum, nTmpFormat ) );
+        pGetField->SetText(FormatNumber(nPageNum, nTmpFormat), &rLayout);
     }
 }
 
@@ -2385,6 +2430,7 @@ bool SwRefPageGetField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
         break;
         case FIELD_PROP_PAR1:
             rAny >>= m_sText;
+            m_sTextRLHidden = m_sText;
         break;
     default:
         assert(false);
diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx
index c4db3035c775..d0cad7b2569c 100644
--- a/sw/source/core/text/txtfld.cxx
+++ b/sw/source/core/text/txtfld.cxx
@@ -221,7 +221,7 @@ SwExpandPortion *SwTextFormatter::NewFieldPortion( SwTextFormatInfo &rInf,
         case SwFieldIds::RefPageGet:
             if( !bName && pSh && !pSh->Imp()->IsUpdateExpFields() )
             {
-                static_cast<SwRefPageGetField*>(pField)->ChangeExpansion(pFrame,
+                static_cast<SwRefPageGetField*>(pField)->ChangeExpansion(*pFrame,
                         static_txtattr_cast<SwTextField const*>(pHint));
             }
             {
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index 4fe387ba3b59..57a101b9f3eb 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -1594,7 +1594,7 @@ void SAL_CALL SwXTextField::attach(
                     static_cast<SwRefPageGetFieldType*>(pFieldType),
                     m_pImpl->m_pProps->nUSHORT1 );
             xField.reset(pRGField);
-            pRGField->SetText(m_pImpl->m_pProps->sPar1);
+            pRGField->SetText(m_pImpl->m_pProps->sPar1, nullptr);
         }
         break;
         case SwServiceType::FieldTypePageNum:
commit cd5ba33850841ae0362d8232ecc2ed779d95d32c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Nov 13 18:53:50 2018 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Nov 14 14:00:20 2018 +0100

    sw_redlinehide_3: add second result to SwAuthorityField
    
    ... and SwAuthorityFieldType, which needs 2 lists of the fields because
    each citation may occur multiple times, so their order might change on
    deletions.
    
    This is for when there is a bibliography in the document, and it is set
    to IsSequence(), i.e.,
    insert Bibliography -> Number entries -> Sort by document position...
    
    Change-Id: Iba2c31267aeebacb779713567eeb0aa6659afefb

diff --git a/sw/inc/IDocumentFieldsAccess.hxx b/sw/inc/IDocumentFieldsAccess.hxx
index 617ea990614c..00ceff6fcc2a 100644
--- a/sw/inc/IDocumentFieldsAccess.hxx
+++ b/sw/inc/IDocumentFieldsAccess.hxx
@@ -39,6 +39,7 @@ enum class SwFieldIds : sal_uInt16;
 template <class T> class SwHashTable;
 struct HashStr;
 class SwRootFrame;
+class IDocumentRedlineAccess;
 
 namespace rtl { class OUString; }
 using rtl::OUString;
@@ -139,6 +140,11 @@ protected:
     virtual ~IDocumentFieldsAccess() {};
  };
 
+namespace sw {
+bool IsFieldDeletedInModel(IDocumentRedlineAccess const& rIDRA,
+        SwTextField const& rTextField);
+}
+
 #endif // INCLUDED_SW_INC_IDOCUMENTFIELDSACCESS_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/authfld.hxx b/sw/inc/authfld.hxx
index c6bab5ccf91c..72837f765c65 100644
--- a/sw/inc/authfld.hxx
+++ b/sw/inc/authfld.hxx
@@ -62,6 +62,7 @@ class SW_DLLPUBLIC SwAuthorityFieldType : public SwFieldType
     SwDoc*                  m_pDoc;
     SwAuthDataArr           m_DataArr;
     std::vector<sal_IntPtr> m_SequArr;
+    std::vector<sal_IntPtr> m_SequArrRLHidden; ///< hidden redlines
     SortKeyArr              m_SortKeyArr;
     sal_Unicode             m_cPrefix;
     sal_Unicode             m_cSuffix;
@@ -90,6 +91,7 @@ public:
     void                DelSequenceArray()
                         {
                             m_SequArr.clear();
+                            m_SequArrRLHidden.clear();
                         }
 
     const SwAuthEntry*  GetEntryByHandle(sal_IntPtr nHandle) const;
@@ -102,7 +104,7 @@ public:
     sal_uInt16          AppendField(const SwAuthEntry& rInsert);
     sal_IntPtr          GetHandle(sal_uInt16 nPos);
 
-    sal_uInt16          GetSequencePos(sal_IntPtr nHandle);
+    sal_uInt16          GetSequencePos(sal_IntPtr nHandle, SwRootFrame const* pLayout);
 
     bool            IsSequence() const      {return m_bIsSequence;}
     void                SetSequence(bool bSet)
@@ -142,20 +144,29 @@ public:
 
 };
 
+/** invariant for SwAuthorityField is that it is always registered at its
+    SwAuthorityFieldType via AddField()/RemoveField() & therefore has m_nHandle
+    set - but it's possible that multiple SwAuthorityField have the same
+    m_nHandle & so the number of instances is an upper bound on
+    SwAuthorityField::m_DataArr.size() - it's not clear to me if more than one
+    one of the instances with the same m_nHandle is actually in the document,
+    they're all cloned via CopyField()...
+ */
 class SwAuthorityField : public SwField
 {
     sal_IntPtr          m_nHandle;
     mutable sal_IntPtr  m_nTempSequencePos;
+    mutable sal_IntPtr  m_nTempSequencePosRLHidden; ///< hidden redlines
 
     virtual OUString    ExpandImpl(SwRootFrame const* pLayout) const override;
     virtual std::unique_ptr<SwField> Copy() const override;
 
 public:
     /// For internal use only, in general continue using ExpandField() instead.
-    OUString ConditionalExpandAuthIdentifier() const;
+    OUString ConditionalExpandAuthIdentifier(SwRootFrame const* pLayout) const;
 
     //To handle Citation
-    SW_DLLPUBLIC OUString ExpandCitation(ToxAuthorityField eField) const;
+    SW_DLLPUBLIC OUString ExpandCitation(ToxAuthorityField eField, SwRootFrame const* pLayout) const;
 
     SwAuthorityField(SwAuthorityFieldType* pType, const OUString& rFieldContents);
     SwAuthorityField(SwAuthorityFieldType* pType, sal_IntPtr nHandle);
diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx
index e089f88ec7fb..efe6c60357ff 100644
--- a/sw/source/core/doc/DocumentFieldsManager.cxx
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -59,6 +59,21 @@
 
 using namespace ::com::sun::star::uno;
 
+namespace sw
+{
+    bool IsFieldDeletedInModel(IDocumentRedlineAccess const& rIDRA,
+            SwTextField const& rTextField)
+    {
+        SwRedlineTable::size_type tmp;
+        SwPosition const pos(rTextField.GetTextNode(),
+                rTextField.GetStart());
+        SwRangeRedline const*const pRedline(rIDRA.GetRedline(pos, &tmp));
+        return (pRedline
+            && pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE
+            && *pRedline->GetPoint() != *pRedline->GetMark());
+    }
+}
+
 namespace
 {
     #if HAVE_FEATURE_DBCONNECTIVITY
@@ -94,13 +109,7 @@ namespace
             // for *any* layout...
             return true;
         }
-        SwRedlineTable::size_type tmp;
-        SwPosition const pos(const_cast<SwTextNode&>(rTextField.GetTextNode()),
-                rTextField.GetStart());
-        SwRangeRedline const*const pRedline(rIDRA.GetRedline(pos, &tmp));
-        return (pRedline
-            && pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE
-            && *pRedline->GetPoint() != *pRedline->GetMark());
+        return sw::IsFieldDeletedInModel(rIDRA, rTextField);
     }
 
     void lcl_CalcField( SwDoc& rDoc, SwCalc& rCalc, const SetGetExpField& rSGEField,
diff --git a/sw/source/core/fields/authfld.cxx b/sw/source/core/fields/authfld.cxx
index 034a221e72e5..1e9c1ab6ed74 100644
--- a/sw/source/core/fields/authfld.cxx
+++ b/sw/source/core/fields/authfld.cxx
@@ -30,6 +30,7 @@
 #include <expfld.hxx>
 #include <pam.hxx>
 #include <cntfrm.hxx>
+#include <rootfrm.hxx>
 #include <tox.hxx>
 #include <txmsrt.hxx>
 #include <doctxm.hxx>
@@ -231,7 +232,8 @@ sal_IntPtr SwAuthorityFieldType::GetHandle(sal_uInt16 nPos)
     return 0;
 }
 
-sal_uInt16  SwAuthorityFieldType::GetSequencePos(sal_IntPtr nHandle)
+sal_uInt16 SwAuthorityFieldType::GetSequencePos(sal_IntPtr nHandle,
+        SwRootFrame const*const pLayout)
 {
     //find the field in a sorted array of handles,
 #if OSL_DEBUG_LEVEL > 0
@@ -241,7 +243,11 @@ sal_uInt16  SwAuthorityFieldType::GetSequencePos(sal_IntPtr nHandle)
         DelSequenceArray();
     if(m_SequArr.empty())
     {
+        IDocumentRedlineAccess const& rIDRA(m_pDoc->getIDocumentRedlineAccess());
+        // sw_redlinehide: need 2 arrays because the sorting may be different,
+        // if multiple fields refer to the same entry and first one is deleted
         std::vector<std::unique_ptr<SwTOXSortTabBase>> aSortArr;
+        std::vector<std::unique_ptr<SwTOXSortTabBase>> aSortArrRLHidden;
         SwIterator<SwFormatField,SwFieldType> aIter( *this );
 
         SwTOXInternational aIntl(m_eLanguage, SwTOIOptions::NONE, m_sSortAlgorithm);
@@ -268,16 +274,21 @@ sal_uInt16  SwAuthorityFieldType::GetSequencePos(sal_IntPtr nHandle)
             //body the directly available text node will be used
             if(!pTextNode)
                 pTextNode = &rFieldTextNode;
-            if (!pTextNode->GetText().isEmpty() &&
-                pTextNode->getLayoutFrame( rDoc.getIDocumentLayoutAccess().GetCurrentLayout() ) &&
-                pTextNode->GetNodes().IsDocNodes() )
+            if (pTextNode->GetText().isEmpty()
+                || !pTextNode->getLayoutFrame(rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
+                || !pTextNode->GetNodes().IsDocNodes())
+            {
+                continue;
+            }
+            auto const InsertImpl = [&aIntl, pTextNode, pFormatField]
+                (std::vector<std::unique_ptr<SwTOXSortTabBase>> & rSortArr)
             {
                 std::unique_ptr<SwTOXAuthority> pNew(
                     new SwTOXAuthority(*pTextNode, *pFormatField, aIntl));
 
-                for(size_t i = 0; i < aSortArr.size(); ++i)
+                for (size_t i = 0; i < rSortArr.size(); ++i)
                 {
-                    SwTOXSortTabBase* pOld = aSortArr[i].get();
+                    SwTOXSortTabBase* pOld = rSortArr[i].get();
                     if(*pOld == *pNew)
                     {
                         //only the first occurrence in the document
@@ -285,7 +296,7 @@ sal_uInt16  SwAuthorityFieldType::GetSequencePos(sal_IntPtr nHandle)
                         if(*pOld < *pNew)
                             pNew.reset();
                         else // remove the old content
-                            aSortArr.erase(aSortArr.begin() + i);
+                            rSortArr.erase(rSortArr.begin() + i);
                         break;
                     }
                 }
@@ -294,31 +305,41 @@ sal_uInt16  SwAuthorityFieldType::GetSequencePos(sal_IntPtr nHandle)
                 {
                     size_t j {0};
 
-                    while(j < aSortArr.size())
+                    while (j < rSortArr.size())
                     {
-                        SwTOXSortTabBase* pOld = aSortArr[j].get();
+                        SwTOXSortTabBase* pOld = rSortArr[j].get();
                         if(*pNew < *pOld)
                             break;
                         ++j;
                     }
-                    aSortArr.insert(aSortArr.begin() + j, std::move(pNew));
+                    rSortArr.insert(rSortArr.begin() + j, std::move(pNew));
                 }
+            };
+            InsertImpl(aSortArr);
+            if (!sw::IsFieldDeletedInModel(rIDRA, *pTextField))
+            {
+                InsertImpl(aSortArrRLHidden);
             }
         }
 
         for(auto & pBase : aSortArr)
         {
-            SwTOXSortTabBase& rBase = *pBase;
-            SwFormatField& rFormatField = static_cast<SwTOXAuthority&>(rBase).GetFieldFormat();
+            SwFormatField& rFormatField = static_cast<SwTOXAuthority&>(*pBase).GetFieldFormat();
             SwAuthorityField* pAField = static_cast<SwAuthorityField*>(rFormatField.GetField());
             m_SequArr.push_back(pAField->GetHandle());
         }
-        aSortArr.clear();
+        for (auto & pBase : aSortArrRLHidden)
+        {
+            SwFormatField& rFormatField = static_cast<SwTOXAuthority&>(*pBase).GetFieldFormat();
+            SwAuthorityField* pAField = static_cast<SwAuthorityField*>(rFormatField.GetField());
+            m_SequArrRLHidden.push_back(pAField->GetHandle());
+        }
     }
     //find nHandle
-    for(std::vector<sal_IntPtr>::size_type i = 0; i < m_SequArr.size(); ++i)
+    auto const& rSequArr(pLayout && pLayout->IsHideRedlines() ? m_SequArrRLHidden : m_SequArr);
+    for (std::vector<sal_IntPtr>::size_type i = 0; i < rSequArr.size(); ++i)
     {
-        if(m_SequArr[i] == nHandle)
+        if (rSequArr[i] == nHandle)
         {
             return i + 1;
         }
@@ -491,17 +512,19 @@ void SwAuthorityFieldType::SetSortKeys(sal_uInt16 nKeyCount, SwTOXSortKey  const
 
 SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pInitType,
                                     const OUString& rFieldContents )
-    : SwField(pInitType),
-    m_nTempSequencePos( -1 )
+    : SwField(pInitType)
+    , m_nTempSequencePos( -1 )
+    , m_nTempSequencePosRLHidden( -1 )
 {
     m_nHandle = pInitType->AddField( rFieldContents );
 }
 
 SwAuthorityField::SwAuthorityField( SwAuthorityFieldType* pInitType,
                                                 sal_IntPtr nSetHandle )
-    : SwField( pInitType ),
-    m_nHandle( nSetHandle ),
-    m_nTempSequencePos( -1 )
+    : SwField( pInitType )
+    , m_nHandle( nSetHandle )
+    , m_nTempSequencePos( -1 )
+    , m_nTempSequencePosRLHidden( -1 )
 {
     pInitType->AddField( m_nHandle );
 }
@@ -511,12 +534,13 @@ SwAuthorityField::~SwAuthorityField()
     static_cast<SwAuthorityFieldType* >(GetTyp())->RemoveField(m_nHandle);
 }
 
-OUString SwAuthorityField::ExpandImpl(SwRootFrame const*const) const
+OUString SwAuthorityField::ExpandImpl(SwRootFrame const*const pLayout) const
 {
-    return ConditionalExpandAuthIdentifier();
+    return ConditionalExpandAuthIdentifier(pLayout);
 }
 
-OUString SwAuthorityField::ConditionalExpandAuthIdentifier() const
+OUString SwAuthorityField::ConditionalExpandAuthIdentifier(
+        SwRootFrame const*const pLayout) const
 {
     SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(GetTyp());
     OUString sRet;
@@ -525,10 +549,12 @@ OUString SwAuthorityField::ConditionalExpandAuthIdentifier() const
 
     if( pAuthType->IsSequence() )
     {
+        sal_IntPtr & rnTempSequencePos(pLayout && pLayout->IsHideRedlines()
+                ? m_nTempSequencePosRLHidden : m_nTempSequencePos);
        if(!pAuthType->GetDoc()->getIDocumentFieldsAccess().IsExpFieldsLocked())
-           m_nTempSequencePos = pAuthType->GetSequencePos( m_nHandle );
-       if( m_nTempSequencePos >= 0 )
-           sRet += OUString::number( m_nTempSequencePos );
+            rnTempSequencePos = pAuthType->GetSequencePos(m_nHandle, pLayout);
+        if (0 <= rnTempSequencePos)
+            sRet += OUString::number(rnTempSequencePos);
     }
     else
     {
@@ -542,17 +568,20 @@ OUString SwAuthorityField::ConditionalExpandAuthIdentifier() const
     return sRet;
 }
 
-OUString SwAuthorityField::ExpandCitation(ToxAuthorityField eField) const
+OUString SwAuthorityField::ExpandCitation(ToxAuthorityField eField,
+        SwRootFrame const*const pLayout) const
 {
     SwAuthorityFieldType* pAuthType = static_cast<SwAuthorityFieldType*>(GetTyp());
     OUString sRet;
 
     if( pAuthType->IsSequence() )
     {
+        sal_IntPtr & rnTempSequencePos(pLayout && pLayout->IsHideRedlines()
+                ? m_nTempSequencePosRLHidden : m_nTempSequencePos);
        if(!pAuthType->GetDoc()->getIDocumentFieldsAccess().IsExpFieldsLocked())
-           m_nTempSequencePos = pAuthType->GetSequencePos( m_nHandle );
-       if( m_nTempSequencePos >= 0 )
-           sRet += OUString::number( m_nTempSequencePos );
+            rnTempSequencePos = pAuthType->GetSequencePos(m_nHandle, pLayout);
+        if (0 <= rnTempSequencePos)
+            sRet += OUString::number(rnTempSequencePos);
     }
     else
     {
diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx
index 7be1be2d0f11..a5008b4c4e3a 100644
--- a/sw/source/core/fields/fldbas.cxx
+++ b/sw/source/core/fields/fldbas.cxx
@@ -418,7 +418,7 @@ SwField::ExpandField(bool const bCached, SwRootFrame const*const pLayout) const
             if (GetTypeId() == TYP_AUTHORITY)
             {
                 const SwAuthorityField* pAuthorityField = static_cast<const SwAuthorityField*>(this);
-                m_Cache = pAuthorityField->ConditionalExpandAuthIdentifier();
+                m_Cache = pAuthorityField->ConditionalExpandAuthIdentifier(pLayout);
             }
             else
                 m_Cache = ExpandImpl(pLayout);
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 796c6e621f8e..756cf145443a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1940,7 +1940,7 @@ void DocxAttributeOutput::EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos
         if(rInfos.eType == ww::eCITATION)
         {
             sExpand = static_cast<SwAuthorityField const*>(rInfos.pField.get())
-                        ->ExpandCitation(AUTH_FIELD_TITLE);
+                        ->ExpandCitation(AUTH_FIELD_TITLE, nullptr);
         }
         else
         {
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index cbe0fa6ac810..3deb8c137891 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -2993,7 +2993,7 @@ void AttributeOutputBase::TextField( const SwFormatField& rField )
     case SwFieldIds::TableOfAuthorities:
     {
         OUString sRet(static_cast<SwAuthorityField const*>(pField)
-                        ->ExpandCitation(AUTH_FIELD_IDENTIFIER));
+                        ->ExpandCitation(AUTH_FIELD_IDENTIFIER, nullptr));
         // FIXME: DomainMapper_Impl::CloseFieldCommand() stuffs fully formed
         // field instructions in here, but if the field doesn't originate
         // from those filters it won't have that


More information about the Libreoffice-commits mailing list