sw/source/core/inc/frmtool.hxx    |    3 ++-
 sw/source/core/inc/txtfrm.hxx     |    4 +++-
 sw/source/core/layout/frmtool.cxx |   12 ++++++++----
 sw/source/core/text/txtfrm.cxx    |   11 +++++++++--
 sw/source/core/txtnode/ndtxt.cxx  |    2 +-
 5 files changed, 23 insertions(+), 9 deletions(-)

New commits:
commit 4093811d1327e83edf216639d7b1173d8ebf7165
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Fri Aug 9 16:03:44 2019 +0200
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Sat Aug 10 12:39:37 2019 +0200

    tdf#126627 sw_redlinehide: fix corner case in SwUndoDelete::UndoImpl()
    
    The assumption that the merge by the moved nodes would be sufficient to
    handle the end node's frames is wrong: the MakeFrames() uses
    FrameMode::New, so the frames on the end node are not deleted, even if a
    previous node is merged with the end node, so the end node has 2 frames
    in the same layout, which will cause all sorts of problems.
    
    Ensure that the ::MakeFrames() that is called from SwUndoDelete will
    *once* use FrameMode::Existing, which will delete the existing frames on
    the end node *iff* it is merged.  Subsequent SwTextNode::MakeFrames()
    calls on the nodes must use FrameMode::New of course, to prevent
    deleting the newly created frames immediately.
    
    Hopefully the SwUndoDelete is the only caller of MakeFrames() that will
    run into this corner case, as the others typically operate on a
    nodes-array section...
    
    (regression from 723728cd358693b8f4bc9d913541aa4479f2bd48)
    
    Change-Id: I829c1e7a92434f93d56e3c88a4ba4a55bab818d4
    Reviewed-on: https://gerrit.libreoffice.org/77211
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>
    (cherry picked from commit f6a7dee56c984f36261c75a1056cc3a5bf43b2f1)
    Reviewed-on: https://gerrit.libreoffice.org/77220
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    Tested-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index a127579c59ad..d2a5b7704cb1 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -22,6 +22,7 @@
 
 #include <swtypes.hxx>
 #include "frame.hxx"
+#include "txtfrm.hxx"
 #include "swcache.hxx"
 #include <swatrset.hxx>
 
@@ -131,7 +132,7 @@ void RestoreContent( SwFrame *pSav, SwLayoutFrame *pParent, 
SwFrame *pSibling );
 // Get ContentNodes, create ContentFrames, and add them to LayFrame.
 void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc, sal_uLong nIndex,
                  bool bPages = false, sal_uLong nEndIndex = 0,
-                 SwFrame *pPrv = nullptr );
+                 SwFrame *pPrv = nullptr, sw::FrameMode eMode = 
sw::FrameMode::New);
 
 // Creation of frames for a specific section (uses InsertCnt_)
 void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index afe590517923..a4774cbf567e 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -100,8 +100,10 @@ struct MergedPara;
 std::pair<SwTextNode*, sal_Int32> MapViewToModel(MergedPara const&, 
TextFrameIndex nIndex);
 TextFrameIndex MapModelToView(MergedPara const&, SwTextNode const* pNode, 
sal_Int32 nIndex);
 
+// warning: Existing must be used only once; a second use would delete the 
frame created by the first one...
 enum class FrameMode { New, Existing };
 std::unique_ptr<sw::MergedPara> CheckParaRedlineMerge(SwTextFrame & rFrame, 
SwTextNode & rTextNode, FrameMode eMode);
+SwTextFrame * MakeTextFrame(SwTextNode & rNode, SwFrame *, sw::FrameMode 
eMode);
 
 bool FrameContainsNode(SwContentFrame const& rFrame, sal_uLong nNodeIndex);
 bool IsParaPropsNode(SwRootFrame const& rLayout, SwTextNode const& rNode);
@@ -449,7 +451,7 @@ public:
         { return const_cast<SwDoc &>(const_cast<SwTextFrame 
const*>(this)->GetDoc()); }
     SwDoc const& GetDoc() const;
 
-    SwTextFrame(SwTextNode * const, SwFrame* );
+    SwTextFrame(SwTextNode * const, SwFrame*, sw::FrameMode eMode);
 
     /**
      * SwContentFrame: the shortcut for the Frames
diff --git a/sw/source/core/layout/frmtool.cxx 
b/sw/source/core/layout/frmtool.cxx
index 624b2701e8d1..65fe4546b5be 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -1380,7 +1380,7 @@ static void lcl_SetPos( SwFrame&             _rNewFrame,
 
 void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
                              sal_uLong nIndex, bool bPages, sal_uLong 
nEndIndex,
-                             SwFrame *pPrv )
+                             SwFrame *pPrv, sw::FrameMode const eMode )
 {
     pDoc->getIDocumentTimerAccess().BlockIdling();
     SwRootFrame* pLayout = pLay->getRootFrame();
@@ -1474,7 +1474,9 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
                 }
                 continue; // skip it
             }
-            pFrame = pNode->MakeFrame(pLay);
+            pFrame = pNode->IsTextNode()
+                        ? sw::MakeTextFrame(*pNode->GetTextNode(), pLay, eMode)
+                        : pNode->MakeFrame(pLay);
             if( pPageMaker )
                 pPageMaker->CheckInsert( nIndex );
 
@@ -1840,6 +1842,7 @@ void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
         bool bApres = aTmp < rSttIdx;
         SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
         SwFrame* pFrame;
+        sw::FrameMode eMode = sw::FrameMode::Existing;
         while( nullptr != (pFrame = aNode2Layout.NextFrame()) )
         {
             SwLayoutFrame *pUpper = pFrame->GetUpper();
@@ -1967,7 +1970,7 @@ void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
                         pTmp->UnlockJoin();
                 }
                 ::InsertCnt_( pUpper, pDoc, rSttIdx.GetIndex(),
-                              pFrame->IsInDocBody(), nEndIdx, pPrev );
+                              pFrame->IsInDocBody(), nEndIdx, pPrev, eMode );
             }
             else
             {
@@ -1987,7 +1990,7 @@ void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
                     bSplit = false;
 
                 ::InsertCnt_( pUpper, pDoc, rSttIdx.GetIndex(), false,
-                              nEndIdx, pPrv );
+                              nEndIdx, pPrv, eMode );
                 // OD 23.06.2003 #108784# - correction: append objects doesn't
                 // depend on value of <bAllowMove>
                 if( !bDontCreateObjects )
@@ -2023,6 +2026,7 @@ void MakeFrames( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
                     SwFrame::DestroyFrame(pSct);
                 }
             }
+            eMode = sw::FrameMode::New; // use Existing only once!
         }
     }
 
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 5dc660ba0d4a..4d64aa9e4e5a 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -771,7 +771,8 @@ void SwTextFrame::Init()
     }
 }
 
-SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib )
+SwTextFrame::SwTextFrame(SwTextNode * const pNode, SwFrame* pSib,
+        sw::FrameMode const eMode)
     : SwContentFrame( pNode, pSib )
     , mnAllLines( 0 )
     , mnThisLines( 0 )
@@ -799,11 +800,17 @@ SwTextFrame::SwTextFrame(SwTextNode * const pNode, 
SwFrame* pSib )
     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);
+    m_pMergedPara = CheckParaRedlineMerge(*this, *pNode, eMode);
 }
 
 namespace sw {
 
+SwTextFrame * MakeTextFrame(SwTextNode & rNode, SwFrame *const pSibling,
+        sw::FrameMode const eMode)
+{
+    return new SwTextFrame(&rNode, pSibling, eMode);
+}
+
 void RemoveFootnotesForNode(
         SwRootFrame const& rLayout, SwTextNode const& rTextNode,
         std::vector<std::pair<sal_Int32, sal_Int32>> const*const pExtents)
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index cced7186d49e..2d6807c92185 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -277,7 +277,7 @@ void SwTextNode::FileLoadedInitHints()
 
 SwContentFrame *SwTextNode::MakeFrame( SwFrame* pSib )
 {
-    SwContentFrame *pFrame = new SwTextFrame( this, pSib );
+    SwContentFrame *pFrame = sw::MakeTextFrame(*this, pSib, 
sw::FrameMode::New);
     return pFrame;
 }
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to