diff options
author | Miklos Vajna <vmiklos@suse.cz> | 2012-11-09 10:42:47 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2012-11-09 10:55:15 +0100 |
commit | bd6ae389008e110be62a335dfcd82c655d512e63 (patch) | |
tree | a29be0c92f7da7ef8977a3b4539c3452b7702df7 /sw | |
parent | 52a7a8e81a0cc3327de5ee27d02f9320c2cee3e4 (diff) |
fdo#51550 fix DOCX export dataloss on non-math/chart OLE export
This is still not complete, but having the replacement graphic only is
far better than having nothing.
Change-Id: I141a3de1a449f4261c7086e10f2c141b3f6cdb10
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/fdo51550.odt | bin | 0 -> 13611 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 10 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 45 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.hxx | 11 |
4 files changed, 44 insertions, 22 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/fdo51550.odt b/sw/qa/extras/ooxmlexport/data/fdo51550.odt Binary files differnew file mode 100644 index 000000000000..4cade5b21b9c --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/fdo51550.odt diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 24618ff472aa..1a1c15791b16 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -65,6 +65,7 @@ public: void testTablePosition(); void testFdo47669(); void testTableBorders(); + void testFdo51550(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -101,6 +102,7 @@ void Test::run() {"table-position.docx", &Test::testTablePosition}, {"fdo47669.docx", &Test::testFdo47669}, {"table-borders.docx", &Test::testTableBorders}, + {"fdo51550.odt", &Test::testFdo51550}, }; // Don't test the first import of these, for some reason those tests fail const char* aBlacklist[] = { @@ -472,6 +474,14 @@ void Test::testTableBorders() { } } +void Test::testFdo51550() +{ + // The problem was that we lacked the fallback to export the replacement graphic for OLE objects. + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDraws->getCount()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 5a91c4354fbf..9a9b30faab65 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -984,7 +984,7 @@ void DocxAttributeOutput::WritePostponedGraphic() for( std::list< PostponedGraphic >::const_iterator it = m_postponedGraphic->begin(); it != m_postponedGraphic->end(); ++it ) - FlyFrameGraphic( *( it->grfNode ), it->size ); + FlyFrameGraphic( it->grfNode, it->size ); delete m_postponedGraphic; m_postponedGraphic = NULL; } @@ -1988,17 +1988,18 @@ void DocxAttributeOutput::DefaultStyle( sal_uInt16 nStyle ) #endif } -void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ) +void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode ) { - OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ) - some stuff still missing" ); + OSL_TRACE( "TODO DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode ) - some stuff still missing" ); + const SwFrmFmt* pFrmFmt = pGrfNode ? pGrfNode->GetFlyFmt() : pOLEFrmFmt; // create the relation ID OString aRelId; sal_Int32 nImageType; - if ( rGrfNode.IsLinkedFile() ) + if ( pGrfNode && pGrfNode->IsLinkedFile() ) { // linked image, just create the relation String aFileName; - rGrfNode.GetFileFilterNms( &aFileName, 0 ); + pGrfNode->GetFileFilterNms( &aFileName, 0 ); // TODO Convert the file name to relative for better interoperability @@ -2011,10 +2012,14 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size else { // inline, we also have to write the image itself - Graphic& rGraphic = const_cast< Graphic& >( rGrfNode.GetGrf() ); + Graphic* pGraphic = 0; + if (pGrfNode) + pGraphic = &const_cast< Graphic& >( pGrfNode->GetGrf() ); + else + pGraphic = pOLENode->GetGraphic(); m_rDrawingML.SetFS( m_pSerializer ); // to be sure that we write to the right stream - OUString aImageId = m_rDrawingML.WriteImage( rGraphic ); + OUString aImageId = m_rDrawingML.WriteImage( *pGraphic ); aRelId = OUStringToOString( aImageId, RTL_TEXTENCODING_UTF8 ); @@ -2026,11 +2031,11 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size m_pSerializer->startElementNS( XML_w, XML_drawing, FSEND ); - bool isAnchor = rGrfNode.GetFlyFmt()->GetAnchor().GetAnchorId() != FLY_AS_CHAR; + bool isAnchor = pFrmFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR; if( isAnchor ) { ::sax_fastparser::FastAttributeList* attrList = m_pSerializer->createAttrList(); - attrList->add( XML_behindDoc, rGrfNode.GetFlyFmt()->GetOpaque().GetValue() ? "0" : "1" ); + attrList->add( XML_behindDoc, pFrmFmt->GetOpaque().GetValue() ? "0" : "1" ); attrList->add( XML_distT, "0" ); attrList->add( XML_distB, "0" ); attrList->add( XML_distL, "0" ); @@ -2039,13 +2044,13 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size attrList->add( XML_locked, "0" ); attrList->add( XML_layoutInCell, "1" ); attrList->add( XML_allowOverlap, "1" ); // TODO - if( const SdrObject* pObj = rGrfNode.GetFlyFmt()->FindRealSdrObject()) + if( const SdrObject* pObj = pFrmFmt->FindRealSdrObject()) attrList->add( XML_relativeHeight, OString::valueOf( sal_Int32( pObj->GetOrdNum()))); m_pSerializer->startElementNS( XML_wp, XML_anchor, XFastAttributeListRef( attrList )); m_pSerializer->singleElementNS( XML_wp, XML_simplePos, XML_x, "0", XML_y, "0", FSEND ); // required, unused const char* relativeFromH; const char* relativeFromV; - switch( rGrfNode.GetFlyFmt()->GetAnchor().GetAnchorId()) + switch( pFrmFmt->GetAnchor().GetAnchorId()) { case FLY_AT_PAGE: relativeFromV = relativeFromH = "page"; @@ -2061,7 +2066,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size break; }; Point pos( 0, 0 ); - if( SwFlyFrmFmt* flyfmt = dynamic_cast<SwFlyFrmFmt*>(rGrfNode.GetFlyFmt())) // TODO is always true? + if( const SwFlyFrmFmt* flyfmt = dynamic_cast<const SwFlyFrmFmt*>(pFrmFmt)) // TODO is always true? pos = flyfmt->GetAnchoredObj()->GetCurrRelPos(); OString x( OString::valueOf( TwipsToEMU( pos.X()))); OString y( OString::valueOf( TwipsToEMU( pos.Y()))); @@ -2097,7 +2102,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size if( isAnchor ) { - switch( rGrfNode.GetFlyFmt()->GetSurround().GetValue()) + switch( pFrmFmt->GetSurround().GetValue()) { case SURROUND_NONE: m_pSerializer->singleElementNS( XML_wp, XML_wrapTopAndBottom, FSEND ); @@ -2120,9 +2125,9 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size ::sax_fastparser::FastAttributeList* docPrattrList = m_pSerializer->createAttrList(); docPrattrList->add( XML_id, OString::valueOf( sal_Int32( m_anchorId++ )).getStr()); docPrattrList->add( XML_name, "Picture" ); - docPrattrList->add( XML_descr, OUStringToOString( rGrfNode.GetDescription(), RTL_TEXTENCODING_UTF8 ).getStr()); + docPrattrList->add( XML_descr, OUStringToOString( pGrfNode ? pGrfNode->GetDescription() : pOLEFrmFmt->GetObjDescription(), RTL_TEXTENCODING_UTF8 ).getStr()); if( GetExport().GetFilter().getVersion( ) != oox::core::ECMA_DIALECT ) - docPrattrList->add( XML_title, OUStringToOString( rGrfNode.GetTitle(), RTL_TEXTENCODING_UTF8 ).getStr()); + docPrattrList->add( XML_title, OUStringToOString( pGrfNode ? pGrfNode->GetTitle() : pOLEFrmFmt->GetObjTitle(), RTL_TEXTENCODING_UTF8 ).getStr()); XFastAttributeListRef docPrAttrListRef( docPrattrList ); m_pSerializer->startElementNS( XML_wp, XML_docPr, docPrAttrListRef ); // TODO hyperlink @@ -2224,7 +2229,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size m_pSerializer->endElementNS( XML_a, XML_ln ); // Output effects - SvxShadowItem aShadowItem = rGrfNode.GetFlyFmt()->GetShadow(); + SvxShadowItem aShadowItem = pFrmFmt->GetShadow(); if ( aShadowItem.GetLocation() != SVX_SHADOW_NONE ) { // Distance is measured diagonally from corner @@ -2265,12 +2270,14 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size m_pSerializer->endElementNS( XML_w, XML_drawing ); } -void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, const SwOLENode& rOLENode, const Size& rSize ) +void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rOLENode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt ) { if( WriteOLEChart( pSdrObj, rSize )) return; if( WriteOLEMath( pSdrObj, rOLENode, rSize )) return; + // Then we fall back to just export the object as a graphic. + FlyFrameGraphic( 0, rSize, pFlyFrmFmt, &rOLENode ); } bool DocxAttributeOutput::WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize ) @@ -2391,7 +2398,7 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po if ( pGrfNode ) { if( m_postponedGraphic == NULL ) - FlyFrameGraphic( *pGrfNode, rFrame.GetLayoutSize() ); + FlyFrameGraphic( pGrfNode, rFrame.GetLayoutSize() ); else // we are writting out attributes, but w:drawing should not be inside w:rPr, { // so write it out later m_postponedGraphic->push_back( PostponedGraphic( pGrfNode, rFrame.GetLayoutSize())); @@ -2443,7 +2450,7 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po { SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1); SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode(); - WriteOLE2Obj( pSdrObj, rOLENd, rFrame.GetLayoutSize() ); + WriteOLE2Obj( pSdrObj, rOLENd, rFrame.GetLayoutSize(), dynamic_cast<const SwFlyFrmFmt*>( &rFrmFmt )); } } break; diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index be0c361a3d0f..b1302b69fd30 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -299,9 +299,14 @@ private: /// @see InitCollectedRunProperies(), WriteCollectedParagraphProperties() void WriteCollectedRunProperties(); - /// Output graphic fly frames. - void FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize ); - void WriteOLE2Obj( const SdrObject* pSdrObj, const SwOLENode& rNode, const Size& rSize ); + /// Output graphic fly frames or replacement graphics for OLE nodes. + /// + /// For graphic frames, just use the first two parameters, for OLE + /// replacement graphics, set the first as 0, and pass the remaining three. + /// + /// @see WriteOLE2Obj() + void FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt = 0, SwOLENode* pOLENode = 0); + void WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt); bool WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize ); bool WriteOLEMath( const SdrObject* pSdrObj, const SwOLENode& rNode, const Size& rSize ); |