nss: upgrade to release 3.73
[LibreOffice.git] / svtools / source / filter / exportdialog.cxx
blob43f7cedcba7bc7a7745c871d621add1f4276abb0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <algorithm>
24 #include <o3tl/safeint.hxx>
25 #include <tools/stream.hxx>
26 #include <tools/fract.hxx>
27 #include <vcl/graphicfilter.hxx>
28 #include <vcl/FilterConfigItem.hxx>
29 #include <svtools/strings.hrc>
30 #include <svtools/svtresid.hxx>
31 #include <svtools/DocumentToGraphicRenderer.hxx>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/awt/Size.hpp>
34 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
35 #include <com/sun/star/drawing/XDrawView.hpp>
36 #include <com/sun/star/frame/XModel.hpp>
37 #include <com/sun/star/frame/XController.hpp>
38 #include <com/sun/star/graphic/PrimitiveFactory2D.hpp>
39 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
40 #include <com/sun/star/io/XStream.hpp>
41 #include <unotools/streamwrap.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/outdev.hxx>
44 #include <vcl/graph.hxx>
45 #include <rtl/ustrbuf.hxx>
46 #include <basegfx/matrix/b2dhommatrix.hxx>
47 #include "exportdialog.hxx"
49 #define FORMAT_UNKNOWN 0
50 #define FORMAT_JPG 1
51 #define FORMAT_PNG 2
52 #define FORMAT_BMP 3
53 #define FORMAT_GIF 4
54 #define FORMAT_TIF 10
55 #define FORMAT_WMF 12
56 #define FORMAT_EMF 13
57 #define FORMAT_EPS 14
58 #define FORMAT_SVG 16
60 #define UNIT_DEFAULT -1
61 #define UNIT_INCH 0
62 #define UNIT_CM 1
63 #define UNIT_MM 2
64 #define UNIT_POINT 3
65 #define UNIT_PIXEL 4
66 #define UNIT_MAX_ID UNIT_PIXEL
68 using namespace ::com::sun::star;
70 static sal_Int16 GetFilterFormat(const OUString& rExt)
72 sal_Int16 nFormat = FORMAT_UNKNOWN;
73 if ( rExt == "JPG" )
74 nFormat = FORMAT_JPG;
75 else if ( rExt == "PNG" )
76 nFormat = FORMAT_PNG;
77 else if ( rExt == "BMP" )
78 nFormat = FORMAT_BMP;
79 else if ( rExt == "GIF" )
80 nFormat = FORMAT_GIF;
81 else if ( rExt == "TIF" )
82 nFormat = FORMAT_TIF;
83 else if ( rExt == "WMF" )
84 nFormat = FORMAT_WMF;
85 else if ( rExt == "EMF" )
86 nFormat = FORMAT_EMF;
87 else if ( rExt == "EPS" )
88 nFormat = FORMAT_EPS;
89 else if ( rExt == "SVG" )
90 nFormat = FORMAT_SVG;
91 return nFormat;
94 static MapUnit GetMapUnit( sal_Int32 nUnit )
96 MapUnit aMapUnit( MapUnit::MapPixel );
97 switch( nUnit )
99 case UNIT_INCH : aMapUnit = MapUnit::MapInch; break;
100 case UNIT_CM : aMapUnit = MapUnit::MapCM; break;
101 case UNIT_MM : aMapUnit = MapUnit::MapMM; break;
102 case UNIT_POINT : aMapUnit = MapUnit::MapPoint; break;
103 case UNIT_PIXEL : aMapUnit = MapUnit::MapPixel; break;
105 return aMapUnit;
108 sal_Int32 ExportDialog::GetDefaultUnit() const
110 sal_Int32 nDefaultUnit = UNIT_CM;
111 switch( mrFltCallPara.eFieldUnit )
113 // case FieldUnit::NONE :
114 // case FieldUnit::PERCENT :
115 // case FieldUnit::CUSTOM :
116 default: nDefaultUnit = UNIT_CM; break;
118 case FieldUnit::MILE : // PASSTHROUGH INTENDED
119 case FieldUnit::FOOT :
120 case FieldUnit::TWIP :
121 case FieldUnit::PICA : nDefaultUnit = UNIT_INCH; break;
123 case FieldUnit::KM : // PASSTHROUGH INTENDED
124 case FieldUnit::M :
125 case FieldUnit::MM_100TH : nDefaultUnit = UNIT_CM; break;
127 case FieldUnit::INCH : nDefaultUnit = UNIT_INCH; break;
128 case FieldUnit::CM : nDefaultUnit = UNIT_CM; break;
129 case FieldUnit::MM : nDefaultUnit = UNIT_MM; break;
130 case FieldUnit::POINT : nDefaultUnit = UNIT_POINT; break;
132 return nDefaultUnit;
135 static basegfx::B2DRange GetShapeRangeForXShape( const uno::Reference< drawing::XShape >& rxShape,
136 const uno::Reference< graphic::XPrimitiveFactory2D >& rxPrimitiveFactory2D, const uno::Sequence< beans::PropertyValue >& rViewInformation )
138 basegfx::B2DRange aShapeRange;
140 const uno::Sequence< beans::PropertyValue > aParams;
141 const uno::Sequence< uno::Reference< graphic::XPrimitive2D > > aPrimitiveSequence( rxPrimitiveFactory2D->createPrimitivesFromXShape( rxShape, aParams ) );
143 for( const auto& rPrimitive : aPrimitiveSequence )
145 const geometry::RealRectangle2D aRect( rPrimitive->getRange( rViewInformation ) );
146 aShapeRange.expand( basegfx::B2DTuple( aRect.X1, aRect.Y1 ) );
147 aShapeRange.expand( basegfx::B2DTuple( aRect.X2, aRect.Y2 ) );
149 return aShapeRange;
152 uno::Sequence< beans::PropertyValue > ExportDialog::GetFilterData( bool bUpdateConfig )
154 if ( bUpdateConfig )
156 sal_Int32 nUnit = mxLbSizeX->get_active();
157 if ( nUnit < 0 )
158 nUnit = UNIT_CM;
160 if ( ( mnInitialResolutionUnit == UNIT_DEFAULT ) && ( nUnit == GetDefaultUnit() ) )
161 nUnit = UNIT_DEFAULT;
163 // updating ui configuration
164 if ( mbIsPixelFormat )
166 if ( nUnit > UNIT_MAX_ID )
167 nUnit = UNIT_PIXEL;
169 sal_Int32 nResolution = mxNfResolution->get_value();
170 if ( nResolution < 1 )
171 nResolution = 96;
173 mpOptionsItem->WriteInt32("PixelExportUnit", nUnit);
174 mpOptionsItem->WriteInt32("PixelExportResolution", nResolution);
175 mpOptionsItem->WriteInt32("PixelExportResolutionUnit", mxLbResolution->get_active());
177 else
179 if ( nUnit >= UNIT_PIXEL )
180 nUnit = UNIT_CM;
182 mpOptionsItem->WriteInt32("VectorExportUnit", nUnit);
186 FilterConfigItem* pFilterOptions;
187 if ( bUpdateConfig )
188 pFilterOptions = mpFilterOptionsItem.get();
189 else
191 uno::Sequence< beans::PropertyValue > aFilterData( mpFilterOptionsItem->GetFilterData() );
192 pFilterOptions = new FilterConfigItem( &aFilterData );
195 const OUString sLogicalWidth("LogicalWidth");
196 const OUString sLogicalHeight("LogicalHeight");
197 if ( mbIsPixelFormat )
199 pFilterOptions->WriteInt32("PixelWidth", maSize.Width );
200 pFilterOptions->WriteInt32("PixelHeight", maSize.Height );
201 if ( maResolution.Width && maResolution.Height )
203 const double f100thmmPerPixelX = 100000.0 / maResolution.Width;
204 const double f100thmmPerPixelY = 100000.0 / maResolution.Height;
205 sal_Int32 nLogicalWidth = static_cast< sal_Int32 >( f100thmmPerPixelX * maSize.Width );
206 sal_Int32 nLogicalHeight= static_cast< sal_Int32 >( f100thmmPerPixelY * maSize.Height );
207 if ( nLogicalWidth && nLogicalHeight )
209 pFilterOptions->WriteInt32( sLogicalWidth, nLogicalWidth );
210 pFilterOptions->WriteInt32( sLogicalHeight, nLogicalHeight );
214 else
216 pFilterOptions->WriteInt32( sLogicalWidth, maSize.Width );
217 pFilterOptions->WriteInt32( sLogicalHeight, maSize.Height );
219 switch ( mnFormat )
221 case FORMAT_JPG :
223 sal_Int32 nColor = mxLbColorDepth->get_active();
224 if ( nColor == 1 )
225 nColor = 0;
226 else
227 nColor = 1;
228 pFilterOptions->WriteInt32("ColorMode", nColor);
229 assert(mpSbCompression);
230 pFilterOptions->WriteInt32("Quality", static_cast<sal_Int32>(mpSbCompression->get_value()));
232 break;
234 case FORMAT_PNG :
236 assert(mpSbCompression);
237 pFilterOptions->WriteInt32("Compression", static_cast<sal_Int32>(mpSbCompression->get_value()));
238 sal_Int32 nInterlace = 0;
239 if ( mxCbInterlaced->get_active() )
240 nInterlace++;
241 pFilterOptions->WriteInt32("Interlaced", nInterlace);
242 sal_Int32 nValue = 0;
243 if ( mxCbSaveTransparency->get_active() )
244 nValue++;
245 pFilterOptions->WriteInt32("Translucent", nValue);
247 break;
249 case FORMAT_BMP :
251 pFilterOptions->WriteInt32("Color", mxLbColorDepth->get_active() + 1);
252 pFilterOptions->WriteBool("RLE_Coding", mxCbRLEEncoding->get_active());
254 break;
256 case FORMAT_GIF :
258 sal_Int32 nValue = 0;
259 if ( mxCbInterlaced->get_active() )
260 nValue++;
261 pFilterOptions->WriteInt32("Interlaced", nValue);
263 nValue = 0;
264 if (mxCbSaveTransparency->get_active())
265 nValue++;
266 pFilterOptions->WriteInt32("Translucent", nValue);
268 break;
270 case FORMAT_EPS :
272 sal_Int32 nCheck = 0;
273 if ( mxCbEPSPreviewTIFF->get_active() )
274 nCheck++;
275 if ( mxCbEPSPreviewEPSI->get_active() )
276 nCheck += 2;
277 pFilterOptions->WriteInt32("Preview", nCheck);
279 nCheck = 1;
280 if ( mxRbEPSLevel2->get_active() )
281 nCheck++;
282 pFilterOptions->WriteInt32("Version", nCheck);
284 nCheck = 1;
285 if ( mxRbEPSColorFormat2->get_active() )
286 nCheck++;
287 pFilterOptions->WriteInt32("ColorFormat", nCheck);
289 nCheck = 1;
290 if ( mxRbEPSCompressionNone->get_active() )
291 nCheck++;
292 pFilterOptions->WriteInt32("CompressionMode", nCheck);
294 break;
297 uno::Sequence< beans::PropertyValue > aRet( pFilterOptions->GetFilterData() );
298 if ( !bUpdateConfig )
299 delete pFilterOptions;
300 return aRet;
304 awt::Size ExportDialog::GetOriginalSize()
306 basegfx::B2DRange aShapesRange;
308 if ( mxPage.is () )
310 uno::Reference< beans::XPropertySet > xPagePropSet( mxPage, uno::UNO_QUERY );
311 if ( xPagePropSet.is() )
313 sal_Int32 nWidth = 0;
314 sal_Int32 nHeight= 0;
315 css::uno::Any aAny;
316 aAny = xPagePropSet->getPropertyValue("Width");
317 aAny >>= nWidth;
318 aAny = xPagePropSet->getPropertyValue("Height");
319 aAny >>= nHeight;
320 aShapesRange = basegfx::B2DRange( 0, 0, nWidth, nHeight );
323 else if (mxShapes.is() || mxShape.is())
325 uno::Reference< graphic::XPrimitiveFactory2D > xPrimitiveFactory = graphic::PrimitiveFactory2D::create( mxContext );
327 basegfx::B2DHomMatrix aViewTransformation( Application::GetDefaultDevice()->GetViewTransformation() );
328 css::geometry::AffineMatrix2D aTransformation;
329 aTransformation.m00 = aViewTransformation.get(0,0);
330 aTransformation.m01 = aViewTransformation.get(0,1);
331 aTransformation.m02 = aViewTransformation.get(0,2);
332 aTransformation.m10 = aViewTransformation.get(1,0);
333 aTransformation.m11 = aViewTransformation.get(1,1);
334 aTransformation.m12 = aViewTransformation.get(1,2);
336 uno::Sequence< beans::PropertyValue > aViewInformation( 1 );
337 aViewInformation[ 0 ].Value <<= aTransformation;
338 aViewInformation[ 0 ].Name = "ViewTransformation";
340 if ( mxShape.is() )
341 aShapesRange = GetShapeRangeForXShape( mxShape, xPrimitiveFactory, aViewInformation );
342 else if ( mxShapes.is() )
344 const sal_Int32 nCount = mxShapes->getCount();
345 for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
347 uno::Reference< drawing::XShape > xShape;
348 mxShapes->getByIndex( nIndex ) >>= xShape;
349 aShapesRange.expand( GetShapeRangeForXShape( xShape, xPrimitiveFactory, aViewInformation ) );
353 else if (!mbGraphicsSource)
355 DocumentToGraphicRenderer aRenderer( mxSourceDocument, mbExportSelection);
356 const sal_Int32 nCurrentPage = aRenderer.getCurrentPage();
357 const Size aSize = aRenderer.getDocumentSizeIn100mm( nCurrentPage);
358 return awt::Size( aSize.Width(), aSize.Height());
360 return awt::Size( static_cast<sal_Int32>(aShapesRange.getWidth()), static_cast<sal_Int32>(aShapesRange.getHeight()) );
363 void ExportDialog::GetGraphicSource()
365 if (mxGraphic.is())
366 return;
368 if ( !mxSourceDocument.is() )
369 return;
371 uno::Reference< frame::XModel > xModel( mxSourceDocument, uno::UNO_QUERY );
372 if ( !xModel.is() )
373 return;
375 uno::Reference< frame::XController > xController( xModel->getCurrentController() );
376 if ( !xController.is() )
377 return;
379 if ( mbExportSelection ) // check if there is a selection
381 if (DocumentToGraphicRenderer::isShapeSelected( mxShapes, mxShape, xController))
382 mbGraphicsSource = true;
384 if ( !mxShape.is() && !mxShapes.is() && mbGraphicsSource )
386 uno::Reference< drawing::XDrawView > xDrawView( xController, uno::UNO_QUERY );
387 if ( xDrawView.is() )
389 uno::Reference< drawing::XDrawPage > xCurrentPage( xDrawView->getCurrentPage() );
390 if ( xCurrentPage.is() )
392 mxPage = xCurrentPage; // exporting whole page
396 // For !mbGraphicsSource the mxSourceDocument is used, from
397 // which XRenderable can query XController and
398 // XSelectionSupplier the same.
401 void ExportDialog::GetGraphicStream()
403 if ( !IsTempExportAvailable() )
405 mpTempStream.reset(new SvMemoryStream());
406 return;
409 bool bRecreateOutputStream = mpTempStream->Tell() == 0;
411 static uno::Sequence< beans::PropertyValue > aOldFilterData;
412 uno::Sequence< beans::PropertyValue > aNewFilterData( GetFilterData( false ) );
413 if ( aOldFilterData != aNewFilterData )
415 aOldFilterData = aNewFilterData;
416 bRecreateOutputStream = true;
420 if ( bRecreateOutputStream )
422 mpTempStream.reset(new SvMemoryStream());
424 uno::Reference< graphic::XGraphic > xGraphic;
425 if (!mbGraphicsSource && !mxGraphic.is())
427 // Create a Graphic to be used below.
428 DocumentToGraphicRenderer aRenderer( mxSourceDocument, mbExportSelection);
429 const sal_Int32 nCurrentPage = aRenderer.getCurrentPage();
430 const Size aDocumentSizePixel = aRenderer.getDocumentSizeInPixels( nCurrentPage);
432 const Size aTargetSizePixel( mbIsPixelFormat ?
433 Size( maSize.Width, maSize.Height) :
434 aDocumentSizePixel );
436 Graphic aGraphic( aRenderer.renderToGraphic( nCurrentPage,
437 aDocumentSizePixel, aTargetSizePixel, COL_WHITE, /*bExtOutDevData=*/false));
438 xGraphic = aGraphic.GetXGraphic();
441 if ( mxGraphic.is() || xGraphic.is() )
443 Graphic aGraphic( mxGraphic.is() ? mxGraphic : xGraphic );
445 if ( aGraphic.GetType() == GraphicType::Bitmap )
447 Size aSizePixel( aGraphic.GetSizePixel() );
448 if( maSize.Width && maSize.Height &&
449 ( ( maSize.Width != aSizePixel.Width() ) ||
450 ( maSize.Height != aSizePixel.Height() ) ) )
452 BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
453 // export: use highest quality
454 aBmpEx.Scale( Size( maSize.Width, maSize.Height ), BmpScaleFlag::Lanczos );
455 aGraphic = aBmpEx;
459 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
460 const sal_uInt16 nFilter = rFilter.GetExportFormatNumberForShortName( maExt );
461 if ( rFilter.IsExportPixelFormat( nFilter ) )
463 mpTempStream->SetResizeOffset(1024);
464 mpTempStream->SetStreamSize(1024);
465 rFilter.ExportGraphic( aGraphic, "", *mpTempStream, nFilter, &aNewFilterData );
468 else
470 uno::Reference< lang::XComponent > xSourceDoc;
471 if ( mxPage.is() )
472 xSourceDoc.set( mxPage, uno::UNO_QUERY_THROW );
473 else if ( mxShapes.is() )
474 xSourceDoc.set( mxShapes, uno::UNO_QUERY_THROW );
475 else if ( mxShape.is() )
476 xSourceDoc.set( mxShape, uno::UNO_QUERY_THROW );
477 if ( xSourceDoc.is() )
479 uno::Reference < io::XStream > xStream( new utl::OStreamWrapper( *mpTempStream ) );
480 uno::Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() );
482 OUString sFormat( maExt );
483 uno::Sequence< beans::PropertyValue > aDescriptor( 3 );
484 aDescriptor[0].Name = "OutputStream";
485 aDescriptor[0].Value <<= xOutputStream;
486 aDescriptor[1].Name = "FilterName";
487 aDescriptor[1].Value <<= sFormat;
488 aDescriptor[2].Name = "FilterData";
489 aDescriptor[2].Value <<= aNewFilterData;
491 uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter =
492 drawing::GraphicExportFilter::create( mxContext );
494 xGraphicExporter->setSourceDocument( xSourceDoc );
495 xGraphicExporter->filter( aDescriptor );
500 catch( uno::Exception& )
503 // ups
508 sal_uInt32 ExportDialog::GetRawFileSize() const
510 sal_uInt64 nRawFileSize = 0;
511 if ( mbIsPixelFormat )
513 sal_Int32 nBitsPerPixel = 24;
514 OUString aEntry(mxLbColorDepth->get_active_text());
515 if ( ms1BitThreshold == aEntry )
516 nBitsPerPixel = 1;
517 else if ( ms1BitDithered == aEntry )
518 nBitsPerPixel = 1;
519 else if ( ms4BitGrayscale == aEntry )
520 nBitsPerPixel = 4;
521 else if ( ms4BitColorPalette == aEntry )
522 nBitsPerPixel = 8;
523 else if ( ms8BitGrayscale == aEntry )
524 nBitsPerPixel = 8;
525 else if ( ms8BitColorPalette == aEntry )
526 nBitsPerPixel = 8;
527 else if ( ms24BitColor == aEntry )
528 nBitsPerPixel = 24;
530 if ( mbIsPixelFormat )
532 nRawFileSize = ( maSize.Width * nBitsPerPixel + 7 ) &~ 7; // rounding up to 8 bits
533 nRawFileSize /= 8; // in bytes
534 nRawFileSize *= maSize.Height;
536 if ( nRawFileSize > SAL_MAX_UINT32 )
537 nRawFileSize = 0;
539 return static_cast< sal_uInt32 >( nRawFileSize );
542 // checks if the source dimension/resolution is not too big
543 // to determine the exact graphic output size and preview for jpg
544 bool ExportDialog::IsTempExportAvailable() const
546 return GetRawFileSize() < o3tl::make_unsigned( mnMaxFilesizeForRealtimePreview );
549 ExportDialog::ExportDialog(FltCallDialogParameter& rPara,
550 const css::uno::Reference< css::uno::XComponentContext >& rxContext,
551 const css::uno::Reference< css::lang::XComponent >& rxSourceDocument,
552 bool bExportSelection, bool bIsPixelFormat, bool bGraphicsSource,
553 const css::uno::Reference< css::graphic::XGraphic >& rxGraphic)
554 : GenericDialogController(rPara.pWindow, "svt/ui/graphicexport.ui", "GraphicExportDialog")
555 , mrFltCallPara(rPara)
556 , mxContext(rxContext)
557 , mxSourceDocument(rxSourceDocument)
558 , mxGraphic(rxGraphic)
559 , msEstimatedSizePix1(SvtResId(STR_SVT_ESTIMATED_SIZE_PIX_1))
560 , msEstimatedSizePix2(SvtResId(STR_SVT_ESTIMATED_SIZE_PIX_2))
561 , msEstimatedSizeVec(SvtResId(STR_SVT_ESTIMATED_SIZE_VEC))
562 , ms1BitThreshold(SvtResId(STR_SVT_1BIT_THRESHOLD))
563 , ms1BitDithered(SvtResId(STR_SVT_1BIT_DITHERED))
564 , ms4BitGrayscale(SvtResId(STR_SVT_4BIT_GRAYSCALE))
565 , ms4BitColorPalette(SvtResId(STR_SVT_4BIT_COLOR_PALETTE))
566 , ms8BitGrayscale(SvtResId(STR_SVT_8BIT_GRAYSCALE))
567 , ms8BitColorPalette(SvtResId(STR_SVT_8BIT_COLOR_PALETTE))
568 , ms24BitColor(SvtResId(STR_SVT_24BIT_TRUE_COLOR))
569 , maExt(rPara.aFilterExt)
570 , mnFormat(FORMAT_UNKNOWN)
571 , mnMaxFilesizeForRealtimePreview(0)
572 , mpTempStream(new SvMemoryStream())
573 , maOriginalSize(awt::Size(0, 0))
574 , mbIsPixelFormat(bIsPixelFormat)
575 , mbExportSelection(bExportSelection)
576 , mbGraphicsSource(bGraphicsSource)
577 , mpSbCompression(nullptr)
578 , mpNfCompression(nullptr)
579 , mxMfSizeX(m_xBuilder->weld_spin_button("widthmf"))
580 , mxLbSizeX(m_xBuilder->weld_combo_box("widthlb"))
581 , mxMfSizeY(m_xBuilder->weld_spin_button( "heightmf"))
582 , mxFtResolution(m_xBuilder->weld_label("resolutionft"))
583 , mxNfResolution(m_xBuilder->weld_spin_button("resolutionmf"))
584 , mxLbResolution(m_xBuilder->weld_combo_box("resolutionlb"))
585 , mxColorDepth(m_xBuilder->weld_widget("colordepth"))
586 , mxLbColorDepth(m_xBuilder->weld_combo_box("colordepthlb"))
587 , mxJPGQuality(m_xBuilder->weld_widget("jpgquality"))
588 , mxPNGCompression(m_xBuilder->weld_widget("pngcompression"))
589 , mxSbPngCompression(m_xBuilder->weld_scale("compressionpngsb"))
590 , mxNfPngCompression(m_xBuilder->weld_spin_button("compressionpngnf"))
591 , mxSbJpgCompression(m_xBuilder->weld_scale("compressionjpgsb"))
592 , mxNfJpgCompression(m_xBuilder->weld_spin_button("compressionjpgnf"))
593 , mxMode(m_xBuilder->weld_widget("mode"))
594 , mxCbInterlaced(m_xBuilder->weld_check_button("interlacedcb"))
595 , mxBMPCompression(m_xBuilder->weld_widget("bmpcompression"))
596 , mxCbRLEEncoding(m_xBuilder->weld_check_button("rlecb"))
597 , mxDrawingObjects(m_xBuilder->weld_widget("drawingobjects"))
598 , mxCbSaveTransparency(m_xBuilder->weld_check_button("savetransparencycb"))
599 , mxEncoding(m_xBuilder->weld_widget("encoding"))
600 , mxRbBinary(m_xBuilder->weld_radio_button("binarycb"))
601 , mxRbText(m_xBuilder->weld_radio_button("textcb"))
602 , mxEPSGrid(m_xBuilder->weld_widget("epsgrid"))
603 , mxCbEPSPreviewTIFF(m_xBuilder->weld_check_button("tiffpreviewcb"))
604 , mxCbEPSPreviewEPSI(m_xBuilder->weld_check_button("epsipreviewcb"))
605 , mxRbEPSLevel1(m_xBuilder->weld_radio_button("level1rb"))
606 , mxRbEPSLevel2(m_xBuilder->weld_radio_button("level2rb"))
607 , mxRbEPSColorFormat1(m_xBuilder->weld_radio_button("color1rb"))
608 , mxRbEPSColorFormat2(m_xBuilder->weld_radio_button("color2rb"))
609 , mxRbEPSCompressionLZW(m_xBuilder->weld_radio_button("compresslzw"))
610 , mxRbEPSCompressionNone(m_xBuilder->weld_radio_button("compressnone"))
611 , mxInfo(m_xBuilder->weld_widget("information"))
612 , mxFtEstimatedSize(m_xBuilder->weld_label("estsizeft"))
613 , mxBtnOK(m_xBuilder->weld_button("ok"))
615 GetGraphicSource();
617 maExt = maExt.toAsciiUpperCase();
619 OUString aFilterConfigPath( "Office.Common/Filter/Graphic/Export/" );
620 mpOptionsItem.reset(new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData ));
621 aFilterConfigPath += maExt;
622 mpFilterOptionsItem.reset(new FilterConfigItem( aFilterConfigPath, &rPara.aFilterData ));
624 mnInitialResolutionUnit = mbIsPixelFormat
625 ? mpOptionsItem->ReadInt32("PixelExportUnit", UNIT_DEFAULT)
626 : mpOptionsItem->ReadInt32("VectorExportUnit", UNIT_DEFAULT);
628 mnMaxFilesizeForRealtimePreview = std::max(
629 mpOptionsItem->ReadInt32("MaxFilesizeForRealtimePreview", 0), sal_Int32(0));
630 mxFtEstimatedSize->set_label(" \n ");
632 m_xDialog->set_title(m_xDialog->get_title().replaceFirst("%1", maExt)); //Set dialog title
634 mnFormat = GetFilterFormat( maExt );
636 Size aResolution( Application::GetDefaultDevice()->LogicToPixel(Size(100, 100), MapMode(MapUnit::MapCM)) );
637 maResolution.Width = aResolution.Width();
638 maResolution.Height= aResolution.Height();
640 if ( mxGraphic.is() )
642 Graphic aGraphic(mxGraphic);
643 Size aSize = aGraphic.GetSizePixel();
644 maSize = awt::Size(aSize.getWidth(), aSize.getHeight());
645 double f100thmmPerPixel = 100000.0 / static_cast< double >( maResolution.Width );
646 maOriginalSize = awt::Size(
647 static_cast< sal_Int32 >( f100thmmPerPixel * maSize.Width ),
648 static_cast< sal_Int32 >( f100thmmPerPixel * maSize.Height ) );
650 else
652 maOriginalSize = GetOriginalSize();
653 if ( bIsPixelFormat )
655 double fPixelsPer100thmm = static_cast< double >( maResolution.Width ) / 100000.0;
656 maSize = awt::Size( static_cast< sal_Int32 >( ( fPixelsPer100thmm * maOriginalSize.Width ) + 0.5 ),
657 static_cast< sal_Int32 >( ( fPixelsPer100thmm * maOriginalSize.Height ) + 0.5 ) );
659 else
661 maSize = maOriginalSize;
664 setupControls();
666 // Size
667 mxLbSizeX->connect_changed( LINK( this, ExportDialog, SelectListBoxHdl ) );
669 if (mpSbCompression)
670 mpSbCompression->connect_value_changed(LINK(this, ExportDialog, SbCompressionUpdateHdl));
671 if (mpNfCompression)
672 mpNfCompression->connect_value_changed(LINK(this, ExportDialog, SelectHdl));
674 mxMfSizeX->connect_value_changed( LINK( this, ExportDialog, UpdateHdlMtfSizeX ) );
675 mxMfSizeY->connect_value_changed( LINK( this, ExportDialog, UpdateHdlMtfSizeY ) );
677 mxNfResolution->connect_value_changed( LINK( this, ExportDialog, UpdateHdlNfResolution ) );
678 mxLbResolution->connect_changed( LINK( this, ExportDialog, SelectListBoxHdl ) );
680 mxLbColorDepth->connect_changed( LINK( this, ExportDialog, SelectListBoxHdl ) );
682 mxCbInterlaced->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
684 mxCbSaveTransparency->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
686 mxCbEPSPreviewTIFF->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
687 mxCbEPSPreviewEPSI->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
689 mxRbEPSCompressionLZW->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
690 mxRbEPSCompressionNone->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
692 mxRbBinary->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
693 mxRbText->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
695 // BMP
696 mxCbRLEEncoding->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
698 // EPS
699 mxRbEPSLevel1->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
700 mxRbEPSLevel2->connect_toggled( LINK( this, ExportDialog, UpdateHdl ) );
702 mxBtnOK->connect_clicked( LINK( this, ExportDialog, OK ) );
704 updateControls();
707 void ExportDialog::setupSizeControls()
709 sal_Int32 nUnit = mnInitialResolutionUnit;
710 if (nUnit == UNIT_DEFAULT)
711 nUnit = GetDefaultUnit();
713 if (!mbIsPixelFormat)
715 mxFtResolution->hide();
716 mxNfResolution->hide();
717 mxLbResolution->hide();
718 mxLbSizeX->remove( UNIT_PIXEL ); // removing pixel
719 if ( nUnit >= UNIT_PIXEL )
720 nUnit = UNIT_CM;
722 else if ( nUnit > UNIT_MAX_ID )
723 nUnit = UNIT_PIXEL;
724 if ( nUnit < 0 )
725 nUnit = UNIT_CM;
726 mxLbSizeX->set_active( static_cast< sal_uInt16 >( nUnit ) );
728 if ( !mbIsPixelFormat ) // TODO: (metafileresolutionsupport) should be supported for vector formats also... this makes
729 return;
731 // sense eg for bitmap fillings in metafiles, to preserve high dpi output
732 // (atm without special vector support the bitmaps are rendered with 96dpi)
733 sal_Int32 nResolution = mpOptionsItem->ReadInt32("PixelExportResolution", 96);
734 if ( nResolution < 1 )
735 nResolution = 96;
736 mxNfResolution->set_value( nResolution );
738 sal_Int32 nResolutionUnit = mpOptionsItem->ReadInt32("PixelExportResolutionUnit", 1);
739 if ( ( nResolutionUnit < 0 ) || ( nResolutionUnit > 2 ) )
740 nResolutionUnit = 1;
741 mxLbResolution->set_active( static_cast< sal_uInt16 >( nResolutionUnit ) );
744 void ExportDialog::createFilterOptions()
746 switch( mnFormat )
748 case FORMAT_JPG :
750 sal_Int32 nColor = mpFilterOptionsItem->ReadInt32("ColorMode", 0);
751 if ( nColor == 1 )
752 nColor = 0;
753 else
754 nColor = 1;
755 mxLbColorDepth->append_text( ms8BitGrayscale );
756 mxLbColorDepth->append_text( ms24BitColor );
757 mxLbColorDepth->set_active( nColor );
758 mxColorDepth->show();
760 // Quality
761 mxJPGQuality->show();
762 sal_Int32 nQuality = mpFilterOptionsItem->ReadInt32("Quality", 75);
763 if ((nQuality < 1 ) || (nQuality > 100))
764 nQuality = 75;
765 mpSbCompression = mxSbJpgCompression.get();
766 mpNfCompression = mxNfJpgCompression.get();
767 mpSbCompression->set_range(1, 100);
768 mpNfCompression->set_range(1, 100);
769 mpNfCompression->set_value(nQuality);
771 break;
772 case FORMAT_PNG :
774 // Compression 1..9
775 mxPNGCompression->show();
776 sal_Int32 nCompression = mpFilterOptionsItem->ReadInt32("Compression", 6);
777 if ( ( nCompression < 1 ) || ( nCompression > 9 ) )
778 nCompression = 6;
780 mpSbCompression = mxSbPngCompression.get();
781 mpNfCompression = mxNfPngCompression.get();
782 mpSbCompression->set_range(1, 9);
783 mpNfCompression->set_range(1, 9);
784 mpNfCompression->set_value(nCompression);
786 // Interlaced
787 mxMode->show();
788 mxCbInterlaced->set_active(mpFilterOptionsItem->ReadInt32("Interlaced", 0) != 0);
790 // Transparency
791 mxDrawingObjects->show();
792 mxCbSaveTransparency->set_active(mpFilterOptionsItem->ReadInt32("Translucent", 1) != 0);
794 break;
795 case FORMAT_BMP :
797 sal_Int32 nColor = mpFilterOptionsItem->ReadInt32("Color", 0);
798 if ( nColor == 0 )
799 nColor = 6;
800 else
801 nColor--;
802 mxLbColorDepth->append_text( ms1BitThreshold );
803 mxLbColorDepth->append_text( ms1BitDithered );
804 mxLbColorDepth->append_text( ms4BitGrayscale );
805 mxLbColorDepth->append_text( ms4BitColorPalette );
806 mxLbColorDepth->append_text( ms8BitGrayscale );
807 mxLbColorDepth->append_text( ms8BitColorPalette );
808 mxLbColorDepth->append_text( ms24BitColor );
809 mxLbColorDepth->set_active( nColor );
810 mxColorDepth->show();
812 // RLE coding
813 mxBMPCompression->show();
814 mxCbRLEEncoding->set_active(mpFilterOptionsItem->ReadBool("RLE_Coding", true));
816 break;
817 case FORMAT_GIF :
819 // Interlaced
820 mxMode->show();
821 mxCbInterlaced->set_active(mpFilterOptionsItem->ReadInt32("Interlaced", 1) != 0);
823 // Transparency
824 mxDrawingObjects->show();
825 mxCbSaveTransparency->set_active(mpFilterOptionsItem->ReadInt32("Translucent", 1) != 0);
827 break;
828 case FORMAT_EPS :
830 mxEPSGrid->show();
832 sal_Int32 nPreview = mpFilterOptionsItem->ReadInt32("Preview", 0);
833 sal_Int32 nVersion = mpFilterOptionsItem->ReadInt32("Version", 2);
834 sal_Int32 nColor = mpFilterOptionsItem->ReadInt32("ColorFormat", 0);
835 sal_Int32 nCompr = mpFilterOptionsItem->ReadInt32("CompressionMode", 2);
837 mpFilterOptionsItem->ReadInt32("TextMode", 0);
839 mxCbEPSPreviewTIFF->set_active( ( nPreview & 1 ) != 0 );
840 mxCbEPSPreviewEPSI->set_active( ( nPreview & 2 ) != 0 );
842 mxRbEPSLevel1->set_active( nVersion == 1 );
843 mxRbEPSLevel2->set_active( nVersion == 2 );
845 mxRbEPSColorFormat1->set_active( nColor == 1 );
846 mxRbEPSColorFormat2->set_active( nColor != 1 );
848 mxRbEPSCompressionLZW->set_active( nCompr == 1 );
849 mxRbEPSCompressionNone->set_active( nCompr != 1 );
851 break;
855 void ExportDialog::setupControls()
857 setupSizeControls();
858 createFilterOptions();
860 if (mnMaxFilesizeForRealtimePreview || mbIsPixelFormat)
861 mxInfo->show();
864 static OUString ImpValueOfInKB( sal_Int64 rVal )
866 double fVal( static_cast<double>( rVal ) );
867 fVal /= ( 1 << 10 );
868 fVal += 0.05;
869 OUStringBuffer aVal( OUString::number( fVal ) );
870 sal_Int32 nX( aVal.indexOf( '.' ) );
871 if ( nX > 0 )
872 aVal.setLength( nX + 2 );
873 return aVal.makeStringAndClear();
876 void ExportDialog::updateControls()
878 // Size Controls
879 if ( !mbIsPixelFormat )
881 awt::Size aSize100thmm( maSize );
882 Size aSize( OutputDevice::LogicToLogic( Size(aSize100thmm.Width * 100, aSize100thmm.Height * 100),
883 MapMode(MapUnit::Map100thMM),
884 MapMode( GetMapUnit( mxLbSizeX->get_active() ) ) ) );
885 mxMfSizeX->set_value( aSize.Width() );
886 mxMfSizeY->set_value( aSize.Height() );
888 else
890 MapUnit aMapUnit( GetMapUnit( mxLbSizeX->get_active() ) );
891 if ( aMapUnit == MapUnit::MapPixel )
892 { // calculating pixel count via resolution and original graphic size
893 mxMfSizeX->set_digits( 0 );
894 mxMfSizeY->set_digits( 0 );
895 mxMfSizeX->set_value( maSize.Width );
896 mxMfSizeY->set_value( maSize.Height );
898 else
900 mxMfSizeX->set_digits( 2 );
901 mxMfSizeY->set_digits( 2 );
902 double fRatio;
903 switch( GetMapUnit( mxLbSizeX->get_active() ) )
905 case MapUnit::MapInch : fRatio = static_cast< double >( maResolution.Width ) * 0.0254; break;
906 case MapUnit::MapMM : fRatio = static_cast< double >( maResolution.Width ) * 0.001; break;
907 case MapUnit::MapPoint :fRatio = ( static_cast< double >( maResolution.Width ) * 0.0254 ) / 72.0; break;
908 default:
909 case MapUnit::MapCM : fRatio = static_cast< double >( maResolution.Width ) * 0.01; break;
911 mxMfSizeX->set_value( static_cast< sal_Int32 >( ( static_cast< double >( maSize.Width * 100 ) / fRatio ) + 0.5 ) );
912 mxMfSizeY->set_value( static_cast< sal_Int32 >( ( static_cast< double >( maSize.Height * 100 ) / fRatio ) + 0.5 ) );
915 sal_Int32 nResolution = 0;
916 switch( mxLbResolution->get_active() )
918 case 0 : nResolution = maResolution.Width / 100; break; // pixels / cm
919 case 2 : nResolution = maResolution.Width; break; // pixels / meter
920 default:
921 case 1 : nResolution = static_cast< sal_Int32 >(maResolution.Width * 0.0254); break; // pixels / inch
923 mxNfResolution->set_value( nResolution );
925 if (mpSbCompression && mpSbCompression->get_visible() && mpNfCompression)
926 mpSbCompression->set_value(mpNfCompression->get_value());
928 GetGraphicStream();
930 // updating estimated size
931 sal_Int64 nRealFileSize( mpTempStream->Tell() );
932 if ( mbIsPixelFormat )
934 OUString aEst( nRealFileSize ? msEstimatedSizePix2 : msEstimatedSizePix1 );
935 sal_Int64 nRawFileSize( GetRawFileSize() );
936 sal_Int32 nInd = aEst.indexOf( "%" );
937 if (nInd != -1)
938 aEst = aEst.replaceAt( nInd, 2, ImpValueOfInKB( nRawFileSize ) );
940 if ( nRealFileSize && nInd != -1 )
942 nInd = aEst.indexOf( "%", nInd );
943 if (nInd != -1)
944 aEst = aEst.replaceAt( nInd, 2, ImpValueOfInKB( nRealFileSize ) );
946 mxFtEstimatedSize->set_label( aEst );
948 else
950 if ( mnMaxFilesizeForRealtimePreview )
952 OUString aEst( msEstimatedSizeVec );
953 sal_Int32 nInd = aEst.indexOf( "%" );
954 if (nInd != -1)
955 aEst = aEst.replaceAt( nInd, 2, ImpValueOfInKB( nRealFileSize ) );
956 mxFtEstimatedSize->set_label( aEst );
960 // EPS
961 if ( mxRbEPSLevel1->get_visible() )
963 bool bEnabled = !mxRbEPSLevel1->get_active();
964 mxRbEPSColorFormat1->set_sensitive( bEnabled );
965 mxRbEPSColorFormat2->set_sensitive( bEnabled );
966 mxRbEPSCompressionLZW->set_sensitive( bEnabled );
967 mxRbEPSCompressionNone->set_sensitive( bEnabled );
971 ExportDialog::~ExportDialog()
975 /*************************************************************************
977 |* stores values set in the ini-file
979 \************************************************************************/
980 IMPL_LINK_NOARG(ExportDialog, SelectHdl, weld::SpinButton&, void)
982 updateControls();
985 IMPL_LINK_NOARG(ExportDialog, SelectListBoxHdl, weld::ComboBox&, void)
987 updateControls();
990 IMPL_LINK_NOARG(ExportDialog, UpdateHdl, weld::ToggleButton&, void)
992 updateControls();
995 IMPL_LINK_NOARG(ExportDialog, UpdateHdlMtfSizeX, weld::SpinButton&, void)
997 double fRatio = static_cast< double >( maOriginalSize.Height ) / maOriginalSize.Width;
999 if ( mbIsPixelFormat )
1001 switch( GetMapUnit( mxLbSizeX->get_active() ) )
1003 case MapUnit::MapInch : maSize.Width = static_cast< sal_Int32 >( static_cast< double >( maResolution.Width ) * 0.0254 * mxMfSizeX->get_value() / 100.0 + 0.5 ); break;
1004 case MapUnit::MapCM : maSize.Width = static_cast< sal_Int32 >( static_cast< double >( maResolution.Width ) * 0.01 * mxMfSizeX->get_value() / 100.0 + 0.5 ); break;
1005 case MapUnit::MapMM : maSize.Width = static_cast< sal_Int32 >( static_cast< double >( maResolution.Width ) * 0.001 * mxMfSizeX->get_value() / 100.0 + 0.5 ); break;
1006 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;
1007 default:
1008 case MapUnit::MapPixel : maSize.Width = mxMfSizeX->get_value(); break;
1010 maSize.Height = static_cast< sal_Int32 >( fRatio * maSize.Width + 0.5 );
1012 else
1014 Fraction aFract( 1, 100 );
1015 sal_Int32 nWidth = mxMfSizeX->get_value();
1016 sal_Int32 nHeight= static_cast< sal_Int32 >( nWidth * fRatio );
1017 const Size aSource( nWidth, nHeight );
1018 MapMode aSourceMapMode( GetMapUnit( mxLbSizeX->get_active() ),Point(), aFract, aFract );
1019 Size aDest(OutputDevice::LogicToLogic(aSource, aSourceMapMode, MapMode(MapUnit::Map100thMM)));
1021 maSize.Width = aDest.Width();
1022 maSize.Height = aDest.Height();
1024 updateControls();
1027 IMPL_LINK_NOARG(ExportDialog, UpdateHdlMtfSizeY, weld::SpinButton&, void)
1029 double fRatio = static_cast< double >( maOriginalSize.Width ) / maOriginalSize.Height;
1031 if ( mbIsPixelFormat )
1033 switch( GetMapUnit( mxLbSizeX->get_active() ) )
1035 case MapUnit::MapInch : maSize.Height = static_cast< sal_Int32 >( static_cast< double >( maResolution.Height ) * 0.0254 * mxMfSizeY->get_value() / 100.0 + 0.5 ); break;
1036 case MapUnit::MapCM : maSize.Height = static_cast< sal_Int32 >( static_cast< double >( maResolution.Height ) * 0.01 * mxMfSizeY->get_value() / 100.0 + 0.5 ); break;
1037 case MapUnit::MapMM : maSize.Height = static_cast< sal_Int32 >( static_cast< double >( maResolution.Height ) * 0.001 * mxMfSizeY->get_value() / 100.0 + 0.5 ); break;
1038 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;
1039 default:
1040 case MapUnit::MapPixel : maSize.Height = mxMfSizeY->get_value(); break;
1042 maSize.Width = static_cast< sal_Int32 >( fRatio * maSize.Height + 0.5 );
1044 else
1046 Fraction aFract( 1, 100 );
1047 sal_Int32 nHeight= mxMfSizeY->get_value();
1048 sal_Int32 nWidth = static_cast< sal_Int32 >( nHeight * fRatio );
1049 const Size aSource( nWidth, nHeight );
1050 MapMode aSourceMapMode( GetMapUnit( mxLbSizeX->get_active() ),Point(), aFract, aFract );
1051 Size aDest( OutputDevice::LogicToLogic(aSource, aSourceMapMode, MapMode(MapUnit::Map100thMM)) );
1053 maSize.Height = aDest.Height();
1054 maSize.Width = aDest.Width();
1056 updateControls();
1059 IMPL_LINK_NOARG(ExportDialog, UpdateHdlNfResolution, weld::SpinButton&, void)
1061 auto nResolution = mxNfResolution->get_value();
1062 if ( mxLbResolution->get_active() == 0 ) // pixels / cm
1063 nResolution *= 100;
1064 else if ( mxLbResolution->get_active() == 1 ) // pixels / inch
1065 nResolution = static_cast< sal_Int32 >( ( ( static_cast< double >( nResolution ) + 0.5 ) / 0.0254 ) );
1066 maResolution.Width = nResolution;
1067 maResolution.Height= nResolution;
1069 updateControls();
1072 IMPL_LINK_NOARG(ExportDialog, SbCompressionUpdateHdl, weld::Scale&, void)
1074 mpNfCompression->set_value(mpSbCompression->get_value());
1075 updateControls();
1078 IMPL_LINK_NOARG(ExportDialog, OK, weld::Button&, void)
1080 // writing config parameter
1082 mrFltCallPara.aFilterData = GetFilterData( true );
1083 m_xDialog->response(RET_OK);
1086 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */