summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2019-10-09 14:54:03 +0200
committerLászló Németh <nemeth@numbertext.org>2019-10-09 19:48:09 +0200
commit39090afac268f9ae985832c2f08863b41e6c06f2 (patch)
treed55d2659f17e9ac9233972e54789fec70df0e502
parentb8e1eebaccf65040f98c27001eb853bdc8b6a344 (diff)
tdf#120336 DOCX import: fix page break after tracked deletion
Actual text content lost its page break, when the last paragraph of the section was empty and preceded only with tracked deletion. See also commit b696600821d8aafb63b6a88016d299ef89478f56 "n#766481 dmapper: don't import fake paragraph containing sectpr only, take two" Change-Id: I6b1c47da2b618f10ca4887f050469f94efa2a7cb Reviewed-on: https://gerrit.libreoffice.org/80540 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r--sw/qa/extras/uiwriter/data2/tdf120336.docxbin0 -> 21892 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter2.cxx26
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx4
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx20
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx4
5 files changed, 48 insertions, 6 deletions
diff --git a/sw/qa/extras/uiwriter/data2/tdf120336.docx b/sw/qa/extras/uiwriter/data2/tdf120336.docx
new file mode 100644
index 000000000000..a9152bf31d07
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data2/tdf120336.docx
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 86412fd3ab24..50df467a168f 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -1719,6 +1719,32 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf125310b)
CPPUNIT_ASSERT_EQUAL(1, getPages());
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf120336)
+{
+ load(DATA_DIRECTORY, "tdf120336.docx");
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+
+ // turn on red-lining and show changes
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+ pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete
+ | RedlineFlags::ShowInsert);
+ CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+ pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+ CPPUNIT_ASSERT_MESSAGE(
+ "redlines should be visible",
+ IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
+
+ CPPUNIT_ASSERT_EQUAL(2, getPages());
+
+ IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess());
+ rIDRA.AcceptAllRedline(true);
+
+ // keep page break, as without redlining
+ CPPUNIT_ASSERT_EQUAL(2, getPages());
+}
+
CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testImageComment)
{
// Load a document with an as-char image in it.
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 3eb61085fcb2..c8c4ce04f850 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2850,6 +2850,7 @@ void DomainMapper::lcl_startSectionGroup()
m_pImpl->PushProperties(CONTEXT_SECTION);
}
m_pImpl->SetIsFirstParagraphInSection(true);
+ m_pImpl->SetIsFirstParagraphInSectionAfterRedline(true);
}
void DomainMapper::lcl_endSectionGroup()
@@ -3283,6 +3284,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
}
const bool bSingleParagraph = m_pImpl->GetIsFirstParagraphInSection() && m_pImpl->GetIsLastParagraphInSection();
+ const bool bSingleParagraphAfterRedline = m_pImpl->GetIsFirstParagraphInSection(true) && m_pImpl->GetIsLastParagraphInSection();
PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
if (pContext && !pContext->GetFootnote().is())
{
@@ -3320,7 +3322,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
// no runs, we should not create a paragraph for it in Writer, unless that would remove the whole section.
SectionPropertyMap* pSectionContext = m_pImpl->GetSectionContext();
bool bRemove = !m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr()
- && !bSingleParagraph
+ && !bSingleParagraphAfterRedline
&& !m_pImpl->GetIsDummyParaAddedForTableInSection()
&& !( pSectionContext && pSectionContext->GetBreakType() != -1 && pContext && pContext->isSet(PROP_BREAK_TYPE) )
&& !m_pImpl->GetIsPreviousParagraphFramed();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 509ca2384109..cb6eb815c49e 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -225,6 +225,7 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bIsParaMarkerChange( false ),
m_bParaChanged( false ),
m_bIsFirstParaInSection( true ),
+ m_bIsFirstParaInSectionAfterRedline( true ),
m_bDummyParaAddedForTableInSection( false ),
m_bTextFrameInserted(false),
m_bIsPreviousParagraphFramed( false ),
@@ -508,11 +509,16 @@ void DomainMapper_Impl::SetIsFirstParagraphInSection( bool bIsFirst )
m_bIsFirstParaInSection = bIsFirst;
}
-bool DomainMapper_Impl::GetIsFirstParagraphInSection() const
+void DomainMapper_Impl::SetIsFirstParagraphInSectionAfterRedline( bool bIsFirstAfterRedline )
+{
+ m_bIsFirstParaInSectionAfterRedline = bIsFirstAfterRedline;
+}
+
+bool DomainMapper_Impl::GetIsFirstParagraphInSection( bool bAfterRedline ) const
{
// Anchored objects may include multiple paragraphs,
// and none of them should be considered the first para in section.
- return m_bIsFirstParaInSection
+ return ( bAfterRedline ? m_bIsFirstParaInSectionAfterRedline : m_bIsFirstParaInSection )
&& !IsInShape()
&& !m_bIsInComments
&& !m_bInFootOrEndnote;
@@ -1596,7 +1602,6 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
// Extend the redline ranges for empty paragraphs
if ( !m_bParaChanged && m_previousRedline.get() )
CreateRedline( xCur, m_previousRedline );
- m_previousRedline.clear();
CheckParaMarkerRedline( xCur );
}
@@ -1685,8 +1690,15 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
if( !IsInHeaderFooter() && !IsInShape() && (!pParaContext || !pParaContext->IsFrameMode()) )
{ // If the paragraph is in a frame, shape or header/footer, it's not a paragraph of the section itself.
SetIsFirstParagraphInSection(false);
- SetIsLastParagraphInSection(false);
+ // count first not deleted paragraph as first paragraph in section to avoid of
+ // its deletion later, resulting loss of the associated page break
+ if (!m_previousRedline.get())
+ {
+ SetIsFirstParagraphInSectionAfterRedline(false);
+ SetIsLastParagraphInSection(false);
+ }
}
+ m_previousRedline.clear();
if (m_bIsFirstParaInShape)
m_bIsFirstParaInShape = false;
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 40ac9db86fdd..fb4fcaf03349 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -512,6 +512,7 @@ private:
/// If the current paragraph has any runs.
bool m_bParaChanged;
bool m_bIsFirstParaInSection;
+ bool m_bIsFirstParaInSectionAfterRedline;
bool m_bIsFirstParaInShape = false;
bool m_bDummyParaAddedForTableInSection;
bool m_bTextFrameInserted;
@@ -605,7 +606,8 @@ public:
void SetIsLastSectionGroup( bool bIsLast );
bool GetIsLastSectionGroup() const { return m_bIsLastSectionGroup;}
void SetIsFirstParagraphInSection( bool bIsFirst );
- bool GetIsFirstParagraphInSection() const;
+ void SetIsFirstParagraphInSectionAfterRedline( bool bIsFirstAfterRedline );
+ bool GetIsFirstParagraphInSection( bool bAfterRedline = false ) const;
void SetIsFirstParagraphInShape(bool bIsFirst);
bool GetIsFirstParagraphInShape() const { return m_bIsFirstParaInShape; }
void SetIsDummyParaAddedForTableInSection( bool bIsAdded );