/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
 
#include <sal/config.h>
 
#include <algorithm>
 
#include <comphelper/propertyvalue.hxx>
#include <o3tl/safeint.hxx>
#include <tools/stream.hxx>
#include <tools/fract.hxx>
#include <utility>
#include <vcl/graphicfilter.hxx>
#include <vcl/FilterConfigItem.hxx>
#include <svtools/strings.hrc>
#include <svtools/svtresid.hxx>
#include <svtools/DocumentToGraphicRenderer.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/drawing/GraphicExportFilter.hpp>
#include <com/sun/star/drawing/XDrawView.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/graphic/PrimitiveFactory2D.hpp>
#include <com/sun/star/geometry/AffineMatrix2D.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <unotools/streamwrap.hxx>
#include <vcl/svapp.hxx>
#include <vcl/outdev.hxx>
#include <vcl/graph.hxx>
#include <rtl/ustrbuf.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include "exportdialog.hxx"
 
#define FORMAT_UNKNOWN  0
#define FORMAT_JPG      1
#define FORMAT_PNG      2
#define FORMAT_BMP      3
#define FORMAT_GIF      4
#define FORMAT_TIF      10
#define FORMAT_WMF      12
#define FORMAT_EMF      13
#define FORMAT_EPS      14
#define FORMAT_SVG      16
#define FORMAT_WEBP     17
 
#define UNIT_DEFAULT    -1
#define UNIT_INCH       0
#define UNIT_CM         1
#define UNIT_MM         2
#define UNIT_POINT      3
#define UNIT_PIXEL      4
#define UNIT_MAX_ID     UNIT_PIXEL
 
using namespace ::com::sun::star;
 
static sal_Int16 GetFilterFormat(std::u16string_view rExt)
{
    sal_Int16 nFormat = FORMAT_UNKNOWN;
    if ( rExt == u"JPG" )
        nFormat = FORMAT_JPG;
    else if ( rExt == u"PNG" )
        nFormat = FORMAT_PNG;
    else if ( rExt == u"BMP" )
        nFormat = FORMAT_BMP;
    else if ( rExt == u"GIF" )
        nFormat = FORMAT_GIF;
    else if ( rExt == u"TIF" )
        nFormat = FORMAT_TIF;
    else if ( rExt == u"WMF" )
        nFormat = FORMAT_WMF;
    else if ( rExt == u"EMF" )
        nFormat = FORMAT_EMF;
    else if ( rExt == u"EPS" )
        nFormat = FORMAT_EPS;
    else if ( rExt == u"SVG" )
        nFormat = FORMAT_SVG;
    else if ( rExt == u"WEBP" )
        nFormat = FORMAT_WEBP;
    return nFormat;
}
 
static MapUnit GetMapUnit( sal_Int32 nUnit )
{
    MapUnit aMapUnit( MapUnit::MapPixel );
    switch( nUnit )
    {
        case UNIT_INCH  :   aMapUnit = MapUnit::MapInch; break;
        case UNIT_CM    :   aMapUnit = MapUnit::MapCM; break;
        case UNIT_MM    :   aMapUnit = MapUnit::MapMM; break;
        case UNIT_POINT :   aMapUnit = MapUnit::MapPoint; break;
        case UNIT_PIXEL :   aMapUnit = MapUnit::MapPixel; break;
    }
    return aMapUnit;
}
 
sal_Int32 ExportDialog::GetDefaultUnit() const
{
    sal_Int32 nDefaultUnit;
    switch( mrFltCallPara.eFieldUnit )
    {
//      case FieldUnit::NONE :
//      case FieldUnit::PERCENT :
//      case FieldUnit::CUSTOM :
        case FieldUnit::KM :         // PASSTHROUGH INTENDED
        case FieldUnit::M :
        case FieldUnit::MM_100TH :
        case FieldUnit::CM :
        default:                nDefaultUnit = UNIT_CM; break;
 
        case FieldUnit::MILE :       // PASSTHROUGH INTENDED
        case FieldUnit::FOOT :
        case FieldUnit::TWIP :
        case FieldUnit::PICA :
        case FieldUnit::INCH :       nDefaultUnit = UNIT_INCH; break;
 
        case FieldUnit::MM :         nDefaultUnit = UNIT_MM; break;
        case FieldUnit::POINT :      nDefaultUnit = UNIT_POINT; break;
    }
    return nDefaultUnit;
}
 
static basegfx::B2DRange GetShapeRangeForXShape( const uno::Reference< drawing::XShape >& rxShape,
    const uno::Reference< graphic::XPrimitiveFactory2D >& rxPrimitiveFactory2D, const uno::Sequence< beans::PropertyValue >& rViewInformation )
{
    basegfx::B2DRange aShapeRange;
 
    const uno::Sequence< beans::PropertyValue > aParams;
    const uno::Sequence< uno::Reference< graphic::XPrimitive2D > > aPrimitiveSequence( rxPrimitiveFactory2D->createPrimitivesFromXShape( rxShape, aParams ) );
 
    for( const auto& rPrimitive : aPrimitiveSequence )
    {
        const geometry::RealRectangle2D aRect( rPrimitive->getRange( rViewInformation ) );
        aShapeRange.expand( basegfx::B2DTuple( aRect.X1, aRect.Y1 ) );
        aShapeRange.expand( basegfx::B2DTuple( aRect.X2, aRect.Y2 ) );
    }
    return aShapeRange;
}
 
uno::Sequence< beans::PropertyValue > ExportDialog::GetFilterData( bool bUpdateConfig )
{
    if ( bUpdateConfig )
    {
        sal_Int32 nUnit = mxLbSizeX->get_active();
        if ( nUnit < 0 )
            nUnit = UNIT_CM;
 
        if ( ( mnInitialResolutionUnit == UNIT_DEFAULT ) && ( nUnit == GetDefaultUnit() ) )
            nUnit = UNIT_DEFAULT;
 
        // updating ui configuration
        if ( mbIsPixelFormat )
        {
            if ( nUnit > UNIT_MAX_ID )
                nUnit = UNIT_PIXEL;
 
            sal_Int32 nResolution = mxNfResolution->get_value();
            if ( nResolution < 1 )
                nResolution = 96;
 
            mpOptionsItem->WriteInt32(u"PixelExportUnit"_ustr, nUnit);
            mpOptionsItem->WriteInt32(u"PixelExportResolution"_ustr, nResolution);
            mpOptionsItem->WriteInt32(u"PixelExportResolutionUnit"_ustr, mxLbResolution->get_active());
        }
        else
        {
            if ( nUnit >= UNIT_PIXEL )
                nUnit = UNIT_CM;
 
            mpOptionsItem->WriteInt32(u"VectorExportUnit"_ustr, nUnit);
        }
    }
 
    FilterConfigItem* pFilterOptions;
    if ( bUpdateConfig )
         pFilterOptions = mpFilterOptionsItem.get();
    else
    {
        uno::Sequence< beans::PropertyValue > aFilterData( mpFilterOptionsItem->GetFilterData() );
        pFilterOptions = new FilterConfigItem( &aFilterData );
    }
 
    static constexpr OUString sLogicalWidth(u"LogicalWidth"_ustr);
    static constexpr OUString sLogicalHeight(u"LogicalHeight"_ustr);
    if ( mbIsPixelFormat )
    {
        pFilterOptions->WriteInt32(u"PixelWidth"_ustr, maSize.Width );
        pFilterOptions->WriteInt32(u"PixelHeight"_ustr, maSize.Height );
        if ( maResolution.Width && maResolution.Height )
        {
            const double f100thmmPerPixelX = 100000.0 / maResolution.Width;
            const double f100thmmPerPixelY = 100000.0 / maResolution.Height;
            sal_Int32 nLogicalWidth = static_cast< sal_Int32 >( f100thmmPerPixelX * maSize.Width );
            sal_Int32 nLogicalHeight= static_cast< sal_Int32 >( f100thmmPerPixelY * maSize.Height );
            if ( nLogicalWidth && nLogicalHeight )
            {
                pFilterOptions->WriteInt32( sLogicalWidth, nLogicalWidth );
                pFilterOptions->WriteInt32( sLogicalHeight, nLogicalHeight );
            }
        }
    }
    else
    {
        pFilterOptions->WriteInt32( sLogicalWidth, maSize.Width );
        pFilterOptions->WriteInt32( sLogicalHeight, maSize.Height );
    }
    switch ( mnFormat )
    {
        case FORMAT_JPG :
        {
            sal_Int32 nColor = mxLbColorDepth->get_active();
            if ( nColor == 1 )
                nColor = 0;
            else
                nColor = 1;
            pFilterOptions->WriteInt32(u"ColorMode"_ustr, nColor);
            assert(mpSbCompression);
            pFilterOptions->WriteInt32(u"Quality"_ustr, static_cast<sal_Int32>(mpSbCompression->get_value()));
        }
        break;
 
        case FORMAT_PNG :
        {
            assert(mpSbCompression);
            pFilterOptions->WriteInt32(u"Compression"_ustr, static_cast<sal_Int32>(mpSbCompression->get_value()));
            sal_Int32 nInterlace = 0;
            if ( mxCbInterlaced->get_active() )
                nInterlace++;
            pFilterOptions->WriteInt32(u"Interlaced"_ustr, nInterlace);
            sal_Int32 nValue = 0;
            if ( mxCbSaveTransparency->get_active() )
                nValue++;
            pFilterOptions->WriteInt32(u"Translucent"_ustr, nValue);
        }
        break;
 
        case FORMAT_BMP :
        {
            pFilterOptions->WriteInt32(u"Color"_ustr, mxLbColorDepth->get_active() + 1);
            pFilterOptions->WriteBool(u"RLE_Coding"_ustr, mxCbRLEEncoding->get_active());
        }
        break;
 
        case FORMAT_GIF :
        {
            sal_Int32 nValue = 0;
            if ( mxCbInterlaced->get_active() )
                nValue++;
            pFilterOptions->WriteInt32(u"Interlaced"_ustr, nValue);
 
            nValue = 0;
            if (mxCbSaveTransparency->get_active())
                nValue++;
            pFilterOptions->WriteInt32(u"Translucent"_ustr, nValue);
        }
        break;
 
        case FORMAT_EPS :
        {
            sal_Int32 nCheck = 0;
            if ( mxCbEPSPreviewTIFF->get_active() )
                nCheck++;
            if ( mxCbEPSPreviewEPSI->get_active() )
                nCheck += 2;
            pFilterOptions->WriteInt32(u"Preview"_ustr, nCheck);
 
            nCheck = 1;
            if ( mxRbEPSLevel2->get_active() )
                nCheck++;
            pFilterOptions->WriteInt32(u"Version"_ustr, nCheck);
 
            nCheck = 1;
            if ( mxRbEPSColorFormat2->get_active() )
                nCheck++;
            pFilterOptions->WriteInt32(u"ColorFormat"_ustr, nCheck);
 
            nCheck = 1;
            if ( mxRbEPSCompressionNone->get_active() )
                nCheck++;
            pFilterOptions->WriteInt32(u"CompressionMode"_ustr, nCheck);
        }
        break;
 
        case FORMAT_WEBP :
        {
            assert(mpSbCompression);
            pFilterOptions->WriteInt32(u"Quality"_ustr, static_cast<sal_Int32>(mpSbCompression->get_value()));
            pFilterOptions->WriteBool(u"Lossless"_ustr, mxCbLossless->get_active());
        }
        break;
 
    }
 
    uno::Sequence< beans::PropertyValue > aRet( pFilterOptions->GetFilterData() );
    if ( !bUpdateConfig )
        delete pFilterOptions;
    return aRet;
}
 
 
awt::Size ExportDialog::GetOriginalSize()
{
    basegfx::B2DRange aShapesRange;
 
    if ( mxPage.is () )
    {
        uno::Reference< beans::XPropertySet > xPagePropSet( mxPage, uno::UNO_QUERY );
        if ( xPagePropSet.is() )
        {
            sal_Int32 nWidth = 0;
            sal_Int32 nHeight= 0;
            css::uno::Any aAny;
            aAny = xPagePropSet->getPropertyValue(u"Width"_ustr);
            aAny >>= nWidth;
            aAny = xPagePropSet->getPropertyValue(u"Height"_ustr);
            aAny >>= nHeight;
            aShapesRange = basegfx::B2DRange( 0, 0, nWidth, nHeight );
        }
    }
    else if (mxShapes.is() || mxShape.is())
    {
        uno::Reference< graphic::XPrimitiveFactory2D > xPrimitiveFactory = graphic::PrimitiveFactory2D::create( mxContext );
 
        basegfx::B2DHomMatrix aViewTransformation( Application::GetDefaultDevice()->GetViewTransformation() );
        css::geometry::AffineMatrix2D aTransformation;
        aTransformation.m00 = aViewTransformation.get(0,0);
        aTransformation.m01 = aViewTransformation.get(0,1);
        aTransformation.m02 = aViewTransformation.get(0,2);
        aTransformation.m10 = aViewTransformation.get(1,0);
        aTransformation.m11 = aViewTransformation.get(1,1);
        aTransformation.m12 = aViewTransformation.get(1,2);
 
        uno::Sequence< beans::PropertyValue > aViewInformation{ comphelper::makePropertyValue(
            u"ViewTransformation"_ustr, aTransformation) };
 
        if ( mxShape.is() )
            aShapesRange = GetShapeRangeForXShape( mxShape, xPrimitiveFactory, aViewInformation );
        else if ( mxShapes.is() )
        {
            const sal_Int32 nCount = mxShapes->getCount();
            for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
            {
                uno::Reference< drawing::XShape > xShape;
                mxShapes->getByIndex( nIndex ) >>= xShape;
                aShapesRange.expand( GetShapeRangeForXShape( xShape, xPrimitiveFactory, aViewInformation ) );
            }
        }
    }
    else if (!mbGraphicsSource)
    {
        DocumentToGraphicRenderer aRenderer( mxSourceDocument, mbExportSelection);
        const sal_Int32 nCurrentPage = aRenderer.getCurrentPage();
        const Size aSize = aRenderer.getDocumentSizeIn100mm( nCurrentPage);
        return awt::Size( aSize.Width(), aSize.Height());
    }
    return awt::Size( static_cast<sal_Int32>(aShapesRange.getWidth()), static_cast<sal_Int32>(aShapesRange.getHeight()) );
}
 
void ExportDialog::GetGraphicSource()
{
    if (mxGraphic.is())
        return;
 
    if ( !mxSourceDocument.is() )
        return;
 
    uno::Reference< frame::XModel > xModel( mxSourceDocument, uno::UNO_QUERY );
    if ( !xModel.is() )
        return;
 
    uno::Reference< frame::XController > xController( xModel->getCurrentController() );
    if ( !xController.is() )
        return;
 
    if ( mbExportSelection )                // check if there is a selection
    {
        if (DocumentToGraphicRenderer::isShapeSelected( mxShapes, mxShape, xController))
            mbGraphicsSource = true;
    }
    if ( !mxShape.is() && !mxShapes.is() && mbGraphicsSource )
    {
        uno::Reference< drawing::XDrawView > xDrawView( xController, uno::UNO_QUERY );
        if ( xDrawView.is() )
        {
            uno::Reference< drawing::XDrawPage > xCurrentPage( xDrawView->getCurrentPage() );
            if ( xCurrentPage.is() )
            {
                mxPage = std::move(xCurrentPage);      // exporting whole page
            }
        }
    }
    // For !mbGraphicsSource the mxSourceDocument is used, from
    // which XRenderable can query XController and
    // XSelectionSupplier the same.
}
 
void ExportDialog::GetGraphicStream()
{
    if ( !IsTempExportAvailable() )
    {
        mpTempStream.reset(new SvMemoryStream());
        return;
    }
 
    bool bRecreateOutputStream = mpTempStream->Tell() == 0;
 
    static uno::Sequence< beans::PropertyValue > aOldFilterData;
    uno::Sequence< beans::PropertyValue > aNewFilterData( GetFilterData( false ) );
    if ( aOldFilterData != aNewFilterData )
    {
        aOldFilterData = aNewFilterData;
        bRecreateOutputStream = true;
    }
    try
    {
        if ( bRecreateOutputStream )
        {
            mpTempStream.reset(new SvMemoryStream());
 
            uno::Reference< graphic::XGraphic > xGraphic;
            if (!mbGraphicsSource && !mxGraphic.is())
            {
                // Create a Graphic to be used below.
                DocumentToGraphicRenderer aRenderer( mxSourceDocument, mbExportSelection);
                const sal_Int32 nCurrentPage = aRenderer.getCurrentPage();
                const Size aDocumentSizePixel = aRenderer.getDocumentSizeInPixels( nCurrentPage);
 
                const Size aTargetSizePixel( mbIsPixelFormat ?
                        Size( maSize.Width, maSize.Height) :
                        aDocumentSizePixel );
 
                Graphic aGraphic( aRenderer.renderToGraphic( nCurrentPage,
                            aDocumentSizePixel, aTargetSizePixel, COL_WHITE, /*bExtOutDevData=*/false));
                xGraphic = aGraphic.GetXGraphic();
            }
 
            if ( mxGraphic.is() || xGraphic.is() )
            {
                Graphic aGraphic( mxGraphic.is() ? mxGraphic : xGraphic );
 
                if ( aGraphic.GetType() == GraphicType::Bitmap )
                {
                    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 ) )
                {
                    mpTempStream->SetResizeOffset(1024);
                    mpTempStream->SetStreamSize(1024);
                    rFilter.ExportGraphic( aGraphic, u"", *mpTempStream, nFilter, &aNewFilterData );
                }
            }
            else
            {
                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() )
                {
                    uno::Reference < io::XStream > xStream( new utl::OStreamWrapper( *mpTempStream ) );
                    uno::Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() );
 
                    OUString sFormat( maExt );
                    uno::Sequence< beans::PropertyValue > aDescriptor{
                        comphelper::makePropertyValue(u"OutputStream"_ustr, xOutputStream),
                        comphelper::makePropertyValue(u"FilterName"_ustr, sFormat),
                        comphelper::makePropertyValue(u"FilterData"_ustr, aNewFilterData)
                    };
 
                    uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter =
                        drawing::GraphicExportFilter::create( mxContext );
 
                    xGraphicExporter->setSourceDocument( xSourceDoc );
                    xGraphicExporter->filter( aDescriptor );
                }
            }
        }
    }
    catch( uno::Exception& )
    {
 
        // ups
 
    }
}
 
sal_uInt32 ExportDialog::GetRawFileSize() const
{
    sal_uInt64 nRawFileSize = 0;
    if ( mbIsPixelFormat )
    {
        sal_Int32 nBitsPerPixel = 24;
        OUString aEntry(mxLbColorDepth->get_active_text());
        if ( ms1BitThreshold == aEntry )
            nBitsPerPixel = 1;
        else if ( ms8BitGrayscale == aEntry )
            nBitsPerPixel = 8;
        else if ( ms8BitColorPalette == aEntry )
            nBitsPerPixel = 8;
        else if ( ms24BitColor == aEntry )
            nBitsPerPixel = 24;
 
        if ( mbIsPixelFormat )
        {
            nRawFileSize = ( maSize.Width * nBitsPerPixel + 7 ) &~ 7;   // rounding up to 8 bits
            nRawFileSize /= 8;                                          // in bytes
            nRawFileSize *= maSize.Height;
        }
        if ( nRawFileSize > SAL_MAX_UINT32 )
            nRawFileSize = 0;
    }
    return static_cast< sal_uInt32 >( nRawFileSize );
}
 
// checks if the source dimension/resolution is not too big
// to determine the exact graphic output size and preview for jpg
bool ExportDialog::IsTempExportAvailable() const
{
    return GetRawFileSize() < o3tl::make_unsigned( mnMaxFilesizeForRealtimePreview );
}
 
ExportDialog::ExportDialog(FltCallDialogParameter& rPara,
    css::uno::Reference< css::uno::XComponentContext > xContext,
    const css::uno::Reference< css::lang::XComponent >& rxSourceDocument,
    bool bExportSelection, bool bIsPixelFormat, bool bGraphicsSource,
    const css::uno::Reference< css::graphic::XGraphic >& rxGraphic)
    : GenericDialogController(rPara.pWindow, u"svt/ui/graphicexport.ui"_ustr, u"GraphicExportDialog"_ustr)
    , mrFltCallPara(rPara)
    , mxContext(std::move(xContext))
    , mxSourceDocument(rxSourceDocument)
    , mxGraphic(rxGraphic)
    , msEstimatedSizePix1(SvtResId(STR_SVT_ESTIMATED_SIZE_PIX_1))
    , msEstimatedSizePix2(SvtResId(STR_SVT_ESTIMATED_SIZE_PIX_2))
    , msEstimatedSizeVec(SvtResId(STR_SVT_ESTIMATED_SIZE_VEC))
    , ms1BitThreshold(SvtResId(STR_SVT_1BIT_THRESHOLD))
    , ms8BitGrayscale(SvtResId(STR_SVT_8BIT_GRAYSCALE))
    , ms8BitColorPalette(SvtResId(STR_SVT_8BIT_COLOR_PALETTE))
    , ms24BitColor(SvtResId(STR_SVT_24BIT_TRUE_COLOR))
    , maExt(rPara.aFilterExt)
    , mnFormat(FORMAT_UNKNOWN)
    , mnMaxFilesizeForRealtimePreview(0)
    , mpTempStream(new SvMemoryStream())
    , maOriginalSize(awt::Size(0, 0))
    , mbIsPixelFormat(bIsPixelFormat)
    , mbExportSelection(bExportSelection)
    , mbGraphicsSource(bGraphicsSource)
    , mpSbCompression(nullptr)
    , mpNfCompression(nullptr)
    , mxMfSizeX(m_xBuilder->weld_spin_button(u"widthmf"_ustr))
    , mxLbSizeX(m_xBuilder->weld_combo_box(u"widthlb"_ustr))
    , mxMfSizeY(m_xBuilder->weld_spin_button( u"heightmf"_ustr))
    , mxFtResolution(m_xBuilder->weld_label(u"resolutionft"_ustr))
    , mxNfResolution(m_xBuilder->weld_spin_button(u"resolutionmf"_ustr))
    , mxLbResolution(m_xBuilder->weld_combo_box(u"resolutionlb"_ustr))
    , mxColorDepth(m_xBuilder->weld_widget(u"colordepth"_ustr))
    , mxLbColorDepth(m_xBuilder->weld_combo_box(u"colordepthlb"_ustr))
    , mxJPGWEBPQuality(m_xBuilder->weld_widget(u"jpgwebpquality"_ustr))
    , mxPNGCompression(m_xBuilder->weld_widget(u"pngcompression"_ustr))
    , mxSbPngCompression(m_xBuilder->weld_scale(u"compressionpngsb"_ustr))
    , mxNfPngCompression(m_xBuilder->weld_spin_button(u"compressionpngnf"_ustr))
    , mxSbJpgWebpCompression(m_xBuilder->weld_scale(u"compressionjpgwebpsb"_ustr))
    , mxNfJpgWebpCompression(m_xBuilder->weld_spin_button(u"compressionjpgwebpnf"_ustr))
    , mxCbLossless(m_xBuilder->weld_check_button(u"losslesscb"_ustr))
    , mxMode(m_xBuilder->weld_widget(u"mode"_ustr))
    , mxCbInterlaced(m_xBuilder->weld_check_button(u"interlacedcb"_ustr))
    , mxBMPCompression(m_xBuilder->weld_widget(u"bmpcompression"_ustr))
    , mxCbRLEEncoding(m_xBuilder->weld_check_button(u"rlecb"_ustr))
    , mxDrawingObjects(m_xBuilder->weld_widget(u"drawingobjects"_ustr))
    , mxCbSaveTransparency(m_xBuilder->weld_check_button(u"savetransparencycb"_ustr))
    , mxEncoding(m_xBuilder->weld_widget(u"encoding"_ustr))
    , mxRbBinary(m_xBuilder->weld_radio_button(u"binarycb"_ustr))
    , mxRbText(m_xBuilder->weld_radio_button(u"textcb"_ustr))
    , mxEPSGrid(m_xBuilder->weld_widget(u"epsgrid"_ustr))
    , mxModifyDimension(m_xBuilder->weld_radio_button(u"modifydimensionscb"_ustr))
    , mxModifyResolution(m_xBuilder->weld_radio_button(u"modifyresolutioncb"_ustr))
    , mxCbEPSPreviewTIFF(m_xBuilder->weld_check_button(u"tiffpreviewcb"_ustr))
    , mxCbEPSPreviewEPSI(m_xBuilder->weld_check_button(u"epsipreviewcb"_ustr))
    , mxRbEPSLevel1(m_xBuilder->weld_radio_button(u"level1rb"_ustr))
    , mxRbEPSLevel2(m_xBuilder->weld_radio_button(u"level2rb"_ustr))
    , mxRbEPSColorFormat1(m_xBuilder->weld_radio_button(u"color1rb"_ustr))
    , mxRbEPSColorFormat2(m_xBuilder->weld_radio_button(u"color2rb"_ustr))
    , mxRbEPSCompressionLZW(m_xBuilder->weld_radio_button(u"compresslzw"_ustr))
    , mxRbEPSCompressionNone(m_xBuilder->weld_radio_button(u"compressnone"_ustr))
    , mxInfo(m_xBuilder->weld_widget(u"information"_ustr))
    , mxFtEstimatedSize(m_xBuilder->weld_label(u"estsizeft"_ustr))
    , mxBtnOK(m_xBuilder->weld_button(u"ok"_ustr))
{
    GetGraphicSource();
 
    maExt = maExt.toAsciiUpperCase();
 
    OUString  aFilterConfigPath( u"Office.Common/Filter/Graphic/Export/"_ustr );
    mpOptionsItem.reset(new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData ));
    aFilterConfigPath += maExt;
    mpFilterOptionsItem.reset(new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData ));
 
    mnInitialResolutionUnit = mbIsPixelFormat
        ? mpOptionsItem->ReadInt32(u"PixelExportUnit"_ustr, UNIT_DEFAULT)
        : mpOptionsItem->ReadInt32(u"VectorExportUnit"_ustr, UNIT_DEFAULT);
 
    mnMaxFilesizeForRealtimePreview = std::max(
        mpOptionsItem->ReadInt32(u"MaxFilesizeForRealtimePreview"_ustr, 0), sal_Int32(0));
    mxFtEstimatedSize->set_label(u" \n "_ustr);
 
    m_xDialog->set_title(m_xDialog->get_title().replaceFirst("%1", maExt)); //Set dialog title
 
    mnFormat = GetFilterFormat( maExt );
 
    Size aResolution( Application::GetDefaultDevice()->LogicToPixel(Size(100, 100), MapMode(MapUnit::MapCM)) );
    maResolution.Width = aResolution.Width();
    maResolution.Height= aResolution.Height();
 
    if ( mxGraphic.is() )
    {
        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
    {
        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
    mxLbSizeX->connect_changed( LINK( this, ExportDialog, SelectListBoxHdl ) );
 
    if (mpSbCompression)
        mpSbCompression->connect_value_changed(LINK(this, ExportDialog, SbCompressionUpdateHdl));
    if (mpNfCompression)
        mpNfCompression->connect_value_changed(LINK(this, ExportDialog, SelectHdl));
 
    mxMfSizeX->connect_value_changed( LINK( this, ExportDialog, UpdateHdlMtfSizeX ) );
    mxMfSizeY->connect_value_changed( LINK( this, ExportDialog, UpdateHdlMtfSizeY ) );
 
    mxNfResolution->connect_value_changed( LINK( this, ExportDialog, UpdateHdlNfResolution ) );
    mxLbResolution->connect_changed( LINK( this, ExportDialog, SelectListBoxHdl ) );
 
    mxLbColorDepth->connect_changed( LINK( this, ExportDialog, SelectListBoxHdl ) );
 
    mxCbInterlaced->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
 
    mxCbLossless->connect_toggled( LINK( this, ExportDialog, UpdateHdlLossless ) );
 
    mxCbSaveTransparency->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
 
    mxModifyDimension->connect_toggled( LINK( this, ExportDialog, UpdateLock ) );
    mxModifyResolution->connect_toggled( LINK( this, ExportDialog, UpdateLock ) );
 
    mxCbEPSPreviewTIFF->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
    mxCbEPSPreviewEPSI->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
 
    mxRbEPSCompressionLZW->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
    mxRbEPSCompressionNone->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
 
    mxRbBinary->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
    mxRbText->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
 
    // BMP
    mxCbRLEEncoding->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
 
    // EPS
    mxRbEPSLevel1->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
    mxRbEPSLevel2->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
 
    mxBtnOK->connect_clicked( LINK( this, ExportDialog, OK ) );
 
    updateControls();
}
 
void ExportDialog::setupSizeControls()
{
    sal_Int32 nUnit = mnInitialResolutionUnit;
    if (nUnit == UNIT_DEFAULT)
        nUnit = GetDefaultUnit();
 
    if (!mbIsPixelFormat)
    {
        mxFtResolution->hide();
        mxNfResolution->hide();
        mxLbResolution->hide();
        mxLbSizeX->remove( UNIT_PIXEL );        // removing pixel
        if ( nUnit >= UNIT_PIXEL )
            nUnit = UNIT_CM;
    }
    else if ( nUnit > UNIT_MAX_ID )
        nUnit = UNIT_PIXEL;
    if ( nUnit < 0 )
        nUnit = UNIT_CM;
    mxLbSizeX->set_active( static_cast< sal_uInt16 >( nUnit ) );
 
    if ( !mbIsPixelFormat )      // TODO: (metafileresolutionsupport) should be supported for vector formats also... this makes
        return;
 
// sense eg for bitmap fillings in metafiles, to preserve high dpi output
                            // (atm without special vector support the bitmaps are rendered with 96dpi)
    sal_Int32 nResolution = mpOptionsItem->ReadInt32(u"PixelExportResolution"_ustr, 96);
    if ( nResolution < 1 )
        nResolution = 96;
    mxNfResolution->set_value( nResolution );
 
    sal_Int32 nResolutionUnit = mpOptionsItem->ReadInt32(u"PixelExportResolutionUnit"_ustr, 1);
    if ( ( nResolutionUnit < 0 ) || ( nResolutionUnit > 2 ) )
        nResolutionUnit = 1;
    mxLbResolution->set_active( static_cast< sal_uInt16 >( nResolutionUnit ) );
}
 
void ExportDialog::createFilterOptions()
{
    switch( mnFormat )
    {
        case FORMAT_JPG :
        {
            sal_Int32 nColor = mpFilterOptionsItem->ReadInt32(u"ColorMode"_ustr, 0);
            if ( nColor == 1 )
                nColor = 0;
            else
                nColor = 1;
            mxLbColorDepth->append_text( ms8BitGrayscale );
            mxLbColorDepth->append_text( ms24BitColor );
            mxLbColorDepth->set_active( nColor );
            mxColorDepth->show();
 
            // Quality
            mxJPGWEBPQuality->show();
            sal_Int32 nQuality = mpFilterOptionsItem->ReadInt32(u"Quality"_ustr, 75);
            if ((nQuality < 1 ) || (nQuality > 100))
                nQuality = 75;
            mpSbCompression = mxSbJpgWebpCompression.get();
            mpNfCompression = mxNfJpgWebpCompression.get();
            mpSbCompression->set_range(1, 100);
            mpNfCompression->set_range(1, 100);
            mpNfCompression->set_value(nQuality);
            mxCbLossless->hide(); // only for WebP
        }
        break;
        case FORMAT_PNG :
        {
            // Compression 1..9
            mxPNGCompression->show();
            sal_Int32 nCompression = mpFilterOptionsItem->ReadInt32(u"Compression"_ustr, 6);
            if ( ( nCompression < 1 ) || ( nCompression > 9 ) )
                nCompression = 6;
 
            mpSbCompression = mxSbPngCompression.get();
            mpNfCompression = mxNfPngCompression.get();
            mpSbCompression->set_range(1, 9);
            mpNfCompression->set_range(1, 9);
            mpNfCompression->set_value(nCompression);
 
            // Interlaced
            mxMode->show();
            mxCbInterlaced->set_active(mpFilterOptionsItem->ReadInt32(u"Interlaced"_ustr, 0) != 0);
 
            // Transparency
            mxDrawingObjects->show();
            mxCbSaveTransparency->set_active(mpFilterOptionsItem->ReadInt32(u"Translucent"_ustr, 1) != 0);
        }
        break;
        case FORMAT_BMP :
        {
            sal_Int32 nColor = mpFilterOptionsItem->ReadInt32(u"Color"_ustr, 0);
            if ( nColor == 0 )
                nColor = 6;
            else
                nColor--;
            mxLbColorDepth->append_text( ms1BitThreshold );
            mxLbColorDepth->append_text( ms8BitGrayscale );
            mxLbColorDepth->append_text( ms8BitColorPalette );
            mxLbColorDepth->append_text( ms24BitColor );
            mxLbColorDepth->set_active( nColor );
            mxColorDepth->show();
 
            // RLE coding
            mxBMPCompression->show();
            mxCbRLEEncoding->set_active(mpFilterOptionsItem->ReadBool(u"RLE_Coding"_ustr, true));
        }
        break;
        case FORMAT_GIF :
        {
            // Interlaced
            mxMode->show();
            mxCbInterlaced->set_active(mpFilterOptionsItem->ReadInt32(u"Interlaced"_ustr, 1) != 0);
 
            // Transparency
            mxDrawingObjects->show();
            mxCbSaveTransparency->set_active(mpFilterOptionsItem->ReadInt32(u"Translucent"_ustr, 1) != 0);
        }
        break;
        case FORMAT_EPS :
        {
            mxEPSGrid->show();
 
            sal_Int32 nPreview = mpFilterOptionsItem->ReadInt32(u"Preview"_ustr, 0);
            sal_Int32 nVersion = mpFilterOptionsItem->ReadInt32(u"Version"_ustr, 2);
            sal_Int32 nColor = mpFilterOptionsItem->ReadInt32(u"ColorFormat"_ustr, 0);
            sal_Int32 nCompr = mpFilterOptionsItem->ReadInt32(u"CompressionMode"_ustr, 2);
 
            mpFilterOptionsItem->ReadInt32(u"TextMode"_ustr, 0);
 
            mxCbEPSPreviewTIFF->set_active( ( nPreview & 1 ) != 0 );
            mxCbEPSPreviewEPSI->set_active( ( nPreview & 2 ) != 0 );
 
            mxRbEPSLevel1->set_active( nVersion == 1 );
            mxRbEPSLevel2->set_active( nVersion == 2 );
 
            mxRbEPSColorFormat1->set_active( nColor == 1 );
            mxRbEPSColorFormat2->set_active( nColor != 1 );
 
            mxRbEPSCompressionLZW->set_active( nCompr == 1 );
            mxRbEPSCompressionNone->set_active( nCompr != 1 );
        }
        break;
        case FORMAT_WEBP :
        {
            // Quality
            mxJPGWEBPQuality->show();
            sal_Int32 nQuality = mpFilterOptionsItem->ReadInt32(u"Quality"_ustr, 75);
            if ((nQuality < 1 ) || (nQuality > 100))
                nQuality = 75;
            mpSbCompression = mxSbJpgWebpCompression.get();
            mpNfCompression = mxNfJpgWebpCompression.get();
            mpSbCompression->set_range(1, 100);
            mpNfCompression->set_range(1, 100);
            mpNfCompression->set_value(nQuality);
 
            // Lossless
            mxCbLossless->set_active(mpFilterOptionsItem->ReadBool(u"Lossless"_ustr, true));
            UpdateHdlLossless(*mxCbLossless);
        }
        break;
    }
}
 
void ExportDialog::setupControls()
{
    setupSizeControls();
    createFilterOptions();
 
    if (mnMaxFilesizeForRealtimePreview || mbIsPixelFormat)
        mxInfo->show();
}
 
static OUString ImpValueOfInKB( sal_Int64 rVal )
{
    double fVal( static_cast<double>( rVal ) );
    fVal /= ( 1 << 10 );
    fVal += 0.05;
    OUStringBuffer aVal( OUString::number( fVal ) );
    sal_Int32 nX( aVal.indexOf( '.' ) );
    if ( nX > 0 )
        aVal.setLength( nX + 2 );
    return aVal.makeStringAndClear();
}
 
void ExportDialog::updateControls()
{
    // Size Controls
    if ( !mbIsPixelFormat )
    {
        awt::Size aSize100thmm( maSize );
        Size aSize( OutputDevice::LogicToLogic( Size(aSize100thmm.Width * 100, aSize100thmm.Height * 100),
            MapMode(MapUnit::Map100thMM),
            MapMode( GetMapUnit( mxLbSizeX->get_active() ) ) ) );
        mxMfSizeX->set_value( aSize.Width() );
        mxMfSizeY->set_value( aSize.Height() );
    }
    else
    {
        MapUnit aMapUnit( GetMapUnit( mxLbSizeX->get_active() ) );
        if ( aMapUnit == MapUnit::MapPixel )
        {   // calculating pixel count via resolution and original graphic size
            mxMfSizeX->set_digits( 0 );
            mxMfSizeY->set_digits( 0 );
            mxMfSizeX->set_value( maSize.Width );
            mxMfSizeY->set_value( maSize.Height );
        }
        else
        {
            mxMfSizeX->set_digits( 2 );
            mxMfSizeY->set_digits( 2 );
            double fRatio;
            switch( GetMapUnit( mxLbSizeX->get_active() ) )
            {
                case MapUnit::MapInch : fRatio = static_cast< double >( maResolution.Width ) * 0.0254; break;
                case MapUnit::MapMM :   fRatio = static_cast< double >( maResolution.Width ) * 0.001; break;
                case MapUnit::MapPoint :fRatio = ( static_cast< double >( maResolution.Width ) * 0.0254 ) / 72.0; break;
                default:
                case MapUnit::MapCM :   fRatio = static_cast< double >( maResolution.Width ) * 0.01; break;
            }
            mxMfSizeX->set_value( static_cast< sal_Int32 >( ( static_cast< double >( maSize.Width * 100 ) / fRatio ) + 0.5 ) );
            mxMfSizeY->set_value( static_cast< sal_Int32 >( ( static_cast< double >( maSize.Height * 100 ) / fRatio ) + 0.5 ) );
        }
    }
    sal_Int32 nResolution = 0;
    switch( mxLbResolution->get_active() )
    {
        case 0 : nResolution = maResolution.Width / 100; break;     // pixels / cm
        case 2 : nResolution = maResolution.Width; break;           // pixels / meter
        default:
        case 1 : nResolution = static_cast< sal_Int32 >(maResolution.Width * 0.0254); break;    // pixels / inch
    }
    mxNfResolution->set_value( nResolution );
 
    if (mpSbCompression && mpSbCompression->get_visible() && mpNfCompression)
        mpSbCompression->set_value(mpNfCompression->get_value());
 
    GetGraphicStream();
 
    // updating estimated size
    sal_Int64 nRealFileSize( mpTempStream->Tell() );
    if ( mbIsPixelFormat )
    {
        OUString aEst( nRealFileSize ? msEstimatedSizePix2 : msEstimatedSizePix1 );
        sal_Int64 nRawFileSize( GetRawFileSize() );
        sal_Int32 nInd = aEst.indexOf( "%" );
        if (nInd != -1)
            aEst = aEst.replaceAt( nInd, 2, ImpValueOfInKB( nRawFileSize ) );
 
        if ( nRealFileSize && nInd != -1 )
        {
            nInd = aEst.indexOf( "%", nInd );
            if (nInd != -1)
                aEst = aEst.replaceAt( nInd, 2, ImpValueOfInKB( nRealFileSize ) );
        }
        mxFtEstimatedSize->set_label( aEst );
    }
    else
    {
        if ( mnMaxFilesizeForRealtimePreview )
        {
            OUString aEst( msEstimatedSizeVec );
            sal_Int32 nInd = aEst.indexOf( "%" );
            if (nInd != -1)
                aEst = aEst.replaceAt( nInd, 2, ImpValueOfInKB( nRealFileSize ) );
            mxFtEstimatedSize->set_label( aEst );
        }
    }
 
    // EPS
    if ( mxRbEPSLevel1->get_visible() )
    {
        bool bEnabled = !mxRbEPSLevel1->get_active();
        mxRbEPSColorFormat1->set_sensitive( bEnabled );
        mxRbEPSColorFormat2->set_sensitive( bEnabled );
        mxRbEPSCompressionLZW->set_sensitive( bEnabled );
        mxRbEPSCompressionNone->set_sensitive( bEnabled );
    }
}
 
ExportDialog::~ExportDialog()
{
}
 
/*************************************************************************
|*
|* stores values set in the ini-file
|*
\************************************************************************/
IMPL_LINK_NOARG(ExportDialog, SelectHdl, weld::SpinButton&, void)
{
    updateControls();
}
 
IMPL_LINK_NOARG(ExportDialog, SelectListBoxHdl, weld::ComboBox&, void)
{
    updateControls();
}
 
IMPL_LINK_NOARG(ExportDialog, UpdateHdl, weld::Toggleable&, void)
{
    updateControls();
}
 
IMPL_LINK_NOARG(ExportDialog, UpdateHdlLossless, weld::Toggleable&, void)
{
    mpSbCompression->set_sensitive(!mxCbLossless->get_active());
    mpNfCompression->set_sensitive(!mxCbLossless->get_active());
    updateControls();
}
 
IMPL_LINK_NOARG(ExportDialog, UpdateLock, weld::Toggleable&, void)
{
    if (mxModifyResolution->get_active())
    {
        mxMfSizeY->set_sensitive(false);
        mxMfSizeX->set_sensitive(false);
        mxNfResolution->set_sensitive(true);
    }
    else
    {
        mxMfSizeY->set_sensitive(true);
        mxMfSizeX->set_sensitive(true);
        mxNfResolution->set_sensitive(false);
    }
    updateControls();
}
 
 
IMPL_LINK_NOARG(ExportDialog, UpdateHdlMtfSizeX, weld::SpinButton&, void)
{
    double fRatio = static_cast< double >( maOriginalSize.Height ) / maOriginalSize.Width;
 
    if ( mbIsPixelFormat )
    {
        switch( GetMapUnit( mxLbSizeX->get_active() ) )
        {
            case MapUnit::MapInch :     maSize.Width = static_cast< sal_Int32 >( static_cast< double >( maResolution.Width ) * 0.0254 * mxMfSizeX->get_value() / 100.0 + 0.5 ); break;
            case MapUnit::MapCM :       maSize.Width = static_cast< sal_Int32 >( static_cast< double >( maResolution.Width ) * 0.01 * mxMfSizeX->get_value() / 100.0 + 0.5 ); break;
            case MapUnit::MapMM :       maSize.Width = static_cast< sal_Int32 >( static_cast< double >( maResolution.Width ) * 0.001 * mxMfSizeX->get_value() / 100.0 + 0.5 ); break;
            case MapUnit::MapPoint :    maSize.Width = static_cast< sal_Int32 >( static_cast< double >( maResolution.Width ) * 0.0254 * mxMfSizeX->get_value() / 100.0 * 72 + 0.5 ); break;
            default:
            case MapUnit::MapPixel :    maSize.Width = mxMfSizeX->get_value(); break;
        }
        maSize.Height = static_cast< sal_Int32 >( fRatio * maSize.Width + 0.5 );
    }
    else
    {
        Fraction aFract( 1, 100 );
        sal_Int32 nWidth = mxMfSizeX->get_value();
        sal_Int32 nHeight= static_cast< sal_Int32 >( nWidth * fRatio );
        const Size aSource( nWidth, nHeight );
        MapMode aSourceMapMode( GetMapUnit( mxLbSizeX->get_active() ),Point(), aFract, aFract );
        Size aDest(OutputDevice::LogicToLogic(aSource, aSourceMapMode, MapMode(MapUnit::Map100thMM)));
 
        maSize.Width = aDest.Width();
        maSize.Height = aDest.Height();
    }
    updateControls();
}
 
IMPL_LINK_NOARG(ExportDialog, UpdateHdlMtfSizeY, weld::SpinButton&, void)
{
    double fRatio = static_cast< double >( maOriginalSize.Width ) / maOriginalSize.Height;
 
    if ( mbIsPixelFormat )
    {
        switch( GetMapUnit( mxLbSizeX->get_active() ) )
        {
            case MapUnit::MapInch :     maSize.Height = static_cast< sal_Int32 >( static_cast< double >( maResolution.Height ) * 0.0254 * mxMfSizeY->get_value() / 100.0 + 0.5 ); break;
            case MapUnit::MapCM :       maSize.Height = static_cast< sal_Int32 >( static_cast< double >( maResolution.Height ) * 0.01 * mxMfSizeY->get_value() / 100.0 + 0.5 ); break;
            case MapUnit::MapMM :       maSize.Height = static_cast< sal_Int32 >( static_cast< double >( maResolution.Height ) * 0.001 * mxMfSizeY->get_value() / 100.0 + 0.5 ); break;
            case MapUnit::MapPoint :    maSize.Height = static_cast< sal_Int32 >( static_cast< double >( maResolution.Height ) * 0.0254 * mxMfSizeY->get_value() / 100.0 * 72 + 0.5 ); break;
            default:
            case MapUnit::MapPixel :    maSize.Height = mxMfSizeY->get_value(); break;
        }
        maSize.Width = static_cast< sal_Int32 >( fRatio * maSize.Height + 0.5 );
    }
    else
    {
        Fraction aFract( 1, 100 );
        sal_Int32 nHeight= mxMfSizeY->get_value();
        sal_Int32 nWidth = static_cast< sal_Int32 >( nHeight * fRatio );
        const Size aSource( nWidth, nHeight );
        MapMode aSourceMapMode( GetMapUnit( mxLbSizeX->get_active() ),Point(), aFract, aFract );
        Size aDest( OutputDevice::LogicToLogic(aSource, aSourceMapMode, MapMode(MapUnit::Map100thMM)) );
 
        maSize.Height = aDest.Height();
        maSize.Width = aDest.Width();
    }
    updateControls();
}
 
IMPL_LINK_NOARG(ExportDialog, UpdateHdlNfResolution, weld::SpinButton&, void)
{
    auto nResolution = mxNfResolution->get_value();
    if ( mxLbResolution->get_active() == 0 )      // pixels / cm
        nResolution *= 100;
    else if ( mxLbResolution->get_active() == 1 ) // pixels / inch
        nResolution = static_cast< sal_Int32 >( ( ( static_cast< double >( nResolution ) + 0.5 ) / 0.0254 ) );
    maResolution.Width = nResolution;
    maResolution.Height= nResolution;
 
    updateControls();
}
 
IMPL_LINK_NOARG(ExportDialog, SbCompressionUpdateHdl, weld::Scale&, void)
{
    mpNfCompression->set_value(mpSbCompression->get_value());
    updateControls();
}
 
IMPL_LINK_NOARG(ExportDialog, OK, weld::Button&, void)
{
    // writing config parameter
 
    mrFltCallPara.aFilterData = GetFilterData( true );
    m_xDialog->response(RET_OK);
}
 
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

V516 Consider inspecting an odd expression. Non-null function pointer is compared to null: 'maResolution.Height'.

V516 Consider inspecting an odd expression. Non-null function pointer is compared to null: 'maResolution.Width'.

V516 Consider inspecting an odd expression. Non-null function pointer is compared to null: 'maSize.Height'.

V516 Consider inspecting an odd expression. Non-null function pointer is compared to null: 'maSize.Width'.

V530 The return value of function 'ExportGraphic' is required to be utilized.

V547 Expression 'mbIsPixelFormat' is always true.

V1048 The 'aMapUnit' variable was assigned the same value.

V1048 The 'nBitsPerPixel' variable was assigned the same value.