summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPallavi Jadhav <pallavi.jadhav@synerzip.com>2014-08-13 18:14:47 +0530
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-08-18 12:52:30 +0200
commit8b9988163c0c0d158fc2d9f5272695ccfec92237 (patch)
treef9d2691b9837fc829a0fce96c879f10da6df9e75
parenta18ff3d5c75c2b468c48bd19439dee0689d24d67 (diff)
fdo#82492 : DOCX: Corruption: File was getting corrupt fafter RT
Issue : - In issue file there were two runs(first run=SDT, second run=Shape). - These two runs were consecutive(no text/space/tab was there in between two runs). - Due to such scenario, "SdtEndBefore" was not getting set on Shape. - Hence at Export EndSdtBlock() was getting called from EndParagraph(). Due to this SDT was not getting end after first run. In order to end SDT after run, EndSdtBlock() should get called from EndRun() (as in Original file) Implementation : - Set "SdtEndBefore" on Shape in DomainMapper_Impl::PushShapeContext() - Retrieved same property at export. - Added export unit test case. Note : Added common functions at Import and Export with reference to https://gerrit.libreoffice.org/#/c/10827/ Conflicts: sw/source/filter/ww8/docxattributeoutput.cxx Reviewed on: https://gerrit.libreoffice.org/10912 Change-Id: I357d77cd179c83b8ae976db331ee46c8993b6cb8
-rw-r--r--sw/qa/extras/ooxmlexport/data/fdo82492.docxbin0 -> 25948 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx10
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx62
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx1
-rw-r--r--sw/source/filter/ww8/docxsdrexport.cxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx91
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx3
7 files changed, 109 insertions, 60 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/fdo82492.docx b/sw/qa/extras/ooxmlexport/data/fdo82492.docx
new file mode 100644
index 000000000000..6533056f47cd
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/fdo82492.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index 9ab1ba22c80a..d52423f8fd75 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -610,6 +610,16 @@ 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(testfdo82492, "fdo82492.docx")
+{
+ xmlDocPtr pXmlDoc = parseExport("word/document.xml");
+ if (!pXmlDoc)
+ return;
+
+ // make sure there is only one run inside first SDT after RT as in the Original file.
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt[1]/w:sdtContent/w:r",1);
+}
+
DECLARE_OOXMLEXPORT_TEST(testSdtHeader, "sdt-header.docx")
{
// Problem was that w:sdt elements in headers were lost on import.
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 4ead52631169..86065cbda2e7 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1917,6 +1917,41 @@ void DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
}
+void DocxAttributeOutput::GetSdtEndBefore(const SdrObject* pSdrObj)
+{
+ if (pSdrObj)
+ {
+ uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY_THROW);
+ if( xShape.is() )
+ {
+ uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
+ if( xPropSet.is() )
+ {
+ xPropSetInfo = xPropSet->getPropertySetInfo();
+ uno::Sequence< beans::PropertyValue > aGrabBag;
+ if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
+ {
+ xPropSet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
+ }
+ else if(xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("InteropGrabBag"))
+ {
+ xPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
+ }
+
+ for (sal_Int32 nProp=0; nProp < aGrabBag.getLength(); ++nProp)
+ {
+ if ("SdtEndBefore" == aGrabBag[nProp].Name && m_bStartedCharSdt && !m_bEndCharSdt)
+ {
+ aGrabBag[nProp].Value >>= m_bEndCharSdt;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
void DocxAttributeOutput::WritePostponedGraphic()
{
for( std::list< PostponedGraphic >::const_iterator it = m_postponedGraphic->begin();
@@ -4011,32 +4046,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size
{
OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj ) - some stuff still missing" );
- if (pSdrObj)
- {
- uno::Reference<drawing::XShape> xShape(const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY_THROW);
- if( xShape.is() )
- {
- uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
- uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
- if( xPropSet.is() )
- {
- xPropSetInfo = xPropSet->getPropertySetInfo();
- if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
- {
- uno::Sequence< beans::PropertyValue > aGrabBag;
- xPropSet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
- for (sal_Int32 nProp=0; nProp < aGrabBag.getLength(); ++nProp)
- {
- if ("SdtEndBefore" == aGrabBag[nProp].Name && m_bStartedCharSdt && !m_bEndCharSdt)
- {
- aGrabBag[nProp].Value >>= m_bEndCharSdt;
- break;
- }
- }
- }
- }
- }
- }
+ GetSdtEndBefore(pSdrObj);
// detect mis-use of the API
assert(pGrfNode || (pOLEFrmFmt && pOLENode));
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 90a31d87a70f..343afaf09213 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -959,6 +959,7 @@ public:
bool GetWritingHeaderFooter( ) { return m_bWritingHeaderFooter; }
void SetAlternateContentChoiceOpen( bool bAltContentChoiceOpen ) { m_bAlternateContentChoiceOpen = bAltContentChoiceOpen; }
bool IsAlternateContentChoiceOpen( ) { return m_bAlternateContentChoiceOpen; }
+ void GetSdtEndBefore(const SdrObject* pSdrObj);
};
#endif // INCLUDED_SW_SOURCE_FILTER_WW8_DOCXATTRIBUTEOUTPUT_HXX
diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx
index 0a88a41d3483..bd34f04596b7 100644
--- a/sw/source/filter/ww8/docxsdrexport.cxx
+++ b/sw/source/filter/ww8/docxsdrexport.cxx
@@ -810,6 +810,8 @@ void DocxSdrExport::writeDMLDrawing(const SdrObject* pSdrObject, const SwFrmFmt*
if (!m_pImpl->isSupportedDMLShape(xShape))
return;
+ m_pImpl->m_rExport.DocxAttrOutput().GetSdtEndBefore(pSdrObject);
+
sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
Size aSize(pSdrObject->GetLogicRect().GetWidth(), pSdrObject->GetLogicRect().GetHeight());
startDMLAnchorInline(pFrmFmt, aSize);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 9f203a951065..0428c8752520 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1906,6 +1906,24 @@ void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape
m_vTextFramesForChaining.push_back(xShape);
}
}
+
+ if(IsSdtEndBefore())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
+ if(xShapePropertySet.is())
+ {
+ xPropSetInfo = xShapePropertySet->getPropertySetInfo();
+ if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("InteropGrabBag"))
+ {
+ uno::Sequence<beans::PropertyValue> aShapeGrabBag(1);
+ beans::PropertyValue aRet;
+ aRet.Name = "SdtEndBefore";
+ aRet.Value <<= uno::makeAny(true);
+ aShapeGrabBag[0] = aRet;
+ xShapePropertySet->setPropertyValue("InteropGrabBag",uno::makeAny(aShapeGrabBag));
+ }
+ }
+ }
}
if (!m_bInHeaderFooterImport && !checkZOrderStatus)
xProps->setPropertyValue(
@@ -1981,6 +1999,32 @@ void DomainMapper_Impl::PopShapeContext()
m_bFrameBtLr = false;
}
+bool DomainMapper_Impl::IsSdtEndBefore()
+{
+ bool bIsSdtEndBefore = false;;
+ PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_CHARACTER);
+ if(pContext)
+ {
+ uno::Sequence< beans::PropertyValue > currentCharProps = pContext->GetPropertyValues();
+ for (int i =0; i< currentCharProps.getLength(); i++)
+ {
+ if (currentCharProps[i].Name == "CharInteropGrabBag")
+ {
+ uno::Sequence<beans::PropertyValue> aCharGrabBag;
+ currentCharProps[i].Value >>= aCharGrabBag;
+ for (int j=0; j < aCharGrabBag.getLength();j++)
+ {
+ if(aCharGrabBag[j].Name == "SdtEndBefore")
+ {
+ aCharGrabBag[j].Value >>= bIsSdtEndBefore;
+ }
+ }
+ }
+ }
+ }
+ return bIsSdtEndBefore;
+}
+
sal_Int16 lcl_ParseNumberingType( const OUString& rCommand )
{
sal_Int16 nRet = style::NumberingType::PAGE_DESCRIPTOR;
@@ -4399,43 +4443,22 @@ void DomainMapper_Impl::ImportGraphic(writerfilter::Reference< Properties >::Po
* there is no text/space/tab in between two runs.
* In this case "SdtEndBefore" property needs to be set on Drawing.
*/
- PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_CHARACTER);
- if(pContext)
+ if(IsSdtEndBefore())
{
- uno::Sequence< beans::PropertyValue > currentCharProps = pContext->GetPropertyValues();
- for (int i =0; i< currentCharProps.getLength(); i++)
+ uno::Reference< beans::XPropertySet > xGraphicObjectProperties(xTextContent,
+ uno::UNO_QUERY_THROW);
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
+ if(xGraphicObjectProperties.is())
{
- if (currentCharProps[i].Name == "CharInteropGrabBag")
+ xPropSetInfo = xGraphicObjectProperties->getPropertySetInfo();
+ if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
{
- uno::Sequence<beans::PropertyValue> aCharGrabBag;
- currentCharProps[i].Value >>= aCharGrabBag;
- for (int j=0; j < aCharGrabBag.getLength();j++)
- {
- if(aCharGrabBag[j].Name == "SdtEndBefore")
- {
- bool bIsSdtEndBefore = false;
- aCharGrabBag[j].Value >>= bIsSdtEndBefore;
- if (bIsSdtEndBefore)
- {
- uno::Reference< beans::XPropertySet > xGraphicObjectProperties(xTextContent,
- uno::UNO_QUERY_THROW);
- uno::Reference< beans::XPropertySetInfo > xPropSetInfo;
- if(xGraphicObjectProperties.is())
- {
- xPropSetInfo = xGraphicObjectProperties->getPropertySetInfo();
- if (xPropSetInfo.is() && xPropSetInfo->hasPropertyByName("FrameInteropGrabBag"))
- {
- uno::Sequence<beans::PropertyValue> aFrameGrabBag(1);
- beans::PropertyValue aRet;
- aRet.Name = "SdtEndBefore";
- aRet.Value <<= uno::makeAny(true);
- aFrameGrabBag[0] = aRet;
- xGraphicObjectProperties->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aFrameGrabBag));
- }
- }
- }
- }
- }
+ uno::Sequence<beans::PropertyValue> aFrameGrabBag(1);
+ beans::PropertyValue aRet;
+ aRet.Name = "SdtEndBefore";
+ aRet.Value <<= uno::makeAny(true);
+ aFrameGrabBag[0] = aRet;
+ xGraphicObjectProperties->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aFrameGrabBag));
}
}
}
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 2bb0478f2c2a..4bee8aceeedc 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -824,6 +824,9 @@ public:
/// If the document needs to split paragraph.
bool m_bIsSplitPara;
+ /// Check if "SdtEndBefore" property is set
+ bool IsSdtEndBefore();
+
private:
void PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType);
std::vector<css::uno::Reference< css::drawing::XShape > > m_vTextFramesForChaining ;