Kaydet (Commit) 3d1bb76e authored tarafından Miklos Vajna's avatar Miklos Vajna

tdf#112109 sw: split section frames inside table cells, ignore nested tables

Commit f8a76d21 (tdf#108524 sw: split
section frames inside table cells, non-split text frames, 2017-07-06)
added support for moving text frame masters to a next page inside
section-in-table frames. But the code in SwFrame::GetNextSctLeaf()
responsible for this is not up to nested tables, so don't try to split
sections in this case.

Otherwise we'll end up with frames which are marked as "in table", but
don't actually have have table frame parents, so we crash in
SwFrame::IsFootnoteAllowed() which assumes being in a table means a
table frame parent.

Change-Id: Iff19a4eda21a4dbfb9562dea7af8ec6767d47873
Reviewed-on: https://gerrit.libreoffice.org/41748Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
üst 98552e46
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
<office:font-face-decls>
<style:font-face style:name="OpenSymbol" svg:font-family="OpenSymbol"/>
<style:font-face style:name="Tahoma1" svg:font-family="Tahoma"/>
<style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="system"/>
<style:font-face style:name="Liberation Sans" svg:font-family="Liberation Sans" style:font-adornments="Regular" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="AR PL SungtiL GB" svg:font-family="&apos;AR PL SungtiL GB&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Lucida Sans" svg:font-family="&apos;Lucida Sans&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="MS Mincho" svg:font-family="&apos;MS Mincho&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
</office:font-face-decls>
<office:styles>
<style:default-style style:family="paragraph">
<style:paragraph-properties fo:line-height="0.559cm" fo:text-align="justify" style:justify-single-word="false" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
<style:text-properties style:use-window-font-color="true" style:font-name="Liberation Sans" fo:font-size="10pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="AR PL SungtiL GB" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
</style:default-style>
<style:default-style style:family="table">
<style:table-properties table:border-model="collapsing"/>
</style:default-style>
<style:default-style style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text">
<style:text-properties fo:language="en" fo:country="GB"/>
</style:style>
</office:styles>
<office:automatic-styles>
<style:style style:name="Table1" style:family="table">
<style:table-properties style:width="16.662cm" table:align="margins"/>
</style:style>
<style:style style:name="Table1.A" style:family="table-column">
<style:table-column-properties style:column-width="16.662cm" style:rel-column-width="65535*"/>
</style:style>
<style:style style:name="Table1.1" style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:style>
<style:style style:name="Table1.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table1.A2" style:family="table-cell">
<style:table-cell-properties fo:padding="0cm"/>
</style:style>
<style:style style:name="Table2" style:family="table">
<style:table-properties style:width="16.623cm" fo:margin-left="0cm" fo:margin-right="0.039cm" table:align="margins"/>
</style:style>
<style:style style:name="Table2.A" style:family="table-column">
<style:table-column-properties style:column-width="7.664cm" style:rel-column-width="30218*"/>
</style:style>
<style:style style:name="Table2.B" style:family="table-column">
<style:table-column-properties style:column-width="3.669cm" style:rel-column-width="14461*"/>
</style:style>
<style:style style:name="Table2.C" style:family="table-column">
<style:table-column-properties style:column-width="2.096cm" style:rel-column-width="8260*"/>
</style:style>
<style:style style:name="Table2.D" style:family="table-column">
<style:table-column-properties style:column-width="3.194cm" style:rel-column-width="12596*"/>
</style:style>
<style:style style:name="Table2.1" style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:style>
<style:style style:name="Table2.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm"/>
</style:style>
<style:style style:name="Table2.D1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm"/>
</style:style>
<style:style style:name="Table2.A2" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm"/>
</style:style>
<style:style style:name="Table2.D2" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm"/>
</style:style>
<style:style style:name="P1" style:family="paragraph" style:master-page-name="PG_5f_Default">
<style:paragraph-properties style:page-number="auto"/>
</style:style>
<style:page-layout style:name="pm1">
<style:page-layout-properties fo:page-width="21.001cm" fo:page-height="9.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="0.4cm" fo:margin-bottom="0.499cm" fo:margin-left="2.54cm" fo:margin-right="1.799cm" fo:border="none" fo:padding="0cm" style:shadow="none" style:writing-mode="lr-tb" style:footnote-max-height="0cm">
<style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="none" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
</style:page-layout-properties>
<style:header-style/>
<style:footer-style/>
</style:page-layout>
</office:automatic-styles>
<office:master-styles>
<style:master-page style:name="PG_5f_Default" style:display-name="PG_Default" style:page-layout-name="pm1"/>
</office:master-styles>
<office:body>
<office:text text:use-soft-page-breaks="true">
<text:p text:style-name="P1"/>
<text:p/>
<text:p/>
<text:p/>
<text:p/>
<text:p/>
<text:p/>
<text:p/>
<text:p/>
<text:p/>
<text:p/>
<table:table table:name="Table1" table:style-name="Table1">
<table:table-column table:style-name="Table1.A"/>
<table:table-row table:style-name="Table1.1">
<table:table-cell table:style-name="Table1.A1" office:value-type="string">
<text:p>Table1.A1</text:p>
</table:table-cell>
</table:table-row>
<text:soft-page-break/>
<table:table-row table:style-name="Table1.1">
<table:table-cell table:style-name="Table1.A2" office:value-type="string">
<table:table table:name="Table2" table:style-name="Table2">
<table:table-column table:style-name="Table2.A"/>
<table:table-column table:style-name="Table2.B"/>
<table:table-column table:style-name="Table2.C"/>
<table:table-column table:style-name="Table2.D"/>
<table:table-row table:style-name="Table2.1">
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:section text:name="Section1">
<text:p>Table2.A1, para 1</text:p>
<text:p>Table2.A1, para 2</text:p>
</text:section>
</table:table-cell>
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:section text:name="Section2">
<text:p>Table2.B1</text:p>
</text:section>
</table:table-cell>
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:section text:name="Section3">
<text:p>Table2.C1</text:p>
</text:section>
</table:table-cell>
<table:table-cell table:style-name="Table2.D1" office:value-type="string">
<text:section text:name="Section4">
<text:p>Table2.D1</text:p>
</text:section>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table2.1">
<table:table-cell table:style-name="Table2.A2" office:value-type="string">
<text:section text:name="Section5">
<text:p>Table2.A2</text:p>
</text:section>
</table:table-cell>
<table:table-cell table:style-name="Table2.A2" office:value-type="string">
<text:section text:name="Section6">
<text:p>Table2.B2</text:p>
</text:section>
</table:table-cell>
<table:table-cell table:style-name="Table2.A2" office:value-type="string">
<text:section text:name="Section7">
<text:p>Table2.C2</text:p>
</text:section>
</table:table-cell>
<table:table-cell table:style-name="Table2.D2" office:value-type="string">
<text:section text:name="Section8">
<text:p>Table2.D2</text:p>
</text:section>
</table:table-cell>
</table:table-row>
</table:table>
<text:p/>
</table:table-cell>
</table:table-row>
</table:table>
<text:p/>
</office:text>
</office:body>
</office:document>
...@@ -265,6 +265,7 @@ public: ...@@ -265,6 +265,7 @@ public:
void testTableInSection(); void testTableInSection();
void testTableInNestedSection(); void testTableInNestedSection();
void testTableInSectionInTable(); void testTableInSectionInTable();
void testSectionInTableInTable();
void testLinesMoveBackwardsInSectionInTable(); void testLinesMoveBackwardsInSectionInTable();
#endif #endif
void testLinesInSectionInTable(); void testLinesInSectionInTable();
...@@ -417,6 +418,7 @@ public: ...@@ -417,6 +418,7 @@ public:
CPPUNIT_TEST(testTableInSection); CPPUNIT_TEST(testTableInSection);
CPPUNIT_TEST(testTableInNestedSection); CPPUNIT_TEST(testTableInNestedSection);
CPPUNIT_TEST(testTableInSectionInTable); CPPUNIT_TEST(testTableInSectionInTable);
CPPUNIT_TEST(testSectionInTableInTable);
CPPUNIT_TEST(testLinesMoveBackwardsInSectionInTable); CPPUNIT_TEST(testLinesMoveBackwardsInSectionInTable);
#endif #endif
CPPUNIT_TEST(testLinesInSectionInTable); CPPUNIT_TEST(testLinesInSectionInTable);
...@@ -5154,6 +5156,14 @@ void SwUiWriterTest::testTableInSectionInTable() ...@@ -5154,6 +5156,14 @@ void SwUiWriterTest::testTableInSectionInTable()
// This crashed the layout. // This crashed the layout.
createDoc("i95698.odt"); createDoc("i95698.odt");
} }
void SwUiWriterTest::testSectionInTableInTable()
{
// The document has a nested table, containing a multi-line section at a
// page boundary.
// This crashed the layout later in SwFrame::IsFootnoteAllowed().
createDoc("tdf112109.fodt");
}
#endif #endif
void SwUiWriterTest::testParagraphOfTextRange() void SwUiWriterTest::testParagraphOfTextRange()
......
...@@ -590,7 +590,7 @@ namespace ...@@ -590,7 +590,7 @@ namespace
} }
/// Checks if pFrame is in a table, which itself is in a section. /// Checks if pFrame is in a table, which itself is in a section.
bool IsInTableInSection(const SwFrame* pFrame) bool IsFrameInTableInSection(const SwFrame* pFrame)
{ {
if (!pFrame->IsInTab()) if (!pFrame->IsInTab())
return false; return false;
...@@ -598,6 +598,26 @@ namespace ...@@ -598,6 +598,26 @@ namespace
// The frame is in a table, see if the table is in a section. // The frame is in a table, see if the table is in a section.
return pFrame->FindTabFrame()->IsInSct(); return pFrame->FindTabFrame()->IsInSct();
} }
/// Checks if pFrame is in a table, which itself is in a table.
bool IsFrameInTableInTable(const SwFrame* pFrame)
{
if (!pFrame->IsInTab())
return false;
// The frame is in a table, see if the inner table is in an outer
// table.
bool bNested = false;
if (const SwFrame* pUpper = pFrame->FindTabFrame()->GetUpper())
bNested = pUpper->IsInTab();
return bNested;
}
/// Checks if pFrame has a parent that can contain a split section frame.
bool CanContainSplitSection(const SwFrame* pFrame)
{
return !IsFrameInTableInSection(pFrame) && !IsFrameInTableInTable(pFrame);
}
} }
void SwSectionFrame::MoveContentAndDelete( SwSectionFrame* pDel, bool bSave ) void SwSectionFrame::MoveContentAndDelete( SwSectionFrame* pDel, bool bSave )
...@@ -1452,7 +1472,7 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) ...@@ -1452,7 +1472,7 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetUpper()->GetNext())->Lower()); return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetUpper()->GetNext())->Lower());
// Inside a table-in-section, or sections of headers/footers, there can be only // Inside a table-in-section, or sections of headers/footers, there can be only
// one column shift be made, one of the above shortcuts should have applied! // one column shift be made, one of the above shortcuts should have applied!
if( IsInTableInSection(GetUpper()) || FindFooterOrHeader() ) if( !CanContainSplitSection(GetUpper()) || FindFooterOrHeader() )
return nullptr; return nullptr;
SwSectionFrame *pSect = FindSctFrame(); SwSectionFrame *pSect = FindSctFrame();
...@@ -1515,7 +1535,7 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) ...@@ -1515,7 +1535,7 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
SwLayoutFrame *pLayLeaf; SwLayoutFrame *pLayLeaf;
SwLayoutFrame* pCellLeaf = nullptr; SwLayoutFrame* pCellLeaf = nullptr;
if (IsInTab() && !IsInTableInSection(this)) if (IsInTab() && CanContainSplitSection(this))
{ {
// We are in a table (which is itself not in a section), see if there // We are in a table (which is itself not in a section), see if there
// is a follow cell frame created already. // is a follow cell frame created already.
...@@ -1535,7 +1555,7 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage ) ...@@ -1535,7 +1555,7 @@ SwLayoutFrame *SwFrame::GetNextSctLeaf( MakePageType eMakePage )
SwContentFrame* pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContent(); SwContentFrame* pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContent();
pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr; pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr;
} }
else if (pCellLeaf && !IsInTableInSection(this)) else if (pCellLeaf && CanContainSplitSection(this))
{ {
// This frame is in a table-not-in-section, its follow should be // This frame is in a table-not-in-section, its follow should be
// inserted under the follow of the frame's cell. // inserted under the follow of the frame's cell.
...@@ -1727,7 +1747,7 @@ SwLayoutFrame *SwFrame::GetPrevSctLeaf() ...@@ -1727,7 +1747,7 @@ SwLayoutFrame *SwFrame::GetPrevSctLeaf()
SwFlowFrame::SetMoveBwdJump( true ); SwFlowFrame::SetMoveBwdJump( true );
SwSectionFrame *pSect = FindSctFrame(); SwSectionFrame *pSect = FindSctFrame();
if (!pCol && pSect && IsInTab() && !IsInTableInSection(this)) if (!pCol && pSect && IsInTab() && CanContainSplitSection(this))
{ {
// We don't have a previous section yet, and we're in a // We don't have a previous section yet, and we're in a
// section-in-table. // section-in-table.
...@@ -2172,8 +2192,8 @@ bool SwSectionFrame::MoveAllowed( const SwFrame* pFrame) const ...@@ -2172,8 +2192,8 @@ bool SwSectionFrame::MoveAllowed( const SwFrame* pFrame) const
return false; return false;
// Now it has to be examined whether there is a layout sheet wherein // Now it has to be examined whether there is a layout sheet wherein
// a section Follow can be created // a section Follow can be created
if( IsInTableInSection(this) || ( !IsInDocBody() && FindFooterOrHeader() ) ) if( !CanContainSplitSection(this) || ( !IsInDocBody() && FindFooterOrHeader() ) )
return false; // It doesn't work in table-in-sections/headers/footers return false; // It doesn't work in table-in-sections/nested tables/headers/footers
if( IsInFly() ) // In column based or chained frames if( IsInFly() ) // In column based or chained frames
return nullptr != const_cast<SwFrame*>(static_cast<SwFrame const *>(GetUpper()))->GetNextLeaf( MAKEPAGE_NONE ); return nullptr != const_cast<SwFrame*>(static_cast<SwFrame const *>(GetUpper()))->GetNextLeaf( MAKEPAGE_NONE );
return true; return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment