include/svx/xoutbmp.hxx | 3 svtools/source/filter/SvFilterOptionsDialog.cxx | 11 +- svtools/source/filter/exportdialog.cxx | 130 +++++++++++++++++------- svtools/source/filter/exportdialog.hxx | 5 svx/source/core/graphichelper.cxx | 123 +++++++++++++++++++++- svx/source/xoutdev/_xoutbmp.cxx | 5 6 files changed, 227 insertions(+), 50 deletions(-)
New commits: commit 5bbd87dd002398a1415acd2650c3a4c667d2d7f0 Author: Marco Cecchetti <marco.cecche...@collabora.com> Date: Thu Jul 20 12:18:37 2017 +0200 support for filter dialog when an image is exported from context menu When user save the selected image in a non-vector format the filter dialog used in Draw pops up for filter setting. Conflicts: svtools/source/filter/SvFilterOptionsDialog.cxx svx/source/xoutdev/_xoutbmp.cxx Change-Id: Ic98b48a47322e807627b7a2ccd8044ec0db30efc Reviewed-on: https://gerrit.libreoffice.org/40243 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Miklos Vajna <vmik...@collabora.co.uk> diff --git a/include/svx/xoutbmp.hxx b/include/svx/xoutbmp.hxx index 4163be681d92..e63180309d91 100644 --- a/include/svx/xoutbmp.hxx +++ b/include/svx/xoutbmp.hxx @@ -60,7 +60,8 @@ public: static Animation MirrorAnimation( const Animation& rAnimation, bool bHMirr, bool bVMirr ); static sal_uInt16 WriteGraphic( const Graphic& rGraphic, OUString& rFileName, const OUString& rFilterName, const XOutFlags nFlags, - const Size* pMtfSize_100TH_MM = nullptr ); + const Size* pMtfSize_100TH_MM = nullptr, + const css::uno::Sequence< css::beans::PropertyValue >* pFilterData = nullptr); static bool GraphicToBase64(const Graphic& rGraphic, OUString& rOUString); static sal_uInt16 ExportGraphic( const Graphic& rGraphic, const INetURLObject& rURL, diff --git a/svtools/source/filter/SvFilterOptionsDialog.cxx b/svtools/source/filter/SvFilterOptionsDialog.cxx index 0ce72954b87a..ed2b32c88665 100644 --- a/svtools/source/filter/SvFilterOptionsDialog.cxx +++ b/svtools/source/filter/SvFilterOptionsDialog.cxx @@ -35,6 +35,7 @@ #include <com/sun/star/document/XExporter.hpp> #include <com/sun/star/document/XViewDataSupplier.hpp> #include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/lang/XInitialization.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/uno/Sequence.h> @@ -217,10 +218,12 @@ sal_Int16 SvFilterOptionsDialog::execute() OUString aFilterNameStr( "FilterName" ); OUString aInternalFilterName; + uno::Reference<graphic::XGraphic> xGraphic; sal_Int32 j, nCount = maMediaDescriptor.getLength(); for ( j = 0; j < nCount; j++ ) { - if ( maMediaDescriptor[ j ].Name.equals( aFilterNameStr ) ) + const OUString& rName = maMediaDescriptor[ j ].Name; + if ( rName.equals( "FilterName" ) ) { OUString aStr; maMediaDescriptor[ j ].Value >>= aStr; @@ -229,6 +232,10 @@ sal_Int16 SvFilterOptionsDialog::execute() aInternalFilterName = aInternalFilterName.replaceAll( "impress_", "" ); break; } + else if ( rName.equals( "Graphic" ) ) + { + maMediaDescriptor[ j ].Value >>= xGraphic; + } } if ( !aInternalFilterName.isEmpty() ) { @@ -246,7 +253,7 @@ sal_Int16 SvFilterOptionsDialog::execute() aFltCallDlgPara.aFilterData = maFilterDataSequence; aFltCallDlgPara.aFilterExt = aGraphicFilter.GetExportFormatShortName( nFormat ); bool bIsPixelFormat( aGraphicFilter.IsExportPixelFormat( nFormat ) ); - if ( ScopedVclPtrInstance<ExportDialog>( aFltCallDlgPara, mxContext, mxSourceDocument, mbExportSelection, bIsPixelFormat )->Execute() == RET_OK ) + if ( ScopedVclPtrInstance<ExportDialog>( aFltCallDlgPara, mxContext, mxSourceDocument, mbExportSelection, bIsPixelFormat, xGraphic )->Execute() == RET_OK ) nRet = ui::dialogs::ExecutableDialogResults::OK; // taking the out parameter from the dialog diff --git a/svtools/source/filter/exportdialog.cxx b/svtools/source/filter/exportdialog.cxx index 645c8df7dd5f..4fc3007b9be8 100644 --- a/svtools/source/filter/exportdialog.cxx +++ b/svtools/source/filter/exportdialog.cxx @@ -352,6 +352,9 @@ awt::Size ExportDialog::GetOriginalSize() void ExportDialog::GetGraphicSource() { + if (mxGraphic.is()) + return; + if ( mxSourceDocument.is() ) { uno::Reference< frame::XModel > xModel( mxSourceDocument, uno::UNO_QUERY ); @@ -414,38 +417,76 @@ void ExportDialog::GetGraphicStream() mpTempStream = new SvMemoryStream(); maBitmap = Bitmap(); - uno::Reference < io::XStream > xStream( new utl::OStreamWrapper( *mpTempStream ) ); - uno::Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() ); - - uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter = - drawing::GraphicExportFilter::create( mxContext ); - - OUString sFormat( maExt ); - uno::Sequence< beans::PropertyValue > aDescriptor( 3 ); - aDescriptor[0].Name = "OutputStream"; - aDescriptor[0].Value <<= xOutputStream; - aDescriptor[1].Name = "FilterName"; - aDescriptor[1].Value <<= sFormat; - aDescriptor[2].Name = "FilterData"; - aDescriptor[2].Value <<= aNewFilterData; - - uno::Reference< lang::XComponent > xSourceDoc; - if ( mxPage.is() ) - xSourceDoc.set( mxPage, uno::UNO_QUERY_THROW ); - else if ( mxShapes.is() ) - xSourceDoc.set( mxShapes, uno::UNO_QUERY_THROW ); - else if ( mxShape.is() ) - xSourceDoc.set( mxShape, uno::UNO_QUERY_THROW ); - if ( xSourceDoc.is() ) + if ( mxGraphic.is() ) { - xGraphicExporter->setSourceDocument( xSourceDoc ); - xGraphicExporter->filter( aDescriptor ); + SvMemoryStream* pTempStream = dynamic_cast<SvMemoryStream*>( mpTempStream ); + Graphic aGraphic( mxGraphic ); - if ( mnFormat == FORMAT_JPG ) + if ( aGraphic.GetType() == GraphicType::Bitmap ) { - mpTempStream->Seek( STREAM_SEEK_TO_BEGIN ); - maBitmap = GetGraphicBitmap( *mpTempStream ); - mpTempStream->Seek( STREAM_SEEK_TO_END ); + Size aSizePixel( aGraphic.GetSizePixel() ); + if( maSize.Width && maSize.Height && + ( ( maSize.Width != aSizePixel.Width() ) || + ( maSize.Height != aSizePixel.Height() ) ) ) + { + BitmapEx aBmpEx( aGraphic.GetBitmapEx() ); + // export: use highest quality + aBmpEx.Scale( Size( maSize.Width, maSize.Height ), BmpScaleFlag::Lanczos ); + aGraphic = aBmpEx; + } + } + + GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); + const sal_uInt16 nFilter = rFilter.GetExportFormatNumberForShortName( maExt ); + if ( rFilter.IsExportPixelFormat( nFilter ) ) + { + pTempStream->SetResizeOffset(1024); + pTempStream->SetStreamSize(1024); + rFilter.ExportGraphic( aGraphic, "", *pTempStream, nFilter, &aNewFilterData ); + + if ( mnFormat == FORMAT_JPG ) + { + mpTempStream->Seek( STREAM_SEEK_TO_BEGIN ); + maBitmap = GetGraphicBitmap( *mpTempStream ); + mpTempStream->Seek( STREAM_SEEK_TO_END ); + } + } + } + else + { + uno::Reference < io::XStream > xStream( new utl::OStreamWrapper( *mpTempStream ) ); + uno::Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() ); + + uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter = + drawing::GraphicExportFilter::create( mxContext ); + + OUString sFormat( maExt ); + uno::Sequence< beans::PropertyValue > aDescriptor( 3 ); + aDescriptor[0].Name = "OutputStream"; + aDescriptor[0].Value <<= xOutputStream; + aDescriptor[1].Name = "FilterName"; + aDescriptor[1].Value <<= sFormat; + aDescriptor[2].Name = "FilterData"; + aDescriptor[2].Value <<= aNewFilterData; + + uno::Reference< lang::XComponent > xSourceDoc; + if ( mxPage.is() ) + xSourceDoc.set( mxPage, uno::UNO_QUERY_THROW ); + else if ( mxShapes.is() ) + xSourceDoc.set( mxShapes, uno::UNO_QUERY_THROW ); + else if ( mxShape.is() ) + xSourceDoc.set( mxShape, uno::UNO_QUERY_THROW ); + if ( xSourceDoc.is() ) + { + xGraphicExporter->setSourceDocument( xSourceDoc ); + xGraphicExporter->filter( aDescriptor ); + + if ( mnFormat == FORMAT_JPG ) + { + mpTempStream->Seek( STREAM_SEEK_TO_BEGIN ); + maBitmap = GetGraphicBitmap( *mpTempStream ); + mpTempStream->Seek( STREAM_SEEK_TO_END ); + } } } } @@ -514,11 +555,13 @@ bool ExportDialog::IsTempExportAvailable() const ExportDialog::ExportDialog(FltCallDialogParameter& rPara, const css::uno::Reference< css::uno::XComponentContext >& rxContext, const css::uno::Reference< css::lang::XComponent >& rxSourceDocument, - bool bExportSelection, bool bIsPixelFormat) + bool bExportSelection, bool bIsPixelFormat, + const css::uno::Reference< css::graphic::XGraphic >& rxGraphic) : ModalDialog(rPara.pWindow, "GraphicExportDialog", "svt/ui/graphicexport.ui") , mrFltCallPara(rPara) , mxContext(rxContext) , mxSourceDocument(rxSourceDocument) + , mxGraphic(rxGraphic) , mpSbCompression(nullptr) , mpNfCompression(nullptr) , msEstimatedSizePix1(SVT_RESSTR(STR_SVT_ESTIMATED_SIZE_PIX_1)) @@ -603,18 +646,31 @@ ExportDialog::ExportDialog(FltCallDialogParameter& rPara, Size aResolution( Application::GetDefaultDevice()->LogicToPixel( Size( 100, 100 ), MapUnit::MapCM ) ); maResolution.Width = aResolution.Width(); maResolution.Height= aResolution.Height(); - maOriginalSize = GetOriginalSize(); - if ( bIsPixelFormat ) + + if ( mxGraphic.is() ) { - double fPixelsPer100thmm = static_cast< double >( maResolution.Width ) / 100000.0; - maSize = awt::Size( static_cast< sal_Int32 >( ( fPixelsPer100thmm * maOriginalSize.Width ) + 0.5 ), - static_cast< sal_Int32 >( ( fPixelsPer100thmm * maOriginalSize.Height ) + 0.5 ) ); + Graphic aGraphic(mxGraphic); + Size aSize = aGraphic.GetSizePixel(); + maSize = awt::Size(aSize.getWidth(), aSize.getHeight()); + double f100thmmPerPixel = 100000.0 / static_cast< double >( maResolution.Width ); + maOriginalSize = awt::Size( + static_cast< sal_Int32 >( f100thmmPerPixel * maSize.Width ), + static_cast< sal_Int32 >( f100thmmPerPixel * maSize.Height ) ); } else { - maSize = maOriginalSize; + maOriginalSize = GetOriginalSize(); + if ( bIsPixelFormat ) + { + double fPixelsPer100thmm = static_cast< double >( maResolution.Width ) / 100000.0; + maSize = awt::Size( static_cast< sal_Int32 >( ( fPixelsPer100thmm * maOriginalSize.Width ) + 0.5 ), + static_cast< sal_Int32 >( ( fPixelsPer100thmm * maOriginalSize.Height ) + 0.5 ) ); + } + else + { + maSize = maOriginalSize; + } } - setupControls(); // Size diff --git a/svtools/source/filter/exportdialog.hxx b/svtools/source/filter/exportdialog.hxx index ec9452239cfb..efa386c0ebd6 100644 --- a/svtools/source/filter/exportdialog.hxx +++ b/svtools/source/filter/exportdialog.hxx @@ -52,6 +52,8 @@ private: mxContext; const css::uno::Reference< css::lang::XComponent >& mxSourceDocument; + const css::uno::Reference< css::graphic::XGraphic >& + mxGraphic; VclPtr<NumericField> mpMfSizeX; VclPtr<ListBox> mpLbSizeX; @@ -171,7 +173,8 @@ public: ExportDialog( FltCallDialogParameter& rPara, const css::uno::Reference< css::uno::XComponentContext >& rxContext, const css::uno::Reference< css::lang::XComponent >& rxSourceDocument, - bool bExportSelection, bool bIsExportVectorFormat ); + bool bExportSelection, bool bIsExportVectorFormat, + const css::uno::Reference< css::graphic::XGraphic >& rxGraphic = nullptr); virtual ~ExportDialog() override; virtual void dispose() override; }; diff --git a/svx/source/core/graphichelper.cxx b/svx/source/core/graphichelper.cxx index 0e2497fa072a..f0d8c5bc8729 100644 --- a/svx/source/core/graphichelper.cxx +++ b/svx/source/core/graphichelper.cxx @@ -32,13 +32,12 @@ #include <comphelper/anytostring.hxx> #include <comphelper/processfactory.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/PropertyValues.hpp> #include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/document/XExporter.hpp> #include <com/sun/star/document/XFilter.hpp> #include <com/sun/star/drawing/GraphicExportFilter.hpp> -#include <com/sun/star/graphic/XGraphicProvider.hpp> -#include <com/sun/star/graphic/GraphicType.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/io/XInputStream.hpp> @@ -46,6 +45,11 @@ #include <com/sun/star/ui/dialogs/XFilePicker2.hpp> #include <com/sun/star/ui/dialogs/XFilterManager.hpp> #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/task/ErrorCodeIOException.hpp> +#include <com/sun/star/task/InteractionHandler.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> using namespace css::uno; using namespace css::lang; @@ -55,6 +59,9 @@ using namespace css::beans; using namespace css::io; using namespace css::document; using namespace css::ui::dialogs; +using namespace css::container; +using namespace com::sun::star::task; +using namespace css::frame; using namespace sfx2; @@ -98,6 +105,59 @@ void GraphicHelper::GetPreferredExtension( OUString& rExtension, const Graphic& rExtension = aExtension; } +namespace { + + +bool lcl_ExecuteFilterDialog( const Sequence< PropertyValue >& rPropsForDialog, + Sequence< PropertyValue >& rFilterData ) +{ + bool bStatus = false; + try + { + const OUString aServiceName("com.sun.star.svtools.SvFilterOptionsDialog"); + Reference< XExecutableDialog > xFilterDialog( + comphelper::getProcessServiceFactory()->createInstance( aServiceName ), UNO_QUERY ); + Reference< XPropertyAccess > xFilterProperties( xFilterDialog, UNO_QUERY ); + + if( xFilterDialog.is() && xFilterProperties.is() ) + { + xFilterProperties->setPropertyValues( rPropsForDialog ); + if( xFilterDialog->execute() ) + { + bStatus = true; + Sequence< PropertyValue > aPropsFromDialog = xFilterProperties->getPropertyValues(); + const sal_Int32 nPropsLen = aPropsFromDialog.getLength(); + for ( sal_Int32 nInd = 0; nInd < nPropsLen; ++nInd ) + { + if (aPropsFromDialog[nInd].Name == "FilterData") + { + aPropsFromDialog[nInd].Value >>= rFilterData; + } + } + } + } + } + catch( const NoSuchElementException& e ) + { + // the filter name is unknown + throw ErrorCodeIOException( + ("lcl_ExecuteFilterDialog: NoSuchElementException" + " \"" + e.Message + "\": ERRCODE_IO_ABORT"), + Reference< XInterface >(), sal_uInt32(ERRCODE_IO_INVALIDPARAMETER)); + } + catch( const ErrorCodeIOException& ) + { + throw; + } + catch( const Exception& e ) + { + SAL_WARN("sfx.doc", "ignoring UNO exception " << e.Message); + } + + return bStatus; +} +} // anonymous ns + OUString GraphicHelper::ExportGraphic( const Graphic& rGraphic, const OUString& rGraphicName ) { SvtPathOptions aPathOpt; @@ -196,11 +256,60 @@ OUString GraphicHelper::ExportGraphic( const Graphic& rGraphic, const OUString& } OUString aFilter( rGraphicFilter.GetExportFormatShortName( nFilter ) ); - XOutBitmap::WriteGraphic( rGraphic, sPath, aFilter, - XOutFlags::DontExpandFilename | - XOutFlags::DontAddExtension | - XOutFlags::UseNativeIfPossible ); - return sPath; + if ( rGraphic.GetType() == GraphicType::Bitmap ) + { + Graphic aGraphic = rGraphic; + Reference<XGraphic> xGraphic = aGraphic.GetXGraphic(); + + OUString aExportFilter = rGraphicFilter.GetExportInternalFilterName(nFilter); + + Sequence< PropertyValue > aPropsForDialog(2); + aPropsForDialog[0].Name = "Graphic"; + aPropsForDialog[0].Value <<= xGraphic; + aPropsForDialog[1].Name = "FilterName"; + aPropsForDialog[1].Value <<= aExportFilter; + + Sequence< PropertyValue > aFilterData; + bool bStatus = lcl_ExecuteFilterDialog(aPropsForDialog, aFilterData); + if (bStatus) + { + sal_Int32 nWidth = 0; + sal_Int32 nHeight = 0; + + sal_Int32 nLen = aFilterData.getLength(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + if (aFilterData[i].Name == "PixelWidth") + { + aFilterData[i].Value >>= nWidth; + } + else if (aFilterData[i].Name == "PixelHeight") + { + aFilterData[i].Value >>= nHeight; + } + } + + // scaling must performed here because png/jpg writer s + // do not take care of that. + Size aSizePixel( aGraphic.GetSizePixel() ); + if( nWidth && nHeight && + ( ( nWidth != aSizePixel.Width() ) || + ( nHeight != aSizePixel.Height() ) ) ) + { + BitmapEx aBmpEx( aGraphic.GetBitmapEx() ); + // export: use highest quality + aBmpEx.Scale( Size( nWidth, nHeight ), BmpScaleFlag::Lanczos ); + aGraphic = aBmpEx; + } + + XOutBitmap::WriteGraphic( aGraphic, sPath, aFilter, + XOutFlags::DontExpandFilename | + XOutFlags::DontAddExtension | + XOutFlags::UseNativeIfPossible, + nullptr, &aFilterData ); + return sPath; + } + } } } return OUString(); diff --git a/svx/source/xoutdev/_xoutbmp.cxx b/svx/source/xoutdev/_xoutbmp.cxx index d458802091a1..58addbc8e5e1 100644 --- a/svx/source/xoutdev/_xoutbmp.cxx +++ b/svx/source/xoutdev/_xoutbmp.cxx @@ -119,7 +119,8 @@ Graphic XOutBitmap::MirrorGraphic( const Graphic& rGraphic, const BmpMirrorFlags sal_uInt16 XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileName, const OUString& rFilterName, const XOutFlags nFlags, - const Size* pMtfSize_100TH_MM ) + const Size* pMtfSize_100TH_MM, + const css::uno::Sequence< css::beans::PropertyValue >* pFilterData ) { if( rGraphic.GetType() != GraphicType::NONE ) { @@ -335,7 +336,7 @@ sal_uInt16 XOutBitmap::WriteGraphic( const Graphic& rGraphic, OUString& rFileNam if( !(nFlags & XOutFlags::DontAddExtension) ) aURL.setExtension( aExt ); rFileName = aURL.GetMainURL( INetURLObject::NO_DECODE ); - nErr = ExportGraphic( aGraphic, aURL, rFilter, nFilter ); + nErr = ExportGraphic( aGraphic, aURL, rFilter, nFilter, pFilterData ); } } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits