summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2013-09-04 16:08:49 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2013-09-04 16:44:51 +0200
commit330b860205c7ba69dd6603f65324d0f89ad9cd5f (patch)
tree39f845453bbf0c1cb6d2b7f0d7f95860b1a3f226
parentdc86610d16a561ff1a0455d5fef157431f9271e3 (diff)
fdo#68787 DOCX import: handle when w:separator is missing for footnotes
There were two problems here: 1) OOXML has no way to explicitly disable the footnote separator, what is does is that it omits the <w:separator/> element in that case. We didn't parse that previously -- now we do, and if it's missing, the separator is disabled. 2) The footnote stream isn't read by the importer, only when the main stream references the footnote one, the relevant part of it is parsed. At the moment we always parse the first (special, "separator") entry in the footnote stream, that may be optimized later if it becomes a bottleneck. Change-Id: Ie588270a212fc90fc41095029a362cfd832b24f8
-rw-r--r--sw/qa/extras/ooxmlimport/data/fdo68787.docxbin0 -> 14436 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx9
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx16
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx4
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx6
-rw-r--r--writerfilter/source/dmapper/PropertyIds.cxx1
-rw-r--r--writerfilter/source/dmapper/PropertyIds.hxx1
-rw-r--r--writerfilter/source/dmapper/PropertyMap.cxx3
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx15
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.hxx3
-rw-r--r--writerfilter/source/ooxml/model.xml2
11 files changed, 56 insertions, 4 deletions
diff --git a/sw/qa/extras/ooxmlimport/data/fdo68787.docx b/sw/qa/extras/ooxmlimport/data/fdo68787.docx
new file mode 100644
index 000000000000..c47b80995848
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/fdo68787.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 973f3b193db5..bfae9a30da3c 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -131,6 +131,7 @@ public:
void testTableStyleParprop();
void testTablePagebreak();
void testFdo68607();
+ void testFdo68787();
CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT)
@@ -228,6 +229,7 @@ void Test::run()
{"table-style-parprop.docx", &Test::testTableStyleParprop},
{"table-pagebreak.docx", &Test::testTablePagebreak},
{"fdo68607.docx", &Test::testFdo68607},
+ {"fdo68787.docx", &Test::testFdo68787},
};
header();
for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1540,6 +1542,13 @@ void Test::testFdo68607()
CPPUNIT_ASSERT(getPages() > 1);
}
+void Test::testFdo68787()
+{
+ uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName(DEFAULT_STYLE), uno::UNO_QUERY);
+ // This was 25, the 'lack of w:separator' <-> '0 line width' mapping was missing.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPageStyle, "FootnoteLineRelativeWidth"));
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 261d99cee165..0dc46675992f 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1465,6 +1465,11 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
if (pSectionContext != NULL)
pSectionContext->SetPageNumber(nIntValue);
break;
+ case NS_ooxml::LN_CT_FtnEdn_type:
+ // This is the "separator" footnote, ignore its linebreak.
+ if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_separator)
+ m_pImpl->m_bIgnoreNextPara = true;
+ break;
default:
{
#if OSL_DEBUG_LEVEL > 0
@@ -3728,6 +3733,12 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
m_pImpl->m_pSdtHelper->createDateControl(sText);
return;
}
+ else if (len == 1 && sText[0] == 0x03)
+ {
+ // This is the uFtnEdnSep, remember that the document has a separator.
+ m_pImpl->m_bHasFtnSep = true;
+ return;
+ }
try
{
@@ -3735,6 +3746,11 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
if(len == 1 && (sText[0] == 0x0d || sText[0] == 0x07))
{
+ if (m_pImpl->m_bIgnoreNextPara)
+ {
+ m_pImpl->m_bIgnoreNextPara = false;
+ return;
+ }
PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH);
if (pContext && m_pImpl->GetSettingsTable()->GetSplitPgBreakAndParaMark())
{
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 8a4b252a33e1..c89fdf2d1f58 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -175,7 +175,9 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bIsNewDoc(bIsNewDoc),
m_bInTableStyleRunProps(false),
m_pSdtHelper(0),
- m_nTableDepth(0)
+ m_nTableDepth(0),
+ m_bHasFtnSep(false),
+ m_bIgnoreNextPara(false)
{
appendTableManager( );
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 9b1ebe120432..0da21a0878c7 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -701,6 +701,12 @@ public:
* PFInTable SPRM or not).
*/
sal_Int32 m_nTableDepth;
+
+ /// If the document has a footnote separator.
+ bool m_bHasFtnSep;
+
+ /// If the next newline should be ignored, used by the special footnote separator paragraph.
+ bool m_bIgnoreNextPara;
};
} //namespace dmapper
} //namespace writerfilter
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index 34a00174513e..27ebabc0a8d7 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -331,6 +331,7 @@ const OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const
case PROP_MIRROR_INDENTS : sName = "MirrorIndents"; break;
case PROP_SURROUND_TEXT_WRAP_SMALL: sName = "SurroundTextWrapSmall"; break;
case PROP_PARA_SHADOW_FORMAT: sName = "ParaShadowFormat"; break;
+ case PROP_FOOTNOTE_LINE_RELATIVE_WIDTH: sName = "FootnoteLineRelativeWidth"; break;
}
::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt =
m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName ));
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index de53e7d70160..f35cdfdc0f00 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -302,6 +302,7 @@ enum PropertyIds
,PROP_MIRROR_INDENTS
,PROP_SURROUND_TEXT_WRAP_SMALL
,PROP_PARA_SHADOW_FORMAT
+ ,PROP_FOOTNOTE_LINE_RELATIVE_WIDTH
};
struct PropertyNameSupplier_Impl;
class PropertyNameSupplier
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index d4cbbf2d89cb..91ab0147c22c 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -864,6 +864,9 @@ void SectionPropertyMap::HandleMarginsHeaderFooter(DomainMapper_Impl& rDM_Impl)
if (rDM_Impl.m_oBackgroundColor)
operator[](PropertyDefinition(PROP_BACK_COLOR )) = uno::makeAny(*rDM_Impl.m_oBackgroundColor);
+ if (!rDM_Impl.m_bHasFtnSep)
+ // Set footnote line width to zero, document has no footnote separator.
+ operator[](PropertyDefinition(PROP_FOOTNOTE_LINE_RELATIVE_WIDTH)) = uno::makeAny(sal_Int32(0));
/*** if headers/footers are available then the top/bottom margins of the
header/footer are copied to the top/bottom margin of the page
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 88456239f0be..e3962f526edd 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -1748,7 +1748,7 @@ void OOXMLFastContextHandlerTable::newPropertySet
OOXMLFastContextHandlerXNote::OOXMLFastContextHandlerXNote
(OOXMLFastContextHandler * pContext)
-: OOXMLFastContextHandlerProperties(pContext), mbForwardEventsSaved(false)
+: OOXMLFastContextHandlerProperties(pContext), mbForwardEventsSaved(false), mnMyXNoteType(0)
{
}
@@ -1763,7 +1763,8 @@ void OOXMLFastContextHandlerXNote::lcl_startFastElement
{
mbForwardEventsSaved = isForwardEvents();
- if (mnMyXNoteId == getXNoteId())
+ // If this is the note we're looking for or this is the footnote separator one.
+ if (mnMyXNoteId == getXNoteId() || static_cast<sal_uInt32>(mnMyXNoteType) == NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_separator)
setForwardEvents(true);
else
setForwardEvents(false);
@@ -1794,6 +1795,16 @@ void OOXMLFastContextHandlerXNote::checkId(OOXMLValue::Pointer_t pValue)
mnMyXNoteId = sal_Int32(pValue->getInt());
}
+void OOXMLFastContextHandlerXNote::checkType(OOXMLValue::Pointer_t pValue)
+{
+#ifdef DEBUG_ELEMENT
+ debug_logger->startElement("checkType");
+ debug_logger->attribute("myType", sal_Int32(pValue->getInt()));
+ debug_logger->endElement();
+#endif
+ mnMyXNoteType = pValue->getInt();
+}
+
/*
class OOXMLFastContextHandlerTextTableCell
*/
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index 5a72be269f93..d26dcda7b482 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -432,11 +432,14 @@ public:
void checkId(OOXMLValue::Pointer_t pValue);
+ void checkType(OOXMLValue::Pointer_t pValue);
+
virtual string getType() const { return "XNote"; }
private:
bool mbForwardEventsSaved;
sal_Int32 mnMyXNoteId;
+ sal_Int32 mnMyXNoteType;
virtual void lcl_startFastElement
(Token_t Element,
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 63c182cab969..3f0ed5aa7c45 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -23120,7 +23120,7 @@
<attribute name="id" tokenid="ooxml:CT_FtnEdnSepRef_id"/>
</resource>
<resource name="CT_FtnEdn" resource="XNote" tag="reference">
- <attribute name="type" tokenid="ooxml:CT_FtnEdn_type"/>
+ <attribute name="type" tokenid="ooxml:CT_FtnEdn_type" action="checkType"/>
<attribute name="id" tokenid="ooxml:CT_FtnEdn_id" action="checkId"/>
<action name="start" action="propagateCharacterProperties"/>
<action name="end" action="endSectionGroup"/>