summaryrefslogtreecommitdiffstats
path: root/svtools/source/filter
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /svtools/source/filter
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svtools/source/filter')
-rw-r--r--svtools/source/filter/DocumentToGraphicRenderer.cxx340
-rw-r--r--svtools/source/filter/SvFilterOptionsDialog.cxx290
-rw-r--r--svtools/source/filter/exportdialog.cxx1136
-rw-r--r--svtools/source/filter/exportdialog.hxx186
4 files changed, 1952 insertions, 0 deletions
diff --git a/svtools/source/filter/DocumentToGraphicRenderer.cxx b/svtools/source/filter/DocumentToGraphicRenderer.cxx
new file mode 100644
index 000000000..c2858a1da
--- /dev/null
+++ b/svtools/source/filter/DocumentToGraphicRenderer.cxx
@@ -0,0 +1,340 @@
+/* -*- 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 <svtools/DocumentToGraphicRenderer.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
+
+#include <tools/fract.hxx>
+
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XToolkit.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/view/XRenderable.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::lang;
+using namespace css::beans;
+
+DocumentToGraphicRenderer::DocumentToGraphicRenderer( const Reference<XComponent>& rxDocument, bool bSelectionOnly ) :
+ mxDocument(rxDocument),
+ mxModel( mxDocument, uno::UNO_QUERY ),
+ mxController( mxModel->getCurrentController() ),
+ mxRenderable (mxDocument, uno::UNO_QUERY ),
+ mxToolkit( VCLUnoHelper::CreateToolkit() ),
+ meDocType( UNKNOWN )
+{
+ try
+ {
+ uno::Reference< lang::XServiceInfo > xServiceInfo( mxDocument, uno::UNO_QUERY);
+ if (xServiceInfo.is())
+ {
+ if (xServiceInfo->supportsService("com.sun.star.text.TextDocument"))
+ meDocType = WRITER;
+ else if (xServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
+ meDocType = CALC;
+ else if (xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument"))
+ meDocType = IMPRESS;
+ else
+ meDocType = UNKNOWN;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ if (!(bSelectionOnly && mxController.is()))
+ return;
+
+ try
+ {
+ uno::Reference< view::XSelectionSupplier > xSelSup( mxController, uno::UNO_QUERY);
+ if (xSelSup.is())
+ {
+ uno::Any aViewSelection( xSelSup->getSelection());
+ if (aViewSelection.hasValue())
+ {
+ /* FIXME: Writer always has a selection even if nothing is
+ * selected, but passing a selection to
+ * XRenderable::render() it always renders an empty page.
+ * So disable the selection already here. The current page
+ * the cursor is on is rendered. */
+ if (!isWriter())
+ maSelection = aViewSelection;
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+DocumentToGraphicRenderer::~DocumentToGraphicRenderer()
+{
+}
+
+Size DocumentToGraphicRenderer::getDocumentSizeInPixels(sal_Int32 nCurrentPage)
+{
+ Size aSize100mm = getDocumentSizeIn100mm(nCurrentPage);
+ return Application::GetDefaultDevice()->LogicToPixel(aSize100mm, MapMode(MapUnit::Map100thMM));
+}
+
+bool DocumentToGraphicRenderer::hasSelection() const
+{
+ return maSelection.hasValue();
+}
+
+uno::Any DocumentToGraphicRenderer::getSelection() const
+{
+ uno::Any aSelection;
+ if (hasSelection())
+ aSelection = maSelection;
+ else
+ aSelection <<= mxDocument; // default: render whole document
+ return aSelection;
+}
+
+Size DocumentToGraphicRenderer::getDocumentSizeIn100mm(sal_Int32 nCurrentPage,
+ Point* pDocumentPosition, Point* pCalcPagePosition, Size* pCalcPageSize)
+{
+ Reference< awt::XDevice > xDevice(mxToolkit->createScreenCompatibleDevice( 32, 32 ) );
+
+ uno::Any selection( getSelection());
+
+ PropertyValues renderProperties{ comphelper::makePropertyValue("IsPrinter", true),
+ comphelper::makePropertyValue("RenderDevice", xDevice),
+ comphelper::makePropertyValue("View", mxController),
+ comphelper::makePropertyValue("RenderToGraphic", true) };
+
+ awt::Size aSize;
+ awt::Size aCalcPageSize;
+ awt::Point aPos;
+ awt::Point aCalcPos;
+
+ sal_Int32 nPages = mxRenderable->getRendererCount( selection, renderProperties );
+ if (nPages >= nCurrentPage)
+ {
+ const Sequence< beans::PropertyValue > aResult = mxRenderable->getRenderer(nCurrentPage - 1, selection, renderProperties );
+ for( const auto& rProperty : aResult )
+ {
+ if ( rProperty.Name == "PageSize" )
+ {
+ rProperty.Value >>= aSize;
+ }
+ else if (rProperty.Name == "PagePos")
+ {
+ rProperty.Value >>= aPos;
+ }
+ else if (rProperty.Name == "CalcPagePos")
+ {
+ rProperty.Value >>= aCalcPos;
+ }
+ else if (rProperty.Name == "CalcPageContentSize")
+ {
+ rProperty.Value >>= aCalcPageSize;
+ }
+ }
+ }
+
+ if (pDocumentPosition)
+ {
+ *pDocumentPosition = Point(aPos.X, aPos.Y);
+ }
+ if (pCalcPagePosition)
+ {
+ *pCalcPagePosition = Point(aCalcPos.X, aCalcPos.Y);
+ }
+ if (pCalcPageSize)
+ {
+ *pCalcPageSize = Size(aCalcPageSize.Width, aCalcPageSize.Height);
+ }
+
+ return Size( aSize.Width, aSize.Height );
+}
+
+Graphic DocumentToGraphicRenderer::renderToGraphic(
+ sal_Int32 nCurrentPage,
+ Size aDocumentSizePixel,
+ Size aTargetSizePixel,
+ Color aPageColor,
+ bool bExtOutDevData)
+
+{
+ if (!mxModel.is() || !mxController.is() || !mxRenderable.is())
+ return Graphic();
+
+ Reference< awt::XDevice > xDevice(mxToolkit->createScreenCompatibleDevice( aTargetSizePixel.Width(), aTargetSizePixel.Height() ) );
+ if (!xDevice.is())
+ return Graphic();
+
+ assert( !aDocumentSizePixel.IsEmpty() && !aTargetSizePixel.IsEmpty());
+
+ double fScaleX = aTargetSizePixel.Width() / static_cast<double>(aDocumentSizePixel.Width());
+ double fScaleY = aTargetSizePixel.Height() / static_cast<double>(aDocumentSizePixel.Height());
+
+ PropertyValues renderProps{
+ comphelper::makePropertyValue("IsPrinter", true),
+ comphelper::makePropertyValue("RenderDevice", xDevice),
+ comphelper::makePropertyValue("View", mxController),
+ comphelper::makePropertyValue("RenderToGraphic", true),
+ comphelper::makePropertyValue("HasPDFExtOutDevData", bExtOutDevData),
+ comphelper::makePropertyValue("PageRange", OUString::number(nCurrentPage))
+ };
+
+ GDIMetaFile aMtf;
+
+ OutputDevice* pOutputDev = VCLUnoHelper::GetOutputDevice( xDevice );
+
+ vcl::PDFExtOutDevData aPDFExtOutDevData(*pOutputDev);
+ if (bExtOutDevData)
+ {
+ aPDFExtOutDevData.SetIsExportBookmarks(true);
+ pOutputDev->SetExtOutDevData(&aPDFExtOutDevData);
+ }
+
+ pOutputDev->SetAntialiasing(pOutputDev->GetAntialiasing() | AntialiasingFlags::Enable);
+ MapMode mm = pOutputDev->GetMapMode();
+ mm.SetScaleX( Fraction(fScaleX) );
+ mm.SetScaleY( Fraction(fScaleY) );
+ pOutputDev->SetMapMode( mm );
+
+ aMtf.Record( pOutputDev );
+
+ if (aPageColor != COL_TRANSPARENT)
+ {
+ pOutputDev->SetBackground(Wallpaper(aPageColor));
+ pOutputDev->Erase();
+ }
+
+ uno::Any aSelection( getSelection());
+ mxRenderable->render(nCurrentPage - 1, aSelection, renderProps );
+
+ aMtf.Stop();
+ aMtf.WindStart();
+ aMtf.SetPrefSize( aTargetSizePixel );
+
+ if (bExtOutDevData)
+ maChapterNames = aPDFExtOutDevData.GetChapterNames();
+
+ return Graphic(aMtf);
+}
+
+const std::vector<OUString>& DocumentToGraphicRenderer::getChapterNames() const
+{
+ return maChapterNames;
+}
+
+sal_Int32 DocumentToGraphicRenderer::getCurrentPage()
+{
+ if (hasSelection())
+ return 1;
+
+ if (isWriter())
+ return getCurrentPageWriter();
+
+ /* TODO: other application specific page detection? */
+ return 1;
+}
+
+sal_Int32 DocumentToGraphicRenderer::getPageCount()
+{
+ Reference< awt::XDevice > xDevice(mxToolkit->createScreenCompatibleDevice( 32, 32 ) );
+
+ uno::Any selection( getSelection() );
+
+ PropertyValues renderProperties{ comphelper::makePropertyValue("IsPrinter", true),
+ comphelper::makePropertyValue("RenderDevice", xDevice),
+ comphelper::makePropertyValue("View", mxController),
+ comphelper::makePropertyValue("RenderToGraphic", true) };
+
+ sal_Int32 nPages = mxRenderable->getRendererCount( selection, renderProperties );
+
+ return nPages;
+}
+
+sal_Int32 DocumentToGraphicRenderer::getCurrentPageWriter()
+{
+ Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(mxModel->getCurrentController(), UNO_QUERY);
+ if (!xTextViewCursorSupplier.is())
+ return 1;
+ Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), UNO_QUERY);
+ return xCursor.is() ? xCursor->getPage() : 1;
+}
+
+// static
+bool DocumentToGraphicRenderer::isShapeSelected(
+ css::uno::Reference< css::drawing::XShapes > & rxShapes,
+ css::uno::Reference< css::drawing::XShape > & rxShape,
+ const css::uno::Reference< css::frame::XController > & rxController )
+{
+ bool bShape = false;
+ if (rxController.is())
+ {
+ uno::Reference< view::XSelectionSupplier > xSelectionSupplier( rxController, uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ {
+ uno::Any aAny( xSelectionSupplier->getSelection());
+ if (aAny >>= rxShapes)
+ bShape = true;
+ else if (aAny >>= rxShape)
+ bShape = true;
+ }
+ }
+ return bShape;
+}
+
+bool DocumentToGraphicRenderer::isWriter() const
+{
+ if (meDocType == WRITER)
+ return true;
+ else
+ return false;
+}
+
+bool DocumentToGraphicRenderer::isCalc() const
+{
+ if (meDocType == CALC)
+ return true;
+ else
+ return false;
+}
+
+bool DocumentToGraphicRenderer::isImpress() const
+{
+ if (meDocType == IMPRESS)
+ return true;
+ else
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/filter/SvFilterOptionsDialog.cxx b/svtools/source/filter/SvFilterOptionsDialog.cxx
new file mode 100644
index 000000000..5d0926ace
--- /dev/null
+++ b/svtools/source/filter/SvFilterOptionsDialog.cxx
@@ -0,0 +1,290 @@
+/* -*- 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 <vcl/FilterConfigItem.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/svapp.hxx>
+#include <FltCallDialogParameter.hxx>
+#include "exportdialog.hxx"
+#include <tools/fldunit.hxx>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/document/XExporter.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>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class SvFilterOptionsDialog : public cppu::WeakImplHelper
+<
+ document::XExporter,
+ ui::dialogs::XExecutableDialog,
+ beans::XPropertyAccess,
+ lang::XInitialization,
+ lang::XServiceInfo
+>
+{
+ const uno::Reference< uno::XComponentContext >
+ mxContext;
+ uno::Sequence< beans::PropertyValue >
+ maMediaDescriptor;
+ uno::Sequence< beans::PropertyValue >
+ maFilterDataSequence;
+ uno::Reference< lang::XComponent >
+ mxSourceDocument;
+
+ css::uno::Reference<css::awt::XWindow> mxParent;
+ FieldUnit meFieldUnit;
+ bool mbExportSelection;
+ bool mbGraphicsSource;
+
+public:
+
+ explicit SvFilterOptionsDialog( const uno::Reference< uno::XComponentContext >& _rxORB );
+
+ // XInterface
+ virtual void SAL_CALL acquire() noexcept override;
+ virtual void SAL_CALL release() noexcept override;
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const uno::Sequence< uno::Any > & aArguments ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ // XPropertyAccess
+ virtual uno::Sequence< beans::PropertyValue > SAL_CALL getPropertyValues() override;
+ virtual void SAL_CALL setPropertyValues( const uno::Sequence< beans::PropertyValue > & aProps ) override;
+
+ // XExecuteDialog
+ virtual sal_Int16 SAL_CALL execute() override;
+ virtual void SAL_CALL setTitle( const OUString& aTitle ) override;
+
+ // XExporter
+ virtual void SAL_CALL setSourceDocument( const uno::Reference< lang::XComponent >& xDoc ) override;
+
+};
+
+SvFilterOptionsDialog::SvFilterOptionsDialog( const uno::Reference< uno::XComponentContext >& rxContext ) :
+ mxContext ( rxContext ),
+ meFieldUnit ( FieldUnit::CM ),
+ mbExportSelection ( false ),
+ mbGraphicsSource ( true )
+{
+}
+
+void SAL_CALL SvFilterOptionsDialog::acquire() noexcept
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL SvFilterOptionsDialog::release() noexcept
+{
+ OWeakObject::release();
+}
+
+// XInitialization
+void SAL_CALL SvFilterOptionsDialog::initialize(const uno::Sequence<uno::Any>& rArguments)
+{
+ for(const uno::Any& rArgument : rArguments)
+ {
+ beans::PropertyValue aProperty;
+ if (rArgument >>= aProperty)
+ {
+ if( aProperty.Name == "ParentWindow" )
+ {
+ aProperty.Value >>= mxParent;
+ }
+ }
+ }
+}
+
+// XServiceInfo
+OUString SAL_CALL SvFilterOptionsDialog::getImplementationName()
+{
+ return "com.sun.star.svtools.SvFilterOptionsDialog";
+}
+sal_Bool SAL_CALL SvFilterOptionsDialog::supportsService( const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+uno::Sequence< OUString > SAL_CALL SvFilterOptionsDialog::getSupportedServiceNames()
+{
+ return { "com.sun.star.ui.dialogs.FilterOptionsDialog" };
+}
+
+// XPropertyAccess
+uno::Sequence< beans::PropertyValue > SvFilterOptionsDialog::getPropertyValues()
+{
+ auto pProp = std::find_if(std::cbegin(maMediaDescriptor), std::cend(maMediaDescriptor),
+ [](const beans::PropertyValue& rProp) { return rProp.Name == "FilterData"; });
+ auto i = static_cast<sal_Int32>(std::distance(std::cbegin(maMediaDescriptor), pProp));
+ sal_Int32 nCount = maMediaDescriptor.getLength();
+ if ( i == nCount )
+ maMediaDescriptor.realloc( ++nCount );
+
+ // the "FilterData" Property is an Any that will contain our PropertySequence of Values
+ auto& item = maMediaDescriptor.getArray()[ i ];
+ item.Name = "FilterData";
+ item.Value <<= maFilterDataSequence;
+ return maMediaDescriptor;
+}
+
+void SvFilterOptionsDialog::setPropertyValues( const uno::Sequence< beans::PropertyValue > & aProps )
+{
+ maMediaDescriptor = aProps;
+
+ for ( const auto& rProp : std::as_const(maMediaDescriptor) )
+ {
+ if ( rProp.Name == "FilterData" )
+ {
+ rProp.Value >>= maFilterDataSequence;
+ }
+ else if ( rProp.Name == "SelectionOnly" )
+ {
+ rProp.Value >>= mbExportSelection;
+ }
+ }
+}
+
+// XExecutableDialog
+void SvFilterOptionsDialog::setTitle( const OUString& )
+{
+}
+
+sal_Int16 SvFilterOptionsDialog::execute()
+{
+ sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL;
+
+ OUString aInternalFilterName;
+ uno::Reference<graphic::XGraphic> xGraphic;
+ for ( const auto& rProp : std::as_const(maMediaDescriptor) )
+ {
+ const OUString& rName = rProp.Name;
+ if ( rName == "FilterName" )
+ {
+ OUString aStr;
+ rProp.Value >>= aStr;
+ aInternalFilterName = aStr.replaceFirst( "draw_", "" );
+ aInternalFilterName = aInternalFilterName.replaceFirst( "impress_", "" );
+ aInternalFilterName = aInternalFilterName.replaceFirst( "calc_", "" );
+ aInternalFilterName = aInternalFilterName.replaceFirst( "writer_", "" );
+ break;
+ }
+ else if ( rName == "Graphic" )
+ {
+ rProp.Value >>= xGraphic;
+ }
+ }
+ if ( !aInternalFilterName.isEmpty() )
+ {
+ GraphicFilter aGraphicFilter( true );
+
+ sal_uInt16 nFormat, nFilterCount = aGraphicFilter.GetExportFormatCount();
+ for ( nFormat = 0; nFormat < nFilterCount; nFormat++ )
+ {
+ if ( aGraphicFilter.GetExportInternalFilterName( nFormat ) == aInternalFilterName )
+ break;
+ }
+ if ( nFormat < nFilterCount )
+ {
+ FltCallDialogParameter aFltCallDlgPara(Application::GetFrameWeld(mxParent), meFieldUnit);
+ aFltCallDlgPara.aFilterData = maFilterDataSequence;
+ aFltCallDlgPara.aFilterExt = aGraphicFilter.GetExportFormatShortName( nFormat );
+ bool bIsPixelFormat( aGraphicFilter.IsExportPixelFormat( nFormat ) );
+
+ ExportDialog aDialog(aFltCallDlgPara, mxContext, mxSourceDocument, mbExportSelection,
+ bIsPixelFormat, mbGraphicsSource, xGraphic);
+ if (aDialog.run() == RET_OK)
+ nRet = ui::dialogs::ExecutableDialogResults::OK;
+
+ // taking the out parameter from the dialog
+ maFilterDataSequence = aFltCallDlgPara.aFilterData;
+ }
+ }
+ return nRet;
+}
+
+// XEmporter
+void SvFilterOptionsDialog::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
+{
+ mxSourceDocument = xDoc;
+
+ mbGraphicsSource = true; // default Draw and Impress like it was before
+
+ // try to set the corresponding metric unit
+ OUString aConfigPath;
+ uno::Reference< lang::XServiceInfo > xServiceInfo
+ ( xDoc, uno::UNO_QUERY );
+ if ( !xServiceInfo.is() )
+ return;
+
+ if ( xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument") )
+ aConfigPath = "Office.Impress/Layout/Other/MeasureUnit";
+ else if ( xServiceInfo->supportsService("com.sun.star.drawing.DrawingDocument") )
+ aConfigPath = "Office.Draw/Layout/Other/MeasureUnit";
+ else
+ {
+ mbGraphicsSource = false;
+ if ( xServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument") )
+ aConfigPath = "Office.Calc/Layout/Other/MeasureUnit";
+ else if ( xServiceInfo->supportsService("com.sun.star.text.TextDocument") )
+ aConfigPath = "Office.Writer/Layout/Other/MeasureUnit";
+ }
+ if ( !aConfigPath.isEmpty() )
+ {
+ FilterConfigItem aConfigItem( aConfigPath );
+ OUString aPropertyName;
+ SvtSysLocale aSysLocale;
+ if ( aSysLocale.GetLocaleData().getMeasurementSystemEnum() == MeasurementSystem::Metric )
+ aPropertyName = "Metric";
+ else
+ aPropertyName = "NonMetric";
+ meFieldUnit = static_cast<FieldUnit>(
+ aConfigItem.ReadInt32(aPropertyName, sal_Int32(FieldUnit::CM)));
+ }
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_svtools_SvFilterOptionsDialog_get_implementation(
+ css::uno::XComponentContext * context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new SvFilterOptionsDialog(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/filter/exportdialog.cxx b/svtools/source/filter/exportdialog.cxx
new file mode 100644
index 000000000..879c8ec01
--- /dev/null
+++ b/svtools/source/filter/exportdialog.cxx
@@ -0,0 +1,1136 @@
+/* -*- 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 <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 = UNIT_CM;
+ switch( mrFltCallPara.eFieldUnit )
+ {
+// case FieldUnit::NONE :
+// case FieldUnit::PERCENT :
+// case FieldUnit::CUSTOM :
+ default: nDefaultUnit = UNIT_CM; break;
+
+ case FieldUnit::MILE : // PASSTHROUGH INTENDED
+ case FieldUnit::FOOT :
+ case FieldUnit::TWIP :
+ case FieldUnit::PICA : nDefaultUnit = UNIT_INCH; break;
+
+ case FieldUnit::KM : // PASSTHROUGH INTENDED
+ case FieldUnit::M :
+ case FieldUnit::MM_100TH : nDefaultUnit = UNIT_CM; break;
+
+ case FieldUnit::INCH : nDefaultUnit = UNIT_INCH; break;
+ case FieldUnit::CM : nDefaultUnit = UNIT_CM; 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("PixelExportUnit", nUnit);
+ mpOptionsItem->WriteInt32("PixelExportResolution", nResolution);
+ mpOptionsItem->WriteInt32("PixelExportResolutionUnit", mxLbResolution->get_active());
+ }
+ else
+ {
+ if ( nUnit >= UNIT_PIXEL )
+ nUnit = UNIT_CM;
+
+ mpOptionsItem->WriteInt32("VectorExportUnit", nUnit);
+ }
+ }
+
+ FilterConfigItem* pFilterOptions;
+ if ( bUpdateConfig )
+ pFilterOptions = mpFilterOptionsItem.get();
+ else
+ {
+ uno::Sequence< beans::PropertyValue > aFilterData( mpFilterOptionsItem->GetFilterData() );
+ pFilterOptions = new FilterConfigItem( &aFilterData );
+ }
+
+ static const OUStringLiteral sLogicalWidth(u"LogicalWidth");
+ static const OUStringLiteral sLogicalHeight(u"LogicalHeight");
+ if ( mbIsPixelFormat )
+ {
+ pFilterOptions->WriteInt32("PixelWidth", maSize.Width );
+ pFilterOptions->WriteInt32("PixelHeight", 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("ColorMode", nColor);
+ assert(mpSbCompression);
+ pFilterOptions->WriteInt32("Quality", static_cast<sal_Int32>(mpSbCompression->get_value()));
+ }
+ break;
+
+ case FORMAT_PNG :
+ {
+ assert(mpSbCompression);
+ pFilterOptions->WriteInt32("Compression", static_cast<sal_Int32>(mpSbCompression->get_value()));
+ sal_Int32 nInterlace = 0;
+ if ( mxCbInterlaced->get_active() )
+ nInterlace++;
+ pFilterOptions->WriteInt32("Interlaced", nInterlace);
+ sal_Int32 nValue = 0;
+ if ( mxCbSaveTransparency->get_active() )
+ nValue++;
+ pFilterOptions->WriteInt32("Translucent", nValue);
+ }
+ break;
+
+ case FORMAT_BMP :
+ {
+ pFilterOptions->WriteInt32("Color", mxLbColorDepth->get_active() + 1);
+ pFilterOptions->WriteBool("RLE_Coding", mxCbRLEEncoding->get_active());
+ }
+ break;
+
+ case FORMAT_GIF :
+ {
+ sal_Int32 nValue = 0;
+ if ( mxCbInterlaced->get_active() )
+ nValue++;
+ pFilterOptions->WriteInt32("Interlaced", nValue);
+
+ nValue = 0;
+ if (mxCbSaveTransparency->get_active())
+ nValue++;
+ pFilterOptions->WriteInt32("Translucent", nValue);
+ }
+ break;
+
+ case FORMAT_EPS :
+ {
+ sal_Int32 nCheck = 0;
+ if ( mxCbEPSPreviewTIFF->get_active() )
+ nCheck++;
+ if ( mxCbEPSPreviewEPSI->get_active() )
+ nCheck += 2;
+ pFilterOptions->WriteInt32("Preview", nCheck);
+
+ nCheck = 1;
+ if ( mxRbEPSLevel2->get_active() )
+ nCheck++;
+ pFilterOptions->WriteInt32("Version", nCheck);
+
+ nCheck = 1;
+ if ( mxRbEPSColorFormat2->get_active() )
+ nCheck++;
+ pFilterOptions->WriteInt32("ColorFormat", nCheck);
+
+ nCheck = 1;
+ if ( mxRbEPSCompressionNone->get_active() )
+ nCheck++;
+ pFilterOptions->WriteInt32("CompressionMode", nCheck);
+ }
+ break;
+
+ case FORMAT_WEBP :
+ {
+ assert(mpSbCompression);
+ pFilterOptions->WriteInt32("Quality", static_cast<sal_Int32>(mpSbCompression->get_value()));
+ pFilterOptions->WriteBool("Lossless", 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("Width");
+ aAny >>= nWidth;
+ aAny = xPagePropSet->getPropertyValue("Height");
+ 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(
+ "ViewTransformation", 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 = 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("OutputStream", xOutputStream),
+ comphelper::makePropertyValue("FilterName", sFormat),
+ comphelper::makePropertyValue("FilterData", 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,
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ 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, "svt/ui/graphicexport.ui", "GraphicExportDialog")
+ , mrFltCallPara(rPara)
+ , mxContext(rxContext)
+ , 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("widthmf"))
+ , mxLbSizeX(m_xBuilder->weld_combo_box("widthlb"))
+ , mxMfSizeY(m_xBuilder->weld_spin_button( "heightmf"))
+ , mxFtResolution(m_xBuilder->weld_label("resolutionft"))
+ , mxNfResolution(m_xBuilder->weld_spin_button("resolutionmf"))
+ , mxLbResolution(m_xBuilder->weld_combo_box("resolutionlb"))
+ , mxColorDepth(m_xBuilder->weld_widget("colordepth"))
+ , mxLbColorDepth(m_xBuilder->weld_combo_box("colordepthlb"))
+ , mxJPGWEBPQuality(m_xBuilder->weld_widget("jpgwebpquality"))
+ , mxPNGCompression(m_xBuilder->weld_widget("pngcompression"))
+ , mxSbPngCompression(m_xBuilder->weld_scale("compressionpngsb"))
+ , mxNfPngCompression(m_xBuilder->weld_spin_button("compressionpngnf"))
+ , mxSbJpgWebpCompression(m_xBuilder->weld_scale("compressionjpgwebpsb"))
+ , mxNfJpgWebpCompression(m_xBuilder->weld_spin_button("compressionjpgwebpnf"))
+ , mxCbLossless(m_xBuilder->weld_check_button("losslesscb"))
+ , mxMode(m_xBuilder->weld_widget("mode"))
+ , mxCbInterlaced(m_xBuilder->weld_check_button("interlacedcb"))
+ , mxBMPCompression(m_xBuilder->weld_widget("bmpcompression"))
+ , mxCbRLEEncoding(m_xBuilder->weld_check_button("rlecb"))
+ , mxDrawingObjects(m_xBuilder->weld_widget("drawingobjects"))
+ , mxCbSaveTransparency(m_xBuilder->weld_check_button("savetransparencycb"))
+ , mxEncoding(m_xBuilder->weld_widget("encoding"))
+ , mxRbBinary(m_xBuilder->weld_radio_button("binarycb"))
+ , mxRbText(m_xBuilder->weld_radio_button("textcb"))
+ , mxEPSGrid(m_xBuilder->weld_widget("epsgrid"))
+ , mxModifyDimension(m_xBuilder->weld_radio_button("modifydimensionscb"))
+ , mxModifyResolution(m_xBuilder->weld_radio_button("modifyresolutioncb"))
+ , mxCbEPSPreviewTIFF(m_xBuilder->weld_check_button("tiffpreviewcb"))
+ , mxCbEPSPreviewEPSI(m_xBuilder->weld_check_button("epsipreviewcb"))
+ , mxRbEPSLevel1(m_xBuilder->weld_radio_button("level1rb"))
+ , mxRbEPSLevel2(m_xBuilder->weld_radio_button("level2rb"))
+ , mxRbEPSColorFormat1(m_xBuilder->weld_radio_button("color1rb"))
+ , mxRbEPSColorFormat2(m_xBuilder->weld_radio_button("color2rb"))
+ , mxRbEPSCompressionLZW(m_xBuilder->weld_radio_button("compresslzw"))
+ , mxRbEPSCompressionNone(m_xBuilder->weld_radio_button("compressnone"))
+ , mxInfo(m_xBuilder->weld_widget("information"))
+ , mxFtEstimatedSize(m_xBuilder->weld_label("estsizeft"))
+ , mxBtnOK(m_xBuilder->weld_button("ok"))
+{
+ GetGraphicSource();
+
+ maExt = maExt.toAsciiUpperCase();
+
+ OUString aFilterConfigPath( "Office.Common/Filter/Graphic/Export/" );
+ mpOptionsItem.reset(new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData ));
+ aFilterConfigPath += maExt;
+ mpFilterOptionsItem.reset(new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData ));
+
+ mnInitialResolutionUnit = mbIsPixelFormat
+ ? mpOptionsItem->ReadInt32("PixelExportUnit", UNIT_DEFAULT)
+ : mpOptionsItem->ReadInt32("VectorExportUnit", UNIT_DEFAULT);
+
+ mnMaxFilesizeForRealtimePreview = std::max(
+ mpOptionsItem->ReadInt32("MaxFilesizeForRealtimePreview", 0), sal_Int32(0));
+ mxFtEstimatedSize->set_label(" \n ");
+
+ 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("PixelExportResolution", 96);
+ if ( nResolution < 1 )
+ nResolution = 96;
+ mxNfResolution->set_value( nResolution );
+
+ sal_Int32 nResolutionUnit = mpOptionsItem->ReadInt32("PixelExportResolutionUnit", 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("ColorMode", 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("Quality", 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("Compression", 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("Interlaced", 0) != 0);
+
+ // Transparency
+ mxDrawingObjects->show();
+ mxCbSaveTransparency->set_active(mpFilterOptionsItem->ReadInt32("Translucent", 1) != 0);
+ }
+ break;
+ case FORMAT_BMP :
+ {
+ sal_Int32 nColor = mpFilterOptionsItem->ReadInt32("Color", 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("RLE_Coding", true));
+ }
+ break;
+ case FORMAT_GIF :
+ {
+ // Interlaced
+ mxMode->show();
+ mxCbInterlaced->set_active(mpFilterOptionsItem->ReadInt32("Interlaced", 1) != 0);
+
+ // Transparency
+ mxDrawingObjects->show();
+ mxCbSaveTransparency->set_active(mpFilterOptionsItem->ReadInt32("Translucent", 1) != 0);
+ }
+ break;
+ case FORMAT_EPS :
+ {
+ mxEPSGrid->show();
+
+ sal_Int32 nPreview = mpFilterOptionsItem->ReadInt32("Preview", 0);
+ sal_Int32 nVersion = mpFilterOptionsItem->ReadInt32("Version", 2);
+ sal_Int32 nColor = mpFilterOptionsItem->ReadInt32("ColorFormat", 0);
+ sal_Int32 nCompr = mpFilterOptionsItem->ReadInt32("CompressionMode", 2);
+
+ mpFilterOptionsItem->ReadInt32("TextMode", 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("Quality", 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("Lossless", 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: */
diff --git a/svtools/source/filter/exportdialog.hxx b/svtools/source/filter/exportdialog.hxx
new file mode 100644
index 000000000..9b10d3411
--- /dev/null
+++ b/svtools/source/filter/exportdialog.hxx
@@ -0,0 +1,186 @@
+/* -*- 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 .
+ */
+
+
+#pragma once
+
+#include <FltCallDialogParameter.hxx>
+#include <vcl/weld.hxx>
+#include <tools/stream.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <memory>
+
+/*************************************************************************
+|*
+|* dialog to set filter options for pixel formats
+|*
+\************************************************************************/
+
+class FilterConfigItem;
+class ExportDialog : public weld::GenericDialogController
+{
+private:
+
+ FltCallDialogParameter& mrFltCallPara;
+
+ const css::uno::Reference< css::uno::XComponentContext >
+ mxContext;
+ const css::uno::Reference< css::lang::XComponent >&
+ mxSourceDocument;
+ const css::uno::Reference< css::graphic::XGraphic >&
+ mxGraphic;
+
+ OUString msEstimatedSizePix1;
+ OUString msEstimatedSizePix2;
+ OUString msEstimatedSizeVec;
+
+ OUString ms1BitThreshold;
+ OUString ms8BitGrayscale;
+ OUString ms8BitColorPalette;
+ OUString ms24BitColor;
+
+ std::unique_ptr<FilterConfigItem> mpOptionsItem;
+ std::unique_ptr<FilterConfigItem> mpFilterOptionsItem;
+
+ OUString maExt;
+ sal_Int16 mnFormat;
+ sal_Int32 mnMaxFilesizeForRealtimePreview;
+
+ std::unique_ptr<SvMemoryStream> mpTempStream;
+
+ css::awt::Size maOriginalSize; // the original graphic size in 1/100mm
+ css::awt::Size maSize; // for vector graphics it always contains the logical size in 1/100mm
+
+ bool mbIsPixelFormat;
+ bool mbExportSelection;
+ bool mbGraphicsSource; // whether source document is graphics (Draw, Impress) or not (Calc, Writer)
+
+ sal_Int32 mnInitialResolutionUnit;
+
+ // for pixel graphics it always contains the pixel count
+ css::awt::Size maResolution; // it always contains the number of pixels per meter
+
+ css::uno::Reference< css::drawing::XShape >
+ mxShape;
+ css::uno::Reference< css::drawing::XShapes >
+ mxShapes;
+ css::uno::Reference< css::drawing::XDrawPage >
+ mxPage;
+
+ weld::Scale* mpSbCompression;
+ weld::SpinButton* mpNfCompression;
+
+ std::unique_ptr<weld::SpinButton> mxMfSizeX;
+ std::unique_ptr<weld::ComboBox> mxLbSizeX;
+ std::unique_ptr<weld::SpinButton> mxMfSizeY;
+ std::unique_ptr<weld::Label> mxFtResolution;
+ std::unique_ptr<weld::SpinButton> mxNfResolution;
+ std::unique_ptr<weld::ComboBox> mxLbResolution;
+
+ std::unique_ptr<weld::Widget> mxColorDepth;
+ std::unique_ptr<weld::ComboBox> mxLbColorDepth;
+
+ std::unique_ptr<weld::Widget> mxJPGWEBPQuality;
+ std::unique_ptr<weld::Widget> mxPNGCompression;
+
+ std::unique_ptr<weld::Scale> mxSbPngCompression;
+ std::unique_ptr<weld::SpinButton> mxNfPngCompression;
+
+ std::unique_ptr<weld::Scale> mxSbJpgWebpCompression;
+ std::unique_ptr<weld::SpinButton> mxNfJpgWebpCompression;
+
+ std::unique_ptr<weld::CheckButton> mxCbLossless;
+
+ std::unique_ptr<weld::Widget> mxMode;
+ std::unique_ptr<weld::CheckButton> mxCbInterlaced;
+
+ std::unique_ptr<weld::Widget> mxBMPCompression;
+ std::unique_ptr<weld::CheckButton> mxCbRLEEncoding;
+
+ std::unique_ptr<weld::Widget> mxDrawingObjects;
+ std::unique_ptr<weld::CheckButton> mxCbSaveTransparency;
+
+ std::unique_ptr<weld::Widget> mxEncoding;
+ std::unique_ptr<weld::RadioButton> mxRbBinary;
+ std::unique_ptr<weld::RadioButton> mxRbText;
+
+ std::unique_ptr<weld::Widget> mxEPSGrid;
+ std::unique_ptr<weld::RadioButton> mxModifyDimension;
+ std::unique_ptr<weld::RadioButton> mxModifyResolution;
+ std::unique_ptr<weld::CheckButton> mxCbEPSPreviewTIFF;
+ std::unique_ptr<weld::CheckButton> mxCbEPSPreviewEPSI;
+ std::unique_ptr<weld::RadioButton> mxRbEPSLevel1;
+ std::unique_ptr<weld::RadioButton> mxRbEPSLevel2;
+ std::unique_ptr<weld::RadioButton> mxRbEPSColorFormat1;
+ std::unique_ptr<weld::RadioButton> mxRbEPSColorFormat2;
+ std::unique_ptr<weld::RadioButton> mxRbEPSCompressionLZW;
+ std::unique_ptr<weld::RadioButton> mxRbEPSCompressionNone;
+
+
+ std::unique_ptr<weld::Widget> mxInfo;
+ std::unique_ptr<weld::Label> mxFtEstimatedSize;
+
+ std::unique_ptr<weld::Button> mxBtnOK;
+
+ DECL_LINK(UpdateHdl, weld::Toggleable&, void);
+ DECL_LINK(UpdateLock, weld::Toggleable&, void);
+ DECL_LINK(SelectListBoxHdl, weld::ComboBox&, void);
+ DECL_LINK(SelectHdl, weld::SpinButton&, void);
+ DECL_LINK(UpdateHdlMtfSizeX, weld::SpinButton&, void);
+ DECL_LINK(UpdateHdlMtfSizeY, weld::SpinButton&, void);
+ DECL_LINK(UpdateHdlNfResolution, weld::SpinButton&, void);
+ DECL_LINK(SbCompressionUpdateHdl, weld::Scale&, void);
+ DECL_LINK(UpdateHdlLossless, weld::Toggleable&, void);
+
+ DECL_LINK(OK, weld::Button&, void);
+
+ void setupSizeControls();
+ void createFilterOptions();
+ void setupControls();
+ void updateControls();
+
+ void GetGraphicSource();
+ void GetGraphicStream();
+ css::uno::Sequence< css::beans::PropertyValue >
+ GetFilterData( bool bUpdateConfig );
+
+ sal_uInt32 GetRawFileSize() const;
+ bool IsTempExportAvailable() const;
+
+ css::awt::Size GetOriginalSize();
+
+ sal_Int32 GetDefaultUnit() const;
+
+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 bGraphicsSource,
+ const css::uno::Reference< css::graphic::XGraphic >& rxGraphic);
+ virtual ~ExportDialog() override;
+};
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */