1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26
27 #include "pdfexport.hxx"
28 #include "impdialog.hxx"
29
30 #include "pdf.hrc"
31 #include "tools/urlobj.hxx"
32 #include "tools/fract.hxx"
33 #include "tools/poly.hxx"
34 #include "vcl/mapmod.hxx"
35 #include "vcl/virdev.hxx"
36 #include "vcl/metaact.hxx"
37 #include "vcl/gdimtf.hxx"
38 #include "vcl/jobset.hxx"
39 #include "vcl/salbtype.hxx"
40 #include "vcl/bmpacc.hxx"
41 #include "vcl/svapp.hxx"
42 #include "toolkit/awt/vclxdevice.hxx"
43 #include "unotools/localfilehelper.hxx"
44 #include "unotools/processfactory.hxx"
45 #include "svtools/FilterConfigItem.hxx"
46 #include "svtools/filter.hxx"
47 #include "svl/solar.hrc"
48 #include "comphelper/string.hxx"
49 #include "comphelper/storagehelper.hxx"
50 #include "unotools/streamwrap.hxx"
51 #include "com/sun/star/io/XSeekable.hpp"
52
53 #include "basegfx/polygon/b2dpolygon.hxx"
54 #include "basegfx/polygon/b2dpolypolygon.hxx"
55 #include "basegfx/polygon/b2dpolygontools.hxx"
56
57 #include "unotools/saveopt.hxx" // only for testing of relative saving options in PDF
58
59 #include "vcl/graphictools.hxx"
60 #include "com/sun/star/beans/XPropertySet.hpp"
61 #include "com/sun/star/awt/Rectangle.hpp"
62 #include "com/sun/star/awt/XDevice.hpp"
63 #include "com/sun/star/util/MeasureUnit.hpp"
64 #include "com/sun/star/frame/XModel.hpp"
65 #include "com/sun/star/frame/XModuleManager.hpp"
66 #include "com/sun/star/frame/XStorable.hpp"
67 #include "com/sun/star/frame/XController.hpp"
68 #include "com/sun/star/document/XDocumentProperties.hpp"
69 #include "com/sun/star/document/XDocumentPropertiesSupplier.hpp"
70 #include "com/sun/star/container/XNameAccess.hpp"
71 #include "com/sun/star/view/XViewSettingsSupplier.hpp"
72 #include "com/sun/star/task/XInteractionRequest.hpp"
73 #include "com/sun/star/task/PDFExportException.hpp"
74
75 #include "unotools/configmgr.hxx"
76 #include "cppuhelper/exc_hlp.hxx"
77 #include "cppuhelper/compbase1.hxx"
78 #include "cppuhelper/basemutex.hxx"
79
80 #include "com/sun/star/lang/XServiceInfo.hpp"
81 #include "com/sun/star/drawing/XShapes.hpp"
82 #include "com/sun/star/graphic/XGraphicProvider.hpp"
83
84 using namespace ::rtl;
85 using namespace ::vcl;
86 using namespace ::com::sun::star;
87 using namespace ::com::sun::star::uno;
88 using namespace ::com::sun::star::lang;
89 using namespace ::com::sun::star::beans;
90 using namespace ::com::sun::star::view;
91 using namespace ::com::sun::star::graphic;
92
93 // -------------
94 // - PDFExport -
95 // -------------
96
PDFExport(const Reference<XComponent> & rxSrcDoc,const Reference<task::XStatusIndicator> & rxStatusIndicator,const Reference<task::XInteractionHandler> & rxIH,const Reference<lang::XMultiServiceFactory> & xFactory)97 PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc,
98 const Reference< task::XStatusIndicator >& rxStatusIndicator,
99 const Reference< task::XInteractionHandler >& rxIH,
100 const Reference< lang::XMultiServiceFactory >& xFactory ) :
101 mxSrcDoc ( rxSrcDoc ),
102 mxMSF ( xFactory ),
103 mxStatusIndicator ( rxStatusIndicator ),
104 mxIH ( rxIH ),
105 mbUseTaggedPDF ( sal_False ),
106 mnPDFTypeSelection ( 0 ),
107 mbExportNotes ( sal_True ),
108 mbExportNotesPages ( sal_False ),
109 mbEmbedStandardFonts ( sal_False ),//in preparation for i54636 and i76458.
110 //already used for i59651 (PDF/A-1)
111 mbUseTransitionEffects ( sal_True ),
112 mbExportBookmarks ( sal_True ),
113 mnOpenBookmarkLevels ( -1 ),
114 mbUseLosslessCompression ( sal_False ),
115 mbReduceImageResolution ( sal_False ),
116 mbSkipEmptyPages ( sal_True ),
117 mbAddStream ( sal_False ),
118 mnMaxImageResolution ( 300 ),
119 mnQuality ( 90 ),
120 mnFormsFormat ( 0 ),
121 mbExportFormFields ( sal_True ),
122 mbAllowDuplicateFieldNames ( sal_False ),
123 mnProgressValue ( 0 ),
124 mbRemoveTransparencies ( sal_False ),
125 mbWatermark ( sal_False ),
126
127 mbHideViewerToolbar ( sal_False ),
128 mbHideViewerMenubar ( sal_False ),
129 mbHideViewerWindowControls ( sal_False ),
130 mbFitWindow ( sal_False ),
131 mbCenterWindow ( sal_False ),
132 mbOpenInFullScreenMode ( sal_False ),
133 mbDisplayPDFDocumentTitle ( sal_True ),
134 mnPDFDocumentMode ( 0 ),
135 mnPDFDocumentAction ( 0 ),
136 mnZoom ( 100 ),
137 mnInitialPage ( 1 ),
138 mnPDFPageLayout ( 0 ),
139 mbFirstPageLeft ( sal_False ),
140
141 mbEncrypt ( sal_False ),
142 mbRestrictPermissions ( sal_False ),
143 mnPrintAllowed ( 2 ),
144 mnChangesAllowed ( 4 ),
145 mbCanCopyOrExtract ( sal_True ),
146 mbCanExtractForAccessibility( sal_True ),
147
148 mnCachePatternId ( -1 ),
149
150 //--->i56629
151 mbExportRelativeFsysLinks ( sal_False ),
152 mnDefaultLinkAction ( 0 ),
153 mbConvertOOoTargetToPDFTarget( sal_False ),
154 mbExportBmkToDest ( sal_False )
155 //<---
156 {
157 }
158
159 // -----------------------------------------------------------------------------
160
~PDFExport()161 PDFExport::~PDFExport()
162 {
163 }
164
165 // -----------------------------------------------------------------------------
166
ExportSelection(vcl::PDFWriter & rPDFWriter,Reference<com::sun::star::view::XRenderable> & rRenderable,Any & rSelection,MultiSelection aMultiSelection,Sequence<PropertyValue> & rRenderOptions,sal_Int32 nPageCount)167 sal_Bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter, Reference< com::sun::star::view::XRenderable >& rRenderable, Any& rSelection,
168 MultiSelection aMultiSelection, Sequence< PropertyValue >& rRenderOptions, sal_Int32 nPageCount )
169 {
170 sal_Bool bRet = sal_False;
171 try
172 {
173 Any* pFirstPage = NULL;
174 Any* pLastPage = NULL;
175
176 sal_Bool bExportNotesPages = sal_False;
177
178 for( sal_Int32 nData = 0, nDataCount = rRenderOptions.getLength(); nData < nDataCount; ++nData )
179 {
180 if( rRenderOptions[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) ) )
181 pFirstPage = &rRenderOptions[ nData ].Value;
182 else if( rRenderOptions[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) ) )
183 pLastPage = &rRenderOptions[ nData ].Value;
184 else if( rRenderOptions[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) ) )
185 rRenderOptions[ nData ].Value >>= bExportNotesPages;
186 }
187
188 OutputDevice* pOut = rPDFWriter.GetReferenceDevice();
189
190 if( pOut )
191 {
192 vcl::PDFExtOutDevData* pPDFExtOutDevData = PTR_CAST( vcl::PDFExtOutDevData, pOut->GetExtOutDevData() );
193 if ( nPageCount )
194 {
195 pPDFExtOutDevData->SetIsExportNotesPages( bExportNotesPages );
196
197 sal_Int32 nSel = aMultiSelection.FirstSelected();
198 sal_Int32 nIncreasingPageNumber(0);
199
200 while ( nSel != sal_Int32(SFX_ENDOFSELECTION) )
201 {
202 Sequence< PropertyValue > aRenderer( rRenderable->getRenderer( nSel - 1, rSelection, rRenderOptions ) );
203 awt::Size aPageSize;
204
205 for( sal_Int32 nProperty = 0, nPropertyCount = aRenderer.getLength(); nProperty < nPropertyCount; ++nProperty )
206 {
207 if( aRenderer[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) )
208 aRenderer[ nProperty].Value >>= aPageSize;
209 }
210
211 // #119348# The PageNumber at PDFExtOutDevDatahas to be the target page number,
212 // e.g. when exporting only page#2 from two pages, the old mechanism would
213 // have set it to '1', but a �page '1' does not yet exist in the export. This
214 // will make PDFWriterImpl::createLink and PDFWriterImpl::setLinkURL fail (see there).
215 pPDFExtOutDevData->SetCurrentPageNumber(nIncreasingPageNumber++ /* nSel - 1 */);
216
217 GDIMetaFile aMtf;
218 const MapMode aMapMode( MAP_100TH_MM );
219 const Size aMtfSize( aPageSize.Width, aPageSize.Height );
220
221 pOut->Push();
222 pOut->EnableOutput( sal_False );
223 pOut->SetMapMode( aMapMode );
224
225 aMtf.SetPrefSize( aMtfSize );
226 aMtf.SetPrefMapMode( aMapMode );
227 aMtf.Record( pOut );
228
229 // --> FME 2004-10-08 #i35176#
230 // IsLastPage property.
231 const sal_Int32 nCurrentRenderer = nSel - 1;
232 nSel = aMultiSelection.NextSelected();
233 if ( pLastPage && sal_Int32(SFX_ENDOFSELECTION) == nSel )
234 *pLastPage <<= sal_True;
235 // <--
236
237 rRenderable->render( nCurrentRenderer, rSelection, rRenderOptions );
238
239 aMtf.Stop();
240 aMtf.WindStart();
241
242 if( aMtf.GetActionCount() &&
243 ( !mbSkipEmptyPages || aPageSize.Width || aPageSize.Height ) )
244 bRet = ImplExportPage( rPDFWriter, *pPDFExtOutDevData, aMtf ) || bRet;
245
246 pOut->Pop();
247
248 if ( mxStatusIndicator.is() )
249 mxStatusIndicator->setValue( mnProgressValue );
250 if ( pFirstPage )
251 *pFirstPage <<= sal_False;
252
253 ++mnProgressValue;
254 }
255 }
256 else
257 {
258 bRet = sal_True; // #i18334# SJ: nPageCount == 0,
259 rPDFWriter.NewPage( 10000, 10000 ); // creating dummy page
260 rPDFWriter.SetMapMode( MAP_100TH_MM ); //
261 }
262 }
263 }
264 catch( RuntimeException )
265 {
266 }
267 return bRet;
268 }
269
270 class PDFExportStreamDoc : public vcl::PDFOutputStream
271 {
272 Reference< XComponent > m_xSrcDoc;
273 Sequence< beans::NamedValue > m_aPreparedPassword;
274 public:
PDFExportStreamDoc(const Reference<XComponent> & xDoc,const Sequence<beans::NamedValue> & rPwd)275 PDFExportStreamDoc( const Reference< XComponent >& xDoc, const Sequence<beans::NamedValue>& rPwd )
276 : m_xSrcDoc( xDoc ),
277 m_aPreparedPassword( rPwd )
278 {}
279 virtual ~PDFExportStreamDoc();
280
281 virtual void write( const Reference< XOutputStream >& xStream );
282 };
283
~PDFExportStreamDoc()284 PDFExportStreamDoc::~PDFExportStreamDoc()
285 {
286 }
287
write(const Reference<XOutputStream> & xStream)288 void PDFExportStreamDoc::write( const Reference< XOutputStream >& xStream )
289 {
290 Reference< com::sun::star::frame::XStorable > xStore( m_xSrcDoc, UNO_QUERY );
291 if( xStore.is() )
292 {
293 Sequence< beans::PropertyValue > aArgs( 2 + ((m_aPreparedPassword.getLength() > 0) ? 1 : 0) );
294 aArgs.getArray()[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
295 aArgs.getArray()[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
296 aArgs.getArray()[1].Value <<= xStream;
297 if( m_aPreparedPassword.getLength() )
298 {
299 aArgs.getArray()[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionData" ) );
300 aArgs.getArray()[2].Value <<= m_aPreparedPassword;
301 }
302
303 try
304 {
305 xStore->storeToURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ),
306 aArgs );
307 }
308 catch( IOException& )
309 {
310 }
311 }
312 }
313
getMimetypeForDocument(const Reference<XMultiServiceFactory> & xFactory,const Reference<XComponent> & xDoc)314 static OUString getMimetypeForDocument( const Reference< XMultiServiceFactory >& xFactory,
315 const Reference< XComponent >& xDoc ) throw()
316 {
317 OUString aDocMimetype;
318 // get document service name
319 Reference< com::sun::star::frame::XStorable > xStore( xDoc, UNO_QUERY );
320 Reference< frame::XModuleManager > xModuleManager(
321 xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ),
322 uno::UNO_QUERY );
323 if( xModuleManager.is() && xStore.is() )
324 {
325 OUString aDocServiceName = xModuleManager->identify( Reference< XInterface >( xStore, uno::UNO_QUERY ) );
326 if ( aDocServiceName.getLength() )
327 {
328 // get the actual filter name
329 OUString aFilterName;
330 Reference< lang::XMultiServiceFactory > xConfigProvider(
331 xFactory->createInstance(
332 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ) ),
333 uno::UNO_QUERY );
334 if( xConfigProvider.is() )
335 {
336 uno::Sequence< uno::Any > aArgs( 1 );
337 beans::PropertyValue aPathProp;
338 aPathProp.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
339 aPathProp.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/" ) );
340 aArgs[0] <<= aPathProp;
341
342 Reference< container::XNameAccess > xSOFConfig(
343 xConfigProvider->createInstanceWithArguments(
344 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ),
345 aArgs ),
346 uno::UNO_QUERY );
347
348 Reference< container::XNameAccess > xApplConfig;
349 xSOFConfig->getByName( aDocServiceName ) >>= xApplConfig;
350 if ( xApplConfig.is() )
351 {
352 xApplConfig->getByName( OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualFilter" ) ) ) >>= aFilterName;
353 if( aFilterName.getLength() )
354 {
355 // find the related type name
356 OUString aTypeName;
357 Reference< container::XNameAccess > xFilterFactory(
358 xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
359 uno::UNO_QUERY );
360
361 Sequence< beans::PropertyValue > aFilterData;
362 xFilterFactory->getByName( aFilterName ) >>= aFilterData;
363 for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
364 if ( aFilterData[nInd].Name.equalsAscii( "Type" ) )
365 aFilterData[nInd].Value >>= aTypeName;
366
367 if ( aTypeName.getLength() )
368 {
369 // find the mediatype
370 Reference< container::XNameAccess > xTypeDetection(
371 xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
372 UNO_QUERY );
373
374 Sequence< beans::PropertyValue > aTypeData;
375 xTypeDetection->getByName( aTypeName ) >>= aTypeData;
376 for ( sal_Int32 nInd = 0; nInd < aTypeData.getLength(); nInd++ )
377 if ( aTypeData[nInd].Name.equalsAscii( "MediaType" ) )
378 aTypeData[nInd].Value >>= aDocMimetype;
379 }
380 }
381 }
382 }
383 }
384 }
385 return aDocMimetype;
386 }
387
Export(const OUString & rFile,const Sequence<PropertyValue> & rFilterData)388 sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& rFilterData )
389 {
390 INetURLObject aURL( rFile );
391 OUString aFile;
392 sal_Bool bRet = sal_False;
393
394 std::set< PDFWriter::ErrorCode > aErrors;
395
396 if( aURL.GetProtocol() != INET_PROT_FILE )
397 {
398 String aTmp;
399
400 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFile, aTmp ) )
401 aURL = INetURLObject(aTmp);
402 }
403
404 if( aURL.GetProtocol() == INET_PROT_FILE )
405 {
406 Reference< XRenderable > xRenderable( mxSrcDoc, UNO_QUERY );
407
408 if( xRenderable.is() )
409 {
410 VCLXDevice* pXDevice = new VCLXDevice;
411 OUString aPageRange;
412 Any aSelection;
413 PDFWriter::PDFWriterContext aContext;
414 rtl::OUString aOpenPassword, aPermissionPassword;
415 Reference< beans::XMaterialHolder > xEnc;
416 Sequence< beans::NamedValue > aPreparedPermissionPassword;
417
418
419 // getting the string for the creator
420 String aCreator;
421 Reference< XServiceInfo > xInfo( mxSrcDoc, UNO_QUERY );
422 if ( xInfo.is() )
423 {
424 if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.presentation.PresentationDocument" ) ) )
425 aCreator.AppendAscii( "Impress" );
426 else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.drawing.DrawingDocument" ) ) )
427 aCreator.AppendAscii( "Draw" );
428 else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.text.TextDocument" ) ) )
429 aCreator.AppendAscii( "Writer" );
430 else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.sheet.SpreadsheetDocument" ) ) )
431 aCreator.AppendAscii( "Calc" );
432 else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.formula.FormulaProperties" ) ) )
433 aCreator.AppendAscii( "Math" );
434 }
435
436 Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY );
437 if ( xDocumentPropsSupplier.is() )
438 {
439 Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() );
440 if ( xDocumentProps.is() )
441 {
442 aContext.DocumentInfo.Title = xDocumentProps->getTitle();
443 aContext.DocumentInfo.Author = xDocumentProps->getAuthor();
444 aContext.DocumentInfo.Subject = xDocumentProps->getSubject();
445 aContext.DocumentInfo.Keywords = ::comphelper::string::convertCommaSeparated(xDocumentProps->getKeywords());
446 }
447 }
448 // getting the string for the producer
449 String aProducer;
450 ::utl::ConfigManager* pMgr = ::utl::ConfigManager::GetConfigManager();
451 if ( pMgr )
452 {
453 Any aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
454 ::rtl::OUString sProductName;
455 aProductName >>= sProductName;
456 aProducer = sProductName;
457 aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
458 aProductName >>= sProductName;
459 aProducer.AppendAscii(" ");
460 aProducer += String( sProductName );
461 }
462 aContext.DocumentInfo.Producer = aProducer;
463 aContext.DocumentInfo.Creator = aCreator;
464
465 for( sal_Int32 nData = 0, nDataCount = rFilterData.getLength(); nData < nDataCount; ++nData )
466 {
467 if( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ) )
468 rFilterData[ nData ].Value >>= aPageRange;
469 else if( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Selection" ) ) )
470 rFilterData[ nData ].Value >>= aSelection;
471 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseLosslessCompression" ) ) )
472 rFilterData[ nData ].Value >>= mbUseLosslessCompression;
473 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ) )
474 rFilterData[ nData ].Value >>= mnQuality;
475 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ReduceImageResolution" ) ) )
476 rFilterData[ nData ].Value >>= mbReduceImageResolution;
477 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) ) )
478 rFilterData[ nData ].Value >>= mbSkipEmptyPages;
479 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxImageResolution" ) ) )
480 rFilterData[ nData ].Value >>= mnMaxImageResolution;
481 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseTaggedPDF" ) ) )
482 rFilterData[ nData ].Value >>= mbUseTaggedPDF;
483 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectPdfVersion" ) ) )
484 rFilterData[ nData ].Value >>= mnPDFTypeSelection;
485 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotes" ) ) )
486 rFilterData[ nData ].Value >>= mbExportNotes;
487 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) ) )
488 rFilterData[ nData ].Value >>= mbExportNotesPages;
489 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbedStandardFonts" ) ) )
490 rFilterData[ nData ].Value >>= mbEmbedStandardFonts;
491 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseTransitionEffects" ) ) )
492 rFilterData[ nData ].Value >>= mbUseTransitionEffects;
493 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportFormFields" ) ) )
494 rFilterData[ nData ].Value >>= mbExportFormFields;
495 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "FormsType" ) ) )
496 rFilterData[ nData ].Value >>= mnFormsFormat;
497 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowDuplicateFieldNames" ) ) )
498 rFilterData[ nData ].Value >>= mbAllowDuplicateFieldNames;
499 //viewer properties
500 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerToolbar" ) ) )
501 rFilterData[ nData ].Value >>= mbHideViewerToolbar;
502 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerMenubar" ) ) )
503 rFilterData[ nData ].Value >>= mbHideViewerMenubar;
504 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerWindowControls" ) ) )
505 rFilterData[ nData ].Value >>= mbHideViewerWindowControls;
506 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ResizeWindowToInitialPage" ) ) )
507 rFilterData[ nData ].Value >>= mbFitWindow;
508 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "CenterWindow" ) ) )
509 rFilterData[ nData ].Value >>= mbCenterWindow;
510 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenInFullScreenMode" ) ) )
511 rFilterData[ nData ].Value >>= mbOpenInFullScreenMode;
512 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "DisplayPDFDocumentTitle" ) ) )
513 rFilterData[ nData ].Value >>= mbDisplayPDFDocumentTitle;
514 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialView" ) ) )
515 rFilterData[ nData ].Value >>= mnPDFDocumentMode;
516 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Magnification" ) ) )
517 rFilterData[ nData ].Value >>= mnPDFDocumentAction;
518 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) ) )
519 rFilterData[ nData ].Value >>= mnZoom;
520 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialPage" ) ) )
521 rFilterData[ nData ].Value >>= mnInitialPage;
522 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageLayout" ) ) )
523 rFilterData[ nData ].Value >>= mnPDFPageLayout;
524 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "FirstPageOnLeft" ) ) )
525 rFilterData[ nData ].Value >>= aContext.FirstPageLeft;
526 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsAddStream" ) ) )
527 rFilterData[ nData ].Value >>= mbAddStream;
528 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) ) )
529 {
530 maWatermark = rFilterData[ nData ].Value;
531 mbWatermark = sal_True;
532 }
533 //now all the security related properties...
534 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptFile" ) ) )
535 rFilterData[ nData ].Value >>= mbEncrypt;
536 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentOpenPassword" ) ) )
537 rFilterData[ nData ].Value >>= aOpenPassword;
538 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "RestrictPermissions" ) ) )
539 rFilterData[ nData ].Value >>= mbRestrictPermissions;
540 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PermissionPassword" ) ) )
541 rFilterData[ nData ].Value >>= aPermissionPassword;
542 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPasswords" ) ) )
543 rFilterData[ nData ].Value >>= xEnc;
544 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPermissionPassword" ) ) )
545 rFilterData[ nData ].Value >>= aPreparedPermissionPassword;
546 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Printing" ) ) )
547 rFilterData[ nData ].Value >>= mnPrintAllowed;
548 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Changes" ) ) )
549 rFilterData[ nData ].Value >>= mnChangesAllowed;
550 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableCopyingOfContent" ) ) )
551 rFilterData[ nData ].Value >>= mbCanCopyOrExtract;
552 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableTextAccessForAccessibilityTools" ) ) )
553 rFilterData[ nData ].Value >>= mbCanExtractForAccessibility;
554 //--->i56629 links extra (relative links and other related stuff)
555 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportLinksRelativeFsys" ) ) )
556 rFilterData[ nData ].Value >>= mbExportRelativeFsysLinks;
557 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PDFViewSelection" ) ) )
558 rFilterData[ nData ].Value >>= mnDefaultLinkAction;
559 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ConvertOOoTargetToPDFTarget" ) ) )
560 rFilterData[ nData ].Value >>= mbConvertOOoTargetToPDFTarget;
561 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarksToPDFDestination" ) ) )
562 rFilterData[ nData ].Value >>= mbExportBmkToDest;
563 //<---
564 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarks" ) ) )
565 rFilterData[ nData ].Value >>= mbExportBookmarks;
566 else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenBookmarkLevels" ) ) )
567 rFilterData[ nData ].Value >>= mnOpenBookmarkLevels;
568 }
569 aContext.URL = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
570
571 //set the correct version, depending on user request
572 switch( mnPDFTypeSelection )
573 {
574 default:
575 case 0:
576 aContext.Version = PDFWriter::PDF_1_4;
577 break;
578 case 1:
579 aContext.Version = PDFWriter::PDF_A_1;
580 //force the tagged PDF as well
581 mbUseTaggedPDF = sal_True;
582 //force embedding of standard fonts
583 mbEmbedStandardFonts = sal_True;
584 //force disabling of form conversion
585 mbExportFormFields = sal_False;
586 // PDF/A does not allow transparencies
587 mbRemoveTransparencies = sal_True;
588 // no encryption
589 mbEncrypt = sal_False;
590 xEnc.clear();
591 break;
592 }
593
594 //copy in context the values default in the contructor or set by the FilterData sequence of properties
595 aContext.Tagged = mbUseTaggedPDF;
596
597 //values used in viewer
598 aContext.HideViewerToolbar = mbHideViewerToolbar;
599 aContext.HideViewerMenubar = mbHideViewerMenubar;
600 aContext.HideViewerWindowControls = mbHideViewerWindowControls;
601 aContext.FitWindow = mbFitWindow;
602 aContext.CenterWindow = mbCenterWindow;
603 aContext.OpenInFullScreenMode = mbOpenInFullScreenMode;
604 aContext.DisplayPDFDocumentTitle = mbDisplayPDFDocumentTitle;
605 aContext.InitialPage = mnInitialPage-1;
606 aContext.OpenBookmarkLevels = mnOpenBookmarkLevels;
607 aContext.EmbedStandardFonts = mbEmbedStandardFonts;
608
609 switch( mnPDFDocumentMode )
610 {
611 default:
612 case 0:
613 aContext.PDFDocumentMode = PDFWriter::ModeDefault;
614 break;
615 case 1:
616 aContext.PDFDocumentMode = PDFWriter::UseOutlines;
617 break;
618 case 2:
619 aContext.PDFDocumentMode = PDFWriter::UseThumbs;
620 break;
621 }
622 switch( mnPDFDocumentAction )
623 {
624 default:
625 case 0:
626 aContext.PDFDocumentAction = PDFWriter::ActionDefault;
627 break;
628 case 1:
629 aContext.PDFDocumentAction = PDFWriter::FitInWindow;
630 break;
631 case 2:
632 aContext.PDFDocumentAction = PDFWriter::FitWidth;
633 break;
634 case 3:
635 aContext.PDFDocumentAction = PDFWriter::FitVisible;
636 break;
637 case 4:
638 aContext.PDFDocumentAction = PDFWriter::ActionZoom;
639 aContext.Zoom = mnZoom;
640 break;
641 }
642
643 switch( mnPDFPageLayout )
644 {
645 default:
646 case 0:
647 aContext.PageLayout = PDFWriter::DefaultLayout;
648 break;
649 case 1:
650 aContext.PageLayout = PDFWriter::SinglePage;
651 break;
652 case 2:
653 aContext.PageLayout = PDFWriter::Continuous;
654 break;
655 case 3:
656 aContext.PageLayout = PDFWriter::ContinuousFacing;
657 break;
658 }
659
660 aContext.FirstPageLeft = mbFirstPageLeft;
661
662 //check if PDF/A, which does not allow encryption
663 if( aContext.Version != PDFWriter::PDF_A_1 )
664 {
665 //set values needed in encryption
666 //set encryption level, fixed, but here it can set by the UI if needed.
667 // true is 128 bit, false 40
668 //note that in 40 bit mode the UI needs reworking, since the current UI is meaningfull only for
669 //128bit security mode
670 aContext.Encryption.Security128bit = sal_True;
671
672 //set check for permission change password
673 // if not enabled and no permission password, force permissions to default as if PDF where without encryption
674 if( mbRestrictPermissions && (xEnc.is() || aPermissionPassword.getLength() > 0) )
675 {
676 mbEncrypt = sal_True;
677 //permission set as desired, done after
678 }
679 else
680 {
681 //force permission to default
682 mnPrintAllowed = 2 ;
683 mnChangesAllowed = 4 ;
684 mbCanCopyOrExtract = sal_True;
685 mbCanExtractForAccessibility = sal_True ;
686 }
687
688 switch( mnPrintAllowed )
689 {
690 case 0: //initialized when aContext is build, means no printing
691 break;
692 default:
693 case 2:
694 aContext.Encryption.CanPrintFull = sal_True;
695 case 1:
696 aContext.Encryption.CanPrintTheDocument = sal_True;
697 break;
698 }
699
700 switch( mnChangesAllowed )
701 {
702 case 0: //already in struct PDFSecPermissions CTOR
703 break;
704 case 1:
705 aContext.Encryption.CanAssemble = sal_True;
706 break;
707 case 2:
708 aContext.Encryption.CanFillInteractive = sal_True;
709 break;
710 case 3:
711 aContext.Encryption.CanAddOrModify = sal_True;
712 break;
713 default:
714 case 4:
715 aContext.Encryption.CanModifyTheContent =
716 aContext.Encryption.CanCopyOrExtract =
717 aContext.Encryption.CanAddOrModify =
718 aContext.Encryption.CanFillInteractive = sal_True;
719 break;
720 }
721
722 aContext.Encryption.CanCopyOrExtract = mbCanCopyOrExtract;
723 aContext.Encryption.CanExtractForAccessibility = mbCanExtractForAccessibility;
724 if( mbEncrypt && ! xEnc.is() )
725 xEnc = PDFWriter::InitEncryption( aPermissionPassword, aOpenPassword, aContext.Encryption.Security128bit );
726 if( mbEncrypt && aPermissionPassword.getLength() && ! aPreparedPermissionPassword.getLength() )
727 aPreparedPermissionPassword = comphelper::OStorageHelper::CreatePackageEncryptionData( aPermissionPassword );
728 }
729 // after this point we don't need the legacy clear passwords anymore
730 // however they are still inside the passed filter data sequence
731 // which is sadly out out our control
732 aPermissionPassword = rtl::OUString();
733 aOpenPassword = rtl::OUString();
734
735 /*
736 * FIXME: the entries are only implicitly defined by the resource file. Should there
737 * ever be an additional form submit format this could get invalid.
738 */
739 switch( mnFormsFormat )
740 {
741 case 1:
742 aContext.SubmitFormat = PDFWriter::PDF;
743 break;
744 case 2:
745 aContext.SubmitFormat = PDFWriter::HTML;
746 break;
747 case 3:
748 aContext.SubmitFormat = PDFWriter::XML;
749 break;
750 default:
751 case 0:
752 aContext.SubmitFormat = PDFWriter::FDF;
753 break;
754 }
755 aContext.AllowDuplicateFieldNames = mbAllowDuplicateFieldNames;
756
757 //get model
758 Reference< frame::XModel > xModel( mxSrcDoc, UNO_QUERY );
759 {
760 //---> i56629 Relative link stuff
761 //set the base URL of the file:
762 //then base URL
763 aContext.BaseURL = xModel->getURL();
764 //relative link option is private to PDF Export filter and limited to local filesystem only
765 aContext.RelFsys = mbExportRelativeFsysLinks;
766 //determine the default acton for PDF links
767 switch( mnDefaultLinkAction )
768 {
769 default:
770 //default: URI, without fragment conversion (the bookmark in PDF may not work)
771 case 0:
772 aContext.DefaultLinkAction = PDFWriter::URIAction;
773 break;
774 //view PDF through the reader application
775 case 1:
776 aContext.ForcePDFAction = sal_True;
777 aContext.DefaultLinkAction = PDFWriter::LaunchAction;
778 break;
779 //view PDF through an Internet browser
780 case 2:
781 aContext.DefaultLinkAction = PDFWriter::URIActionDestination;
782 break;
783 }
784 aContext.ConvertOOoTargetToPDFTarget = mbConvertOOoTargetToPDFTarget;
785 // check for Link Launch action, not allowed on PDF/A-1
786 // this code chunk checks when the filter is called from scripting
787 if( aContext.Version == PDFWriter::PDF_A_1 &&
788 aContext.DefaultLinkAction == PDFWriter::LaunchAction )
789 { //force the similar allowed URI action
790 aContext.DefaultLinkAction = PDFWriter::URIActionDestination;
791 //and remove the remote goto action forced on PDF file
792 aContext.ForcePDFAction = sal_False;
793 }
794 //<---
795 }
796 // all context data set, time to create the printing device
797 PDFWriter* pPDFWriter = new PDFWriter( aContext, xEnc );
798 OutputDevice* pOut = pPDFWriter->GetReferenceDevice();
799 vcl::PDFExtOutDevData* pPDFExtOutDevData = NULL;
800
801 DBG_ASSERT( pOut, "PDFExport::Export: no reference device" );
802 pXDevice->SetOutputDevice( pOut );
803
804 if( mbAddStream )
805 {
806 // export stream
807 // get mimetype
808 OUString aSrcMimetype = getMimetypeForDocument( mxMSF, mxSrcDoc );
809 pPDFWriter->AddStream( aSrcMimetype,
810 new PDFExportStreamDoc( mxSrcDoc, aPreparedPermissionPassword ),
811 false
812 );
813 }
814
815 if ( pOut )
816 {
817 DBG_ASSERT( pOut->GetExtOutDevData() == NULL, "PDFExport: ExtOutDevData already set!!!" );
818 pPDFExtOutDevData = new vcl::PDFExtOutDevData( *pOut );
819 pOut->SetExtOutDevData( pPDFExtOutDevData );
820 pPDFExtOutDevData->SetIsExportNotes( mbExportNotes );
821 pPDFExtOutDevData->SetIsExportTaggedPDF( mbUseTaggedPDF );
822 pPDFExtOutDevData->SetIsExportTransitionEffects( mbUseTransitionEffects );
823 pPDFExtOutDevData->SetFormsFormat( mnFormsFormat );
824 pPDFExtOutDevData->SetIsExportFormFields( mbExportFormFields );
825 pPDFExtOutDevData->SetIsExportBookmarks( mbExportBookmarks );
826 pPDFExtOutDevData->SetIsLosslessCompression( mbUseLosslessCompression );
827 pPDFExtOutDevData->SetIsReduceImageResolution( mbReduceImageResolution );
828 pPDFExtOutDevData->SetIsExportNamedDestinations( mbExportBmkToDest );
829
830 Sequence< PropertyValue > aRenderOptions( 6 );
831 aRenderOptions[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) );
832 aRenderOptions[ 0 ].Value <<= Reference< awt::XDevice >( pXDevice );
833 aRenderOptions[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) );
834 aRenderOptions[ 1 ].Value <<= sal_False;
835 Any& rExportNotesValue = aRenderOptions[ 1 ].Value;
836 aRenderOptions[ 2 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) );
837 aRenderOptions[ 2 ].Value <<= sal_True;
838 aRenderOptions[ 3 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) );
839 aRenderOptions[ 3 ].Value <<= sal_False;
840 aRenderOptions[ 4 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) );
841 aRenderOptions[ 4 ].Value <<= mbSkipEmptyPages;
842 aRenderOptions[ 5 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) );
843 aRenderOptions[ 5 ].Value <<= aPageRange;
844
845 if( aPageRange.getLength() || !aSelection.hasValue() )
846 {
847 aSelection = Any();
848 aSelection <<= mxSrcDoc;
849 }
850 sal_Bool bSecondPassForImpressNotes = sal_False;
851 bool bReChangeToNormalView = false;
852 ::rtl::OUString sShowOnlineLayout( RTL_CONSTASCII_USTRINGPARAM( "ShowOnlineLayout"));
853 uno::Reference< beans::XPropertySet > xViewProperties;
854
855 if ( aCreator.EqualsAscii( "Writer" ) )
856 {
857 //i92835 if Writer is in web layout mode this has to be switched to normal view and back to web view in the end
858 try
859 {
860 Reference< view::XViewSettingsSupplier > xVSettingsSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
861 xViewProperties = xVSettingsSupplier->getViewSettings();
862 xViewProperties->getPropertyValue( sShowOnlineLayout ) >>= bReChangeToNormalView;
863 if( bReChangeToNormalView )
864 {
865 xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( false ) );
866 }
867 }
868 catch( const uno::Exception& )
869 {
870 }
871
872 }
873
874 const sal_Int32 nPageCount = xRenderable->getRendererCount( aSelection, aRenderOptions );
875 const Range aRange( 1, nPageCount );
876 MultiSelection aMultiSelection;
877
878 if ( mbExportNotesPages && aCreator.EqualsAscii( "Impress" ) )
879 {
880 uno::Reference< drawing::XShapes > xShapes; // sj: do not allow to export notes when
881 if ( ! ( aSelection >>= xShapes ) ) // exporting a selection -> todo: in the dialog
882 bSecondPassForImpressNotes = sal_True; // the export notes checkbox needs to be disabled
883 }
884
885 if( !aPageRange.getLength() )
886 {
887 aMultiSelection.SetTotalRange( aRange );
888 aMultiSelection.Select( aRange );
889 }
890 else
891 {
892 aMultiSelection = MultiSelection( aPageRange );
893 aMultiSelection.SetTotalRange( aRange );
894 }
895 if ( mxStatusIndicator.is() )
896 {
897 ByteString aResMgrName( "pdffilter" );
898 ResMgr* pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
899 if ( pResMgr )
900 {
901 sal_Int32 nTotalPageCount = aMultiSelection.GetSelectCount();
902 if ( bSecondPassForImpressNotes )
903 nTotalPageCount *= 2;
904 mxStatusIndicator->start( String( ResId( PDF_PROGRESS_BAR, *pResMgr ) ), nTotalPageCount );
905 delete pResMgr;
906 }
907 }
908
909 if( nPageCount > 0 )
910 bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aMultiSelection, aRenderOptions, nPageCount );
911 else
912 bRet = sal_False;
913
914 if ( bRet && bSecondPassForImpressNotes )
915 {
916 rExportNotesValue <<= sal_True;
917 bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aMultiSelection, aRenderOptions, nPageCount );
918 }
919 if ( mxStatusIndicator.is() )
920 mxStatusIndicator->end();
921
922 // if during the export the doc locale was set copy it to PDF writer
923 const com::sun::star::lang::Locale& rLoc( pPDFExtOutDevData->GetDocumentLocale() );
924 if( rLoc.Language.getLength() )
925 pPDFWriter->SetDocumentLocale( rLoc );
926
927 if( bRet )
928 {
929 pPDFExtOutDevData->PlayGlobalActions( *pPDFWriter );
930 pPDFWriter->Emit();
931 aErrors = pPDFWriter->GetErrors();
932 }
933 pOut->SetExtOutDevData( NULL );
934 if( bReChangeToNormalView )
935 {
936 try
937 {
938 xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( true ) );
939 }
940 catch( const uno::Exception& )
941 {
942 }
943 }
944 }
945
946 delete pPDFExtOutDevData;
947 delete pPDFWriter;
948 }
949 }
950
951 // show eventual errors during export
952 showErrors( aErrors );
953
954 return bRet;
955 }
956
957 namespace
958 {
959
960 typedef cppu::WeakComponentImplHelper1< task::XInteractionRequest > PDFErrorRequestBase;
961
962 class PDFErrorRequest : private cppu::BaseMutex,
963 public PDFErrorRequestBase
964 {
965 task::PDFExportException maExc;
966 public:
967 PDFErrorRequest( const task::PDFExportException& i_rExc );
968
969 // XInteractionRequest
970 virtual uno::Any SAL_CALL getRequest() throw (uno::RuntimeException);
971 virtual uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL getContinuations() throw (uno::RuntimeException);
972 };
973
PDFErrorRequest(const task::PDFExportException & i_rExc)974 PDFErrorRequest::PDFErrorRequest( const task::PDFExportException& i_rExc ) :
975 PDFErrorRequestBase( m_aMutex ),
976 maExc( i_rExc )
977 {
978 }
979
getRequest()980 uno::Any SAL_CALL PDFErrorRequest::getRequest() throw (uno::RuntimeException)
981 {
982 osl::MutexGuard const guard( m_aMutex );
983
984 uno::Any aRet;
985 aRet <<= maExc;
986 return aRet;
987 }
988
getContinuations()989 uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL PDFErrorRequest::getContinuations() throw (uno::RuntimeException)
990 {
991 return uno::Sequence< uno::Reference< task::XInteractionContinuation > >();
992 }
993
994 } // namespace
995
showErrors(const std::set<PDFWriter::ErrorCode> & rErrors)996 void PDFExport::showErrors( const std::set< PDFWriter::ErrorCode >& rErrors )
997 {
998 if( ! rErrors.empty() && mxIH.is() )
999 {
1000 task::PDFExportException aExc;
1001 aExc.ErrorCodes.realloc( sal_Int32(rErrors.size()) );
1002 sal_Int32 i = 0;
1003 for( std::set< PDFWriter::ErrorCode >::const_iterator it = rErrors.begin();
1004 it != rErrors.end(); ++it, i++ )
1005 {
1006 aExc.ErrorCodes.getArray()[i] = (sal_Int32)*it;
1007 }
1008 Reference< task::XInteractionRequest > xReq( new PDFErrorRequest( aExc ) );
1009 mxIH->handle( xReq );
1010 }
1011 }
1012
1013 // -----------------------------------------------------------------------------
1014
ImplExportPage(PDFWriter & rWriter,PDFExtOutDevData & rPDFExtOutDevData,const GDIMetaFile & rMtf)1015 sal_Bool PDFExport::ImplExportPage( PDFWriter& rWriter, PDFExtOutDevData& rPDFExtOutDevData, const GDIMetaFile& rMtf )
1016 {
1017 const Size aSizePDF( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_POINT ) );
1018 Point aOrigin;
1019 Rectangle aPageRect( aOrigin, rMtf.GetPrefSize() );
1020 sal_Bool bRet = sal_True;
1021
1022 rWriter.NewPage( aSizePDF.Width(), aSizePDF.Height() );
1023 rWriter.SetMapMode( rMtf.GetPrefMapMode() );
1024
1025 vcl::PDFWriter::PlayMetafileContext aCtx;
1026 GDIMetaFile aMtf;
1027 if( mbRemoveTransparencies )
1028 {
1029 aCtx.m_bTransparenciesWereRemoved = rWriter.GetReferenceDevice()->
1030 RemoveTransparenciesFromMetaFile( rMtf, aMtf, mnMaxImageResolution, mnMaxImageResolution,
1031 false, true, mbReduceImageResolution );
1032 }
1033 else
1034 {
1035 aMtf = rMtf;
1036 }
1037 aCtx.m_nMaxImageResolution = mbReduceImageResolution ? mnMaxImageResolution : 0;
1038 aCtx.m_bOnlyLosslessCompression = mbUseLosslessCompression;
1039 aCtx.m_nJPEGQuality = mnQuality;
1040
1041
1042 basegfx::B2DRectangle aB2DRect( aPageRect.Left(), aPageRect.Top(), aPageRect.Right(), aPageRect.Bottom() );
1043 rWriter.SetClipRegion( basegfx::B2DPolyPolygon( basegfx::tools::createPolygonFromRect( aB2DRect ) ) );
1044
1045 rWriter.PlayMetafile( aMtf, aCtx, &rPDFExtOutDevData );
1046
1047 rPDFExtOutDevData.ResetSyncData();
1048
1049 if( mbWatermark )
1050 ImplWriteWatermark( rWriter, aSizePDF );
1051
1052 return bRet;
1053 }
1054
1055 // -----------------------------------------------------------------------------
1056
ImplWriteWatermark(PDFWriter & rWriter,const Size & rPageSize)1057 void PDFExport::ImplWriteWatermark( PDFWriter& rWriter, const Size& rPageSize )
1058 {
1059 OUString aText( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) );
1060 Font aFont( OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica" ) ), Size( 0, 3*rPageSize.Height()/4 ) );
1061 aFont.SetItalic( ITALIC_NONE );
1062 aFont.SetWidthType( WIDTH_NORMAL );
1063 aFont.SetWeight( WEIGHT_NORMAL );
1064 aFont.SetAlign( ALIGN_BOTTOM );
1065 long nTextWidth = rPageSize.Width();
1066 if( rPageSize.Width() < rPageSize.Height() )
1067 {
1068 nTextWidth = rPageSize.Height();
1069 aFont.SetOrientation( 2700 );
1070 }
1071
1072 if( ! ( maWatermark >>= aText ) )
1073 {
1074 // more complicated watermark ?
1075 }
1076
1077 // adjust font height for text to fit
1078 OutputDevice* pDev = rWriter.GetReferenceDevice();
1079 pDev->Push( PUSH_ALL );
1080 pDev->SetFont( aFont );
1081 pDev->SetMapMode( MapMode( MAP_POINT ) );
1082 int w = 0;
1083 while( ( w = pDev->GetTextWidth( aText ) ) > nTextWidth )
1084 {
1085 long nNewHeight = aFont.GetHeight() * nTextWidth / w;
1086 if( nNewHeight == aFont.GetHeight() )
1087 {
1088 nNewHeight--;
1089 if( nNewHeight <= 0 )
1090 break;
1091 }
1092 aFont.SetHeight( nNewHeight );
1093 pDev->SetFont( aFont );
1094 }
1095 long nTextHeight = pDev->GetTextHeight();
1096 // leave some maneuvering room for rounding issues, also
1097 // some fonts go a little outside ascent/descent
1098 nTextHeight += nTextHeight/20;
1099 pDev->Pop();
1100
1101 rWriter.Push( PUSH_ALL );
1102 rWriter.SetMapMode( MapMode( MAP_POINT ) );
1103 rWriter.SetFont( aFont );
1104 rWriter.SetTextColor( COL_RED );
1105 Point aTextPoint;
1106 Rectangle aTextRect;
1107 if( rPageSize.Width() > rPageSize.Height() )
1108 {
1109 aTextPoint = Point( (rPageSize.Width()-w)/2,
1110 rPageSize.Height()-(rPageSize.Height()-nTextHeight)/2 );
1111 aTextRect = Rectangle( Point( (rPageSize.Width()-w)/2,
1112 (rPageSize.Height()-nTextHeight)/2 ),
1113 Size( w, nTextHeight ) );
1114 }
1115 else
1116 {
1117 aTextPoint = Point( (rPageSize.Width()-nTextHeight)/2,
1118 (rPageSize.Height()-w)/2 );
1119 aTextRect = Rectangle( aTextPoint, Size( nTextHeight, w ) );
1120 }
1121 rWriter.SetClipRegion();
1122 rWriter.BeginTransparencyGroup();
1123 rWriter.DrawText( aTextPoint, aText );
1124 rWriter.EndTransparencyGroup( aTextRect, 50 );
1125 rWriter.Pop();
1126 }
1127
1128
1129