summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2014-08-08 18:17:43 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-08-08 18:40:24 +0200
commitea258e380eb87db2eb468ba5354df9f957b7660f (patch)
treebb96343b27376312cce62beb1c7c29ce9d3c79d6
parent3f02b29b6573a637592f096c2d2659534b1683ab (diff)
DOCX export: handle date SDT on paragraphs
Date SDT's are normally imported as form controls, while most other SDT types are just custom properties on regular text portions or paragraphs. However, given that form controls are not supported in headers/footers, in that case even date SDT's are just custom properties. So support such properties on paragraphs in the exporter to properly roundtrip date SDT's in headers/footers. Change-Id: I19eb73a3673e387a7b8780756ce7426a1851e796
-rw-r--r--sw/qa/extras/ooxmlexport/data/sdt-header.docxbin0 -> 18551 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx8
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx54
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx2
5 files changed, 60 insertions, 6 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/sdt-header.docx b/sw/qa/extras/ooxmlexport/data/sdt-header.docx
new file mode 100644
index 000000000000..6a4bdfb2d059
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/sdt-header.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index 4c44216a17a7..be347b5134b1 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -600,6 +600,14 @@ DECLARE_OOXMLEXPORT_TEST(testfdo81946, "fdo81946.docx")
assertXPath(pXmlDoc, "/w:hdr[1]/w:p[1]/w:sdt[1]/w:sdtContent[1]/w:r[2]/mc:AlternateContent[1]",0);
}
+DECLARE_OOXMLEXPORT_TEST(testSdtHeader, "sdt-header.docx")
+{
+ // Problem was that w:sdt elements in headers were lost on import.
+ if (xmlDocPtr pXmlDoc = parseExport("word/header1.xml"))
+ // This was 0, w:sdt (and then w:date) was missing.
+ assertXPath(pXmlDoc, "//w:sdt/w:sdtPr/w:date", 1);
+}
+
#endif
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index a8bcc8903c5a..b0447cfbef2b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -549,7 +549,7 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
m_pSerializer->endElementNS( XML_w, XML_p );
// on export sdt blocks are never nested ATM
if( !m_bAnchorLinkedToNode && !m_bStartedParaSdt )
- WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs, m_aParagraphSdtPrAlias, /*bPara=*/true );
+ WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrTokenAttributes, m_pParagraphSdtPrDataBindingAttrs, m_aParagraphSdtPrAlias, /*bPara=*/true );
else
{
//These should be written out to the actual Node and not to the anchor.
@@ -591,6 +591,7 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken,
::sax_fastparser::FastAttributeList*& pSdtPrTokenChildren,
+ ::sax_fastparser::FastAttributeList*& pSdtPrTokenAttributes,
::sax_fastparser::FastAttributeList*& pSdtPrDataBindingAttrs,
OUString& rSdtPrAlias,
bool bPara )
@@ -607,7 +608,14 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken,
if( nSdtPrToken > 0 && pSdtPrTokenChildren )
{
- m_pSerializer->startElement( nSdtPrToken, FSEND );
+ if (!pSdtPrTokenAttributes)
+ m_pSerializer->startElement( nSdtPrToken, FSEND );
+ else
+ {
+ XFastAttributeListRef xAttrList(pSdtPrTokenAttributes);
+ m_pSerializer->startElement(nSdtPrToken, xAttrList);
+ pSdtPrTokenAttributes = 0;
+ }
uno::Sequence<xml::FastAttribute> aChildren = pSdtPrTokenChildren->getFastAttributes();
for( sal_Int32 i=0; i < aChildren.getLength(); ++i )
@@ -619,7 +627,16 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken,
m_pSerializer->endElement( nSdtPrToken );
}
else if( (nSdtPrToken > 0) && nSdtPrToken != FSNS( XML_w, XML_id ) && !(m_bRunTextIsOn && m_rExport.SdrExporter().IsParagraphHasDrawing()))
- m_pSerializer->singleElement( nSdtPrToken, FSEND );
+ {
+ if (!pSdtPrTokenAttributes)
+ m_pSerializer->singleElement( nSdtPrToken, FSEND );
+ else
+ {
+ XFastAttributeListRef xAttrList(pSdtPrTokenAttributes);
+ m_pSerializer->singleElement(nSdtPrToken, xAttrList);
+ pSdtPrTokenAttributes = 0;
+ }
+ }
if( nSdtPrToken == FSNS( XML_w, XML_id ) || ( bPara && m_bParagraphSdtHasId ) )
//Word won't open a document with an empty id tag, we fill it with a random number
@@ -1136,7 +1153,10 @@ void DocxAttributeOutput::EndRun()
// enclose in a sdt block, if necessary: if one is already started, then don't do it for now
// (so on export sdt blocks are never nested ATM)
if ( !m_bAnchorLinkedToNode && !m_bStartedCharSdt )
- WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs, m_aRunSdtPrAlias, /*bPara=*/false );
+ {
+ ::sax_fastparser::FastAttributeList* pRunSdtPrTokenAttributes = 0;
+ WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, pRunSdtPrTokenAttributes, m_pRunSdtPrDataBindingAttrs, m_aRunSdtPrAlias, /*bPara=*/false );
+ }
else
{
//These should be written out to the actual Node and not to the anchor.
@@ -7854,8 +7874,30 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
}
else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id")
m_bParagraphSdtHasId = true;
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_date")
+ {
+ m_nParagraphSdtPrToken = FSNS(XML_w, XML_date);
+ uno::Sequence<beans::PropertyValue> aGrabBag = aPropertyValue.Value.get< uno::Sequence<beans::PropertyValue> >();
+ for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
+ {
+ OString sValue = OUStringToOString(aGrabBag[j].Value.get<OUString>(), RTL_TEXTENCODING_UTF8);
+
+ if (aGrabBag[j].Name == "ooxml:CT_SdtDate_fullDate")
+ AddToAttrList(m_pParagraphSdtPrTokenAttributes, FSNS(XML_w, XML_fullDate), sValue.getStr());
+ else if (aGrabBag[j].Name == "ooxml:CT_SdtDate_dateFormat")
+ AddToAttrList(m_pParagraphSdtPrTokenChildren, FSNS(XML_w, XML_dateFormat), sValue.getStr());
+ else if (aGrabBag[j].Name == "ooxml:CT_SdtDate_lid")
+ AddToAttrList(m_pParagraphSdtPrTokenChildren, FSNS(XML_w, XML_lid), sValue.getStr());
+ else if (aGrabBag[j].Name == "ooxml:CT_SdtDate_storeMappedDataAs")
+ AddToAttrList(m_pParagraphSdtPrTokenChildren, FSNS(XML_w, XML_storeMappedDataAs), sValue.getStr());
+ else if (aGrabBag[j].Name == "ooxml:CT_SdtDate_calendar")
+ AddToAttrList(m_pParagraphSdtPrTokenChildren, FSNS(XML_w, XML_calendar), sValue.getStr());
+ else
+ SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled SdtPr / ooxml:CT_SdtPr_date grab bag property " << aGrabBag[j].Name);
+ }
+ }
else
- SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled SdtPr grab bag property " << aPropertyValue.Name);
+ SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled SdtPr grab bag property " << aPropertyValue.Name);
}
}
else if (i->first == "ParaCnfStyle")
@@ -8122,6 +8164,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
m_setFootnote(false)
, m_nParagraphSdtPrToken(0)
, m_pParagraphSdtPrTokenChildren(NULL)
+ , m_pParagraphSdtPrTokenAttributes(NULL)
, m_pParagraphSdtPrDataBindingAttrs(NULL)
, m_nRunSdtPrToken(0)
, m_pRunSdtPrTokenChildren(NULL)
@@ -8146,6 +8189,7 @@ DocxAttributeOutput::~DocxAttributeOutput()
delete m_pTableWrt, m_pTableWrt = NULL;
delete m_pParagraphSdtPrTokenChildren; m_pParagraphSdtPrTokenChildren = NULL;
+ delete m_pParagraphSdtPrTokenAttributes; m_pParagraphSdtPrTokenAttributes = NULL;
delete m_pParagraphSdtPrDataBindingAttrs; m_pParagraphSdtPrDataBindingAttrs = NULL;
delete m_pRunSdtPrTokenChildren; m_pRunSdtPrTokenChildren = NULL;
delete m_pRunSdtPrDataBindingAttrs; m_pRunSdtPrDataBindingAttrs = NULL;
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 6ba3b484d6ac..90a31d87a70f 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -700,6 +700,7 @@ private:
void WriteSdtBlock(sal_Int32& nSdtPrToken,
::sax_fastparser::FastAttributeList*& pSdtPrTokenChildren,
+ ::sax_fastparser::FastAttributeList*& pSdtPrTokenAttributes,
::sax_fastparser::FastAttributeList*& pSdtPrDataBindingAttrs,
OUString& rSdtPrAlias,
bool bPara);
@@ -900,6 +901,7 @@ private:
/// members to control the existence of grabbagged SDT properties in the paragraph
sal_Int32 m_nParagraphSdtPrToken;
::sax_fastparser::FastAttributeList *m_pParagraphSdtPrTokenChildren;
+ ::sax_fastparser::FastAttributeList *m_pParagraphSdtPrTokenAttributes;
::sax_fastparser::FastAttributeList *m_pParagraphSdtPrDataBindingAttrs;
/// members to control the existence of grabbagged SDT properties in the text run
sal_Int32 m_nRunSdtPrToken;
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 0da5178400cf..bd2c226e4d93 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2358,7 +2358,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext )
resourcemodel::resolveSprmProps(*this, rSprm);
else
{
- OUString sName = "ooxml::CT_SdtPr_date";
+ OUString sName = "ooxml:CT_SdtPr_date";
enableInteropGrabBag(sName);
resourcemodel::resolveSprmProps(*this, rSprm);
m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());