summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2020-05-26 16:46:57 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2020-06-02 23:41:00 +0200
commit136ab7e2b88a91e8a29d80253b97e6a5081ea4e0 (patch)
tree2f59993a29926c1f203cd0f2a7034f130c2a0818
parent0361bb27b6900fb055a77bcc987305442134334c (diff)
tdf#132236 sw_redlinehide: fix SwUndoDelete with sections even more
SwUndoDelete::UndoImpl may want to move something like this into the nodes-array: [ 9] 0x6356fe0 TextNode "", [ 10] 0x31cba00 ~DeletedNode , [ 11] 0x64d8840 TextNode "Introduction - xzn Overview Of KmneqxziTY\t3", [ 12] 0x64e9750 TextNode "shell\t20", [ 13] 0x7a0f0a0 ~DeletedNode , The ~DeletedNode become end nodes of section nodes; in this case m_nSectDiff != 0. Don't skip these end nodes because in the above "Untitled 1.odt" example, they are not necessarily consecutive. Between the 1st and 2nd one a new SwSectionFrame must be created via the outer section, so adapt InsertCnt_() to check for extra end nodes in the range and do this. (regression from 723728cd358693b8f4bc9d913541aa4479f2bd48) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94883 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@cib.de> (cherry picked from commit ca8e04f1ab739e14288ab5e0be44723536b9ca4e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94963 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit 9c84242dcee576147e520624641b208e874e908c) Change-Id: I7bfba9efca1789392495ebec37eb3e5b6138bd07 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95365 Tested-by: Thorsten Behrens <Thorsten.Behrens@CIB.de> Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rw-r--r--sw/qa/extras/uiwriter/data2/tdf132236.odtbin0 -> 10140 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter2.cxx26
-rw-r--r--sw/source/core/layout/frmtool.cxx23
-rw-r--r--sw/source/core/layout/layhelp.hxx1
-rw-r--r--sw/source/core/undo/undel.cxx1
5 files changed, 48 insertions, 3 deletions
diff --git a/sw/qa/extras/uiwriter/data2/tdf132236.odt b/sw/qa/extras/uiwriter/data2/tdf132236.odt
new file mode 100644
index 000000000000..f37c9befc095
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data2/tdf132236.odt
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index bf6cd3bc39f8..237405f1e6fb 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -32,6 +32,7 @@ public:
void testRedlineInHiddenSection();
void testTdf101534();
void testTdf131684();
+ void testTdf132236();
void testTdf109376();
CPPUNIT_TEST_SUITE(SwUiWriterTest2);
@@ -39,6 +40,7 @@ public:
CPPUNIT_TEST(testRedlineInHiddenSection);
CPPUNIT_TEST(testTdf101534);
CPPUNIT_TEST(testTdf131684);
+ CPPUNIT_TEST(testTdf132236);
CPPUNIT_TEST(testTdf109376);
CPPUNIT_TEST_SUITE_END();
@@ -237,6 +239,30 @@ void SwUiWriterTest2::testRedlineInHiddenSection()
CPPUNIT_ASSERT(pNode->GetNodes()[pNode->GetIndex() + 4]->IsEndNode());
}
+void SwUiWriterTest2::testTdf132236()
+{
+ load(DATA_DIRECTORY, "tdf132236.odt");
+
+ SwXTextDocument* const pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+
+ // select everything and delete
+ SwWrtShell* const pWrtShell(pTextDoc->GetDocShell()->GetWrtShell());
+ pWrtShell->Down(true);
+ pWrtShell->Down(true);
+ pWrtShell->Down(true);
+ pWrtShell->Delete();
+ SwDoc* const pDoc(pWrtShell->GetDoc());
+ sw::UndoManager& rUndoManager(pDoc->GetUndoManager());
+ rUndoManager.Undo();
+
+ // check that the text frames exist inside their sections
+ xmlDocPtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt", 1);
+ assertXPath(pXmlDoc, "/root/page[1]/body/section[2]/txt", 2);
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
+}
+
void SwUiWriterTest2::testTdf109376()
{
SwDoc* pDoc = createDoc();
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index 9e8ee48a4b72..c427fed767d0 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -1414,7 +1414,23 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
if( ( !pLay->IsInFootnote() || pSct->IsInFootnote() ) &&
( !pLay->IsInTab() || pSct->IsInTab() ) )
{
- pActualSection = new SwActualSection( nullptr, pSct, nullptr );
+ pActualSection = new SwActualSection(nullptr, pSct, pSct->GetSection()->GetFormat()->GetSectionNode());
+ // tdf#132236 for SwUndoDelete: find outer sections whose start
+ // nodes aren't contained in the range but whose end nodes are,
+ // because section frames may need to be created for them
+ SwActualSection * pUpperSection(pActualSection);
+ while (pUpperSection->GetSectionNode()->EndOfSectionIndex() < nEndIndex)
+ {
+ SwStartNode *const pStart(pUpperSection->GetSectionNode()->StartOfSectionNode());
+ if (!pStart->IsSectionNode())
+ {
+ break;
+ }
+ // note: these don't have a section frame, check it in EndNode case!
+ auto const pTmp(new SwActualSection(nullptr, nullptr, static_cast<SwSectionNode*>(pStart)));
+ pUpperSection->SetUpper(pTmp);
+ pUpperSection = pTmp;
+ }
OSL_ENSURE( !pLay->Lower() || !pLay->Lower()->IsColumnFrame(),
"InsertCnt_: Wrong Call" );
}
@@ -1734,7 +1750,7 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
SwSectionFrame* pOuterSectionFrame = pActualSection->GetSectionFrame();
// a follow has to be appended to the new section frame
- SwSectionFrame* pFollow = pOuterSectionFrame->GetFollow();
+ SwSectionFrame* pFollow = pOuterSectionFrame ? pOuterSectionFrame->GetFollow() : nullptr;
if ( pFollow )
{
pOuterSectionFrame->SetFollow( nullptr );
@@ -1743,7 +1759,8 @@ void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
}
// We don't want to leave empty parts back.
- if( ! pOuterSectionFrame->IsColLocked() &&
+ if (pOuterSectionFrame &&
+ ! pOuterSectionFrame->IsColLocked() &&
! pOuterSectionFrame->ContainsContent() )
{
pOuterSectionFrame->DelEmpty( true );
diff --git a/sw/source/core/layout/layhelp.hxx b/sw/source/core/layout/layhelp.hxx
index 01ad81845417..acf0d5152c77 100644
--- a/sw/source/core/layout/layhelp.hxx
+++ b/sw/source/core/layout/layhelp.hxx
@@ -92,6 +92,7 @@ public:
SwSectionFrame *GetSectionFrame() { return pSectFrame; }
void SetSectionFrame( SwSectionFrame *p ) { pSectFrame = p; }
SwSectionNode *GetSectionNode() { return pSectNode;}
+ void SetUpper(SwActualSection *p) { pUpper = p; }
SwActualSection *GetUpper() { return pUpper; }
};
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index ada018e207be..68230663d3af 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -1099,6 +1099,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
// tdf#121031 if the start node is a text node, it already has a frame;
// if it's a table, it does not
// tdf#109376 exception: end on non-text-node -> start node was inserted
+ assert(!m_bDelFullPara || (m_nSectDiff == 0));
SwNodeIndex const start(rDoc.GetNodes(), nSttNode +
((m_bDelFullPara || !rDoc.GetNodes()[nSttNode]->IsTextNode() || pInsNd)
? 0 : 1));