Kaydet (Commit) 60974f56 authored tarafından Miklos Vajna's avatar Miklos Vajna

DOCX export: prevent multiple paragraphs in some SDT containers

E.g. Word doesn't do anything if you hit return in the middle of a
title; if that's so, then we should handle this situation on export as
well.

Change-Id: Ib5b52a59250b09c97023b53906b8046f530d0e31
üst 42faa9f0
...@@ -628,6 +628,15 @@ DECLARE_OOXMLEXPORT_TEST(testSdtHeader, "sdt-header.docx") ...@@ -628,6 +628,15 @@ DECLARE_OOXMLEXPORT_TEST(testSdtHeader, "sdt-header.docx")
assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date", 1); assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date", 1);
} }
DECLARE_OOXMLEXPORT_TEST(testSdtCompanyMultipara, "sdt-company-multipara.docx")
{
if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
{
// This was 3, but multiple paragraphs inside "Company" SDT is now allowed.
assertXPath(pXmlDoc, "//w:sdtContent/w:p", 1);
}
}
#endif #endif
CPPUNIT_PLUGIN_IMPLEMENT(); CPPUNIT_PLUGIN_IMPLEMENT();
......
...@@ -223,6 +223,12 @@ void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ ) ...@@ -223,6 +223,12 @@ void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ )
m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND ); m_pSerializer->singleElementNS( XML_w, XML_rtl, FSNS( XML_w, XML_val ), "true", FSEND );
} }
/// Are multiple paragraphs disallowed inside this type of SDT?
static bool lcl_isOnelinerSdt(const OUString& rName)
{
return rName == "Title" || rName == "Subtitle" || rName == "Company";
}
void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo ) void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
{ {
if ( m_nColBreakStatus == COLBRK_POSTPONE ) if ( m_nColBreakStatus == COLBRK_POSTPONE )
...@@ -292,12 +298,15 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText ...@@ -292,12 +298,15 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
bEndParaSdt = m_bStartedParaSdt && rMap.find("ParaSdtEndBefore") != rMap.end(); bEndParaSdt = m_bStartedParaSdt && rMap.find("ParaSdtEndBefore") != rMap.end();
} }
} }
if (bEndParaSdt || (m_bStartedParaSdt && m_bHadSectPr)) // TODO also avoid multiline paragarphs in those SDT types for shape text
bool bOneliner = m_bStartedParaSdt && !m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen() && lcl_isOnelinerSdt(m_aStartedParagraphSdtPrAlias);
if (bEndParaSdt || (m_bStartedParaSdt && m_bHadSectPr) || bOneliner)
{ {
// This is the common case: "close sdt before the current paragraph" was requrested by the next paragraph. // This is the common case: "close sdt before the current paragraph" was requrested by the next paragraph.
EndSdtBlock(); EndSdtBlock();
bEndParaSdt = false; bEndParaSdt = false;
m_bStartedParaSdt = false; m_bStartedParaSdt = false;
m_aStartedParagraphSdtPrAlias = "";
} }
m_bHadSectPr = false; m_bHadSectPr = false;
...@@ -7951,6 +7960,7 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem) ...@@ -7951,6 +7960,7 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
{ {
if (!(aPropertyValue.Value >>= m_aParagraphSdtPrAlias)) if (!(aPropertyValue.Value >>= m_aParagraphSdtPrAlias))
SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unexpected sdt alias value"); SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unexpected sdt alias value");
m_aStartedParagraphSdtPrAlias = m_aParagraphSdtPrAlias;
} }
else if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox") else if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
{ {
...@@ -8007,6 +8017,10 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem) ...@@ -8007,6 +8017,10 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
uno::Sequence<beans::PropertyValue> aAttributes = i->second.get< uno::Sequence<beans::PropertyValue> >(); uno::Sequence<beans::PropertyValue> aAttributes = i->second.get< uno::Sequence<beans::PropertyValue> >();
m_pTableStyleExport->CnfStyle(aAttributes); m_pTableStyleExport->CnfStyle(aAttributes);
} }
else if (i->first == "ParaSdtEndBefore")
{
// Handled already in StartParagraph().
}
else else
SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first ); SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first );
} }
......
...@@ -911,6 +911,8 @@ private: ...@@ -911,6 +911,8 @@ private:
::sax_fastparser::FastAttributeList *m_pRunSdtPrDataBindingAttrs; ::sax_fastparser::FastAttributeList *m_pRunSdtPrDataBindingAttrs;
/// Value of the <w:alias> paragraph SDT element. /// Value of the <w:alias> paragraph SDT element.
OUString m_aParagraphSdtPrAlias; OUString m_aParagraphSdtPrAlias;
/// Same as m_aParagraphSdtPrAlias, but its content is aviailable till the SDT is closed.
OUString m_aStartedParagraphSdtPrAlias;
OUString m_aRunSdtPrAlias; OUString m_aRunSdtPrAlias;
/// Currently paragraph SDT has a <w:id> child element. /// Currently paragraph SDT has a <w:id> child element.
bool m_bParagraphSdtHasId; bool m_bParagraphSdtHasId;
......
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