/* -*- 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() ) ) )
                    {
                        Bitmap aBmp( aGraphic.GetBitmap() );
                        // export: use highest quality
                        aBmp.Scale( Size( maSize.Width, maSize.Height ), BmpScaleFlag::Lanczos );
                        aGraphic = aBmp;
                    }
                }
 
                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();
 
    // resizing SVG can take a long time
    if (mnFormat == FORMAT_SVG)
    {
        mxFtEstimatedSize->hide();
        mxInfo->hide();
    }
}
 
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
        {
            double x = double(maSize.Width) / maResolution.Width; // pixels -> meters
            x = o3tl::convert(x, o3tl::Length::m, MapToO3tlLength(aMapUnit));
            mxMfSizeX->set_digits( 2 );
            mxMfSizeX->set_value(x * weld::SpinButton::Power10(mxMfSizeX->get_digits()) + 0.5);
            double y = double(maSize.Height) / maResolution.Height; // pixels -> meters
            y = o3tl::convert(y, o3tl::Length::m, MapToO3tlLength(aMapUnit));
            mxMfSizeY->set_digits( 2 );
            mxMfSizeY->set_value(y * weld::SpinButton::Power10(mxMfSizeY->get_digits()) + 0.5);
        }
    }
    sal_Int32 nResolution = maResolution.Width;
    if (mxLbResolution->get_active() == 0) // pixels / cm
        nResolution = o3tl::convert(nResolution, o3tl::Length::cm, o3tl::Length::m); // reverse
    else if (mxLbResolution->get_active() == 1) // pixels / inch
        nResolution = o3tl::convert(nResolution, o3tl::Length::in, o3tl::Length::m); // reverse
    mxNfResolution->set_value( nResolution );
 
    if (mpSbCompression && mpSbCompression->get_visible() && mpNfCompression)
        mpSbCompression->set_value(mpNfCompression->get_value());
 
    // resizing SVG can take a long time
    if (mnFormat != FORMAT_SVG)
    {
        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 )
    {
        const MapUnit unit = GetMapUnit(mxLbSizeX->get_active());
        if (unit == MapUnit::MapPixel)
        {
            maSize.Width = mxMfSizeX->get_value();
        }
        else
        {
            double val = mxMfSizeX->get_value()
                         / static_cast<double>(weld::SpinButton::Power10(mxMfSizeX->get_digits()));
            // Convert to meters, since resolution is in pixels per meter
            val = o3tl::convert(val, MapToO3tlLength(unit), o3tl::Length::m);
            maSize.Width = static_cast<sal_Int32>(maResolution.Width * val + 0.5);
        }
        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 )
    {
        const MapUnit unit = GetMapUnit(mxLbSizeX->get_active());
        if (unit == MapUnit::MapPixel)
        {
            maSize.Height = mxMfSizeY->get_value();
        }
        else
        {
            double val = mxMfSizeY->get_value()
                         / static_cast<double>(weld::SpinButton::Power10(mxMfSizeY->get_digits()));
            // Convert to meters, since resolution is in pixels per meter
            val = o3tl::convert(val, MapToO3tlLength(unit), o3tl::Length::m);
            maSize.Height = static_cast<sal_Int32>(maResolution.Height * val + 0.5);
        }
        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 = o3tl::convert(nResolution, o3tl::Length::m, o3tl::Length::cm); // reverse
    else if ( mxLbResolution->get_active() == 1 ) // pixels / inch
        nResolution = o3tl::convert(nResolution, o3tl::Length::m, o3tl::Length::in); // reverse
    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.