summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacobo Aragunde Pérez <jaragunde@igalia.com>2014-03-19 19:44:27 +0100
committerJacobo Aragunde Pérez <jaragunde@igalia.com>2014-03-20 10:28:24 +0100
commit306859babd5a997a1e5d50e7791e8e5852a7ea2e (patch)
tree1d5c95f0b1a6599518e59fa37cb34aed2f06cd40
parent876f1cf9bfcbd9f0e578aea6e2a96443ecf823fd (diff)
ooxml: preserve dataBinding tag in SDT properties
SDT blocks can contain document properties, like the author. This is done with the dataBinding tag inside sdtPr. Added a resource definition to the ooxml model file, so the parser can process this tag. The attributes are stored in the existing grab bag used for other sdt properties and written back on export. The code to write the SDT block in the exporter has been modified to be able to extract the new tag from the grab bag and write it to the document. Added a unit test. Change-Id: I18f35a61784eb0a03ab9ca2cc398ca0df289956c
-rw-r--r--sw/qa/extras/ooxmlexport/data/author-property.docxbin0 -> 18198 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport.cxx15
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx48
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx4
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx11
-rw-r--r--writerfilter/source/ooxml/model.xml5
6 files changed, 75 insertions, 8 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/author-property.docx b/sw/qa/extras/ooxmlexport/data/author-property.docx
new file mode 100644
index 000000000000..474bb7933d6c
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/author-property.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 9b0e110cc595..a7657fb1e4d4 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -2927,6 +2927,21 @@ DECLARE_OOXMLEXPORT_TEST(test76317_2K10, "test76317_2K10.docx")
assertXPath(pXmlDoc, "/w:document[1]/w:body[1]/w:p[1]/w:r[1]/mc:AlternateContent[1]/mc:Choice[1]/w:drawing[1]/wp:anchor[1]/a:graphic[1]/a:graphicData[1]/wps:wsp[1]/wps:spPr[1]/a:prstGeom[1]/a:avLst[1]/a:gd[1]", "name", "adj");
}
+DECLARE_OOXMLEXPORT_TEST(testAuthorPropertySdt, "author-property.docx")
+{
+ xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+
+ if (!pXmlDoc)
+ return;
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:dataBinding", "xpath", "/ns1:coreProperties[1]/ns0:creator[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:dataBinding", "storeItemID","{6C3C8BC8-F283-45AE-878A-BAB7291924A1}");
+ // FIXME: the next property doesn't match, though it's correct in theory. A bug in assertXPath?
+ // assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:dataBinding", "prefixMappings",
+ // "xmlns:ns0='http://purl.org/dc/elements/1.1/' xmlns:ns1='http://schemas.openxmlformats.org/package/2006/metadata/core-properties'");
+}
+
+
#endif
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 8d2627f68d8a..4792dc145d4c 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -371,7 +371,7 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
m_pSerializer->endElementNS( XML_w, XML_p );
- WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren );
+ WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs );
m_pSerializer->mergeTopMarks();
// Check for end of cell, rows, tables here
@@ -381,9 +381,9 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
}
-void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren )
+void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren, ::sax_fastparser::FastAttributeList* &pSdtPrDataBindingAttrs )
{
- if( nSdtPrToken > 0 )
+ if( nSdtPrToken > 0 || pSdtPrDataBindingAttrs )
{
// sdt start mark
m_pSerializer->mark();
@@ -393,7 +393,7 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparse
// output sdt properties
m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND );
- if( pSdtPrTokenChildren )
+ if( nSdtPrToken > 0 && pSdtPrTokenChildren )
{
m_pSerializer->startElement( nSdtPrToken, FSEND );
@@ -406,9 +406,15 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparse
m_pSerializer->endElement( nSdtPrToken );
}
- else
+ else if( nSdtPrToken > 0 )
m_pSerializer->singleElement( nSdtPrToken, FSEND );
+ if( pSdtPrDataBindingAttrs )
+ {
+ XFastAttributeListRef xAttrList( pSdtPrDataBindingAttrs );
+ m_pSerializer->singleElementNS( XML_w, XML_dataBinding, xAttrList );
+ }
+
m_pSerializer->endElementNS( XML_w, XML_sdtPr );
// sdt contents start tag
@@ -424,6 +430,11 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparse
// clear sdt status
nSdtPrToken = 0;
delete pSdtPrTokenChildren; pSdtPrTokenChildren = NULL;
+ if( pSdtPrDataBindingAttrs )
+ {
+ // do not delete yet; it's in xAttrList inside the parser
+ pSdtPrDataBindingAttrs = NULL;
+ }
}
}
@@ -812,7 +823,7 @@ void DocxAttributeOutput::EndRun()
m_pSerializer->endElementNS( XML_w, XML_r );
// enclose in a sdt block, if necessary
- WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren );
+ WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs );
m_pSerializer->mergeTopMarks();
WritePostponedMath();
@@ -7072,6 +7083,27 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem )
rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
}
}
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding")
+ {
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ aPropertyValue.Value >>= aGrabBag;
+ for (sal_Int32 j=0; j < aGrabBag.getLength(); ++j)
+ {
+ OUString sValue = aGrabBag[j].Value.get<OUString>();
+ if (aGrabBag[j].Name == "ooxml:CT_DataBinding_prefixMappings")
+ AddToAttrList( m_pRunSdtPrDataBindingAttrs,
+ FSNS( XML_w, XML_prefixMappings ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_xpath")
+ AddToAttrList( m_pRunSdtPrDataBindingAttrs,
+ FSNS( XML_w, XML_xpath ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_storeItemID")
+ AddToAttrList( m_pRunSdtPrDataBindingAttrs,
+ FSNS( XML_w, XML_storeItemID ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
}
else
SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << i->first);
@@ -7135,8 +7167,10 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
m_setFootnote(false)
, m_nParagraphSdtPrToken(0)
, m_pParagraphSdtPrTokenChildren(NULL)
+ , m_pParagraphSdtPrDataBindingAttrs(NULL)
, m_nRunSdtPrToken(0)
, m_pRunSdtPrTokenChildren(NULL)
+ , m_pRunSdtPrDataBindingAttrs(NULL)
{
}
@@ -7156,7 +7190,9 @@ DocxAttributeOutput::~DocxAttributeOutput()
delete m_pTableWrt, m_pTableWrt = NULL;
delete m_pParagraphSdtPrTokenChildren; m_pParagraphSdtPrTokenChildren = NULL;
+ delete m_pParagraphSdtPrDataBindingAttrs; m_pParagraphSdtPrDataBindingAttrs = NULL;
delete m_pRunSdtPrTokenChildren; m_pRunSdtPrTokenChildren = NULL;
+ delete m_pRunSdtPrDataBindingAttrs; m_pRunSdtPrDataBindingAttrs = NULL;
}
DocxExport& DocxAttributeOutput::GetExport()
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index bccd33a6f2fe..da94c87370c0 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -682,7 +682,7 @@ private:
void WritePostponedVMLDrawing();
void WritePostponedDMLDrawing();
- void WriteSdtBlock(sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren);
+ void WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren, ::sax_fastparser::FastAttributeList* &pSdtPrDataBindingAttrs );
void StartField_Impl( FieldInfos& rInfos, bool bWriteRun = false );
void DoWriteCmd( const OUString& rCmd );
@@ -861,9 +861,11 @@ 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_pParagraphSdtPrDataBindingAttrs;
/// members to control the existence of grabbagged SDT properties in the text run
sal_Int32 m_nRunSdtPrToken;
::sax_fastparser::FastAttributeList *m_pRunSdtPrTokenChildren;
+ ::sax_fastparser::FastAttributeList *m_pRunSdtPrDataBindingAttrs;
public:
DocxAttributeOutput( DocxExport &rExport, ::sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML );
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 85cbcec2fd59..f57c142bcd7b 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -898,6 +898,14 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
if (static_cast<sal_uInt32>(nIntValue) == NS_ooxml::LN_Value_wordprocessingml_ST_FtnEdn_separator)
m_pImpl->m_bIgnoreNextPara = true;
break;
+ case NS_ooxml::LN_CT_DataBinding_prefixMappings:
+ case NS_ooxml::LN_CT_DataBinding_xpath:
+ case NS_ooxml::LN_CT_DataBinding_storeItemID:
+ {
+ OUString sName = OUString::createFromAscii((*QNameToString::Instance())(nName).c_str());
+ m_pImpl->m_pSdtHelper->appendToInteropGrabBag(sName, uno::Any(sStringValue));
+ }
+ break;
default:
{
#if OSL_DEBUG_LEVEL > 0
@@ -2234,6 +2242,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext )
m_pImpl->m_pSdtHelper->getLocale().append(sStringValue);
}
break;
+ case NS_ooxml::LN_CT_SdtPr_dataBinding:
case NS_ooxml::LN_CT_SdtPr_equation:
case NS_ooxml::LN_CT_SdtPr_checkbox:
case NS_ooxml::LN_CT_SdtPr_docPartObj:
@@ -2656,7 +2665,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
// save them in the paragraph interop grab bag
OUString sName = m_pImpl->m_pSdtHelper->getInteropGrabBagName();
uno::Any aPropValue = uno::makeAny(m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear());
- if(sName == "ooxml:CT_SdtPr_checkbox")
+ if(sName == "ooxml:CT_SdtPr_checkbox" || sName == "ooxml:CT_SdtPr_dataBinding")
m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER)->Insert(PROP_SDTPR, aPropValue, true, CHAR_GRAB_BAG);
else
m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR, aPropValue, true, PARA_GRAB_BAG);
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 2ab502a37785..e60d60e50881 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -24536,6 +24536,11 @@
<attribute name="val" tokenid="ooxml:CT_CalendarType_val" action="setValue"/>
<action name="start" action="setDefaultStringValue"/>
</resource>
+ <resource name="CT_DataBinding" resource="Properties">
+ <attribute name="prefixMappings" tokenid="ooxml:CT_DataBinding_prefixMappings"/>
+ <attribute name="xpath" tokenid="ooxml:CT_DataBinding_xpath"/>
+ <attribute name="storeItemID" tokenid="ooxml:CT_DataBinding_storeItemID"/>
+ </resource>
<resource xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" name="CT_SdtPr" resource="Properties" tag="field">
<element name="rPr" tokenid="ooxml:CT_SdtPr_rPr"/>
<element name="alias" tokenid="ooxml:CT_SdtPr_alias"/>