summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacobo Aragunde Pérez <jaragunde@igalia.com>2014-03-19 17:10:24 +0100
committerJacobo Aragunde Pérez <jaragunde@igalia.com>2014-03-20 10:28:23 +0100
commit692fd140706c9366ee46c651813887c67d5b4a97 (patch)
treeb2218160872c437da6f6bcbbf9844aea05126a99
parentf79f3e072c2ff2f4624c2ec4c577d400733584a5 (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.cxx6
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx104
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx9
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx6
-rw-r--r--writerfilter/source/dmapper/PropertyIds.cxx2
-rw-r--r--writerfilter/source/dmapper/PropertyIds.hxx2
-rw-r--r--writerfilter/source/dmapper/SdtHelper.cxx5
-rw-r--r--writerfilter/source/dmapper/SdtHelper.hxx1
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