[Libreoffice-commits] core.git: sw/qa writerfilter/source
Justin Luth (via logerrit)
logerrit at kemper.freedesktop.org
Fri Dec 20 09:59:39 UTC 2019
sw/qa/extras/ooxmlexport/data/tdf123262_textFootnoteSeparators.docx |binary
sw/qa/extras/ooxmlexport/ooxmlexport5.cxx | 18 ++++++
writerfilter/source/dmapper/DomainMapper.cxx | 28 +++++++---
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 14 -----
writerfilter/source/dmapper/DomainMapper_Impl.hxx | 18 ++++--
5 files changed, 52 insertions(+), 26 deletions(-)
New commits:
commit acb9d901009d026cb48e6a8b94e6200f05110504
Author: Justin Luth <justin.luth at collabora.com>
AuthorDate: Fri Nov 29 22:10:27 2019 +0300
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Dec 20 10:58:33 2019 +0100
tdf#123262 writerfilter: completely ignore footnote separators
... except for processing enough to observe the separator exists.
For each footnote reference, the entire footnote.xml file is
parsed every time. The text in the "separator" footnote was
being added to every footnote. The normal case where this is just
a single paragraph was already handled, but this patch generalizes
everything to handle cases of actual text or multiple paragraphs.
Not every footnote has a type, so we can't depend on that to turn
ignoringText ON/OFF. Every footnote has an ID, but theoretically
the ID could be processed before or after the type, and it has
no idea which type it is. Finally, the skipped text has no idea
how many times/paragaphs it needs to skip. So a three-way
control was needed to handle on/used/off. As a safeguard, finishing
the footnote.xml parse (PopFootOrEndnote) ensures that
ignoring won't be left on in the unlikely case that
the separator is the last footnote.
Change-Id: Ia30ca8d3a36417a4691e3b2e1c978720be017030
Reviewed-on: https://gerrit.libreoffice.org/82172
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth at sil.org>
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
diff --git a/sw/qa/extras/ooxmlexport/data/tdf123262_textFootnoteSeparators.docx b/sw/qa/extras/ooxmlexport/data/tdf123262_textFootnoteSeparators.docx
new file mode 100644
index 000000000000..ceccb767e27e
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf123262_textFootnoteSeparators.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index b0f2cd7dd98c..8e394f7a445c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -526,6 +526,24 @@ DECLARE_OOXMLEXPORT_TEST(testFDO79062, "fdo79062.docx")
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Paragraph starts with W(87), not tab(9)", u'W', sFootnotePara[0] );
}
+DECLARE_OOXMLEXPORT_TEST(testTdf123262_textFootnoteSeparators, "tdf123262_textFootnoteSeparators.docx")
+{
+ //Everything easily fits on one page
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of Pages", 1, getPages() );
+
+ uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
+ uno::Reference<text::XText> xFootnoteText(xFootnotes->getByIndex(0), uno::UNO_QUERY);
+
+ // The text in the separator footnote should not be added to the footnotes
+ OUString sText = " Microsoft Office.";
+ CPPUNIT_ASSERT_EQUAL(sText, xFootnoteText->getString());
+
+ // Ensure that paragraph markers are not lost.
+ xFootnoteText.set(xFootnotes->getByIndex(1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of paragraphs in second footnote", 2, getParagraphs(xFootnoteText) );
+}
+
DECLARE_OOXMLEXPORT_TEST(testfdo79668,"fdo79668.docx")
{
// fdo#79668: Document was Crashing on DebugUtil build while Saving
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index ccbe8d8d197b..2c2d33febd8e 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1078,9 +1078,20 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
}
break;
case NS_ooxml::LN_CT_FtnEdn_type:
- // This is the "separator" footnote, ignore its linebreak.
+ // This is the "separator" footnote, ignore its linebreaks/text.
if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_doc_ST_FtnEdn_separator)
- m_pImpl->SeenFootOrEndnoteSeparator();
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::ON );
+ else
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
+ break;
+ case NS_ooxml::LN_CT_FtnEdn_id:
+ {
+ SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
+ if ( eSkip == SkipFootnoteSeparator::ON )
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
+ else if ( eSkip == SkipFootnoteSeparator::SKIPPING )
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::OFF );
+ }
break;
case NS_ooxml::LN_CT_DataBinding_prefixMappings:
m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "ooxml:CT_DataBinding_prefixMappings", sStringValue);
@@ -3383,18 +3394,19 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
if (!m_pImpl->hasTableManager())
return;
+ SkipFootnoteSeparator eSkip = m_pImpl->GetSkipFootnoteState();
+ if ( eSkip == SkipFootnoteSeparator::ON || eSkip == SkipFootnoteSeparator::SKIPPING )
+ {
+ m_pImpl->SetSkipFootnoteState( SkipFootnoteSeparator::SKIPPING );
+ return;
+ }
+
try
{
m_pImpl->getTableManager().utext(data_, len);
if (bNewLine)
{
- if (m_pImpl->m_bIgnoreNextPara)
- {
- m_pImpl->m_bIgnoreNextPara = false;
- return;
- }
-
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);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index d63e60714fa5..694bd2ec52a3 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -275,7 +275,7 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bInFootOrEndnote(false),
m_bHasFootnoteStyle(false),
m_bCheckFootnoteStyle(false),
- m_bSeenFootOrEndnoteSeparator(false),
+ m_eSkipFootnoteState(SkipFootnoteSeparator::OFF),
m_bLineNumberingSet( false ),
m_bIsInFootnoteProperties( false ),
m_bIsParaMarkerChange( false ),
@@ -307,7 +307,6 @@ DomainMapper_Impl::DomainMapper_Impl(
m_nLastTableCellParagraphDepth(0),
m_bHasFtn(false),
m_bHasFtnSep(false),
- m_bIgnoreNextPara(false),
m_bCheckFirstFootnoteTab(false),
m_bIgnoreNextTab(false),
m_bIsSplitPara(false),
@@ -2512,21 +2511,12 @@ void DomainMapper_Impl::PopFootOrEndnote()
return;
}
m_aRedlines.pop();
- m_bSeenFootOrEndnoteSeparator = false;
+ m_eSkipFootnoteState = SkipFootnoteSeparator::OFF;
m_bInFootOrEndnote = false;
m_pFootnoteContext = nullptr;
m_bFirstParagraphInCell = m_bSaveFirstParagraphInCell;
}
-void DomainMapper_Impl::SeenFootOrEndnoteSeparator()
-{
- if (!m_bSeenFootOrEndnoteSeparator)
- {
- m_bSeenFootOrEndnoteSeparator = true;
- m_bIgnoreNextPara = true;
- }
-}
-
void DomainMapper_Impl::PopAnnotation()
{
RemoveLastParagraph();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 97f7cddb7f16..f3f9f77ce1cf 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -114,6 +114,13 @@ enum BreakType
COLUMN_BREAK
};
+enum SkipFootnoteSeparator
+{
+ OFF,
+ ON,
+ SKIPPING
+};
+
/**
* Storage for state that is relevant outside a header/footer, but not inside it.
*
@@ -505,8 +512,8 @@ private:
PropertyMapPtr m_pFootnoteContext;
bool m_bHasFootnoteStyle;
bool m_bCheckFootnoteStyle;
- /// Did we get a <w:separator/> for this footnote already?
- bool m_bSeenFootOrEndnoteSeparator;
+ /// Skip paragraphs from the <w:separator/> footnote
+ SkipFootnoteSeparator m_eSkipFootnoteState;
bool m_bLineNumberingSet;
bool m_bIsInFootnoteProperties;
@@ -780,8 +787,9 @@ public:
void SetCheckFootnoteStyle(bool bVal) { m_bCheckFootnoteStyle = bVal; }
const PropertyMapPtr& GetFootnoteContext() const { return m_pFootnoteContext; }
- /// Got a <w:separator/>.
- void SeenFootOrEndnoteSeparator();
+
+ SkipFootnoteSeparator GetSkipFootnoteState() const { return m_eSkipFootnoteState; }
+ void SetSkipFootnoteState(SkipFootnoteSeparator eId) { m_eSkipFootnoteState = eId; }
void PushAnnotation();
void PopAnnotation();
@@ -991,8 +999,6 @@ public:
/// If the current section has a footnote separator.
bool m_bHasFtnSep;
- /// If the next newline should be ignored, used by the special footnote separator paragraph.
- bool m_bIgnoreNextPara;
/// If the next tab should be ignored, used for footnotes.
bool m_bCheckFirstFootnoteTab;
bool m_bIgnoreNextTab;
More information about the Libreoffice-commits
mailing list