fdo#73227: Fix for corruption after RT
Issue: 1] Document containing SmartArt inside <wp:anchor> tag gets saved with <wp:inline>, due to which value of attribute "id" of <wp:docPr> gets incorrectly written. Which was causing the corruption. 2] LO was exporting SmartArt inside <wp:inline> bydefault. Hence "ids" of <wp:inline> and <wp:anchor> were same for value 1 and document gets corrupt. Implementation: 1] Added code to export SmartArt inside <wp:anchor> in DocxSdrExport::writeDiagram(). 2] Added export Unit test. Conflicts: sw/qa/extras/ooxmlexport/ooxmlexport.cxx Reviewed on: https://gerrit.libreoffice.org/7292 Change-Id: I5b2efcba030d1736203cf4571d8498fd87600d79
This commit is contained in:
committed by
Miklos Vajna
parent
b69864f3f8
commit
3a6fdd146a
BIN
sw/qa/extras/ooxmlexport/data/fdo73227.docx
Normal file
BIN
sw/qa/extras/ooxmlexport/data/fdo73227.docx
Normal file
Binary file not shown.
@@ -2274,6 +2274,28 @@ DECLARE_OOXMLEXPORT_TEST(testFDO73034, "FDO73034.docx")
|
||||
CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:rPr/w:u", "val").match("single"));
|
||||
}
|
||||
|
||||
DECLARE_OOXMLEXPORT_TEST(testSmartArtAnchoredInline, "fdo73227.docx")
|
||||
{
|
||||
/* Given file conatins 3 DrawingML objects as 1Picture,1SmartArt and 1Shape.
|
||||
* Check for SmartArt.
|
||||
* SmartArt shoould get written as "Floating Object" i.e. inside <wp:anchor> tag.
|
||||
* Also check for value of attribute "id" of <wp:docPr> . It should be unique for
|
||||
* all 3 DrawingML objects in a document.
|
||||
*/
|
||||
|
||||
xmlDocPtr pXmlDoc = parseExport("word/document.xml");
|
||||
if (!pXmlDoc)
|
||||
return;
|
||||
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:drawing[1]/wp:anchor/wp:docPr","id","1");
|
||||
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:drawing[1]/wp:anchor/wp:docPr","name","Diagram1");
|
||||
|
||||
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr","id","2");
|
||||
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr","name","10-Point Star 3");
|
||||
|
||||
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:drawing[2]/wp:anchor/wp:docPr","id","3");
|
||||
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:drawing[2]/wp:anchor/wp:docPr","name","Picture");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
@@ -1248,7 +1248,7 @@ void DocxAttributeOutput::WritePostponedDiagram()
|
||||
for( std::list< PostponedDiagram >::const_iterator it = m_postponedDiagram->begin();
|
||||
it != m_postponedDiagram->end();
|
||||
++it )
|
||||
m_rExport.SdrExporter().writeDiagram( it->object, it->size );
|
||||
m_rExport.SdrExporter().writeDiagram( it->object, *(it->frame), m_anchorId++ );
|
||||
delete m_postponedDiagram;
|
||||
m_postponedDiagram = NULL;
|
||||
}
|
||||
@@ -3269,10 +3269,10 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po
|
||||
if ( IsDiagram( pSdrObj ) )
|
||||
{
|
||||
if ( m_postponedDiagram == NULL )
|
||||
m_rExport.SdrExporter().writeDiagram( pSdrObj, rFrame.GetLayoutSize() );
|
||||
m_rExport.SdrExporter().writeDiagram( pSdrObj, rFrame.GetFrmFmt(), m_anchorId++);
|
||||
else // we are writing out attributes, but w:drawing should not be inside w:rPr,
|
||||
{ // so write it out later
|
||||
m_postponedDiagram->push_back( PostponedDiagram( pSdrObj, rFrame.GetSize() ) );
|
||||
m_postponedDiagram->push_back( PostponedDiagram( pSdrObj, &(rFrame.GetFrmFmt()) ));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@@ -756,9 +756,9 @@ private:
|
||||
std::list< PostponedGraphic >* m_postponedGraphic;
|
||||
struct PostponedDiagram
|
||||
{
|
||||
PostponedDiagram( const SdrObject* o, Size s ) : object( o ), size( s ) {};
|
||||
PostponedDiagram( const SdrObject* o, const SwFrmFmt* frm ) : object( o ), frame( frm ) {};
|
||||
const SdrObject* object;
|
||||
Size size;
|
||||
const SwFrmFmt* frame;
|
||||
};
|
||||
std::list< PostponedDiagram >* m_postponedDiagram;
|
||||
|
||||
|
@@ -588,7 +588,7 @@ void DocxSdrExport::writeDMLEffectLst(const SwFrmFmt& rFrmFmt)
|
||||
|
||||
}
|
||||
|
||||
void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const Size& size)
|
||||
void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFrmFmt, int nAnchorId)
|
||||
{
|
||||
sax_fastparser::FSHelperPtr pFS = m_pImpl->m_pSerializer;
|
||||
uno::Reference< drawing::XShape > xShape(((SdrObject*)sdrObject)->getUnoShape(), uno::UNO_QUERY);
|
||||
@@ -625,32 +625,20 @@ void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const Size& size)
|
||||
return;
|
||||
|
||||
// write necessary tags to document.xml
|
||||
pFS->startElementNS(XML_w, XML_drawing,
|
||||
FSEND);
|
||||
pFS->startElementNS(XML_wp, XML_inline,
|
||||
XML_distT, "0", XML_distB, "0", XML_distL, "0", XML_distR, "0",
|
||||
FSEND);
|
||||
|
||||
OString aWidth(OString::number(TwipsToEMU(size.Width())));
|
||||
OString aHeight(OString::number(TwipsToEMU(size.Height())));
|
||||
pFS->singleElementNS(XML_wp, XML_extent,
|
||||
XML_cx, aWidth.getStr(),
|
||||
XML_cy, aHeight.getStr(),
|
||||
FSEND);
|
||||
// TODO - the right effectExtent, extent including the effect
|
||||
pFS->singleElementNS(XML_wp, XML_effectExtent,
|
||||
XML_l, "0", XML_t, "0", XML_r, "0", XML_b, "0",
|
||||
FSEND);
|
||||
Size aSize(sdrObject->GetSnapRect().GetWidth(), sdrObject->GetSnapRect().GetHeight());
|
||||
startDMLAnchorInline(&rFrmFmt, aSize);
|
||||
|
||||
// generate an unique id
|
||||
static sal_Int32 diagramCount = 0;
|
||||
diagramCount++;
|
||||
OUString sName = "Diagram" + OUString::number(diagramCount);
|
||||
sax_fastparser::FastAttributeList* pDocPrAttrList = pFS->createAttrList();
|
||||
pDocPrAttrList->add(XML_id, OString::number(nAnchorId).getStr());
|
||||
OUString sName = "Diagram" + OUString::number(nAnchorId);
|
||||
pDocPrAttrList->add(XML_name, OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
|
||||
sax_fastparser::XFastAttributeListRef xDocPrAttrListRef(pDocPrAttrList);
|
||||
pFS->singleElementNS(XML_wp, XML_docPr, xDocPrAttrListRef);
|
||||
|
||||
pFS->singleElementNS(XML_wp, XML_docPr,
|
||||
XML_id, I32S(diagramCount),
|
||||
XML_name, USS(sName),
|
||||
FSEND);
|
||||
|
||||
sal_Int32 diagramCount;
|
||||
diagramCount = nAnchorId;
|
||||
|
||||
pFS->singleElementNS(XML_wp, XML_cNvGraphicFramePr,
|
||||
FSEND);
|
||||
@@ -725,8 +713,7 @@ void DocxSdrExport::writeDiagram(const SdrObject* sdrObject, const Size& size)
|
||||
|
||||
pFS->endElementNS(XML_a, XML_graphicData);
|
||||
pFS->endElementNS(XML_a, XML_graphic);
|
||||
pFS->endElementNS(XML_wp, XML_inline);
|
||||
pFS->endElementNS(XML_w, XML_drawing);
|
||||
endDMLAnchorInline(&rFrmFmt);
|
||||
|
||||
uno::Reference< xml::sax::XSAXSerializable > serializer;
|
||||
uno::Reference< xml::sax::XWriter > writer = xml::sax::Writer::create(comphelper::getProcessComponentContext());
|
||||
|
@@ -74,10 +74,10 @@ public:
|
||||
void writeVMLDrawing(const SdrObject* sdrObj, const SwFrmFmt& rFrmFmt,const Point& rNdTopLeft);
|
||||
/// Writes shape in both DML and VML format.
|
||||
void writeDMLAndVMLDrawing(const SdrObject* sdrObj, const SwFrmFmt& rFrmFmt,const Point& rNdTopLeft, int nAnchorId);
|
||||
/// Writes a diagram (smartart).
|
||||
void writeDiagram(const SdrObject* sdrObject, const Size& size);
|
||||
/// Write <a:effectLst>, the effect list.
|
||||
void writeDMLEffectLst(const SwFrmFmt& rFrmFmt);
|
||||
/// Writes a diagram (smartart).
|
||||
void writeDiagram(const SdrObject* sdrObject, const SwFrmFmt& rFrmFmt, int nAnchorId);
|
||||
/// Writes text frame in VML format.
|
||||
void writeVMLTextFrame(sw::Frame* pParentFrame);
|
||||
/// Undo the text direction mangling done by the frame btLr handler in writerfilter::dmapper::DomainMapper::lcl_startCharacterGroup()
|
||||
|
Reference in New Issue
Block a user