summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2024-01-31 14:33:46 +0100
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2024-02-01 12:43:49 +0100
commitae3f45e39b59583a60a751dcb54889f1ee28197b (patch)
tree6242eecb7fbfce27477d2a0b6091e34d9a48d6fd
parent0d66c56d48476efdf8d9d9d9549f59cdad5cb25d (diff)
tdf#158586 writerfilter: RTF import: fix \page \sect \skbnone w/ header
The problem was not fixed yet for the less-minimized bugzilla attachment where the sections contain headers and footers. What happened there is that first \page caused a deferred page break, then \sect and sectBreak() delayed-read the header substream and the \par in the header resets all the deferred break flags. Add the deferred break to an already existing Context class, and remove the direct members in DomainMapper_Impl in favor of always using the m_StreamStateStack. Probably this problem cannot occur for DOCX import, because it imports header/footer eagerly where the reference element is, and sectPr is before any runs that contain breaks in the same paragraph element. Change-Id: Iba971955e9cf0c398d416518e72d99307d3e1cfd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162833 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> (cherry picked from commit 17e2c7226a73675d69febf0915aaeae61ad8e9f1) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162848 Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r--sw/qa/extras/rtfexport/data/tdf158586_pageBreak1_header.rtf17
-rw-r--r--sw/qa/extras/rtfexport/rtfexport8.cxx13
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx9
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx105
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx41
-rw-r--r--writerfilter/source/dmapper/SdtHelper.cxx2
6 files changed, 105 insertions, 82 deletions
diff --git a/sw/qa/extras/rtfexport/data/tdf158586_pageBreak1_header.rtf b/sw/qa/extras/rtfexport/data/tdf158586_pageBreak1_header.rtf
new file mode 100644
index 000000000000..cd8eefabb276
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf158586_pageBreak1_header.rtf
@@ -0,0 +1,17 @@
+{\rtf1
+
+\paperw8419\paperh5953
+
+\spltpgpar
+
+\ltrpar \sectd
+
+{\headerl \pard\plain \par}
+
+\pard\plain \wrapdefault\pvmrg\posxl\absw0\absh0\phcol \posyil\abslock\dxfrtext10
+
+\page \sect \sectd \sbknone
+
+\pard\plain Second page
+\par
+}
diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx
index 70dd0974c616..d0b2ed0f2c2e 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -82,6 +82,19 @@ DECLARE_RTFEXPORT_TEST(testTdf158586_1, "tdf158586_pageBreak1.rtf")
assertXPathContent(pLayout, "/root/page[2]/body//txt", "Second page");
}
+DECLARE_RTFEXPORT_TEST(testTdf158586_1header, "tdf158586_pageBreak1_header.rtf")
+{
+ // None of the specified text frame settings initiates a real text frame - page break not lost
+ CPPUNIT_ASSERT_EQUAL(2, getPages());
+ CPPUNIT_ASSERT_EQUAL(2, getParagraphs());
+
+ // There should be no empty carriage return at the start of the second page
+ const auto& pLayout = parseLayoutDump();
+ // on import there is a section on page 2; on reimport there is no section
+ // (probably not an important difference?)
+ assertXPathContent(pLayout, "/root/page[2]/body//txt", "Second page");
+}
+
DECLARE_RTFEXPORT_TEST(testTdf158586_lostFrame, "tdf158586_lostFrame.rtf")
{
// The anchor and align properties are sufficient to define a frame
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 4ca1900ee173..c4001cf0fe61 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3257,7 +3257,8 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
* section is a table. So in case first element is a table add a dummy para
* and remove it again when lcl_endSectionGroup is called
*/
- if(m_pImpl->m_nTableDepth == 0 && m_pImpl->GetIsFirstParagraphInSection()
+ if (m_pImpl->m_StreamStateStack.top().nTableDepth == 0
+ && m_pImpl->GetIsFirstParagraphInSection()
&& !m_pImpl->GetIsDummyParaAddedForTableInSection() && !m_pImpl->GetIsTextFrameInserted()
&& !m_pImpl->GetIsPreviousParagraphFramed() && !IsInHeaderFooter())
{
@@ -3265,7 +3266,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
}
// if first paragraph style in table has break-before-page, transfer that setting to the table itself.
- if( m_pImpl->m_nTableDepth == 0 )
+ if (m_pImpl->m_StreamStateStack.top().nTableDepth == 0)
{
const uno::Any aBreakType(style::BreakType_PAGE_BEFORE);
const PropertyMapPtr pParagraphProps = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
@@ -3286,11 +3287,11 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
}
}
- m_pImpl->m_nTableDepth++;
+ m_pImpl->m_StreamStateStack.top().nTableDepth++;
}
break;
case NS_ooxml::LN_tblEnd:
- m_pImpl->m_nTableDepth--;
+ m_pImpl->m_StreamStateStack.top().nTableDepth--;
break;
case NS_ooxml::LN_tcStart:
m_pImpl->m_nTableCellDepth++;
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index d4da6625be61..2461c62b023b 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -339,9 +339,6 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bSetCitation( false ),
m_bSetDateValue( false ),
m_bIsFirstSection( true ),
- m_bIsColumnBreakDeferred( false ),
- m_bIsPageBreakDeferred( false ),
- m_nLineBreaksDeferred( 0 ),
m_bSdtEndDeferred(false),
m_bParaSdtEndDeferred(false),
m_bStartTOC(false),
@@ -350,7 +347,6 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bStartIndex(false),
m_bStartBibliography(false),
m_nStartGenericField(0),
- m_bTextInserted(false),
m_bTextDeleted(false),
m_sCurrentPermId(0),
m_bFrameDirectionSet(false),
@@ -397,7 +393,6 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bIsNewDoc(!rMediaDesc.getUnpackedValueOrDefault("InsertMode", false)),
m_bIsAltChunk(rMediaDesc.getUnpackedValueOrDefault("AltChunkMode", false)),
m_bIsReadGlossaries(rMediaDesc.getUnpackedValueOrDefault("ReadGlossaries", false)),
- m_nTableDepth(0),
m_nTableCellDepth(0),
m_nLastTableCellParagraphDepth(0),
m_bHasFtn(false),
@@ -414,6 +409,7 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bParaWithInlineObject(false),
m_bSaxError(false)
{
+ m_StreamStateStack.emplace(); // add state for document body
m_aBaseUrl = rMediaDesc.getUnpackedValueOrDefault(
utl::MediaDescriptor::PROP_DOCUMENTBASEURL, OUString());
if (m_aBaseUrl.isEmpty()) {
@@ -453,6 +449,7 @@ DomainMapper_Impl::DomainMapper_Impl(
DomainMapper_Impl::~DomainMapper_Impl()
{
+ assert(!m_StreamStateStack.empty());
ChainTextFrames();
// Don't remove last paragraph when pasting, sw expects that empty paragraph.
if (m_bIsNewDoc)
@@ -1562,21 +1559,22 @@ ListsManager::Pointer const & DomainMapper_Impl::GetListTable()
void DomainMapper_Impl::deferBreak( BreakType deferredBreakType)
{
+ assert(!m_StreamStateStack.empty());
switch (deferredBreakType)
{
case LINE_BREAK:
- m_nLineBreaksDeferred++;
+ m_StreamStateStack.top().nLineBreaksDeferred++;
break;
case COLUMN_BREAK:
- m_bIsColumnBreakDeferred = true;
+ m_StreamStateStack.top().bIsColumnBreakDeferred = true;
break;
case PAGE_BREAK:
// See SwWW8ImplReader::HandlePageBreakChar(), page break should be
// ignored inside tables.
- if (m_nTableDepth > 0)
+ if (0 < m_StreamStateStack.top().nTableDepth)
return;
- m_bIsPageBreakDeferred = true;
+ m_StreamStateStack.top().bIsPageBreakDeferred = true;
break;
default:
return;
@@ -1585,14 +1583,15 @@ void DomainMapper_Impl::deferBreak( BreakType deferredBreakType)
bool DomainMapper_Impl::isBreakDeferred( BreakType deferredBreakType )
{
+ assert(!m_StreamStateStack.empty());
switch (deferredBreakType)
{
case LINE_BREAK:
- return m_nLineBreaksDeferred > 0;
+ return 0 < m_StreamStateStack.top().nLineBreaksDeferred;
case COLUMN_BREAK:
- return m_bIsColumnBreakDeferred;
+ return m_StreamStateStack.top().bIsColumnBreakDeferred;
case PAGE_BREAK:
- return m_bIsPageBreakDeferred;
+ return m_StreamStateStack.top().bIsPageBreakDeferred;
default:
return false;
}
@@ -1600,17 +1599,18 @@ bool DomainMapper_Impl::isBreakDeferred( BreakType deferredBreakType )
void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType)
{
+ assert(!m_StreamStateStack.empty());
switch (deferredBreakType)
{
case LINE_BREAK:
- assert(m_nLineBreaksDeferred > 0);
- m_nLineBreaksDeferred--;
+ assert(0 < m_StreamStateStack.top().nLineBreaksDeferred);
+ m_StreamStateStack.top().nLineBreaksDeferred--;
break;
case COLUMN_BREAK:
- m_bIsColumnBreakDeferred = false;
+ m_StreamStateStack.top().bIsColumnBreakDeferred = false;
break;
case PAGE_BREAK:
- m_bIsPageBreakDeferred = false;
+ m_StreamStateStack.top().bIsPageBreakDeferred = false;
break;
default:
break;
@@ -1619,9 +1619,10 @@ void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType)
void DomainMapper_Impl::clearDeferredBreaks()
{
- m_nLineBreaksDeferred = 0;
- m_bIsColumnBreakDeferred = false;
- m_bIsPageBreakDeferred = false;
+ assert(!m_StreamStateStack.empty());
+ m_StreamStateStack.top().nLineBreaksDeferred = 0;
+ m_StreamStateStack.top().bIsColumnBreakDeferred = false;
+ m_StreamStateStack.top().bIsPageBreakDeferred = false;
}
void DomainMapper_Impl::setSdtEndDeferred(bool bSdtEndDeferred)
@@ -2317,7 +2318,9 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
{
if ( GetIsFirstParagraphInShape() ||
(GetIsFirstParagraphInSection() && GetSectionContext() && GetSectionContext()->IsFirstSection()) ||
- (m_bFirstParagraphInCell && m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth) )
+ (m_bFirstParagraphInCell
+ && 0 < m_StreamStateStack.top().nTableDepth
+ && m_StreamStateStack.top().nTableDepth == m_nTableCellDepth))
{
// export requires grabbag to match top_margin, so keep them in sync
if (nBeforeAutospacing && bIsAutoSet)
@@ -2614,7 +2617,7 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
}
else if ( m_xPreviousParagraph->getPropertySetInfo()->hasPropertyByName("NumberingStyleName") &&
// don't update before tables
- (m_nTableDepth == 0 || !m_bFirstParagraphInCell))
+ (m_StreamStateStack.top().nTableDepth == 0 || !m_bFirstParagraphInCell))
{
aCurrentNumberingName = GetListStyleName(nListId);
m_xPreviousParagraph->getPropertyValue("NumberingStyleName") >>= aPreviousNumberingName;
@@ -2769,7 +2772,7 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
// tdf#77417 trim right white spaces in table cells in 2010 compatibility mode
sal_Int32 nMode = GetSettingsTable()->GetWordCompatibilityMode();
- if ( m_nTableDepth > 0 && nMode > 0 && nMode <= 14 )
+ if (0 < m_StreamStateStack.top().nTableDepth && 0 < nMode && nMode <= 14)
{
// skip new line
xCur->goLeft(1, false);
@@ -2799,7 +2802,8 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
// table style precedence and not hidden shapes anchored to hidden empty table paragraphs
if (xParaProps && !m_bIsInComments
- && (m_nTableDepth > 0 || !m_aAnchoredObjectAnchors.empty()))
+ && (0 < m_StreamStateStack.top().nTableDepth
+ || !m_aAnchoredObjectAnchors.empty()))
{
// table style has got bigger precedence than docDefault style
// collect these pending paragraph properties to process in endTable()
@@ -2809,7 +2813,7 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
uno::Reference<text::XTextCursor> xCur2 = xTextRange->getText()->createTextCursorByRange(xCur);
uno::Reference<text::XParagraphCursor> xParaCursor(xCur2, uno::UNO_QUERY_THROW);
xParaCursor->gotoStartOfParagraph(false);
- if (m_nTableDepth > 0)
+ if (0 < m_StreamStateStack.top().nTableDepth)
{
TableParagraph aPending{xParaCursor, xCur, pParaContext, xParaProps};
getTableManager().getCurrentParagraphs()->push_back(aPending);
@@ -2976,8 +2980,12 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
// don't overwrite m_bFirstParagraphInCell in table separator nodes
// and in text boxes anchored to the first paragraph of table cells
- if (m_nTableDepth > 0 && m_nTableDepth == m_nTableCellDepth && !IsInShape() && !m_bIsInComments)
+ if (0 < m_StreamStateStack.top().nTableDepth
+ && m_StreamStateStack.top().nTableDepth == m_nTableCellDepth
+ && !IsInShape() && !m_bIsInComments)
+ {
m_bFirstParagraphInCell = false;
+ }
m_bParaAutoBefore = false;
m_bParaWithInlineObject = false;
@@ -3077,7 +3085,7 @@ void DomainMapper_Impl::appendTextPortion( const OUString& rString, const Proper
SAL_WARN_IF(!xTextRange.is(), "writerfilter.dmapper", "insertTextPortion failed");
if (!xTextRange.is())
throw uno::Exception("insertTextPortion failed", nullptr);
- m_bTextInserted = true;
+ m_StreamStateStack.top().bTextInserted = true;
xTOCTextCursor->gotoRange(xTextRange->getEnd(), true);
if (m_nStartGenericField == 0)
{
@@ -3477,9 +3485,7 @@ void DomainMapper_Impl::ConvertHeaderFooterToTextFrame(bool bDynamicHeightTop, b
void DomainMapper_Impl::PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType)
{
m_bSaveParaHadField = m_bParaHadField;
- m_aHeaderFooterStack.push(HeaderFooterContext(m_bTextInserted, m_nTableDepth));
- m_bTextInserted = false;
- m_nTableDepth = 0;
+ m_StreamStateStack.emplace();
const PropertyIds ePropIsOn = bHeader? PROP_HEADER_IS_ON: PROP_FOOTER_IS_ON;
const PropertyIds ePropShared = bHeader? PROP_HEADER_IS_SHARED: PROP_FOOTER_IS_SHARED;
@@ -3598,12 +3604,8 @@ void DomainMapper_Impl::PopPageHeaderFooter()
}
m_eInHeaderFooterImport = HeaderFooterImportState::none;
- if (!m_aHeaderFooterStack.empty())
- {
- m_bTextInserted = m_aHeaderFooterStack.top().getTextInserted();
- m_nTableDepth = m_aHeaderFooterStack.top().getTableDepth();
- m_aHeaderFooterStack.pop();
- }
+ assert(!m_StreamStateStack.empty());
+ m_StreamStateStack.pop();
m_bParaHadField = m_bSaveParaHadField;
}
@@ -3728,7 +3730,7 @@ void DomainMapper_Impl::CreateRedline(uno::Reference<text::XTextRange> const& xR
}
// store frame and (possible floating) table redline data for restoring them after frame conversion
enum StoredRedlines eType;
- if (m_bIsActualParagraphFramed || m_nTableDepth > 0)
+ if (m_bIsActualParagraphFramed || 0 < m_StreamStateStack.top().nTableDepth)
eType = StoredRedlines::FRAME;
else if (IsInFootOrEndnote())
eType = IsInFootnote() ? StoredRedlines::FOOTNOTE : StoredRedlines::ENDNOTE;
@@ -4584,7 +4586,7 @@ bool DomainMapper_Impl::IsDiscardHeaderFooter() const
void DomainMapper_Impl::ClearPreviousParagraph()
{
// in table cells, set bottom auto margin of last paragraph to 0, except in paragraphs with numbering
- if ((m_nTableDepth == (m_nTableCellDepth + 1))
+ if ((m_StreamStateStack.top().nTableDepth == (m_nTableCellDepth + 1))
&& m_xPreviousParagraph.is()
&& hasTableManager() && getTableManager().isCellLastParaAfterAutospacing())
{
@@ -5591,18 +5593,6 @@ void DomainMapper_Impl::SetFieldLocked()
m_aFieldStack.back()->SetFieldLocked();
}
-HeaderFooterContext::HeaderFooterContext(bool bTextInserted, sal_Int32 nTableDepth)
- : m_bTextInserted(bTextInserted)
- , m_nTableDepth(nTableDepth)
-{
-}
-
-bool HeaderFooterContext::getTextInserted() const
-{
- return m_bTextInserted;
-}
-
-sal_Int32 HeaderFooterContext::getTableDepth() const { return m_nTableDepth; }
FieldContext::FieldContext(uno::Reference< text::XTextRange > xStart)
: m_bFieldCommandCompleted(false)
@@ -8240,7 +8230,7 @@ void DomainMapper_Impl::PopFieldContext()
}
m_bStartedTOC = false;
m_aTextAppendStack.pop();
- m_bTextInserted = false;
+ m_StreamStateStack.top().bTextInserted = false;
m_bParaChanged = true; // the paragraph must stay anyway
}
m_bStartTOC = false;
@@ -8362,9 +8352,9 @@ void DomainMapper_Impl::PopFieldContext()
{
--m_nStartGenericField;
PopFieldmark(m_aTextAppendStack, xCrsr, pContext->GetFieldId());
- if(m_bTextInserted)
+ if (m_StreamStateStack.top().bTextInserted)
{
- m_bTextInserted = false;
+ m_StreamStateStack.top().bTextInserted = false;
}
}
}
@@ -8436,8 +8426,10 @@ void DomainMapper_Impl::StartOrEndBookmark( const OUString& rId )
* iff the first element in the section is a table. If the dummy para is not added yet, then add it;
* So bookmark is not attached to the wrong paragraph.
*/
- if(hasTableManager() && getTableManager().isInCell() && m_nTableDepth == 0 && GetIsFirstParagraphInSection()
- && !GetIsDummyParaAddedForTableInSection() &&!GetIsTextFrameInserted())
+ if (hasTableManager() && getTableManager().isInCell()
+ && m_StreamStateStack.top().nTableDepth == 0
+ && GetIsFirstParagraphInSection()
+ && !GetIsDummyParaAddedForTableInSection() && !GetIsTextFrameInserted())
{
AddDummyParaForTableInSection();
}
@@ -8478,7 +8470,7 @@ void DomainMapper_Impl::StartOrEndBookmark( const OUString& rId )
// keep bookmark range, if it doesn't exceed cell boundary
uno::Reference< text::XTextRange > xStart = xCursor->getStart();
xCursor->goLeft( 1, false );
- if (m_nTableDepth == 0 || !m_bFirstParagraphInCell)
+ if (m_StreamStateStack.top().nTableDepth == 0 || !m_bFirstParagraphInCell)
xCursor->gotoRange(xStart, true );
}
uno::Reference< container::XNamed > xBkmNamed( xBookmark, uno::UNO_QUERY_THROW );
@@ -8557,7 +8549,8 @@ void DomainMapper_Impl::startOrEndPermissionRange(sal_Int32 permissinId)
* if the first element in the section is a table. If the dummy para is not added yet, then add it;
* So permission is not attached to the wrong paragraph.
*/
- if (getTableManager().isInCell() && m_nTableDepth == 0 && GetIsFirstParagraphInSection()
+ if (getTableManager().isInCell()
+ && m_StreamStateStack.top().nTableDepth == 0 && GetIsFirstParagraphInSection()
&& !GetIsDummyParaAddedForTableInSection() && !GetIsTextFrameInserted())
{
AddDummyParaForTableInSection();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 76be3e6701e3..7b6c504bc3a9 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -152,16 +152,24 @@ enum StoredRedlines
* In case some state of DomainMapper_Impl should be reset before handling the
* header/footer and should be restored once handling of header/footer is done,
* then you can use this class to do so.
+ *
+ * note: presumably more state should be moved here.
*/
-class HeaderFooterContext
+struct SubstreamContext
{
- bool m_bTextInserted;
- sal_Int32 m_nTableDepth;
-
-public:
- explicit HeaderFooterContext(bool bTextInserted, sal_Int32 nTableDepth);
- bool getTextInserted() const;
- sal_Int32 getTableDepth() const;
+ bool bTextInserted = false;
+ /**
+ * This contains the raw table depth. nTableDepth > 0 is the same as
+ * getTableManager().isInTable(), unless we're in the first paragraph of a
+ * table, or first paragraph after a table, as the table manager is only
+ * updated once we ended the paragraph (and know if the para has the
+ * inTbl SPRM or not).
+ */
+ sal_Int32 nTableDepth = 0;
+ // deferred breaks need to be saved for RTF, probably not for DOCX
+ bool bIsColumnBreakDeferred = false;
+ bool bIsPageBreakDeferred = false;
+ sal_Int32 nLineBreaksDeferred = 0;
};
/// Information about a paragraph to be finished after a field end.
@@ -465,8 +473,11 @@ private:
std::stack<TextAppendContext> m_aTextAppendStack;
std::stack<AnchoredContext> m_aAnchoredStack;
- std::stack<HeaderFooterContext> m_aHeaderFooterStack;
+public: // DomainMapper needs it
+ std::stack<SubstreamContext> m_StreamStateStack;
+private:
std::stack<std::pair<TextAppendContext, bool>> m_aHeaderFooterTextAppendStack;
+
std::deque<FieldContextPtr> m_aFieldStack;
bool m_bForceGenericFields;
/// Type of decimal symbol associated to the document language in Writer locale definition
@@ -475,9 +486,6 @@ private:
bool m_bSetCitation;
bool m_bSetDateValue;
bool m_bIsFirstSection;
- bool m_bIsColumnBreakDeferred;
- bool m_bIsPageBreakDeferred;
- sal_Int32 m_nLineBreaksDeferred;
/// If we want to set "sdt end" on the next character context.
bool m_bSdtEndDeferred;
/// If we want to set "paragraph sdt end" on the next paragraph context.
@@ -489,7 +497,6 @@ private:
bool m_bStartIndex;
bool m_bStartBibliography;
unsigned int m_nStartGenericField;
- bool m_bTextInserted;
bool m_bTextDeleted;
LineNumberSettings m_aLineNumberSettings;
@@ -1102,14 +1109,6 @@ public:
/// Document background color, applied to every page style.
std::optional<sal_Int32> m_oBackgroundColor;
- /**
- * This contains the raw table depth. m_nTableDepth > 0 is the same as
- * getTableManager().isInTable(), unless we're in the first paragraph of a
- * table, or first paragraph after a table, as the table manager is only
- * updated once we ended the paragraph (and know if the para has the
- * inTbl SPRM or not).
- */
- sal_Int32 m_nTableDepth;
/// Raw table cell depth.
sal_Int32 m_nTableCellDepth;
/// Table cell depth of the last finished paragraph.
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx
index 041802147605..8b5bf401477f 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -387,7 +387,7 @@ void SdtHelper::createDateContentControl()
// tdf#138093: Date selector reset, if placed inside table
// Modified to XOR relationship and adding dummy paragraph conditions
bool bIsInTable = (m_rDM_Impl.hasTableManager() && m_rDM_Impl.getTableManager().isInTable())
- != (m_rDM_Impl.m_nTableDepth > 0)
+ != (0 < m_rDM_Impl.m_StreamStateStack.top().nTableDepth)
&& m_rDM_Impl.GetIsDummyParaAddedForTableInSection();
if (bIsInTable)
xCrsr->goRight(1, false);