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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Oct 19 15:55:20 UTC 2018


 sw/inc/SwNodeNum.hxx                            |    7 +
 sw/inc/list.hxx                                 |    1 
 sw/inc/ndtxt.hxx                                |   19 +---
 sw/source/core/SwNumberTree/SwNodeNum.cxx       |   23 ++--
 sw/source/core/doc/list.cxx                     |   53 ++++++++---
 sw/source/core/inc/txtfrm.hxx                   |    4 
 sw/source/core/layout/wsfrm.cxx                 |    5 +
 sw/source/core/text/EnhancedPDFExportHelper.cxx |    4 
 sw/source/core/text/redlnitr.cxx                |   18 +++
 sw/source/core/text/txtfld.cxx                  |    5 -
 sw/source/core/text/txtfrm.cxx                  |   12 +-
 sw/source/core/txtnode/ndtxt.cxx                |  113 ++++++++++++++++++------
 sw/source/uibase/utlui/content.cxx              |    2 
 13 files changed, 191 insertions(+), 75 deletions(-)

New commits:
commit fa7b0497979d6de60e92ccb56b94d27f1c69a5c3
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 19 16:06:08 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Fri Oct 19 16:59:57 2018 +0200

    sw_redlinehide_3: invalidate numbered text nodes on Show/Hide
    
    Call the same function as SwNodeNum::NotifyNode().
    
    Change-Id: If2edc5fb9364e97715d4750f3a45c3c918edfebf

diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 7aff243c691a..a8486ef619ad 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -4344,6 +4344,11 @@ static void UnHideRedlines(SwRootFrame & rLayout,
                 }
                 pFrame->Broadcast(SfxHint()); // notify SwAccessibleParagraph
             }
+            // all nodes, not just merged ones! it may be in the same list as
+            if (rTextNode.IsNumbered()) // a preceding merged one...
+            {   // notify frames so they reformat numbering portions
+                rTextNode.NumRuleChgd();
+            }
         }
         if (!rNode.IsCreateFrameWhenHidingRedlines())
         {
commit 8db3d69042ae34e05be168644f8bf9babd380abf
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 19 15:59:53 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Fri Oct 19 16:59:57 2018 +0200

    sw_redlinehide_3: use the second list number in the text formatting
    
    Change-Id: Ibe2afae869b1999772fa6132e35a1e951fffddd2

diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index d171a5fbef80..a666da304538 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -419,7 +419,7 @@ void SwTaggedPDFHelper::BeginTag( vcl::PDFWriter::StructElement eType, const OUS
     {
         const SwTextFrame& rTextFrame = static_cast<const SwTextFrame&>(mpNumInfo->mrFrame);
         SwTextNode const*const pTextNd = rTextFrame.GetTextNodeForParaProps();
-        const SwNodeNum* pNodeNum = pTextNd->GetNum();
+        const SwNodeNum* pNodeNum = pTextNd->GetNum(rTextFrame.getRootFrame());
 
         if ( vcl::PDFWriter::List == eType )
         {
@@ -838,7 +838,7 @@ void SwTaggedPDFHelper::BeginNumberedListStructureElements()
 
     const SwTextNode *const pTextNd = rTextFrame.GetTextNodeForParaProps();
     const SwNumRule* pNumRule = pTextNd->GetNumRule();
-    const SwNodeNum* pNodeNum = pTextNd->GetNum();
+    const SwNodeNum* pNodeNum = pTextNd->GetNum(rTextFrame.getRootFrame());
 
     const bool bNumbered = !pTextNd->IsOutline() && pNodeNum && pNodeNum->GetParent() && pNumRule;
 
diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx
index 196b11b84cf9..e7fd1223fe95 100644
--- a/sw/source/core/text/txtfld.cxx
+++ b/sw/source/core/text/txtfld.cxx
@@ -472,6 +472,9 @@ SwNumberPortion *SwTextFormatter::NewNumberPortion( SwTextFormatInfo &rInf ) con
         return nullptr;
 
     SwNumberPortion *pRet = nullptr;
+    // sw_redlinehide: at this point it's certain that pTextNd is the node with
+    // the numbering of the frame; only the actual number-vector (GetNumString)
+    // depends on the hide-mode in the layout so other calls don't need to care
     const SwTextNode *const pTextNd = GetTextFrame()->GetTextNodeForParaProps();
     const SwNumRule* pNumRule = pTextNd->GetNumRule();
 
@@ -572,7 +575,7 @@ SwNumberPortion *SwTextFormatter::NewNumberPortion( SwTextFormatInfo &rInf ) con
             }
             else
             {
-                OUString aText( pTextNd->GetNumString() );
+                OUString aText( pTextNd->GetNumString(true, MAXLEVEL, m_pFrame->getRootFrame()) );
                 if ( !aText.isEmpty() )
                 {
                     aText += pTextNd->GetLabelFollowedBy();
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index 91b1024aa9d8..614fa1a9b8bc 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -1868,7 +1868,7 @@ bool SwContentTree::FillTransferData( TransferDataContainer& rTransfer,
                 if( pTextNd && pOutlRule && pTextNd->IsNumbered())
                 {
                     SwNumberTree::tNumberVector aNumVector =
-                        pTextNd->GetNumberVector();
+                        pTextNd->GetNumberVector(pWrtShell->GetLayout());
                     for( int nLevel = 0;
                          nLevel <= pTextNd->GetActualListLevel();
                          nLevel++ )
commit 265ce9585e7c369238b6cae3af38eb818bef1f49
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 19 15:55:42 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Fri Oct 19 16:59:57 2018 +0200

    sw_redlinehide_3: have SwTextFrame ensure that list node is ...
    
    ... always the same as pParaPropsNode.
    
    Change-Id: I1fb225d147ec3558615ad16ec49f873db7f1628f

diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 93c1e9a6b7a1..9e720cbb3260 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -933,14 +933,14 @@ struct MergedPara
     /// const_casts it and modifies it (also, Update will modify it)
     OUString mergedText;
     /// most paragraph properties are taken from the first non-empty node
-    SwTextNode const* pParaPropsNode;
+    SwTextNode * pParaPropsNode;
     /// except break attributes, those are taken from the first node
     SwTextNode *const pFirstNode;
     /// mainly for sanity checks
     SwTextNode const* pLastNode;
     MergedPara(SwTextFrame & rFrame, std::vector<Extent>&& rExtents,
             OUString const& rText,
-            SwTextNode const*const pProps, SwTextNode *const pFirst,
+            SwTextNode *const pProps, SwTextNode *const pFirst,
             SwTextNode const*const pLast)
         : listener(rFrame), extents(std::move(rExtents)), mergedText(rText)
         , pParaPropsNode(pProps), pFirstNode(pFirst), pLastNode(pLast)
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index a6491e618e47..81aac678b427 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -833,7 +833,9 @@ static TextFrameIndex UpdateMergedParaForInsert(MergedPara & rMerged,
         nInserted = nLen;
         if (rNode.GetIndex() < rMerged.pParaPropsNode->GetIndex())
         {   // text inserted before current para-props node
-            rMerged.pParaPropsNode = &rNode;
+            rMerged.pParaPropsNode->RemoveFromListRLHidden();
+            rMerged.pParaPropsNode = &const_cast<SwTextNode&>(rNode);
+            rMerged.pParaPropsNode->AddToListRLHidden();
         }
     }
     rMerged.mergedText = text.makeStringAndClear();
@@ -959,9 +961,11 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
     {   // all visible text from node was erased
         if (rMerged.pParaPropsNode == &rNode)
         {
+            rMerged.pParaPropsNode->RemoveFromListRLHidden();
             rMerged.pParaPropsNode = rMerged.extents.empty()
                 ? rMerged.pFirstNode
                 : rMerged.extents.front().pNode;
+            rMerged.pParaPropsNode->AddToListRLHidden();
         }
 // NOPE must listen on all non-hidden nodes; particularly on pLastNode        rMerged.listener.EndListening(&const_cast<SwTextNode&>(rNode));
     }
commit 5c28522b91008540f38506046d545da97b7f069c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 19 15:51:30 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Fri Oct 19 16:59:57 2018 +0200

    sw_redlinehide_3: CheckParaRedlineMerge maintains second list tree
    
    ... by calling AddToListRLHidden/RemoveFromListRLHidden.
    
    Do this here because it has all the necessary information.
    
    Change-Id: Iac2640b7493267b187e66b1d464c79fe90642afe

diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index ccfc4ac803db..598c0bc321da 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -62,7 +62,7 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode,
     std::vector<SwSectionNode *> sections;
     std::vector<sw::Extent> extents;
     OUStringBuffer mergedText;
-    SwTextNode const* pParaPropsNode(nullptr);
+    SwTextNode * pParaPropsNode(nullptr);
     SwTextNode * pNode(&rTextNode);
     sal_Int32 nLastEnd(0);
     for (auto i = rIDRA.GetRedlinePos(rTextNode, USHRT_MAX);
@@ -180,6 +180,10 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode,
     }
     if (!bHaveRedlines)
     {
+        if (rTextNode.IsInList() && !rTextNode.GetNum(rFrame.getRootFrame()))
+        {
+            rTextNode.AddToListRLHidden(); // try to add it...
+        }
         return nullptr;
     }
     if (nLastEnd != pNode->Len())
@@ -197,6 +201,18 @@ CheckParaRedlineMerge(SwTextFrame & rFrame, SwTextNode & rTextNode,
         assert(!mergedText.isEmpty());
         pParaPropsNode = extents.begin()->pNode; // para props from first node that isn't empty
     }
+    // keep lists up to date with visible nodes
+    if (pParaPropsNode->IsInList() && !pParaPropsNode->GetNum(rFrame.getRootFrame()))
+    {
+        pParaPropsNode->AddToListRLHidden(); // try to add it...
+    }
+    for (auto const pTextNode : nodes)
+    {
+        if (pTextNode != pParaPropsNode)
+        {
+            pTextNode->RemoveFromListRLHidden();
+        }
+    }
     if (eMode == FrameMode::Existing)
     {
         // remove existing footnote frames for first node;
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 74d6253381d4..a6491e618e47 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -611,8 +611,7 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib )
     , mnFootnoteLine( 0 )
     , mnHeightOfLastLine( 0 )
     , mnAdditionalFirstLineOffset( 0 )
-    // note: this may change this->pRegisteredIn to m_pMergedPara->listeners
-    , m_pMergedPara(CheckParaRedlineMerge(*this, *pNode, sw::FrameMode::New)) // ensure it is inited
+    , m_pMergedPara(nullptr)
     , mnOffset( 0 )
     , mnCacheIndex( USHRT_MAX )
     , mbLocked( false )
@@ -629,6 +628,9 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib )
     , mbFollowFormatAllowed( true )
 {
     mnFrameType = SwFrameType::Txt;
+    // note: this may call SwClientNotify if it's in a list so do it last
+    // note: this may change this->pRegisteredIn to m_pMergedPara->listeners
+    m_pMergedPara = CheckParaRedlineMerge(*this, *pNode, sw::FrameMode::New);
 }
 
 namespace sw {
commit 0d3894eaac20dcda68ca88c3f89e3b6f591ab983
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 19 15:46:27 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Fri Oct 19 16:59:57 2018 +0200

    sw_redlinehide_3: apparently a live SwNodeNum always has a parent
    
    ... so assert that somewhere.
    
    Change-Id: I928c55ffa57ec037e9406618d20b454e11dd80d4

diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 109c9b67f005..215a0c79783b 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -4335,6 +4335,8 @@ void SwTextNode::RemoveFromListRLHidden()
 
 bool SwTextNode::IsInList() const
 {
+    // it looks like an unconnected Num can't happen, except in the undo-array
+    assert(!GetNum() || GetNum()->GetParent() || !GetNodes().IsDocNodes());
     return GetNum() != nullptr && GetNum()->GetParent() != nullptr;
 }
 
commit f596201e98afe6ca82a1ada8782fcb3e4195e755
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 19 15:27:09 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Fri Oct 19 16:59:57 2018 +0200

    sw_redlinehide_3: add second SwNodeNum to SwTextNode
    
    Change-Id: I62ebdb92ee384905bba9ef3865fcdb306775baf2

diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index d84c3053533c..97450d63a7a6 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -92,6 +92,7 @@ class SW_DLLPUBLIC SwTextNode
     std::unique_ptr<SwpHints> m_pSwpHints;
 
     mutable SwNodeNum* mpNodeNum;  ///< Numbering for this paragraph.
+    mutable SwNodeNum* mpNodeNumRLHidden; ///< Numbering for this paragraph (hidden redlines)
 
     OUString m_Text;
 
@@ -165,12 +166,6 @@ class SW_DLLPUBLIC SwTextNode
 
     SAL_DLLPRIVATE void InitSwParaStatistics( bool bNew );
 
-    /** create number for this text node, if not already existing
-
-        @return number of this node
-    */
-    SwNodeNum* CreateNum() const;
-
     inline void TryDeleteSwpHints();
 
     SAL_DLLPRIVATE void impl_FormatToTextAttr(const SfxItemSet& i_rAttrSet);
@@ -428,12 +423,9 @@ public:
      */
     SwNumRule *GetNumRule(bool bInParent = true) const;
 
-    const SwNodeNum* GetNum() const
-    {
-        return mpNodeNum;
-    }
+    const SwNodeNum* GetNum(SwRootFrame const* pLayout = nullptr) const;
 
-    SwNumberTree::tNumberVector GetNumberVector() const;
+    SwNumberTree::tNumberVector GetNumberVector(SwRootFrame const* pLayout = nullptr) const;
 
     /**
        Returns if this text node is an outline.
@@ -467,7 +459,8 @@ public:
         MAXLEVEL
     */
     OUString GetNumString( const bool _bInclPrefixAndSuffixStrings = true,
-            const unsigned int _nRestrictToThisLevel = MAXLEVEL ) const;
+            const unsigned int _nRestrictToThisLevel = MAXLEVEL,
+            SwRootFrame const* pLayout = nullptr) const;
 
     /**
        Returns the additional indents of this text node and its numbering.
@@ -773,7 +766,9 @@ public:
     bool IsCountedInList() const;
 
     void AddToList();
+    void AddToListRLHidden();
     void RemoveFromList();
+    void RemoveFromListRLHidden();
     bool IsInList() const;
 
     bool IsFirstOfNumRule() const;
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 98768f0422d0..109c9b67f005 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -201,6 +201,7 @@ SwTextNode *SwNodes::MakeTextNode( const SwNodeIndex & rWhere,
 SwTextNode::SwTextNode( const SwNodeIndex &rWhere, SwTextFormatColl *pTextColl, const SfxItemSet* pAutoAttr )
 :   SwContentNode( rWhere, SwNodeType::Text, pTextColl ),
     mpNodeNum( nullptr ),
+    mpNodeNumRLHidden(nullptr),
     m_Text(),
     m_pParaIdleData_Impl(nullptr),
     m_bContainsHiddenChars(false),
@@ -2872,6 +2873,7 @@ void SwTextNode::NumRuleChgd()
         if ( pNumRule && pNumRule != GetNum()->GetNumRule() )
         {
             mpNodeNum->ChangeNumRule( *pNumRule );
+            mpNodeNumRLHidden->ChangeNumRule( *pNumRule );
         }
     }
 
@@ -3138,14 +3140,15 @@ bool SwTextNode::HasBullet() const
 // #128041# - introduce parameter <_bInclPrefixAndSuffixStrings>
 //i53420 added max outline parameter
 OUString SwTextNode::GetNumString( const bool _bInclPrefixAndSuffixStrings,
-        const unsigned int _nRestrictToThisLevel ) const
+        const unsigned int _nRestrictToThisLevel,
+        SwRootFrame const*const pLayout) const
 {
     if (GetDoc()->IsClipBoard() && m_pNumStringCache.get())
     {
         // #i111677# do not expand number strings in clipboard documents
         return *m_pNumStringCache;
     }
-    const SwNumRule* pRule = GetNum() ? GetNum()->GetNumRule() : nullptr;
+    const SwNumRule* pRule = GetNum(pLayout) ? GetNum(pLayout)->GetNumRule() : nullptr;
     if ( pRule &&
          IsCountedInList() )
     {
@@ -3155,7 +3158,7 @@ OUString SwTextNode::GetNumString( const bool _bInclPrefixAndSuffixStrings,
 
             (style::NumberingType::NUMBER_NONE == rNumberType.GetNumberingType()))
         {
-            return pRule->MakeNumString( GetNum()->GetNumberVector(),
+            return pRule->MakeNumString( GetNum(pLayout)->GetNumberVector(),
                                      _bInclPrefixAndSuffixStrings,
                                      false,
                                      _nRestrictToThisLevel,
@@ -3964,20 +3967,19 @@ SwFormatColl* SwTextNode::ChgFormatColl( SwFormatColl *pNewColl )
     return pOldColl;
 }
 
-SwNodeNum* SwTextNode::CreateNum() const
+const SwNodeNum* SwTextNode::GetNum(SwRootFrame const*const pLayout) const
 {
-    if ( !mpNodeNum )
-    {
-        mpNodeNum = new SwNodeNum( const_cast<SwTextNode*>(this), false );
-    }
-    return mpNodeNum;
+    // invariant: it's only in list in Hide mode if it's in list in normal mode
+    assert(mpNodeNum || !mpNodeNumRLHidden);
+    return pLayout && pLayout->IsHideRedlines() ? mpNodeNumRLHidden : mpNodeNum;
 }
 
-SwNumberTree::tNumberVector SwTextNode::GetNumberVector() const
+SwNumberTree::tNumberVector
+SwTextNode::GetNumberVector(SwRootFrame const*const pLayout) const
 {
-    if ( GetNum() )
+    if (SwNodeNum const*const pNum = GetNum(pLayout))
     {
-        return GetNum()->GetNumberVector();
+        return pNum->GetNumberVector();
     }
     else
     {
@@ -4083,6 +4085,8 @@ int SwTextNode::GetAttrListLevel() const
 
 int SwTextNode::GetActualListLevel() const
 {
+    assert(!GetNum() || !mpNodeNumRLHidden || // must be in sync
+        GetNum()->GetLevelInListTree() == mpNodeNumRLHidden->GetLevelInListTree());
     return GetNum() ? GetNum()->GetLevelInListTree() : -1;
 }
 
@@ -4267,11 +4271,45 @@ void SwTextNode::AddToList()
         assert(!mpNodeNum);
         mpNodeNum = new SwNodeNum(this, false);
         pList->InsertListItem(*mpNodeNum, false, GetAttrListLevel());
+        // iterate all frames & if there's one with hidden layout...
+        SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> iter(*this);
+        for (SwTextFrame* pFrame = iter.First(); pFrame; pFrame = iter.Next())
+        {
+            if (pFrame->getRootFrame()->IsHideRedlines())
+            {
+                sw::MergedPara const*const pMerged = pFrame->GetMergedPara();
+                if (!pMerged || this == pMerged->pParaPropsNode)
+                {
+                    AddToListRLHidden();
+                }
+                break; // assume it's consistent, need to check only once
+            }
+        }
+    }
+}
+
+void SwTextNode::AddToListRLHidden()
+{
+    if (mpNodeNumRLHidden)
+    {
+        assert(false);
+        OSL_FAIL( "<SwTextNode::AddToListRLHidden()> - the text node is already added to a list. Serious defect" );
+        return;
+    }
+
+    SwList *const pList(FindList(this));
+    if (pList)
+    {
+        assert(!mpNodeNumRLHidden);
+        mpNodeNumRLHidden = new SwNodeNum(this, true);
+        pList->InsertListItem(*mpNodeNumRLHidden, true, GetAttrListLevel());
     }
 }
 
 void SwTextNode::RemoveFromList()
 {
+    // sw_redlinehide: ensure it's removed from the other half too!
+    RemoveFromListRLHidden();
     if ( IsInList() )
     {
         SwList::RemoveListItem( *mpNodeNum );
@@ -4282,6 +4320,19 @@ void SwTextNode::RemoveFromList()
     }
 }
 
+void SwTextNode::RemoveFromListRLHidden()
+{
+    if (mpNodeNumRLHidden) // direct access because RemoveFromList doesn't have layout
+    {
+        assert(mpNodeNumRLHidden->GetParent() || !GetNodes().IsDocNodes());
+        SwList::RemoveListItem(*mpNodeNumRLHidden);
+        delete mpNodeNumRLHidden;
+        mpNodeNumRLHidden = nullptr;
+
+        SetWordCountDirty( true );
+    }
+}
+
 bool SwTextNode::IsInList() const
 {
     return GetNum() != nullptr && GetNum()->GetParent() != nullptr;
commit 69df472db920aad80f373340bf4e28fec3b174c2
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 19 15:08:01 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Fri Oct 19 16:59:57 2018 +0200

    sw_redlinehide_3: add flag to SwNodeNum
    
    Disable the NumRule/DocumentListsItemManager manipulations on the
    second tree; only the "main" tree does that.
    
    Change-Id: I0da8ced53f8d55758e3c02fd24b9253bbf603b38

diff --git a/sw/inc/SwNodeNum.hxx b/sw/inc/SwNodeNum.hxx
index d9e61b115b55..cb277b7e7880 100644
--- a/sw/inc/SwNodeNum.hxx
+++ b/sw/inc/SwNodeNum.hxx
@@ -30,7 +30,9 @@ class SW_DLLPUBLIC SwNodeNum : public SwNumberTreeNode
 {
 public:
 
-    explicit SwNodeNum( SwTextNode* pTextNode );
+    explicit SwNodeNum( SwTextNode* pTextNode, bool isHiddenRedlines );
+    // note: this is only for creating phantom nodes and root nodes; these
+    // never have a text node
     explicit SwNodeNum( SwNumRule* pNumRule );
     virtual ~SwNodeNum() override;
 
@@ -79,8 +81,9 @@ protected:
     // method called at a child after this child has been removed from the list tree
     virtual void PostRemove() override;
 private:
-    SwTextNode * mpTextNode;
+    SwTextNode *const mpTextNode;
     SwNumRule * mpNumRule;
+    bool m_isHiddenRedlines;
 
     static void UnregisterMeAndChildrenDueToRootDelete( SwNodeNum& rNodeNum );
 
diff --git a/sw/source/core/SwNumberTree/SwNodeNum.cxx b/sw/source/core/SwNumberTree/SwNodeNum.cxx
index 72d5691e987a..40bf1b2eb0c2 100644
--- a/sw/source/core/SwNumberTree/SwNodeNum.cxx
+++ b/sw/source/core/SwNumberTree/SwNodeNum.cxx
@@ -27,17 +27,17 @@
 #include <IDocumentListItems.hxx>
 #include <doc.hxx>
 
-SwNodeNum::SwNodeNum( SwTextNode* pTextNode )
-    : SwNumberTreeNode(),
-      mpTextNode( pTextNode ),
-      mpNumRule( nullptr )
+SwNodeNum::SwNodeNum(SwTextNode* pTextNode, bool const isHiddenRedlines)
+    : mpTextNode( pTextNode )
+    , mpNumRule( nullptr )
+    , m_isHiddenRedlines(isHiddenRedlines)
 {
 }
 
 SwNodeNum::SwNodeNum( SwNumRule* pNumRule )
-    : SwNumberTreeNode(),
-      mpTextNode( nullptr ),
-      mpNumRule( pNumRule )
+    : mpTextNode( nullptr )
+    , mpNumRule( pNumRule )
+    , m_isHiddenRedlines(false)
 {
 }
 
@@ -87,11 +87,12 @@ void SwNodeNum::PreAdd()
     }
     OSL_ENSURE( GetNumRule(),
             "<SwNodeNum::PreAdd()> - no list style set at <SwNodeNum> instance" );
-    if ( GetNumRule() && GetTextNode() )
+    if (!m_isHiddenRedlines && GetNumRule() && GetTextNode())
     {
         GetNumRule()->AddTextNode( *(GetTextNode()) );
     }
 
+    if (!m_isHiddenRedlines)
     {
         if ( GetTextNode() &&
              GetTextNode()->GetNodes().IsDocNodes() )
@@ -108,14 +109,14 @@ void SwNodeNum::PostRemove()
     OSL_ENSURE( GetNumRule(),
             "<SwNodeNum::PostRemove()> - no list style set at <SwNodeNum> instance" );
 
-    if ( GetTextNode() )
+    if (!m_isHiddenRedlines && GetTextNode())
     {
         GetTextNode()->getIDocumentListItems().removeListItem( *this );
     }
 
     if ( GetNumRule() )
     {
-        if ( GetTextNode() )
+        if (!m_isHiddenRedlines && GetTextNode())
         {
             GetNumRule()->RemoveTextNode( *(GetTextNode()) );
         }
@@ -370,7 +371,7 @@ const SwNodeNum* SwNodeNum::GetPrecedingNodeNumOf( const SwTextNode& rTextNode )
     const SwNodeNum* pPrecedingNodeNum( nullptr );
 
     // #i83479#
-    SwNodeNum aNodeNumForTextNode( const_cast<SwTextNode*>(&rTextNode) );
+    SwNodeNum aNodeNumForTextNode( const_cast<SwTextNode*>(&rTextNode), false/*doesn't matter*/ );
 
     pPrecedingNodeNum = dynamic_cast<const SwNodeNum*>(
                             GetRoot()
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 0e539ba2c94e..98768f0422d0 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -3968,7 +3968,7 @@ SwNodeNum* SwTextNode::CreateNum() const
 {
     if ( !mpNodeNum )
     {
-        mpNodeNum = new SwNodeNum( const_cast<SwTextNode*>(this) );
+        mpNodeNum = new SwNodeNum( const_cast<SwTextNode*>(this), false );
     }
     return mpNodeNum;
 }
@@ -4265,7 +4265,7 @@ void SwTextNode::AddToList()
     if (pList)
     {
         assert(!mpNodeNum);
-        mpNodeNum = new SwNodeNum(this);
+        mpNodeNum = new SwNodeNum(this, false);
         pList->InsertListItem(*mpNodeNum, false, GetAttrListLevel());
     }
 }
commit 94ef7c6b02329536470a50f5ad9fca3dbaac3a17
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 19 14:49:12 2018 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Fri Oct 19 16:48:52 2018 +0200

    sw_redlinehide_3: add second SwNodeNum tree to SwList
    
    ... so it can be used when redlines are hidden in the layout.
    
    Change-Id: I6cb2bca2fb8ba3913bbf6633996341b52639fe41

diff --git a/sw/inc/list.hxx b/sw/inc/list.hxx
index 1c5bfc7d4478..1cfdad5e0716 100644
--- a/sw/inc/list.hxx
+++ b/sw/inc/list.hxx
@@ -44,6 +44,7 @@ class SwList
         void SetDefaultListStyleName(OUString const&);
 
         void InsertListItem( SwNodeNum& rNodeNum,
+                             bool isHiddenRedlines,
                              const int nLevel );
         static void RemoveListItem( SwNodeNum& rNodeNum );
 
diff --git a/sw/source/core/doc/list.cxx b/sw/source/core/doc/list.cxx
index a3c4e90dcc49..c449c58e97b0 100644
--- a/sw/source/core/doc/list.cxx
+++ b/sw/source/core/doc/list.cxx
@@ -39,7 +39,7 @@ class SwListImpl
 
         const OUString& GetDefaultListStyleName() const { return msDefaultListStyleName;}
 
-        void InsertListItem( SwNodeNum& rNodeNum,
+        void InsertListItem( SwNodeNum& rNodeNum, bool isHiddenRedlines,
                              const int nLevel );
         static void RemoveListItem( SwNodeNum& rNodeNum );
 
@@ -57,7 +57,24 @@ class SwListImpl
         OUString msDefaultListStyleName;
 
         // list trees for certain document ranges
-        typedef std::pair<std::unique_ptr<SwNodeNum>, std::unique_ptr<SwPaM>> tListTreeForRange;
+        struct tListTreeForRange
+        {
+            /// tree always corresponds to document model
+            std::unique_ptr<SwNodeNum> pRoot;
+            /// Tree that is missing those nodes that are merged or hidden
+            /// by delete redlines; this is only used if there is a layout
+            /// that has IsHideRedlines() enabled.
+            /// A second tree is needed because not only are the numbers in
+            /// the nodes different, the structure of the tree may be different
+            /// as well, if a high-level node is hidden its children go under
+            /// the previous node on the same level.
+            /// The nodes of pRootRLHidden are a subset of the nodes of pRoot.
+            std::unique_ptr<SwNodeNum> pRootRLHidden;
+            /// top-level SwNodes section
+            std::unique_ptr<SwPaM> pSection;
+            tListTreeForRange(SwNodeNum *const p1, SwNodeNum *const p2, SwPaM *const p3)
+                : pRoot(p1), pRootRLHidden(p2), pSection(p3) {}
+        };
         typedef std::vector<tListTreeForRange> tListTrees;
         tListTrees maListTrees;
 
@@ -81,8 +98,9 @@ SwListImpl::SwListImpl( const OUString& sListId,
         SwPaM aPam( *pNode, *pNode->EndOfSectionNode() );
 
         SwNodeNum* pNumberTreeRootNode = new SwNodeNum( &rDefaultListStyle );
+        SwNodeNum* pNumberTreeRootNodeRL = new SwNodeNum( &rDefaultListStyle );
         SwPaM* pPam = new SwPaM( *(aPam.Start()), *(aPam.End()) );
-        maListTrees.emplace_back(pNumberTreeRootNode, pPam);
+        maListTrees.emplace_back(pNumberTreeRootNode, pNumberTreeRootNodeRL, pPam);
 
         pNode = pNode->EndOfSectionNode();
         if (pNode != &rNodes.GetEndOfContent())
@@ -102,12 +120,12 @@ SwListImpl::~SwListImpl() COVERITY_NOEXCEPT_FALSE
           aNumberTreeIter != maListTrees.end();
           ++aNumberTreeIter )
     {
-        SwNodeNum::HandleNumberTreeRootNodeDelete( *((*aNumberTreeIter).first) );
+        SwNodeNum::HandleNumberTreeRootNodeDelete(*((*aNumberTreeIter).pRoot));
+        SwNodeNum::HandleNumberTreeRootNodeDelete(*((*aNumberTreeIter).pRootRLHidden));
     }
 }
 
-
-void SwListImpl::InsertListItem( SwNodeNum& rNodeNum,
+void SwListImpl::InsertListItem( SwNodeNum& rNodeNum, bool const isHiddenRedlines,
                                  const int nLevel )
 {
     const SwPosition aPosOfNodeNum( rNodeNum.GetPosition() );
@@ -118,15 +136,17 @@ void SwListImpl::InsertListItem( SwNodeNum& rNodeNum,
           aNumberTreeIter != maListTrees.end();
           ++aNumberTreeIter )
     {
-        const SwPosition* pStart = (*aNumberTreeIter).second->Start();
-        const SwPosition* pEnd = (*aNumberTreeIter).second->End();
+        const SwPosition* pStart = (*aNumberTreeIter).pSection->Start();
+        const SwPosition* pEnd = (*aNumberTreeIter).pSection->End();
         const SwNodes* pRangeNodes = &(pStart->nNode.GetNode().GetNodes());
 
         if ( pRangeNodes == pNodesOfNodeNum &&
              *pStart <= aPosOfNodeNum && aPosOfNodeNum <= *pEnd)
         {
-            (*aNumberTreeIter).first->AddChild( &rNodeNum, nLevel );
-
+            auto const& pRoot(isHiddenRedlines
+                    ? (*aNumberTreeIter).pRootRLHidden
+                    : (*aNumberTreeIter).pRoot);
+            pRoot->AddChild(&rNodeNum, nLevel);
             break;
         }
     }
@@ -144,7 +164,8 @@ void SwListImpl::InvalidateListTree()
           aNumberTreeIter != maListTrees.end();
           ++aNumberTreeIter )
     {
-        (*aNumberTreeIter).first->InvalidateTree();
+        (*aNumberTreeIter).pRoot->InvalidateTree();
+        (*aNumberTreeIter).pRootRLHidden->InvalidateTree();
     }
 }
 
@@ -155,7 +176,8 @@ void SwListImpl::ValidateListTree()
           aNumberTreeIter != maListTrees.end();
           ++aNumberTreeIter )
     {
-        (*aNumberTreeIter).first->NotifyInvalidChildren();
+        (*aNumberTreeIter).pRoot->NotifyInvalidChildren();
+        (*aNumberTreeIter).pRootRLHidden->NotifyInvalidChildren();
     }
 }
 
@@ -202,7 +224,8 @@ void SwListImpl::NotifyItemsOnListLevel( const int nLevel )
           aNumberTreeIter != maListTrees.end();
           ++aNumberTreeIter )
     {
-        (*aNumberTreeIter).first->NotifyNodesOnListLevel( nLevel );
+        (*aNumberTreeIter).pRoot->NotifyNodesOnListLevel( nLevel );
+        (*aNumberTreeIter).pRootRLHidden->NotifyNodesOnListLevel( nLevel );
     }
 }
 
@@ -232,10 +255,10 @@ void SwList::SetDefaultListStyleName(OUString const& rNew)
     mpListImpl->msDefaultListStyleName = rNew;
 }
 
-void SwList::InsertListItem( SwNodeNum& rNodeNum,
+void SwList::InsertListItem( SwNodeNum& rNodeNum, bool const isHiddenRedlines,
                              const int nLevel )
 {
-    mpListImpl->InsertListItem( rNodeNum, nLevel );
+    mpListImpl->InsertListItem( rNodeNum, isHiddenRedlines, nLevel );
 }
 
 void SwList::RemoveListItem( SwNodeNum& rNodeNum )
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index e0e6d4223840..0e539ba2c94e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -4230,33 +4230,43 @@ bool SwTextNode::IsCountedInList() const
     return aIsCountedInListItem.GetValue();
 }
 
-void SwTextNode::AddToList()
+static SwList * FindList(SwTextNode *const pNode)
 {
-    if ( IsInList() )
-    {
-        OSL_FAIL( "<SwTextNode::AddToList()> - the text node is already added to a list. Serious defect" );
-        return;
-    }
-
-    const OUString sListId = GetListId();
+    const OUString sListId = pNode->GetListId();
     if (!sListId.isEmpty())
     {
-        SwList* pList = GetDoc()->getIDocumentListsAccess().getListByName( sListId );
+        auto & rIDLA(pNode->GetDoc()->getIDocumentListsAccess());
+        SwList* pList = rIDLA.getListByName( sListId );
         if ( pList == nullptr )
         {
             // Create corresponding list.
-            SwNumRule* pNumRule = GetNumRule();
+            SwNumRule* pNumRule = pNode->GetNumRule();
             if ( pNumRule )
             {
-                pList = GetDoc()->getIDocumentListsAccess().createList( sListId, GetNumRule()->GetName() );
+                pList = rIDLA.createList(sListId, pNode->GetNumRule()->GetName());
             }
         }
         OSL_ENSURE( pList != nullptr,
                 "<SwTextNode::AddToList()> - no list for given list id. Serious defect" );
-        if ( pList )
-        {
-            pList->InsertListItem( *CreateNum(), GetAttrListLevel() );
-        }
+        return pList;
+    }
+    return nullptr;
+}
+
+void SwTextNode::AddToList()
+{
+    if ( IsInList() )
+    {
+        OSL_FAIL( "<SwTextNode::AddToList()> - the text node is already added to a list. Serious defect" );
+        return;
+    }
+
+    SwList *const pList(FindList(this));
+    if (pList)
+    {
+        assert(!mpNodeNum);
+        mpNodeNum = new SwNodeNum(this);
+        pList->InsertListItem(*mpNodeNum, false, GetAttrListLevel());
     }
 }
 


More information about the Libreoffice-commits mailing list