[Libreoffice-commits] core.git: sw/qa sw/source writerfilter/source
Miklos Vajna
vmiklos at collabora.co.uk
Tue Jul 29 09:55:49 PDT 2014
sw/qa/extras/ooxmlexport/data/paragraph-sdt.docx |binary
sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 18 ++---
sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx | 10 +++
sw/source/filter/ww8/docxattributeoutput.cxx | 70 ++++++++++++++++++++---
sw/source/filter/ww8/docxattributeoutput.hxx | 4 +
writerfilter/source/dmapper/DomainMapper.cxx | 7 +-
writerfilter/source/dmapper/SdtHelper.cxx | 1
writerfilter/source/dmapper/SdtHelper.hxx | 12 +++
8 files changed, 104 insertions(+), 18 deletions(-)
New commits:
commit 28a315694348c4d1a4fd9aea7e720b3e821e8eb3
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Tue Jul 29 17:56:08 2014 +0200
DOCX filter: map <w:sdt> outside paragraphs to paragraph properties
Previously the type of the SDT was used to decide if the SDT will be a
character or paragraph property. Improve this situation by always
mapping <w:sdt> elements outside paragraph to paragraph properties.
In practice, this means that if the SDT was a rectangle (as it wasn't
only around a run), then it remains so, while previously it could become
a polygon instead (when painted).
Fix several testcases that tested that a <w:sdt> outside a paragraph is
exported as a character property.
Change-Id: Ia26c1a4cf6bc553b46224e4b17ee40725c5f3622
diff --git a/sw/qa/extras/ooxmlexport/data/paragraph-sdt.docx b/sw/qa/extras/ooxmlexport/data/paragraph-sdt.docx
new file mode 100644
index 0000000..c86f599
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/paragraph-sdt.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 77d8b4c..207ad5b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -2603,9 +2603,9 @@ DECLARE_OOXMLEXPORT_TEST(testCheckBoxControl, "checkbox-control.docx")
xmlDocPtr pXmlDoc = parseExport("word/document.xml");
if (!pXmlDoc)
return;
- 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");
+ 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");
// TODO: import control and add a check here
}
@@ -2664,7 +2664,7 @@ DECLARE_OOXMLEXPORT_TEST(testSdtContent, "SdtContent.docx")
xmlDocPtr pXmlDoc = parseExport("word/header1.xml");
if (!pXmlDoc)
return;
- assertXPath(pXmlDoc, "/w:hdr[1]/w:p[1]/w:sdt[1]/w:sdtContent[1]/w:del[1]");
+ assertXPath(pXmlDoc, "/w:hdr[1]/w:sdt[1]/w:sdtContent[1]/w:p[1]/w:del[1]");
}
DECLARE_OOXMLEXPORT_TEST(testFdo76016, "fdo76016.docx")
@@ -2749,8 +2749,8 @@ DECLARE_OOXMLEXPORT_TEST(testSimpleSdts, "simple-sdts.docx")
if (!pXmlDoc)
return;
- assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:sdt/w:sdtPr/w:text", 1);
- assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:sdt/w:sdtPr/w:id", 1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:text", 1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:id", 3);
assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:picture", 1);
assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:group", 1);
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:citation", 1);
@@ -2797,8 +2797,8 @@ DECLARE_OOXMLEXPORT_TEST(testAuthorPropertySdt, "author-property.docx")
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}");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:dataBinding", "xpath", "/ns1:coreProperties[1]/ns0:creator[1]");
+ assertXPath(pXmlDoc, "/w:document/w:body/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'");
@@ -3366,7 +3366,7 @@ DECLARE_OOXMLEXPORT_TEST(testSdtAlias, "sdt-alias.docx")
return;
// <w:alias> was completely missing.
- assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:alias", "val", "Subtitle");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:alias", "val", "Subtitle");
}
DECLARE_OOXMLEXPORT_TEST(testSdtDateCharformat, "sdt-date-charformat.docx")
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index 5d2732b..9b4b380 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -510,6 +510,16 @@ DECLARE_OOXMLEXPORT_TEST(testSdtCitationRun, "sdt-citation-run.docx")
}
}
+DECLARE_OOXMLEXPORT_TEST(testParagraphSdt, "paragraph-sdt.docx")
+{
+ // The problem was that the SDT was around the run only, not the whole paragraph.
+ if (xmlDocPtr pXmlDoc = parseExport())
+ {
+ // The path to w:sdt contained a w:p.
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc/w:sdt");
+ }
+}
+
#endif
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 8eb11f8..ec65d8b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -518,15 +518,15 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
}
m_pSerializer->endElementNS( XML_w, XML_p );
- OUString aParagraphSdtPrAlias;
if( !m_bAnchorLinkedToNode )
- WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs, aParagraphSdtPrAlias, /*bPara=*/true );
+ WriteSdtBlock( m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs, m_aParagraphSdtPrAlias, /*bPara=*/true );
else
{
//These should be written out to the actual Node and not to the anchor.
//Clear them as they will be repopulated when the node is processed.
m_nParagraphSdtPrToken = 0;
- lcl_deleteAndResetTheLists( m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs, aParagraphSdtPrAlias );
+ m_bParagraphSdtHasId = false;
+ lcl_deleteAndResetTheLists( m_pParagraphSdtPrTokenChildren, m_pParagraphSdtPrDataBindingAttrs, m_aParagraphSdtPrAlias );
}
//sdtcontent is written so Set m_bParagraphHasDrawing to false
@@ -588,13 +588,14 @@ void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken,
m_pSerializer->endElement( nSdtPrToken );
}
- else if( nSdtPrToken == FSNS( XML_w, XML_id ) )
+ else if( (nSdtPrToken > 0) && !(m_bRunTextIsOn && m_rExport.SdrExporter().IsParagraphHasDrawing()))
+ m_pSerializer->singleElement( nSdtPrToken, FSEND );
+
+ 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
- m_pSerializer->singleElement( nSdtPrToken,
+ m_pSerializer->singleElementNS(XML_w, XML_id,
FSNS(XML_w, XML_val), OString::number( rand() ),
FSEND );
- else if( (nSdtPrToken > 0) && !(m_bRunTextIsOn && m_rExport.SdrExporter().IsParagraphHasDrawing()))
- m_pSerializer->singleElement( nSdtPrToken, FSEND );
if(( pSdtPrDataBindingAttrs ) && !m_rExport.SdrExporter().IsParagraphHasDrawing())
{
@@ -7663,6 +7664,60 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation );
else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group")
m_nParagraphSdtPrToken = FSNS( XML_w, XML_group );
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text")
+ m_nParagraphSdtPrToken = FSNS(XML_w, XML_text);
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding" && !m_pParagraphSdtPrDataBindingAttrs)
+ {
+ 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_pParagraphSdtPrDataBindingAttrs,
+ FSNS( XML_w, XML_prefixMappings ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_xpath")
+ AddToAttrList( m_pParagraphSdtPrDataBindingAttrs,
+ FSNS( XML_w, XML_xpath ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ else if (aGrabBag[j].Name == "ooxml:CT_DataBinding_storeItemID")
+ AddToAttrList( m_pParagraphSdtPrDataBindingAttrs,
+ FSNS( XML_w, XML_storeItemID ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_alias" && m_aParagraphSdtPrAlias.isEmpty())
+ {
+ if (!(aPropertyValue.Value >>= m_aParagraphSdtPrAlias))
+ SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unexpected sdt alias value");
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
+ {
+ m_nParagraphSdtPrToken = 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_pParagraphSdtPrTokenChildren,
+ FSNS( XML_w14, XML_checked ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_checkedState")
+ AddToAttrList( m_pParagraphSdtPrTokenChildren,
+ FSNS( XML_w14, XML_checkedState ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ else if (aGrabBag[j].Name == "ooxml:CT_SdtCheckbox_uncheckedState")
+ AddToAttrList( m_pParagraphSdtPrTokenChildren,
+ FSNS( XML_w14, XML_uncheckedState ),
+ rtl::OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id")
+ m_bParagraphSdtHasId = true;
+ else
+ SAL_INFO("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled SdtPr grab bag property " << aPropertyValue.Name);
}
}
else
@@ -7927,6 +7982,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
, m_nRunSdtPrToken(0)
, m_pRunSdtPrTokenChildren(NULL)
, m_pRunSdtPrDataBindingAttrs(NULL)
+ , m_bParagraphSdtHasId(false)
{
}
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 04770c5..ff4ed70 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -897,7 +897,11 @@ private:
sal_Int32 m_nRunSdtPrToken;
::sax_fastparser::FastAttributeList *m_pRunSdtPrTokenChildren;
::sax_fastparser::FastAttributeList *m_pRunSdtPrDataBindingAttrs;
+ /// Value of the <w:alias> paragraph SDT element.
+ OUString m_aParagraphSdtPrAlias;
OUString m_aRunSdtPrAlias;
+ /// Currently paragraph SDT has a <w:id> child element.
+ bool m_bParagraphSdtHasId;
std::map<sal_uInt16, css::table::BorderLine2> m_aTableStyleConf;
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index c32d86a..b305afd 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2371,6 +2371,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext )
}
else
m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag());
+ m_pImpl->m_pSdtHelper->setOutsideAParagraph(m_pImpl->IsOutsideAParagraph());
m_pImpl->disableInteropGrabBag();
}
break;
@@ -2669,6 +2670,8 @@ void DomainMapper::lcl_endShape( )
lcl_endParagraphGroup();
m_pImpl->PopShapeContext( );
+ // A shape is always inside a shape (anchored or inline).
+ m_pImpl->SetIsOutsideAParagraph(false);
}
}
@@ -2833,12 +2836,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
- if(m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") ||
+ if((m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_checkbox") ||
m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") ||
m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") ||
m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") ||
(m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") &&
- m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1))
+ m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph())
{
PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER);
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx
index ce57d60..bf268a3 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -70,6 +70,7 @@ awt::Size lcl_getOptimalWidth(StyleSheetTablePtr pStyleSheet, OUString& rDefault
SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl)
: m_rDM_Impl(rDM_Impl)
, m_bHasElements(false)
+ , m_bOutsideAParagraph(false)
{
}
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx
index f4f56ab..c8d59bc 100644
--- a/writerfilter/source/dmapper/SdtHelper.hxx
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -60,6 +60,8 @@ class SdtHelper
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> m_aGrabBag;
bool m_bHasElements;
+ /// The last stored SDT element is outside paragraphs.
+ bool m_bOutsideAParagraph;
/// Create and append the drawing::XControlShape, containing the various models.
void createControlShape(css::awt::Size aSize, css::uno::Reference<css::awt::XControlModel> const&);
@@ -94,6 +96,16 @@ public:
return m_bHasElements;
}
+ void setOutsideAParagraph(bool bOutsideAParagraph)
+ {
+ m_bOutsideAParagraph = bOutsideAParagraph;
+ }
+
+ bool isOutsideAParagraph()
+ {
+ return m_bOutsideAParagraph;
+ }
+
/// Create drop-down control from w:sdt's w:dropDownList.
void createDropDownControl();
/// Create date control from w:sdt's w:date.
More information about the Libreoffice-commits
mailing list