diff options
author | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-03-19 17:10:24 +0100 |
---|---|---|
committer | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-03-20 10:28:23 +0100 |
commit | 692fd140706c9366ee46c651813887c67d5b4a97 (patch) | |
tree | b2218160872c437da6f6bcbbf9844aea05126a99 | |
parent | f79f3e072c2ff2f4624c2ec4c577d400733584a5 (diff) |
fdo#76327: only enclose the checkbox in the sdt block.
The exporter writes the sdt blocks enclosing an entire paragraph, but
that's not the proper behaviour in all cases. The documents that mix
checkboxes and text in the same paragraph export the text inside the
sdt box and that's incorrect.
We have added code to be able to write sdt blocks that enclose
paragraphs or text runs, depending on the type of block. We have
applied it to checkboxes now.
There are two sets of properties in DocxAttributeOutput that store
sdt properties for the text run and for the paragraph. We have
modified the method WriteParagraphSdt to be generic enough to support
both cases. To write the sdt block enclosing the text run we used
parser marks.
We have renamed the property id PROP_PARA_SDTPR to the more generic
name PROP_SDTPR.
Checkbox unit test was modified to match the new structure of the
generated document.
Change-Id: I81ffe0062e1a5f80fc4638f7ee454a9bc18e63ee
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 6 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 104 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.hxx | 9 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 6 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyIds.cxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyIds.hxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SdtHelper.cxx | 5 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SdtHelper.hxx | 1 |
8 files changed, 81 insertions, 54 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 105bd36da5d2..8c4c21bfefa3 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -2757,9 +2757,9 @@ DECLARE_OOXMLEXPORT_TEST(testCheckBoxControl, "checkbox-control.docx") xmlDocPtr pXmlDoc = parseExport("word/document.xml"); if (!pXmlDoc) return; - assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:checked", "val", "1"); - assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:checkedState", "val", "2612"); - assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w14:checkbox/w14:uncheckedState", "val", "2610"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w14:checkbox/w14:checked", "val", "1"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w14:checkbox/w14:checkedState", "val", "2612"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w14:checkbox/w14:uncheckedState", "val", "2610"); // TODO: import control and add a check here } diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 6e2edb27217a..8d2627f68d8a 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 ); - WriteParagraphSdt(); + WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren ); 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::WriteParagraphSdt() +void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren ) { - if( m_nSdtPrToken > 0 ) + if( nSdtPrToken > 0 ) { // sdt start mark m_pSerializer->mark(); @@ -393,21 +393,21 @@ void DocxAttributeOutput::WriteParagraphSdt() // output sdt properties m_pSerializer->startElementNS( XML_w, XML_sdtPr, FSEND ); - if( m_pSdtPrTokenChildren ) + if( pSdtPrTokenChildren ) { - m_pSerializer->startElement( m_nSdtPrToken, FSEND ); + m_pSerializer->startElement( nSdtPrToken, FSEND ); - uno::Sequence<xml::FastAttribute> aChildren = m_pSdtPrTokenChildren->getFastAttributes(); + uno::Sequence<xml::FastAttribute> aChildren = pSdtPrTokenChildren->getFastAttributes(); for( sal_Int32 i=0; i < aChildren.getLength(); ++i ) m_pSerializer->singleElement( aChildren[i].Token, FSNS(XML_w, XML_val), rtl::OUStringToOString( aChildren[i].Value, RTL_TEXTENCODING_UTF8 ).getStr(), FSEND ); - m_pSerializer->endElement( m_nSdtPrToken ); + m_pSerializer->endElement( nSdtPrToken ); } else - m_pSerializer->singleElement( m_nSdtPrToken, FSEND ); + m_pSerializer->singleElement( nSdtPrToken, FSEND ); m_pSerializer->endElementNS( XML_w, XML_sdtPr ); @@ -422,8 +422,8 @@ void DocxAttributeOutput::WriteParagraphSdt() m_pSerializer->endElementNS( XML_w, XML_sdt ); // clear sdt status - m_nSdtPrToken = 0; - delete m_pSdtPrTokenChildren; m_pSdtPrTokenChildren = NULL; + nSdtPrToken = 0; + delete pSdtPrTokenChildren; pSdtPrTokenChildren = NULL; } } @@ -676,6 +676,9 @@ void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool /*bS // that has to be started first. m_pRedlineData = pRedlineData; + // this mark is used to be able to enclose the run inside a sdr tag. + m_pSerializer->mark(); + // postpone the output of the start of a run (there are elements that need // to be written before the start of the run, but we learn which they are // _inside_ of the run) @@ -808,6 +811,10 @@ void DocxAttributeOutput::EndRun() // append the actual run end m_pSerializer->endElementNS( XML_w, XML_r ); + // enclose in a sdt block, if necessary + WriteSdtBlock( m_nRunSdtPrToken, m_pRunSdtPrTokenChildren ); + m_pSerializer->mergeTopMarks(); + WritePostponedMath(); for (std::vector<const SdrObject*>::iterator it = m_aPostponedFormControls.begin(); it != m_aPostponedFormControls.end(); ++it) @@ -6886,16 +6893,16 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem) FSNS(XML_w, XML_themeFill), OUStringToOString(sThemeFill, RTL_TEXTENCODING_UTF8).getStr(), FSNS(XML_w, XML_fill), OUStringToOString(sOriginalFill, RTL_TEXTENCODING_UTF8).getStr()); } - else if (i->first == "ParaSdtPr") + else if (i->first == "SdtPr") { beans::PropertyValue aPropertyValue = i->second.get<beans::PropertyValue>(); if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" || aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList") { if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj") - m_nSdtPrToken = FSNS( XML_w, XML_docPartObj ); + m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartObj ); else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList") - m_nSdtPrToken = FSNS( XML_w, XML_docPartList ); + m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartList ); uno::Sequence<beans::PropertyValue> aGrabBag; aPropertyValue.Value >>= aGrabBag; @@ -6903,47 +6910,25 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem) { OUString sValue = aGrabBag[j].Value.get<OUString>(); if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartGallery") - AddToAttrList( m_pSdtPrTokenChildren, + AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartGallery ), rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartCategory") - AddToAttrList( m_pSdtPrTokenChildren, + AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartCategory ), rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); else if (aGrabBag[j].Name == "ooxml:CT_SdtDocPart_docPartUnique") - AddToAttrList( m_pSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" ); - } - } - else if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox") - { - m_nSdtPrToken = FSNS( XML_w14, XML_checkbox ); - 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_SdtCheckbox_checked") - AddToAttrList( m_pSdtPrTokenChildren, - FSNS( XML_w14, XML_checked ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); - else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState") - AddToAttrList( m_pSdtPrTokenChildren, - FSNS( XML_w14, XML_checkedState ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); - else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState") - AddToAttrList( m_pSdtPrTokenChildren, - FSNS( XML_w14, XML_uncheckedState ), - rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ), "" ); } } else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation") - m_nSdtPrToken = FSNS( XML_w, XML_equation ); + m_nParagraphSdtPrToken = FSNS( XML_w, XML_equation ); else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture") - m_nSdtPrToken = FSNS( XML_w, XML_picture ); + m_nParagraphSdtPrToken = FSNS( XML_w, XML_picture ); else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation") - m_nSdtPrToken = FSNS( XML_w, XML_citation ); + m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation ); else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group") - m_nSdtPrToken = FSNS( XML_w, XML_group ); + m_nParagraphSdtPrToken = FSNS( XML_w, XML_group ); } else SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled grab bag property " << i->first ); @@ -7062,6 +7047,32 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem ) m_aTextEffectsGrabBag.realloc(m_aTextEffectsGrabBag.getLength() + 1); m_aTextEffectsGrabBag[aLength] = aPropertyValue; } + else if (i->first == "SdtPr") + { + beans::PropertyValue aPropertyValue = i->second.get<beans::PropertyValue>(); + if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox") + { + m_nRunSdtPrToken = FSNS( XML_w14, XML_checkbox ); + 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_SdtCheckbox_checked") + AddToAttrList( m_pRunSdtPrTokenChildren, + FSNS( XML_w14, XML_checked ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState") + AddToAttrList( m_pRunSdtPrTokenChildren, + FSNS( XML_w14, XML_checkedState ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState") + AddToAttrList( m_pRunSdtPrTokenChildren, + FSNS( XML_w14, XML_uncheckedState ), + rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + } else SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << i->first); } @@ -7122,8 +7133,10 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri m_nParaBeforeSpacing(0), m_nParaAfterSpacing(0), m_setFootnote(false) - , m_nSdtPrToken(0) - , m_pSdtPrTokenChildren(NULL) + , m_nParagraphSdtPrToken(0) + , m_pParagraphSdtPrTokenChildren(NULL) + , m_nRunSdtPrToken(0) + , m_pRunSdtPrTokenChildren(NULL) { } @@ -7142,7 +7155,8 @@ DocxAttributeOutput::~DocxAttributeOutput() delete m_pEndnotesList, m_pEndnotesList = NULL; delete m_pTableWrt, m_pTableWrt = NULL; - delete m_pSdtPrTokenChildren; m_pSdtPrTokenChildren = NULL; + delete m_pParagraphSdtPrTokenChildren; m_pParagraphSdtPrTokenChildren = NULL; + delete m_pRunSdtPrTokenChildren; m_pRunSdtPrTokenChildren = NULL; } DocxExport& DocxAttributeOutput::GetExport() diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 5b55dc8a32cb..bccd33a6f2fe 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 WriteParagraphSdt(); + void WriteSdtBlock(sal_Int32& nSdtPrToken, ::sax_fastparser::FastAttributeList* &pSdtPrTokenChildren); void StartField_Impl( FieldInfos& rInfos, bool bWriteRun = false ); void DoWriteCmd( const OUString& rCmd ); @@ -859,8 +859,11 @@ private: std::map<const Graphic*, OString> m_aRelIdCache; /// members to control the existence of grabbagged SDT properties in the paragraph - sal_Int32 m_nSdtPrToken; - ::sax_fastparser::FastAttributeList *m_pSdtPrTokenChildren; + sal_Int32 m_nParagraphSdtPrToken; + ::sax_fastparser::FastAttributeList *m_pParagraphSdtPrTokenChildren; + /// members to control the existence of grabbagged SDT properties in the text run + sal_Int32 m_nRunSdtPrToken; + ::sax_fastparser::FastAttributeList *m_pRunSdtPrTokenChildren; 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 0b6283025050..85cbcec2fd59 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2654,8 +2654,12 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) { // there are unsupported SDT properties in the document // 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()); - m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_PARA_SDTPR, aPropValue, true, PARA_GRAB_BAG); + if(sName == "ooxml:CT_SdtPr_checkbox") + 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); } else if (len == 1 && sText[0] == 0x03) { diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index a26cdf9d93b9..8bdba4e404b3 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -387,7 +387,7 @@ OUString PropertyNameSupplier::GetName( PropertyIds eId ) const case PROP_CHAR_NUMSPACING_TEXT_EFFECT : sName = "CharNumSpacingTextEffect"; break; case PROP_CHAR_STYLISTICSETS_TEXT_EFFECT : sName = "CharStylisticSetsTextEffect"; break; case PROP_CHAR_CNTXTALTS_TEXT_EFFECT : sName = "CharCntxtAltsTextEffect"; break; - case PROP_PARA_SDTPR : sName = "ParaSdtPr"; break; + case PROP_SDTPR : sName = "SdtPr"; 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 6370a1d6be83..1d29c0b1c497 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -359,7 +359,7 @@ enum PropertyIds ,PROP_CHAR_NUMSPACING_TEXT_EFFECT ,PROP_CHAR_STYLISTICSETS_TEXT_EFFECT ,PROP_CHAR_CNTXTALTS_TEXT_EFFECT - ,PROP_PARA_SDTPR + ,PROP_SDTPR }; struct PropertyNameSupplier_Impl; class PropertyNameSupplier diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx index 32691d96a811..2ff928bd89cf 100644 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ b/writerfilter/source/dmapper/SdtHelper.cxx @@ -223,6 +223,11 @@ bool SdtHelper::isInteropGrabBagEnabled() return !m_sGrabBagName.isEmpty(); } +OUString SdtHelper::getInteropGrabBagName() +{ + return m_sGrabBagName; +} + } // namespace dmapper } // namespace writerfilter diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx index 95f655939c0b..8f70de9fba10 100644 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ b/writerfilter/source/dmapper/SdtHelper.hxx @@ -88,6 +88,7 @@ public: com::sun::star::beans::PropertyValue getInteropGrabBagAndClear(); void enableInteropGrabBag(const OUString& rName); bool isInteropGrabBagEnabled(); + OUString getInteropGrabBagName(); }; } // namespace dmapper |