This is an automated email from the ASF dual-hosted git repository. damjan pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/openoffice.git
The following commit(s) were added to refs/heads/trunk by this push: new 61aee32379 When copying charts, shapes, etc. out of OpenOffice, export them to the clipboard in the (lossless) SVG graphics format as well. 61aee32379 is described below commit 61aee323790d0a1ed0745ee5a84b8885bcd0a559 Author: Damjan Jovanovic <dam...@apache.org> AuthorDate: Tue Feb 13 05:52:00 2024 +0200 When copying charts, shapes, etc. out of OpenOffice, export them to the clipboard in the (lossless) SVG graphics format as well. This can be pasted into GIMP, Inkscape, and other apps, unlike our current WMF/EMF clipboard formats which use private MIME types that nothing supports. Fixes: https://bz.apache.org/ooo/show_bug.cgi?id=112829 - Copy & paste of OLE object to Gimp fails with error message Patch by: me --- main/sfx2/source/doc/sfxbasemodel.cxx | 50 +++++++++++++++++++++++++++++------ main/sot/inc/sot/formats.hxx | 3 ++- main/sot/source/base/exchange.cxx | 1 + main/svtools/source/misc/transfer.cxx | 33 ++++++++++++++++++++++- 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/main/sfx2/source/doc/sfxbasemodel.cxx b/main/sfx2/source/doc/sfxbasemodel.cxx index e8967d0580..57df31017f 100644 --- a/main/sfx2/source/doc/sfxbasemodel.cxx +++ b/main/sfx2/source/doc/sfxbasemodel.cxx @@ -2175,6 +2175,30 @@ uno::Any SAL_CALL SfxBaseModel::getTransferData( const DATAFLAVOR& aFlavor ) else throw datatransfer::UnsupportedFlavorException(); } + else if ( aFlavor.MimeType.equalsAscii( "image/svg+xml" ) ) + { + if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) + { + ::boost::shared_ptr<GDIMetaFile> pMetaFile = + m_pData->m_pObjectShell->GetPreviewMetaFile( sal_True ); + + if ( pMetaFile ) + { + ::boost::shared_ptr<SvMemoryStream> pStream( + GraphicHelper::getFormatStrFromGDI_Impl( + pMetaFile.get(), CVT_SVG ) ); + + if ( pStream ) + { + pStream->SetVersion( SOFFICE_FILEFORMAT_CURRENT ); + aAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( pStream->GetData() ), + pStream->Seek( STREAM_SEEK_TO_END ) ); + } + } + } + else + throw datatransfer::UnsupportedFlavorException(); + } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) @@ -2240,7 +2264,7 @@ uno::Sequence< DATAFLAVOR > SAL_CALL SfxBaseModel::getTransferDataFlavors() { SfxModelGuard aGuard( *this ); - sal_Int32 nSuppFlavors = GraphicHelper::supportsMetaFileHandle_Impl() ? 10 : 8; + sal_Int32 nSuppFlavors = GraphicHelper::supportsMetaFileHandle_Impl() ? 11 : 9; uno::Sequence< DATAFLAVOR > aFlavorSeq( nSuppFlavors ); aFlavorSeq[0].MimeType = @@ -2283,17 +2307,22 @@ uno::Sequence< DATAFLAVOR > SAL_CALL SfxBaseModel::getTransferDataFlavors() aFlavorSeq[7].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PNG" ) ); aFlavorSeq[7].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); - if ( nSuppFlavors == 10 ) + aFlavorSeq[8].MimeType = + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/svg+xml" ) ); + aFlavorSeq[8].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SVG" ) ); + aFlavorSeq[8].DataType = getCppuType( (const Sequence< sal_Int8 >*) 0 ); + + if ( nSuppFlavors == 11 ) { - aFlavorSeq[8].MimeType = + aFlavorSeq[9].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-emf;windows_formatname=\"Image EMF\"" ) ); - aFlavorSeq[8].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) ); - aFlavorSeq[8].DataType = getCppuType( (const sal_uInt64*) 0 ); + aFlavorSeq[9].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enhanced Windows MetaFile" ) ); + aFlavorSeq[9].DataType = getCppuType( (const sal_uInt64*) 0 ); - aFlavorSeq[9].MimeType = + aFlavorSeq[10].MimeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ) ); - aFlavorSeq[9].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows MetaFile" ) ); - aFlavorSeq[9].DataType = getCppuType( (const sal_uInt64*) 0 ); + aFlavorSeq[10].HumanPresentableName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Windows MetaFile" ) ); + aFlavorSeq[10].DataType = getCppuType( (const sal_uInt64*) 0 ); } return aFlavorSeq; @@ -2335,6 +2364,11 @@ sal_Bool SAL_CALL SfxBaseModel::isDataFlavorSupported( const DATAFLAVOR& aFlavor && aFlavor.DataType == getCppuType( (const sal_uInt64*) 0 ) ) return sal_True; } + else if ( aFlavor.MimeType.equalsAscii( "image/svg+xml" ) ) + { + if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) + return sal_True; + } else if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"" ) ) { if ( aFlavor.DataType == getCppuType( (const Sequence< sal_Int8 >*) 0 ) ) diff --git a/main/sot/inc/sot/formats.hxx b/main/sot/inc/sot/formats.hxx index 07c8ce850b..f62b9bc135 100644 --- a/main/sot/inc/sot/formats.hxx +++ b/main/sot/inc/sot/formats.hxx @@ -183,7 +183,8 @@ #define SOT_FORMATSTR_ID_HC_GDIMETAFILE ((sal_uLong)140) #define SOT_FORMATSTR_ID_PNG ((sal_uLong)141) #define SOT_FORMATSTR_ID_MATHML ((sal_uLong)142) -#define SOT_FORMATSTR_ID_USER_END SOT_FORMATSTR_ID_MATHML +#define SOT_FORMATSTR_ID_SVG ((sal_uLong)143) +#define SOT_FORMATSTR_ID_USER_END SOT_FORMATSTR_ID_SVG #endif // _SOT_FORMATS_HXX diff --git a/main/sot/source/base/exchange.cxx b/main/sot/source/base/exchange.cxx index 7f13d5b39e..5497ae28d0 100644 --- a/main/sot/source/base/exchange.cxx +++ b/main/sot/source/base/exchange.cxx @@ -209,6 +209,7 @@ namespace /*140 SOT_FORMAT_GDIMETAFILE*/ { "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"", "High Contrast GDIMetaFile", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) }, /*141 SOT_FORMATSTR_ID_PNG*/ { "image/png", "PNG Bitmap", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) }, /*142 SOT_FORMATSTR_ID_MATHML*/ { "application/mathml+xml", "MathML", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) }, + /*143 SOT_FORMATSTR_ID_SVG*/ { "image/svg+xml;windows_formatname=\"image/svg+xml\"", "SVG", &::getCppuType( (const Sequence< sal_Int8 >*) 0 ) }, }; return &aInstance[0]; } diff --git a/main/svtools/source/misc/transfer.cxx b/main/svtools/source/misc/transfer.cxx index 8a5c332402..5f83b0527b 100644 --- a/main/svtools/source/misc/transfer.cxx +++ b/main/svtools/source/misc/transfer.cxx @@ -438,6 +438,36 @@ Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor ) th } } } + else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_SVG, aSubstFlavor ) && + TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) && + SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) ) + { + GetData( aSubstFlavor ); + + if( maAny.hasValue() ) + { + Sequence< sal_Int8 > aSeq; + + if( maAny >>= aSeq ) + { + SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC ); + GDIMetaFile aMtf; + + *pSrcStm >> aMtf; + delete pSrcStm; + + Graphic aGraphic( aMtf ); + SvMemoryStream aDstStm( 65535, 65535 ); + + if( GraphicConverter::Export( aDstStm, aGraphic, CVT_SVG ) == ERRCODE_NONE ) + { + maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ), + aDstStm.Seek( STREAM_SEEK_TO_END ) ) ); + bDone = sal_True; + } + } + } + } // reset Any if substitute doesn't work if( !bDone && maAny.hasValue() ) @@ -705,6 +735,7 @@ void TransferableHelper::AddFormat( const DataFlavor& rFlavor ) { AddFormat( SOT_FORMATSTR_ID_EMF ); AddFormat( SOT_FORMATSTR_ID_WMF ); + AddFormat( SOT_FORMATSTR_ID_SVG ); } } } @@ -1476,7 +1507,7 @@ void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor rDataFlavorExVector.push_back( aFlavorEx ); } } - else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId ) + else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_SVG == aFlavorEx.mnSotId ) { if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) ) {