LibreOffice Module vcl (master)  1
print3.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <vcl/weld.hxx>
21 #include <vcl/print.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/metaact.hxx>
24 #include <vcl/configsettings.hxx>
25 #include <tools/urlobj.hxx>
27 #include <comphelper/sequence.hxx>
28 #include <sal/types.h>
29 #include <sal/log.hxx>
30 #include <tools/debug.hxx>
31 
32 #include <printdlg.hxx>
33 #include <svdata.hxx>
34 #include <salinst.hxx>
35 #include <salprn.hxx>
36 #include <strings.hrc>
37 
38 #include <com/sun/star/ui/dialogs/FilePicker.hpp>
39 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
40 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
41 #include <com/sun/star/view/DuplexMode.hpp>
42 #include <com/sun/star/lang/IllegalArgumentException.hpp>
43 #include <com/sun/star/awt/Size.hpp>
44 
45 #include <unordered_map>
46 #include <unordered_set>
47 
48 using namespace vcl;
49 
51 {
52  struct CacheEntry
53  {
56  };
57 
58  std::vector< CacheEntry > maPages;
59  std::vector< sal_Int32 > maPageNumbers;
60  std::vector< sal_Int32 > maCacheRanking;
61 
62  static const sal_Int32 nCacheSize = 6;
63 
64  void updateRanking( sal_Int32 nLastHit )
65  {
66  if( maCacheRanking[0] != nLastHit )
67  {
68  for( sal_Int32 i = nCacheSize-1; i > 0; i-- )
69  maCacheRanking[i] = maCacheRanking[i-1];
70  maCacheRanking[0] = nLastHit;
71  }
72  }
73 
74 public:
76  : maPages( nCacheSize )
77  , maPageNumbers( nCacheSize, -1 )
78  , maCacheRanking( nCacheSize )
79  {
80  for( sal_Int32 i = 0; i < nCacheSize; i++ )
81  maCacheRanking[i] = nCacheSize - i - 1;
82  }
83 
84  // caution: does not ensure uniqueness
85  void insert( sal_Int32 i_nPageNo, const GDIMetaFile& i_rPage, const PrinterController::PageSize& i_rSize )
86  {
87  sal_Int32 nReplacePage = maCacheRanking.back();
88  maPages[ nReplacePage ].aPage = i_rPage;
89  maPages[ nReplacePage ].aSize = i_rSize;
90  maPageNumbers[ nReplacePage ] = i_nPageNo;
91  // cache insertion means in our case, the page was just queried
92  // so update the ranking
93  updateRanking( nReplacePage );
94  }
95 
96  // caution: bad algorithm; should there ever be reason to increase the cache size beyond 6
97  // this needs to be urgently rewritten. However do NOT increase the cache size lightly,
98  // whole pages can be rather memory intensive
99  bool get( sal_Int32 i_nPageNo, GDIMetaFile& o_rPageFile, PrinterController::PageSize& o_rSize )
100  {
101  for( sal_Int32 i = 0; i < nCacheSize; ++i )
102  {
103  if( maPageNumbers[i] == i_nPageNo )
104  {
105  updateRanking( i );
106  o_rPageFile = maPages[i].aPage;
107  o_rSize = maPages[i].aSize;
108  return true;
109  }
110  }
111  return false;
112  }
113 
114  void invalidate()
115  {
116  for( sal_Int32 i = 0; i < nCacheSize; ++i )
117  {
118  maPageNumbers[i] = -1;
119  maPages[i].aPage.Clear();
120  maCacheRanking[i] = nCacheSize - i - 1;
121  }
122  }
123 };
124 
126 {
127 public:
129  {
130  OUString maDependsOnName;
131  sal_Int32 mnDependsOnEntry;
132 
133  ControlDependency() : mnDependsOnEntry( -1 ) {}
134  };
135 
136  typedef std::unordered_map< OUString, size_t > PropertyToIndexMap;
137  typedef std::unordered_map< OUString, ControlDependency > ControlDependencyMap;
138  typedef std::unordered_map< OUString, css::uno::Sequence< sal_Bool > > ChoiceDisableMap;
139 
142  css::uno::Sequence< css::beans::PropertyValue > maUIOptions;
143  std::vector< css::beans::PropertyValue > maUIProperties;
144  std::vector< bool > maUIPropertyEnabled;
145  PropertyToIndexMap maPropertyToIndex;
146  ControlDependencyMap maControlDependencies;
147  ChoiceDisableMap maChoiceDisableMap;
154  css::view::PrintableState meJobState;
155 
157 
158  std::shared_ptr<vcl::PrintProgressDialog> mxProgress;
159 
161 
162  // set by user through printer properties subdialog of printer settings dialog
164  // set by user through print dialog
166  // set by user through printer properties subdialog of printer settings dialog
167  sal_Int32 mnDefaultPaperBin;
168  // Set by user through printer properties subdialog of print dialog.
169  // Overrides application-set tray for a page.
170  sal_Int32 mnFixedPaperBin;
171 
172  // N.B. Apparently we have three levels of paper tray settings
173  // (latter overrides former):
174  // 1. default tray
175  // 2. tray set for a concrete page by an application, e.g., writer
176  // allows setting a printer tray (for the default printer) for a
177  // page style. This setting can be overridden by user by selecting
178  // "Use only paper tray from printer preferences" on the Options
179  // page in the print dialog, in which case the default tray is
180  // used for all pages.
181  // 3. tray set in printer properties the printer dialog
182  // I'm not quite sure why 1. and 3. are distinct, but the commit
183  // history suggests this is intentional...
184 
186  mpWindow( nullptr ),
187  mbFirstPage( true ),
188  mbLastPage( false ),
189  mbReversePageOrder( false ),
190  mbPapersizeFromSetup( false ),
191  mbPapersizeFromUser( false ),
192  mbPrinterModified( false ),
193  meJobState( css::view::PrintableState_JOB_STARTED ),
194  mnDefaultPaperBin( -1 ),
195  mnFixedPaperBin( -1 )
196  {}
197 
199  {
200  if (mxProgress)
201  {
202  mxProgress->response(RET_CANCEL);
203  mxProgress.reset();
204  }
205  }
206 
207  const Size& getRealPaperSize( const Size& i_rPageSize, bool bNoNUP ) const
208  {
209  if ( mbPapersizeFromUser )
210  return maUserPageSize;
211  if( mbPapersizeFromSetup )
212  return maDefaultPageSize;
213  if( maMultiPage.nRows * maMultiPage.nColumns > 1 && ! bNoNUP )
214  return maMultiPage.aPaperSize;
215  return i_rPageSize;
216  }
217  bool isFixedPageSize() const
218  { return mbPapersizeFromSetup; }
219  PrinterController::PageSize modifyJobSetup( const css::uno::Sequence< css::beans::PropertyValue >& i_rProps );
221 };
222 
224  : mpImplData( new ImplPrinterControllerData )
225 {
226  mpImplData->mxPrinter = i_xPrinter;
227  mpImplData->mpWindow = i_pWindow;
228 }
229 
230 static OUString queryFile( Printer const * pPrinter )
231 {
232  OUString aResult;
233 
234  css::uno::Reference< css::uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
235  css::uno::Reference< css::ui::dialogs::XFilePicker3 > xFilePicker = css::ui::dialogs::FilePicker::createWithMode(xContext, css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION);
236 
237  try
238  {
239 #ifdef UNX
240  // add PostScript and PDF
241  bool bPS = true, bPDF = true;
242  if( pPrinter )
243  {
244  if( pPrinter->GetCapabilities( PrinterCapType::PDF ) )
245  bPS = false;
246  else
247  bPDF = false;
248  }
249  if( bPS )
250  xFilePicker->appendFilter( "PostScript", "*.ps" );
251  if( bPDF )
252  xFilePicker->appendFilter( "Portable Document Format", "*.pdf" );
253 #elif defined WNT
254  (void)pPrinter;
255  xFilePicker->appendFilter( "*.PRN", "*.prn" );
256 #endif
257  // add arbitrary files
258  xFilePicker->appendFilter(VclResId(SV_STDTEXT_ALLFILETYPES), "*.*");
259  }
260  catch (const css::lang::IllegalArgumentException&)
261  {
262  SAL_WARN( "vcl.gdi", "caught IllegalArgumentException when registering filter" );
263  }
264 
265  if( xFilePicker->execute() == css::ui::dialogs::ExecutableDialogResults::OK )
266  {
267  css::uno::Sequence< OUString > aPathSeq( xFilePicker->getSelectedFiles() );
268  INetURLObject aObj( aPathSeq[0] );
269  aResult = aObj.PathToFileName();
270  }
271  return aResult;
272 }
273 
275 {
276  std::shared_ptr<PrinterController> mxController;
278 
279  PrintJobAsync(const std::shared_ptr<PrinterController>& i_xController,
280  const JobSetup& i_rInitSetup)
281  : mxController( i_xController ), maInitSetup( i_rInitSetup )
282  {}
283 
284  DECL_LINK( ExecJob, void*, void );
285 };
286 
287 IMPL_LINK_NOARG(PrintJobAsync, ExecJob, void*, void)
288 {
289  Printer::ImplPrintJob(mxController, maInitSetup);
290 
291  // clean up, do not access members after this
292  delete this;
293 }
294 
295 void Printer::PrintJob(const std::shared_ptr<PrinterController>& i_xController,
296  const JobSetup& i_rInitSetup)
297 {
298  bool bSynchronous = false;
299  css::beans::PropertyValue* pVal = i_xController->getValue( "Wait" );
300  if( pVal )
301  pVal->Value >>= bSynchronous;
302 
303  if( bSynchronous )
304  ImplPrintJob(i_xController, i_rInitSetup);
305  else
306  {
307  PrintJobAsync* pAsync = new PrintJobAsync(i_xController, i_rInitSetup);
308  Application::PostUserEvent( LINK( pAsync, PrintJobAsync, ExecJob ) );
309  }
310 }
311 
312 bool Printer::PreparePrintJob(std::shared_ptr<PrinterController> xController,
313  const JobSetup& i_rInitSetup)
314 {
315  // check if there is a default printer; if not, show an error box (if appropriate)
316  if( GetDefaultPrinterName().isEmpty() )
317  {
318  if (xController->isShowDialogs())
319  {
320  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(xController->getWindow(), "vcl/ui/errornoprinterdialog.ui"));
321  std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("ErrorNoPrinterDialog"));
322  xBox->run();
323  }
324  xController->setValue( "IsDirect",
325  css::uno::makeAny( false ) );
326  }
327 
328  // setup printer
329 
330  // #i114306# changed behavior back from persistence
331  // if no specific printer is already set, create the default printer
332  if (!xController->getPrinter())
333  {
334  OUString aPrinterName( i_rInitSetup.GetPrinterName() );
335  VclPtrInstance<Printer> xPrinter( aPrinterName );
336  xPrinter->SetJobSetup(i_rInitSetup);
337  xController->setPrinter(xPrinter);
338  xController->setPapersizeFromSetup(xPrinter->GetPrinterSettingsPreferred());
339  }
340 
341  // reset last page property
342  xController->setLastPage(false);
343 
344  // update "PageRange" property inferring from other properties:
345  // case 1: "Pages" set from UNO API ->
346  // setup "Print Selection" and insert "PageRange" attribute
347  // case 2: "All pages" is selected
348  // update "Page range" attribute to have a sensible default,
349  // but leave "All" as selected
350 
351  // "Pages" attribute from API is now equivalent to "PageRange"
352  // AND "PrintContent" = 1 except calc where it is "PrintRange" = 1
353  // Argh ! That sure needs cleaning up
354  css::beans::PropertyValue* pContentVal = xController->getValue("PrintRange");
355  if( ! pContentVal )
356  pContentVal = xController->getValue("PrintContent");
357 
358  // case 1: UNO API has set "Pages"
359  css::beans::PropertyValue* pPagesVal = xController->getValue("Pages");
360  if( pPagesVal )
361  {
362  OUString aPagesVal;
363  pPagesVal->Value >>= aPagesVal;
364  if( !aPagesVal.isEmpty() )
365  {
366  // "Pages" attribute from API is now equivalent to "PageRange"
367  // AND "PrintContent" = 1 except calc where it is "PrintRange" = 1
368  // Argh ! That sure needs cleaning up
369  if( pContentVal )
370  {
371  pContentVal->Value <<= sal_Int32( 1 );
372  xController->setValue("PageRange", pPagesVal->Value);
373  }
374  }
375  }
376  // case 2: is "All" selected ?
377  else if( pContentVal )
378  {
379  sal_Int32 nContent = -1;
380  if( pContentVal->Value >>= nContent )
381  {
382  if( nContent == 0 )
383  {
384  // do not overwrite PageRange if it is already set
385  css::beans::PropertyValue* pRangeVal = xController->getValue("PageRange");
386  OUString aRange;
387  if( pRangeVal )
388  pRangeVal->Value >>= aRange;
389  if( aRange.isEmpty() )
390  {
391  sal_Int32 nPages = xController->getPageCount();
392  if( nPages > 0 )
393  {
394  OUStringBuffer aBuf( 32 );
395  aBuf.append( "1" );
396  if( nPages > 1 )
397  {
398  aBuf.append( "-" );
399  aBuf.append( nPages );
400  }
401  xController->setValue("PageRange", css::uno::makeAny(aBuf.makeStringAndClear()));
402  }
403  }
404  }
405  }
406  }
407 
408  css::beans::PropertyValue* pReverseVal = xController->getValue("PrintReverse");
409  if( pReverseVal )
410  {
411  bool bReverse = false;
412  pReverseVal->Value >>= bReverse;
413  xController->setReversePrint( bReverse );
414  }
415 
416  css::beans::PropertyValue* pPapersizeFromSetupVal = xController->getValue("PapersizeFromSetup");
417  if( pPapersizeFromSetupVal )
418  {
419  bool bPapersizeFromSetup = false;
420  pPapersizeFromSetupVal->Value >>= bPapersizeFromSetup;
421  xController->setPapersizeFromSetup(bPapersizeFromSetup);
422  }
423 
424  // setup NUp printing from properties
425  sal_Int32 nRows = xController->getIntProperty("NUpRows", 1);
426  sal_Int32 nCols = xController->getIntProperty("NUpColumns", 1);
427  if( nRows > 1 || nCols > 1 )
428  {
430  aMPS.nRows = std::max<sal_Int32>(nRows, 1);
431  aMPS.nColumns = std::max<sal_Int32>(nCols, 1);
432  sal_Int32 nValue = xController->getIntProperty("NUpPageMarginLeft", aMPS.nLeftMargin);
433  if( nValue >= 0 )
434  aMPS.nLeftMargin = nValue;
435  nValue = xController->getIntProperty("NUpPageMarginRight", aMPS.nRightMargin);
436  if( nValue >= 0 )
437  aMPS.nRightMargin = nValue;
438  nValue = xController->getIntProperty( "NUpPageMarginTop", aMPS.nTopMargin );
439  if( nValue >= 0 )
440  aMPS.nTopMargin = nValue;
441  nValue = xController->getIntProperty( "NUpPageMarginBottom", aMPS.nBottomMargin );
442  if( nValue >= 0 )
443  aMPS.nBottomMargin = nValue;
444  nValue = xController->getIntProperty( "NUpHorizontalSpacing", aMPS.nHorizontalSpacing );
445  if( nValue >= 0 )
446  aMPS.nHorizontalSpacing = nValue;
447  nValue = xController->getIntProperty( "NUpVerticalSpacing", aMPS.nVerticalSpacing );
448  if( nValue >= 0 )
449  aMPS.nVerticalSpacing = nValue;
450  aMPS.bDrawBorder = xController->getBoolProperty( "NUpDrawBorder", aMPS.bDrawBorder );
451  aMPS.nOrder = static_cast<NupOrderType>(xController->getIntProperty( "NUpSubPageOrder", static_cast<sal_Int32>(aMPS.nOrder) ));
452  aMPS.aPaperSize = xController->getPrinter()->PixelToLogic( xController->getPrinter()->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) );
453  css::beans::PropertyValue* pPgSizeVal = xController->getValue( "NUpPaperSize" );
454  css::awt::Size aSizeVal;
455  if( pPgSizeVal && (pPgSizeVal->Value >>= aSizeVal) )
456  {
457  aMPS.aPaperSize.setWidth( aSizeVal.Width );
458  aMPS.aPaperSize.setHeight( aSizeVal.Height );
459  }
460 
461  xController->setMultipage( aMPS );
462  }
463 
464  // in direct print case check whether there is anything to print.
465  // if not, show an errorbox (if appropriate)
466  if( xController->isShowDialogs() && xController->isDirectPrint() )
467  {
468  if( xController->getFilteredPageCount() == 0 )
469  {
470  std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(xController->getWindow(), "vcl/ui/errornocontentdialog.ui"));
471  std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("ErrorNoContentDialog"));
472  xBox->run();
473  return false;
474  }
475  }
476 
477  // check if the printer brings up its own dialog
478  // in that case leave the work to that dialog
479  if( ! xController->getPrinter()->GetCapabilities( PrinterCapType::ExternalDialog ) &&
480  ! xController->isDirectPrint() &&
481  xController->isShowDialogs()
482  )
483  {
484  try
485  {
486  PrintDialog aDlg(xController->getWindow(), xController);
487  if (!aDlg.run())
488  {
489  xController->abortJob();
490  return false;
491  }
492  if (aDlg.isPrintToFile())
493  {
494  OUString aFile = queryFile( xController->getPrinter().get() );
495  if( aFile.isEmpty() )
496  {
497  xController->abortJob();
498  return false;
499  }
500  xController->setValue( "LocalFileName",
501  css::uno::makeAny( aFile ) );
502  }
503  else if (aDlg.isSingleJobs())
504  {
505  xController->setValue( "PrintCollateAsSingleJobs",
506  css::uno::makeAny( true ) );
507  }
508  }
509  catch (const std::bad_alloc&)
510  {
511  }
512  }
513 
514  xController->pushPropertiesToPrinter();
515  return true;
516 }
517 
518 bool Printer::ExecutePrintJob(const std::shared_ptr<PrinterController>& xController)
519 {
520  OUString aJobName;
521  css::beans::PropertyValue* pJobNameVal = xController->getValue( "JobName" );
522  if( pJobNameVal )
523  pJobNameVal->Value >>= aJobName;
524 
525  return xController->getPrinter()->StartJob( aJobName, xController );
526 }
527 
528 void Printer::FinishPrintJob(const std::shared_ptr<PrinterController>& xController)
529 {
530  xController->resetPaperToLastConfigured();
531  xController->jobFinished( xController->getJobState() );
532 }
533 
534 void Printer::ImplPrintJob(const std::shared_ptr<PrinterController>& xController,
535  const JobSetup& i_rInitSetup)
536 {
537  if (PreparePrintJob(xController, i_rInitSetup))
538  {
539  ExecutePrintJob(xController);
540  }
541  FinishPrintJob(xController);
542 }
543 
544 bool Printer::StartJob( const OUString& i_rJobName, std::shared_ptr<vcl::PrinterController> const & i_xController)
545 {
546  mnError = ERRCODE_NONE;
547 
548  if ( IsDisplayPrinter() )
549  return false;
550 
551  if ( IsJobActive() || IsPrinting() )
552  return false;
553 
554  sal_uInt32 nCopies = mnCopyCount;
555  bool bCollateCopy = mbCollateCopy;
556  bool bUserCopy = false;
557 
558  if ( nCopies > 1 )
559  {
560  const sal_uInt32 nDevCopy = GetCapabilities( bCollateCopy
563 
564  // need to do copies by hand ?
565  if ( nCopies > nDevCopy )
566  {
567  bUserCopy = true;
568  nCopies = 1;
569  bCollateCopy = false;
570  }
571  }
572  else
573  bCollateCopy = false;
574 
575  ImplSVData* pSVData = ImplGetSVData();
576  mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
577 
578  if (!mpPrinter)
579  return false;
580 
581  bool bSinglePrintJobs = false;
582  css::beans::PropertyValue* pSingleValue = i_xController->getValue("PrintCollateAsSingleJobs");
583  if( pSingleValue )
584  {
585  pSingleValue->Value >>= bSinglePrintJobs;
586  }
587 
588  css::beans::PropertyValue* pFileValue = i_xController->getValue("LocalFileName");
589  if( pFileValue )
590  {
591  OUString aFile;
592  pFileValue->Value >>= aFile;
593  if( !aFile.isEmpty() )
594  {
595  mbPrintFile = true;
596  maPrintFile = aFile;
597  bSinglePrintJobs = false;
598  }
599  }
600 
601  OUString* pPrintFile = nullptr;
602  if ( mbPrintFile )
603  pPrintFile = &maPrintFile;
604  mpPrinterOptions->ReadFromConfig( mbPrintFile );
605 
606  mbPrinting = true;
607  if( GetCapabilities( PrinterCapType::UsePullModel ) )
608  {
609  mbJobActive = true;
610  // SAL layer does all necessary page printing
611  // and also handles showing a dialog
612  // that also means it must call jobStarted when the dialog is finished
613  // it also must set the JobState of the Controller
614  if( mpPrinter->StartJob( pPrintFile,
615  i_rJobName,
617  &maJobSetup.ImplGetData(),
618  *i_xController) )
619  {
620  EndJob();
621  }
622  else
623  {
624  mnError = ImplSalPrinterErrorCodeToVCL(mpPrinter->GetErrorCode());
625  if ( !mnError )
626  mnError = PRINTER_GENERALERROR;
627  mbPrinting = false;
628  mpPrinter.reset();
629  mbJobActive = false;
630 
631  GDIMetaFile aDummyFile;
632  i_xController->setLastPage(true);
633  i_xController->getFilteredPageFile(0, aDummyFile);
634 
635  return false;
636  }
637  }
638  else
639  {
640  // possibly a dialog has been shown
641  // now the real job starts
642  i_xController->setJobState( css::view::PrintableState_JOB_STARTED );
643  i_xController->jobStarted();
644 
645  int nJobs = 1;
646  int nOuterRepeatCount = 1;
647  int nInnerRepeatCount = 1;
648  if( bUserCopy )
649  {
650  if( mbCollateCopy )
651  nOuterRepeatCount = mnCopyCount;
652  else
653  nInnerRepeatCount = mnCopyCount;
654  }
655  if( bSinglePrintJobs )
656  {
657  nJobs = mnCopyCount;
658  nCopies = 1;
659  nOuterRepeatCount = nInnerRepeatCount = 1;
660  }
661 
662  for( int nJobIteration = 0; nJobIteration < nJobs; nJobIteration++ )
663  {
664  bool bError = false;
665  if( mpPrinter->StartJob( pPrintFile,
666  i_rJobName,
668  nCopies,
669  bCollateCopy,
670  i_xController->isDirectPrint(),
671  &maJobSetup.ImplGetData() ) )
672  {
673  bool bAborted = false;
674  mbJobActive = true;
675  i_xController->createProgressDialog();
676  const int nPages = i_xController->getFilteredPageCount();
677  // abort job, if no pages will be printed.
678  if ( nPages == 0 )
679  {
680  i_xController->abortJob();
681  bAborted = true;
682  }
683  for( int nOuterIteration = 0; nOuterIteration < nOuterRepeatCount && ! bAborted; nOuterIteration++ )
684  {
685  for( int nPage = 0; nPage < nPages && ! bAborted; nPage++ )
686  {
687  for( int nInnerIteration = 0; nInnerIteration < nInnerRepeatCount && ! bAborted; nInnerIteration++ )
688  {
689  if( nPage == nPages-1 &&
690  nOuterIteration == nOuterRepeatCount-1 &&
691  nInnerIteration == nInnerRepeatCount-1 &&
692  nJobIteration == nJobs-1 )
693  {
694  i_xController->setLastPage(true);
695  }
696  i_xController->printFilteredPage(nPage);
697  if (i_xController->isProgressCanceled())
698  {
699  i_xController->abortJob();
700  }
701  if (i_xController->getJobState() ==
702  css::view::PrintableState_JOB_ABORTED)
703  {
704  bAborted = true;
705  }
706  }
707  }
708  // FIXME: duplex ?
709  }
710  EndJob();
711 
712  if( nJobIteration < nJobs-1 )
713  {
714  mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
715 
716  if ( mpPrinter )
717  mbPrinting = true;
718  else
719  bError = true;
720  }
721  }
722  else
723  bError = true;
724 
725  if( bError )
726  {
727  mnError = mpPrinter ? ImplSalPrinterErrorCodeToVCL(mpPrinter->GetErrorCode()) : ERRCODE_NONE;
728  if ( !mnError )
729  mnError = PRINTER_GENERALERROR;
730  i_xController->setJobState( mnError == PRINTER_ABORT
731  ? css::view::PrintableState_JOB_ABORTED
732  : css::view::PrintableState_JOB_FAILED );
733  mbPrinting = false;
734  mpPrinter.reset();
735 
736  return false;
737  }
738  }
739 
740  if (i_xController->getJobState() == css::view::PrintableState_JOB_STARTED)
741  i_xController->setJobState(css::view::PrintableState_JOB_SPOOLED);
742  }
743 
744  // make last used printer persistent for UI jobs
745  if (i_xController->isShowDialogs() && !i_xController->isDirectPrint())
746  {
748  pItem->setValue( "PrintDialog",
749  "LastPrinterUsed",
750  GetName()
751  );
752  }
753 
754  return true;
755 }
756 
758 {
759 }
760 
761 css::view::PrintableState PrinterController::getJobState() const
762 {
763  return mpImplData->meJobState;
764 }
765 
766 void PrinterController::setJobState( css::view::PrintableState i_eState )
767 {
768  mpImplData->meJobState = i_eState;
769 }
770 
772 {
773  return mpImplData->mxPrinter;
774 }
775 
777 {
778  return mpImplData->mpWindow;
779 }
780 
782 {
783  mpImplData->mxPrinter = i_rPrinter;
784  setValue( "Name",
785  css::uno::makeAny( i_rPrinter->GetName() ) );
786  mpImplData->mnDefaultPaperBin = mpImplData->mxPrinter->GetPaperBin();
787  mpImplData->mxPrinter->Push();
788  mpImplData->mxPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
789  mpImplData->maDefaultPageSize = mpImplData->mxPrinter->GetPaperSize();
790  mpImplData->mbPapersizeFromUser = false;
791  mpImplData->mxPrinter->Pop();
792  mpImplData->mnFixedPaperBin = -1;
793 }
794 
795 void PrinterController::resetPrinterOptions( bool i_bFileOutput )
796 {
797  PrinterOptions aOpt;
798  aOpt.ReadFromConfig( i_bFileOutput );
799  mpImplData->mxPrinter->SetPrinterOptions( aOpt );
800 }
801 
803 {
804  bool bRet = false;
805 
806  // Important to hold printer alive while doing setup etc.
807  VclPtr< Printer > xPrinter = mpImplData->mxPrinter;
808 
809  if( xPrinter.get() )
810  {
811  xPrinter->Push();
812  xPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
813 
814  // get current data
815  Size aPaperSize(xPrinter->GetPaperSize());
816  Orientation eOrientation = xPrinter->GetOrientation();
817  sal_uInt16 nPaperBin = xPrinter->GetPaperBin();
818 
819  // reset paper size back to last configured size, not
820  // whatever happens to be the current page
821  // (but only if the printer config has changed, otherwise
822  // don't override printer page auto-detection - tdf#91362)
824  {
826  }
827 
828  // call driver setup
829  bRet = xPrinter->Setup( i_pParent, PrinterSetupMode::SingleJob );
830  SAL_WARN_IF(xPrinter != mpImplData->mxPrinter, "vcl.gdi",
831  "Printer changed underneath us during setup");
832  xPrinter = mpImplData->mxPrinter;
833 
834  Size aNewPaperSize(xPrinter->GetPaperSize());
835  if (bRet)
836  {
837  bool bInvalidateCache = false;
839 
840  // was papersize overridden ? if so we need to take action if we're
841  // configured to use the driver papersize
842  if (aNewPaperSize != mpImplData->maDefaultPageSize)
843  {
844  mpImplData->maDefaultPageSize = aNewPaperSize;
845  bInvalidateCache = getPapersizeFromSetup();
846  }
847 
848  // was bin overridden ? if so we need to take action
849  sal_uInt16 nNewPaperBin = xPrinter->GetPaperBin();
850  if (nNewPaperBin != nPaperBin)
851  {
852  mpImplData->mnFixedPaperBin = nNewPaperBin;
853  bInvalidateCache = true;
854  }
855 
856  if (bInvalidateCache)
857  {
858  mpImplData->maPageCache.invalidate();
859  }
860  }
861  else
862  {
863  //restore to whatever it was before we entered this method
864  xPrinter->SetOrientation( eOrientation );
865  if (aPaperSize != aNewPaperSize)
866  xPrinter->SetPaperSizeUser(aPaperSize, !mpImplData->isFixedPageSize());
867  }
868  xPrinter->Pop();
869  }
870 }
871 
872 PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( const css::uno::Sequence< css::beans::PropertyValue >& i_rProps )
873 {
874  PrinterController::PageSize aPageSize;
875  aPageSize.aSize = mxPrinter->GetPaperSize();
876  css::awt::Size aSetSize, aIsSize;
877  sal_Int32 nPaperBin = mnDefaultPaperBin;
878  for( const auto& rProp : i_rProps )
879  {
880  if ( rProp.Name == "PreferredPageSize" )
881  {
882  rProp.Value >>= aSetSize;
883  }
884  else if ( rProp.Name == "PageSize" )
885  {
886  rProp.Value >>= aIsSize;
887  }
888  else if ( rProp.Name == "PageIncludesNonprintableArea" )
889  {
890  bool bVal = false;
891  rProp.Value >>= bVal;
892  aPageSize.bFullPaper = bVal;
893  }
894  else if ( rProp.Name == "PrinterPaperTray" )
895  {
896  sal_Int32 nBin = -1;
897  rProp.Value >>= nBin;
898  if( nBin >= 0 && nBin < static_cast<sal_Int32>(mxPrinter->GetPaperBinCount()) )
899  nPaperBin = nBin;
900  }
901  }
902 
903  Size aCurSize( mxPrinter->GetPaperSize() );
904  if( aSetSize.Width && aSetSize.Height )
905  {
906  Size aSetPaperSize( aSetSize.Width, aSetSize.Height );
907  Size aRealPaperSize( getRealPaperSize( aSetPaperSize, true/*bNoNUP*/ ) );
908  if( aRealPaperSize != aCurSize )
909  aIsSize = aSetSize;
910  }
911 
912  if( aIsSize.Width && aIsSize.Height )
913  {
914  aPageSize.aSize.setWidth( aIsSize.Width );
915  aPageSize.aSize.setHeight( aIsSize.Height );
916 
917  Size aRealPaperSize( getRealPaperSize( aPageSize.aSize, true/*bNoNUP*/ ) );
918  if( aRealPaperSize != aCurSize )
919  mxPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() );
920  }
921 
922  // paper bin set from properties in print dialog overrides
923  // application default for a page
924  if ( mnFixedPaperBin != -1 )
925  nPaperBin = mnFixedPaperBin;
926 
927  if( nPaperBin != -1 && nPaperBin != mxPrinter->GetPaperBin() )
928  mxPrinter->SetPaperBin( nPaperBin );
929 
930  return aPageSize;
931 }
932 
933 //fdo#61886
934 
935 //when printing is finished, set the paper size of the printer to either what
936 //the user explicitly set as the desired paper size, or fallback to whatever
937 //the printer had before printing started. That way it doesn't contain the last
938 //paper size of a multiple paper size using document when we are in our normal
939 //auto accept document paper size mode and end up overwriting the original
940 //paper size setting for file->printer_settings just by pressing "ok" in the
941 //print dialog
943 {
944  mxPrinter->Push();
945  mxPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
946  Size aCurSize(mxPrinter->GetPaperSize());
947  if (aCurSize != maDefaultPageSize)
948  mxPrinter->SetPaperSizeUser(maDefaultPageSize, !isFixedPageSize());
949  mxPrinter->Pop();
950 }
951 
953 {
954  const MapMode aMapMode( MapUnit::Map100thMM );
955 
956  mpImplData->mxPrinter->Push();
957  mpImplData->mxPrinter->SetMapMode( aMapMode );
958  int nPages = getPageCount();
959  mpImplData->mxPrinter->Pop();
960  return nPages;
961 }
962 
963 css::uno::Sequence< css::beans::PropertyValue > PrinterController::getPageParametersProtected( int i_nPage ) const
964 {
965  const MapMode aMapMode( MapUnit::Map100thMM );
966 
967  mpImplData->mxPrinter->Push();
968  mpImplData->mxPrinter->SetMapMode( aMapMode );
969  css::uno::Sequence< css::beans::PropertyValue > aResult( getPageParameters( i_nPage ) );
970  mpImplData->mxPrinter->Pop();
971  return aResult;
972 }
973 
974 PrinterController::PageSize PrinterController::getPageFile( int i_nUnfilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache )
975 {
976  // update progress if necessary
977  if( mpImplData->mxProgress )
978  {
979  // do nothing if printing is canceled
980  if( mpImplData->mxProgress->isCanceled() )
982  mpImplData->mxProgress->tick();
983  Application::Reschedule( true );
984  }
985 
986  if( i_bMayUseCache )
987  {
988  PrinterController::PageSize aPageSize;
989  if( mpImplData->maPageCache.get( i_nUnfilteredPage, o_rMtf, aPageSize ) )
990  {
991  return aPageSize;
992  }
993  }
994  else
995  mpImplData->maPageCache.invalidate();
996 
997  o_rMtf.Clear();
998 
999  // get page parameters
1000  css::uno::Sequence< css::beans::PropertyValue > aPageParm( getPageParametersProtected( i_nUnfilteredPage ) );
1001  const MapMode aMapMode( MapUnit::Map100thMM );
1002 
1003  mpImplData->mxPrinter->Push();
1004  mpImplData->mxPrinter->SetMapMode( aMapMode );
1005 
1006  // modify job setup if necessary
1007  PrinterController::PageSize aPageSize = mpImplData->modifyJobSetup( aPageParm );
1008 
1009  o_rMtf.SetPrefSize( aPageSize.aSize );
1010  o_rMtf.SetPrefMapMode( aMapMode );
1011 
1012  mpImplData->mxPrinter->EnableOutput( false );
1013 
1014  o_rMtf.Record( mpImplData->mxPrinter.get() );
1015 
1016  printPage( i_nUnfilteredPage );
1017 
1018  o_rMtf.Stop();
1019  o_rMtf.WindStart();
1020  mpImplData->mxPrinter->Pop();
1021 
1022  if( i_bMayUseCache )
1023  mpImplData->maPageCache.insert( i_nUnfilteredPage, o_rMtf, aPageSize );
1024 
1025  // reset "FirstPage" property to false now we've gotten at least our first one
1026  mpImplData->mbFirstPage = false;
1027 
1028  return aPageSize;
1029 }
1030 
1031 static void appendSubPage( GDIMetaFile& o_rMtf, const tools::Rectangle& i_rClipRect, GDIMetaFile& io_rSubPage, bool i_bDrawBorder )
1032 {
1033  // intersect all clipregion actions with our clip rect
1034  io_rSubPage.WindStart();
1035  io_rSubPage.Clip( i_rClipRect );
1036 
1037  // save gstate
1038  o_rMtf.AddAction( new MetaPushAction( PushFlags::ALL ) );
1039 
1040  // clip to page rect
1041  o_rMtf.AddAction( new MetaClipRegionAction( vcl::Region( i_rClipRect ), true ) );
1042 
1043  // append the subpage
1044  io_rSubPage.WindStart();
1045  io_rSubPage.Play( o_rMtf );
1046 
1047  // restore gstate
1048  o_rMtf.AddAction( new MetaPopAction() );
1049 
1050  // draw a border
1051  if( i_bDrawBorder )
1052  {
1053  // save gstate
1055  o_rMtf.AddAction( new MetaMapModeAction( MapMode( MapUnit::Map100thMM ) ) );
1056 
1057  tools::Rectangle aBorderRect( i_rClipRect );
1058  o_rMtf.AddAction( new MetaLineColorAction( COL_BLACK, true ) );
1059  o_rMtf.AddAction( new MetaFillColorAction( COL_TRANSPARENT, false ) );
1060  o_rMtf.AddAction( new MetaRectAction( aBorderRect ) );
1061 
1062  // restore gstate
1063  o_rMtf.AddAction( new MetaPopAction() );
1064  }
1065 }
1066 
1067 PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache )
1068 {
1069  const MultiPageSetup& rMPS( mpImplData->maMultiPage );
1070  int nSubPages = rMPS.nRows * rMPS.nColumns;
1071  if( nSubPages < 1 )
1072  nSubPages = 1;
1073 
1074  // reverse sheet order
1075  if( mpImplData->mbReversePageOrder )
1076  {
1077  int nDocPages = getFilteredPageCount();
1078  i_nFilteredPage = nDocPages - 1 - i_nFilteredPage;
1079  }
1080 
1081  // there is no filtering to be done (and possibly the page size of the
1082  // original page is to be set), when N-Up is "neutral" that is there is
1083  // only one subpage and the margins are 0
1084  if( nSubPages == 1 &&
1085  rMPS.nLeftMargin == 0 && rMPS.nRightMargin == 0 &&
1086  rMPS.nTopMargin == 0 && rMPS.nBottomMargin == 0 )
1087  {
1088  PrinterController::PageSize aPageSize = getPageFile( i_nFilteredPage, o_rMtf, i_bMayUseCache );
1089  if (mpImplData->meJobState != css::view::PrintableState_JOB_STARTED)
1090  { // rhbz#657394: check that we are still printing...
1091  return PrinterController::PageSize();
1092  }
1093  Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize, true );
1094  mpImplData->mxPrinter->SetMapMode( MapMode( MapUnit::Map100thMM ) );
1095  mpImplData->mxPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() );
1096  if( aPaperSize != aPageSize.aSize )
1097  {
1098  // user overridden page size, center Metafile
1099  o_rMtf.WindStart();
1100  long nDX = (aPaperSize.Width() - aPageSize.aSize.Width()) / 2;
1101  long nDY = (aPaperSize.Height() - aPageSize.aSize.Height()) / 2;
1102  o_rMtf.Move( nDX, nDY, mpImplData->mxPrinter->GetDPIX(), mpImplData->mxPrinter->GetDPIY() );
1103  o_rMtf.WindStart();
1104  o_rMtf.SetPrefSize( aPaperSize );
1105  aPageSize.aSize = aPaperSize;
1106  }
1107  return aPageSize;
1108  }
1109 
1110  // set last page property really only on the very last page to be rendered
1111  // that is on the last subpage of a NUp run
1112  bool bIsLastPage = mpImplData->mbLastPage;
1113  mpImplData->mbLastPage = false;
1114 
1115  Size aPaperSize( mpImplData->getRealPaperSize( mpImplData->maMultiPage.aPaperSize, false ) );
1116 
1117  // multi page area: page size minus margins + one time spacing right and down
1118  // the added spacing is so each subpage can be calculated including its spacing
1119  Size aMPArea( aPaperSize );
1120  aMPArea.AdjustWidth( -(rMPS.nLeftMargin + rMPS.nRightMargin) );
1121  aMPArea.AdjustWidth(rMPS.nHorizontalSpacing );
1122  aMPArea.AdjustHeight( -(rMPS.nTopMargin + rMPS.nBottomMargin) );
1123  aMPArea.AdjustHeight(rMPS.nVerticalSpacing );
1124 
1125  // determine offsets
1126  long nAdvX = aMPArea.Width() / rMPS.nColumns;
1127  long nAdvY = aMPArea.Height() / rMPS.nRows;
1128 
1129  // determine size of a "cell" subpage, leave a little space around pages
1130  Size aSubPageSize( nAdvX - rMPS.nHorizontalSpacing, nAdvY - rMPS.nVerticalSpacing );
1131 
1132  o_rMtf.Clear();
1133  o_rMtf.SetPrefSize( aPaperSize );
1134  o_rMtf.SetPrefMapMode( MapMode( MapUnit::Map100thMM ) );
1135  o_rMtf.AddAction( new MetaMapModeAction( MapMode( MapUnit::Map100thMM ) ) );
1136 
1137  int nDocPages = getPageCountProtected();
1138  if (mpImplData->meJobState != css::view::PrintableState_JOB_STARTED)
1139  { // rhbz#657394: check that we are still printing...
1140  return PrinterController::PageSize();
1141  }
1142  for( int nSubPage = 0; nSubPage < nSubPages; nSubPage++ )
1143  {
1144  // map current sub page to real page
1145  int nPage = i_nFilteredPage * nSubPages + nSubPage;
1146  if( nSubPage == nSubPages-1 ||
1147  nPage == nDocPages-1 )
1148  {
1149  mpImplData->mbLastPage = bIsLastPage;
1150  }
1151  if( nPage >= 0 && nPage < nDocPages )
1152  {
1153  GDIMetaFile aPageFile;
1154  PrinterController::PageSize aPageSize = getPageFile( nPage, aPageFile, i_bMayUseCache );
1155  if( aPageSize.aSize.Width() && aPageSize.aSize.Height() )
1156  {
1157  long nCellX = 0, nCellY = 0;
1158  switch( rMPS.nOrder )
1159  {
1160  case NupOrderType::LRTB:
1161  nCellX = (nSubPage % rMPS.nColumns);
1162  nCellY = (nSubPage / rMPS.nColumns);
1163  break;
1164  case NupOrderType::TBLR:
1165  nCellX = (nSubPage / rMPS.nRows);
1166  nCellY = (nSubPage % rMPS.nRows);
1167  break;
1168  case NupOrderType::RLTB:
1169  nCellX = rMPS.nColumns - 1 - (nSubPage % rMPS.nColumns);
1170  nCellY = (nSubPage / rMPS.nColumns);
1171  break;
1172  case NupOrderType::TBRL:
1173  nCellX = rMPS.nColumns - 1 - (nSubPage / rMPS.nRows);
1174  nCellY = (nSubPage % rMPS.nRows);
1175  break;
1176  }
1177  // scale the metafile down to a sub page size
1178  double fScaleX = double(aSubPageSize.Width())/double(aPageSize.aSize.Width());
1179  double fScaleY = double(aSubPageSize.Height())/double(aPageSize.aSize.Height());
1180  double fScale = std::min( fScaleX, fScaleY );
1181  aPageFile.Scale( fScale, fScale );
1182  aPageFile.WindStart();
1183 
1184  // move the subpage so it is centered in its "cell"
1185  long nOffX = (aSubPageSize.Width() - long(double(aPageSize.aSize.Width()) * fScale)) / 2;
1186  long nOffY = (aSubPageSize.Height() - long(double(aPageSize.aSize.Height()) * fScale)) / 2;
1187  long nX = rMPS.nLeftMargin + nOffX + nAdvX * nCellX;
1188  long nY = rMPS.nTopMargin + nOffY + nAdvY * nCellY;
1189  aPageFile.Move( nX, nY, mpImplData->mxPrinter->GetDPIX(), mpImplData->mxPrinter->GetDPIY() );
1190  aPageFile.WindStart();
1191  // calculate border rectangle
1192  tools::Rectangle aSubPageRect( Point( nX, nY ),
1193  Size( long(double(aPageSize.aSize.Width())*fScale),
1194  long(double(aPageSize.aSize.Height())*fScale) ) );
1195 
1196  // append subpage to page
1197  appendSubPage( o_rMtf, aSubPageRect, aPageFile, rMPS.bDrawBorder );
1198  }
1199  }
1200  }
1201  o_rMtf.WindStart();
1202 
1203  // subsequent getPageFile calls have changed the paper, reset it to current value
1204  mpImplData->mxPrinter->SetMapMode( MapMode( MapUnit::Map100thMM ) );
1205  mpImplData->mxPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() );
1206 
1207  return PrinterController::PageSize( aPaperSize, true );
1208 }
1209 
1211 {
1212  int nDiv = mpImplData->maMultiPage.nRows * mpImplData->maMultiPage.nColumns;
1213  if( nDiv < 1 )
1214  nDiv = 1;
1215  return (getPageCountProtected() + (nDiv-1)) / nDiv;
1216 }
1217 
1219 {
1220  DrawModeFlags nRestoreDrawMode = mpImplData->mxPrinter->GetDrawMode();
1221  sal_Int32 nMaxBmpDPIX = mpImplData->mxPrinter->GetDPIX();
1222  sal_Int32 nMaxBmpDPIY = mpImplData->mxPrinter->GetDPIY();
1223 
1224  const PrinterOptions& rPrinterOptions = mpImplData->mxPrinter->GetPrinterOptions();
1225 
1226  static const sal_Int32 OPTIMAL_BMP_RESOLUTION = 300;
1227  static const sal_Int32 NORMAL_BMP_RESOLUTION = 200;
1228 
1229  if( rPrinterOptions.IsReduceBitmaps() )
1230  {
1231  // calculate maximum resolution for bitmap graphics
1232  if( PrinterBitmapMode::Optimal == rPrinterOptions.GetReducedBitmapMode() )
1233  {
1234  nMaxBmpDPIX = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIX );
1235  nMaxBmpDPIY = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIY );
1236  }
1237  else if( PrinterBitmapMode::Normal == rPrinterOptions.GetReducedBitmapMode() )
1238  {
1239  nMaxBmpDPIX = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIX );
1240  nMaxBmpDPIY = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIY );
1241  }
1242  else
1243  {
1244  nMaxBmpDPIX = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIX );
1245  nMaxBmpDPIY = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIY );
1246  }
1247  }
1248 
1249  // convert to greyscales
1250  if( rPrinterOptions.IsConvertToGreyscales() )
1251  {
1252  mpImplData->mxPrinter->SetDrawMode( mpImplData->mxPrinter->GetDrawMode() |
1255  }
1256 
1257  // disable transparency output
1258  if( rPrinterOptions.IsReduceTransparency() && ( PrinterTransparencyMode::NONE == rPrinterOptions.GetReducedTransparencyMode() ) )
1259  {
1260  mpImplData->mxPrinter->SetDrawMode( mpImplData->mxPrinter->GetDrawMode() | DrawModeFlags::NoTransparency );
1261  }
1262 
1263  Color aBg( COL_TRANSPARENT ); // default: let RemoveTransparenciesFromMetaFile do its own background logic
1264  if( mpImplData->maMultiPage.nRows * mpImplData->maMultiPage.nColumns > 1 )
1265  {
1266  // in N-Up printing we have no "page" background operation
1267  // we also have no way to determine the paper color
1268  // so let's go for white, which will kill 99.9% of the real cases
1269  aBg = COL_WHITE;
1270  }
1271  mpImplData->mxPrinter->RemoveTransparenciesFromMetaFile( i_rIn, o_rOut, nMaxBmpDPIX, nMaxBmpDPIY,
1272  rPrinterOptions.IsReduceTransparency(),
1274  rPrinterOptions.IsReduceBitmaps() && rPrinterOptions.IsReducedBitmapIncludesTransparency(),
1275  aBg
1276  );
1277  return nRestoreDrawMode;
1278 }
1279 
1281 {
1282  if( mpImplData->meJobState != css::view::PrintableState_JOB_STARTED )
1283  return; // rhbz#657394: check that we are still printing...
1284 
1285  GDIMetaFile aPageFile;
1286  PrinterController::PageSize aPageSize = getFilteredPageFile( i_nPage, aPageFile );
1287 
1288  if( mpImplData->mxProgress )
1289  {
1290  // do nothing if printing is canceled
1291  if( mpImplData->mxProgress->isCanceled() )
1292  {
1293  setJobState( css::view::PrintableState_JOB_ABORTED );
1294  return;
1295  }
1296  }
1297 
1298  // in N-Up printing set the correct page size
1299  mpImplData->mxPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
1300  // aPageSize was filtered through mpImplData->getRealPaperSize already by getFilteredPageFile()
1301  mpImplData->mxPrinter->SetPaperSizeUser( aPageSize.aSize, ! mpImplData->isFixedPageSize() );
1302  if( mpImplData->mnFixedPaperBin != -1 &&
1303  mpImplData->mxPrinter->GetPaperBin() != mpImplData->mnFixedPaperBin )
1304  {
1305  mpImplData->mxPrinter->SetPaperBin( mpImplData->mnFixedPaperBin );
1306  }
1307 
1308  // if full paper is meant to be used, move the output to accommodate for pageoffset
1309  if( aPageSize.bFullPaper )
1310  {
1311  Point aPageOffset( mpImplData->mxPrinter->GetPageOffset() );
1312  aPageFile.WindStart();
1313  aPageFile.Move( -aPageOffset.X(), -aPageOffset.Y(), mpImplData->mxPrinter->GetDPIX(), mpImplData->mxPrinter->GetDPIY() );
1314  }
1315 
1316  GDIMetaFile aCleanedFile;
1317  DrawModeFlags nRestoreDrawMode = removeTransparencies( aPageFile, aCleanedFile );
1318 
1319  mpImplData->mxPrinter->EnableOutput();
1320 
1321  // actually print the page
1322  mpImplData->mxPrinter->ImplStartPage();
1323 
1324  mpImplData->mxPrinter->Push();
1325  aCleanedFile.WindStart();
1326  aCleanedFile.Play( mpImplData->mxPrinter.get() );
1327  mpImplData->mxPrinter->Pop();
1328 
1329  mpImplData->mxPrinter->ImplEndPage();
1330 
1331  mpImplData->mxPrinter->SetDrawMode( nRestoreDrawMode );
1332 }
1333 
1335 {
1336 }
1337 
1338 void PrinterController::jobFinished( css::view::PrintableState )
1339 {
1340 }
1341 
1343 {
1344  setJobState( css::view::PrintableState_JOB_ABORTED );
1345  // applications (well, sw) depend on a page request with "IsLastPage" = true
1346  // to free resources, else they (well, sw) will crash eventually
1347  setLastPage( true );
1348 
1349  if (mpImplData->mxProgress)
1350  {
1351  mpImplData->mxProgress->response(RET_CANCEL);
1352  mpImplData->mxProgress.reset();
1353  }
1354 
1355  GDIMetaFile aMtf;
1356  getPageFile( 0, aMtf );
1357 }
1358 
1359 void PrinterController::setLastPage( bool i_bLastPage )
1360 {
1361  mpImplData->mbLastPage = i_bLastPage;
1362 }
1363 
1364 void PrinterController::setReversePrint( bool i_bReverse )
1365 {
1366  mpImplData->mbReversePageOrder = i_bReverse;
1367 }
1368 
1369 void PrinterController::setPapersizeFromSetup( bool i_bPapersizeFromSetup )
1370 {
1371  mpImplData->mbPapersizeFromSetup = i_bPapersizeFromSetup;
1372  mpImplData->mxPrinter->SetPrinterSettingsPreferred( i_bPapersizeFromSetup );
1373  if ( i_bPapersizeFromSetup )
1374  mpImplData->mbPapersizeFromUser = !i_bPapersizeFromSetup;
1375 }
1376 
1378 {
1379  return mpImplData->mbPapersizeFromSetup;
1380 }
1381 
1383 {
1384  return mpImplData->maDefaultPageSize;
1385 }
1386 
1388 {
1389  mpImplData->mbPapersizeFromUser = true;
1390  mpImplData->mbPapersizeFromSetup = false;
1391  mpImplData->mxPrinter->SetPrinterSettingsPreferred( false );
1392 
1393  mpImplData->maUserPageSize = i_aUserSize;
1394 }
1395 
1397 {
1398  return mpImplData->maUserPageSize;
1399 }
1400 
1402 {
1403  return mpImplData->mbPapersizeFromUser;
1404 }
1405 
1406 void PrinterController::setPrinterModified( bool i_bPrinterModified )
1407 {
1408  mpImplData->mbPrinterModified = i_bPrinterModified;
1409 }
1410 
1412 {
1413  return mpImplData->mbPrinterModified;
1414 }
1415 
1416 css::uno::Sequence< css::beans::PropertyValue > PrinterController::getJobProperties( const css::uno::Sequence< css::beans::PropertyValue >& i_rMergeList ) const
1417 {
1418  std::unordered_set< OUString > aMergeSet;
1419  size_t nResultLen = size_t(i_rMergeList.getLength()) + mpImplData->maUIProperties.size() + 3;
1420  for( const auto& rPropVal : i_rMergeList )
1421  aMergeSet.insert( rPropVal.Name );
1422 
1423  css::uno::Sequence< css::beans::PropertyValue > aResult( nResultLen );
1424  std::copy(i_rMergeList.begin(), i_rMergeList.end(), aResult.begin());
1425  int nCur = i_rMergeList.getLength();
1426  for(const css::beans::PropertyValue & rPropVal : mpImplData->maUIProperties)
1427  {
1428  if( aMergeSet.find( rPropVal.Name ) == aMergeSet.end() )
1429  aResult[nCur++] = rPropVal;
1430  }
1431  // append IsFirstPage
1432  if( aMergeSet.find( "IsFirstPage" ) == aMergeSet.end() )
1433  {
1434  css::beans::PropertyValue aVal;
1435  aVal.Name = "IsFirstPage";
1436  aVal.Value <<= mpImplData->mbFirstPage;
1437  aResult[nCur++] = aVal;
1438  }
1439  // append IsLastPage
1440  if( aMergeSet.find( "IsLastPage" ) == aMergeSet.end() )
1441  {
1442  css::beans::PropertyValue aVal;
1443  aVal.Name = "IsLastPage";
1444  aVal.Value <<= mpImplData->mbLastPage;
1445  aResult[nCur++] = aVal;
1446  }
1447  // append IsPrinter
1448  if( aMergeSet.find( "IsPrinter" ) == aMergeSet.end() )
1449  {
1450  css::beans::PropertyValue aVal;
1451  aVal.Name = "IsPrinter";
1452  aVal.Value <<= true;
1453  aResult[nCur++] = aVal;
1454  }
1455  aResult.realloc( nCur );
1456  return aResult;
1457 }
1458 
1459 const css::uno::Sequence< css::beans::PropertyValue >& PrinterController::getUIOptions() const
1460 {
1461  return mpImplData->maUIOptions;
1462 }
1463 
1464 css::beans::PropertyValue* PrinterController::getValue( const OUString& i_rProperty )
1465 {
1466  std::unordered_map< OUString, size_t >::const_iterator it =
1467  mpImplData->maPropertyToIndex.find( i_rProperty );
1468  return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : nullptr;
1469 }
1470 
1471 const css::beans::PropertyValue* PrinterController::getValue( const OUString& i_rProperty ) const
1472 {
1473  std::unordered_map< OUString, size_t >::const_iterator it =
1474  mpImplData->maPropertyToIndex.find( i_rProperty );
1475  return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : nullptr;
1476 }
1477 
1478 void PrinterController::setValue( const OUString& i_rPropertyName, const css::uno::Any& i_rValue )
1479 {
1480  css::beans::PropertyValue aVal;
1481  aVal.Name = i_rPropertyName;
1482  aVal.Value = i_rValue;
1483 
1484  setValue( aVal );
1485 }
1486 
1487 void PrinterController::setValue( const css::beans::PropertyValue& i_rPropertyValue )
1488 {
1489  std::unordered_map< OUString, size_t >::const_iterator it =
1490  mpImplData->maPropertyToIndex.find( i_rPropertyValue.Name );
1491  if( it != mpImplData->maPropertyToIndex.end() )
1492  mpImplData->maUIProperties[ it->second ] = i_rPropertyValue;
1493  else
1494  {
1495  // insert correct index into property map
1496  mpImplData->maPropertyToIndex[ i_rPropertyValue.Name ] = mpImplData->maUIProperties.size();
1497  mpImplData->maUIProperties.push_back( i_rPropertyValue );
1498  mpImplData->maUIPropertyEnabled.push_back( true );
1499  }
1500 }
1501 
1502 void PrinterController::setUIOptions( const css::uno::Sequence< css::beans::PropertyValue >& i_rOptions )
1503 {
1504  SAL_WARN_IF( mpImplData->maUIOptions.hasElements(), "vcl.gdi", "setUIOptions called twice !" );
1505 
1506  mpImplData->maUIOptions = i_rOptions;
1507 
1508  for( const auto& rOpt : i_rOptions )
1509  {
1510  css::uno::Sequence< css::beans::PropertyValue > aOptProp;
1511  rOpt.Value >>= aOptProp;
1512  bool bIsEnabled = true;
1513  bool bHaveProperty = false;
1514  OUString aPropName;
1516  css::uno::Sequence< sal_Bool > aChoicesDisabled;
1517  for( const css::beans::PropertyValue& rEntry : std::as_const(aOptProp) )
1518  {
1519  if ( rEntry.Name == "Property" )
1520  {
1521  css::beans::PropertyValue aVal;
1522  rEntry.Value >>= aVal;
1523  DBG_ASSERT( mpImplData->maPropertyToIndex.find( aVal.Name )
1524  == mpImplData->maPropertyToIndex.end(), "duplicate property entry" );
1525  setValue( aVal );
1526  aPropName = aVal.Name;
1527  bHaveProperty = true;
1528  }
1529  else if ( rEntry.Name == "Enabled" )
1530  {
1531  bool bValue = true;
1532  rEntry.Value >>= bValue;
1533  bIsEnabled = bValue;
1534  }
1535  else if ( rEntry.Name == "DependsOnName" )
1536  {
1537  rEntry.Value >>= aDep.maDependsOnName;
1538  }
1539  else if ( rEntry.Name == "DependsOnEntry" )
1540  {
1541  rEntry.Value >>= aDep.mnDependsOnEntry;
1542  }
1543  else if ( rEntry.Name == "ChoicesDisabled" )
1544  {
1545  rEntry.Value >>= aChoicesDisabled;
1546  }
1547  }
1548  if( bHaveProperty )
1549  {
1550  vcl::ImplPrinterControllerData::PropertyToIndexMap::const_iterator it =
1551  mpImplData->maPropertyToIndex.find( aPropName );
1552  // sanity check
1553  if( it != mpImplData->maPropertyToIndex.end() )
1554  {
1555  mpImplData->maUIPropertyEnabled[ it->second ] = bIsEnabled;
1556  }
1557  if( !aDep.maDependsOnName.isEmpty() )
1558  mpImplData->maControlDependencies[ aPropName ] = aDep;
1559  if( aChoicesDisabled.hasElements() )
1560  mpImplData->maChoiceDisableMap[ aPropName ] = aChoicesDisabled;
1561  }
1562  }
1563 }
1564 
1565 bool PrinterController::isUIOptionEnabled( const OUString& i_rProperty ) const
1566 {
1567  bool bEnabled = false;
1568  std::unordered_map< OUString, size_t >::const_iterator prop_it =
1569  mpImplData->maPropertyToIndex.find( i_rProperty );
1570  if( prop_it != mpImplData->maPropertyToIndex.end() )
1571  {
1572  bEnabled = mpImplData->maUIPropertyEnabled[prop_it->second];
1573 
1574  if( bEnabled )
1575  {
1576  // check control dependencies
1577  vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
1578  mpImplData->maControlDependencies.find( i_rProperty );
1579  if( it != mpImplData->maControlDependencies.end() )
1580  {
1581  // check if the dependency is enabled
1582  // if the dependency is disabled, we are too
1583  bEnabled = isUIOptionEnabled( it->second.maDependsOnName );
1584 
1585  if( bEnabled )
1586  {
1587  // does the dependency have the correct value ?
1588  const css::beans::PropertyValue* pVal = getValue( it->second.maDependsOnName );
1589  OSL_ENSURE( pVal, "unknown property in dependency" );
1590  if( pVal )
1591  {
1592  sal_Int32 nDepVal = 0;
1593  bool bDepVal = false;
1594  if( pVal->Value >>= nDepVal )
1595  {
1596  bEnabled = (nDepVal == it->second.mnDependsOnEntry) || (it->second.mnDependsOnEntry == -1);
1597  }
1598  else if( pVal->Value >>= bDepVal )
1599  {
1600  // could be a dependency on a checked boolean
1601  // in this case the dependency is on a non zero for checked value
1602  bEnabled = ( bDepVal && it->second.mnDependsOnEntry != 0) ||
1603  ( ! bDepVal && it->second.mnDependsOnEntry == 0);
1604  }
1605  else
1606  {
1607  // if the type does not match something is awry
1608  OSL_FAIL( "strange type in control dependency" );
1609  bEnabled = false;
1610  }
1611  }
1612  }
1613  }
1614  }
1615  }
1616  return bEnabled;
1617 }
1618 
1619 bool PrinterController::isUIChoiceEnabled( const OUString& i_rProperty, sal_Int32 i_nValue ) const
1620 {
1621  bool bEnabled = true;
1622  ImplPrinterControllerData::ChoiceDisableMap::const_iterator it =
1623  mpImplData->maChoiceDisableMap.find( i_rProperty );
1624  if(it != mpImplData->maChoiceDisableMap.end() )
1625  {
1626  const css::uno::Sequence< sal_Bool >& rDisabled( it->second );
1627  if( i_nValue >= 0 && i_nValue < rDisabled.getLength() )
1628  bEnabled = ! rDisabled[i_nValue];
1629  }
1630  return bEnabled;
1631 }
1632 
1633 OUString PrinterController::makeEnabled( const OUString& i_rProperty )
1634 {
1635  OUString aDependency;
1636 
1637  vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
1638  mpImplData->maControlDependencies.find( i_rProperty );
1639  if( it != mpImplData->maControlDependencies.end() )
1640  {
1641  if( isUIOptionEnabled( it->second.maDependsOnName ) )
1642  {
1643  aDependency = it->second.maDependsOnName;
1644  const css::beans::PropertyValue* pVal = getValue( aDependency );
1645  OSL_ENSURE( pVal, "unknown property in dependency" );
1646  if( pVal )
1647  {
1648  sal_Int32 nDepVal = 0;
1649  bool bDepVal = false;
1650  if( pVal->Value >>= nDepVal )
1651  {
1652  if( it->second.mnDependsOnEntry != -1 )
1653  {
1654  setValue( aDependency, css::uno::makeAny( sal_Int32( it->second.mnDependsOnEntry ) ) );
1655  }
1656  }
1657  else if( pVal->Value >>= bDepVal )
1658  {
1659  setValue( aDependency, css::uno::makeAny( it->second.mnDependsOnEntry != 0 ) );
1660  }
1661  else
1662  {
1663  // if the type does not match something is awry
1664  OSL_FAIL( "strange type in control dependency" );
1665  }
1666  }
1667  }
1668  }
1669 
1670  return aDependency;
1671 }
1672 
1674 {
1675  if (!mpImplData->mxProgress)
1676  {
1677  bool bShow = true;
1678  css::beans::PropertyValue* pMonitor = getValue( "MonitorVisible" );
1679  if( pMonitor )
1680  pMonitor->Value >>= bShow;
1681  else
1682  {
1683  const css::beans::PropertyValue* pVal = getValue( "IsApi" );
1684  if( pVal )
1685  {
1686  bool bApi = false;
1687  pVal->Value >>= bApi;
1688  bShow = ! bApi;
1689  }
1690  }
1691 
1692  if( bShow && ! Application::IsHeadlessModeEnabled() )
1693  {
1694  mpImplData->mxProgress.reset(new PrintProgressDialog(getWindow(), getPageCountProtected()));
1695  weld::DialogController::runAsync(mpImplData->mxProgress, [](sal_Int32 /*nResult*/){});
1696  }
1697  }
1698  else
1699  {
1700  mpImplData->mxProgress->response(RET_CANCEL);
1701  mpImplData->mxProgress.reset();
1702  }
1703 }
1704 
1706 {
1707  return mpImplData->mxProgress && mpImplData->mxProgress->isCanceled();
1708 }
1709 
1711 {
1712  mpImplData->maMultiPage = i_rMPS;
1713 }
1714 
1716 {
1717  return mpImplData->maMultiPage;
1718 }
1719 
1721 {
1722  mpImplData->resetPaperToLastConfigured();
1723 }
1724 
1726 {
1727  sal_Int32 nCopyCount = 1;
1728  // set copycount and collate
1729  const css::beans::PropertyValue* pVal = getValue( "CopyCount" );
1730  if( pVal )
1731  pVal->Value >>= nCopyCount;
1732  bool bCollate = false;
1733  pVal = getValue( "Collate" );
1734  if( pVal )
1735  pVal->Value >>= bCollate;
1736  mpImplData->mxPrinter->SetCopyCount( static_cast<sal_uInt16>(nCopyCount), bCollate );
1737 
1738  // duplex mode
1739  pVal = getValue( "DuplexMode" );
1740  if( pVal )
1741  {
1742  sal_Int16 nDuplex = css::view::DuplexMode::UNKNOWN;
1743  pVal->Value >>= nDuplex;
1744  switch( nDuplex )
1745  {
1746  case css::view::DuplexMode::OFF: mpImplData->mxPrinter->SetDuplexMode( DuplexMode::Off ); break;
1747  case css::view::DuplexMode::LONGEDGE: mpImplData->mxPrinter->SetDuplexMode( DuplexMode::LongEdge ); break;
1748  case css::view::DuplexMode::SHORTEDGE: mpImplData->mxPrinter->SetDuplexMode( DuplexMode::ShortEdge ); break;
1749  }
1750  }
1751 }
1752 
1754 {
1755  bool bApi = getBoolProperty( "IsApi", false );
1756  return ! bApi && ! Application::IsHeadlessModeEnabled();
1757 }
1758 
1760 {
1761  bool bDirect = getBoolProperty( "IsDirect", false );
1762  return bDirect;
1763 }
1764 
1765 bool PrinterController::getBoolProperty( const OUString& i_rProperty, bool i_bFallback ) const
1766 {
1767  bool bRet = i_bFallback;
1768  const css::beans::PropertyValue* pVal = getValue( i_rProperty );
1769  if( pVal )
1770  pVal->Value >>= bRet;
1771  return bRet;
1772 }
1773 
1774 sal_Int32 PrinterController::getIntProperty( const OUString& i_rProperty, sal_Int32 i_nFallback ) const
1775 {
1776  sal_Int32 nRet = i_nFallback;
1777  const css::beans::PropertyValue* pVal = getValue( i_rProperty );
1778  if( pVal )
1779  pVal->Value >>= nRet;
1780  return nRet;
1781 }
1782 
1783 /*
1784  * PrinterOptionsHelper
1785 **/
1786 css::uno::Any PrinterOptionsHelper::getValue( const OUString& i_rPropertyName ) const
1787 {
1788  css::uno::Any aRet;
1789  std::unordered_map< OUString, css::uno::Any >::const_iterator it =
1790  m_aPropertyMap.find( i_rPropertyName );
1791  if( it != m_aPropertyMap.end() )
1792  aRet = it->second;
1793  return aRet;
1794 }
1795 
1796 bool PrinterOptionsHelper::getBoolValue( const OUString& i_rPropertyName, bool i_bDefault ) const
1797 {
1798  bool bRet = false;
1799  css::uno::Any aVal( getValue( i_rPropertyName ) );
1800  return (aVal >>= bRet) ? bRet : i_bDefault;
1801 }
1802 
1803 sal_Int64 PrinterOptionsHelper::getIntValue( const OUString& i_rPropertyName, sal_Int64 i_nDefault ) const
1804 {
1805  sal_Int64 nRet = 0;
1806  css::uno::Any aVal( getValue( i_rPropertyName ) );
1807  return (aVal >>= nRet) ? nRet : i_nDefault;
1808 }
1809 
1810 OUString PrinterOptionsHelper::getStringValue( const OUString& i_rPropertyName ) const
1811 {
1812  OUString aRet;
1813  css::uno::Any aVal( getValue( i_rPropertyName ) );
1814  return (aVal >>= aRet) ? aRet : OUString();
1815 }
1816 
1817 bool PrinterOptionsHelper::processProperties( const css::uno::Sequence< css::beans::PropertyValue >& i_rNewProp )
1818 {
1819  bool bChanged = false;
1820 
1821  for( const auto& rVal : i_rNewProp )
1822  {
1823  std::unordered_map< OUString, css::uno::Any >::iterator it =
1824  m_aPropertyMap.find( rVal.Name );
1825 
1826  bool bElementChanged = (it == m_aPropertyMap.end()) || (it->second != rVal.Value);
1827  if( bElementChanged )
1828  {
1829  m_aPropertyMap[ rVal.Name ] = rVal.Value;
1830  bChanged = true;
1831  }
1832  }
1833  return bChanged;
1834 }
1835 
1836 void PrinterOptionsHelper::appendPrintUIOptions( css::uno::Sequence< css::beans::PropertyValue >& io_rProps ) const
1837 {
1838  if( !m_aUIProperties.empty() )
1839  {
1840  sal_Int32 nIndex = io_rProps.getLength();
1841  io_rProps.realloc( nIndex+1 );
1842  css::beans::PropertyValue aVal;
1843  aVal.Name = "ExtraPrintUIOptions";
1845  io_rProps[ nIndex ] = aVal;
1846  }
1847 }
1848 
1849 css::uno::Any PrinterOptionsHelper::setUIControlOpt(const css::uno::Sequence< OUString >& i_rIDs,
1850  const OUString& i_rTitle,
1851  const css::uno::Sequence< OUString >& i_rHelpIds,
1852  const OUString& i_rType,
1853  const css::beans::PropertyValue* i_pVal,
1854  const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
1855 {
1856  sal_Int32 nElements =
1857  2 // ControlType + ID
1858  + (i_rTitle.isEmpty() ? 0 : 1) // Text
1859  + (i_rHelpIds.hasElements() ? 1 : 0) // HelpId
1860  + (i_pVal ? 1 : 0) // Property
1861  + i_rControlOptions.maAddProps.size() // additional props
1862  + (i_rControlOptions.maGroupHint.isEmpty() ? 0 : 1) // grouping
1863  + (i_rControlOptions.mbInternalOnly ? 1 : 0) // internal hint
1864  + (i_rControlOptions.mbEnabled ? 0 : 1) // enabled
1865  ;
1866  if( !i_rControlOptions.maDependsOnName.isEmpty() )
1867  {
1868  nElements += 1;
1869  if( i_rControlOptions.mnDependsOnEntry != -1 )
1870  nElements += 1;
1871  if( i_rControlOptions.mbAttachToDependency )
1872  nElements += 1;
1873  }
1874 
1875  css::uno::Sequence< css::beans::PropertyValue > aCtrl( nElements );
1876  sal_Int32 nUsed = 0;
1877  if( !i_rTitle.isEmpty() )
1878  {
1879  aCtrl[nUsed ].Name = "Text";
1880  aCtrl[nUsed++].Value <<= i_rTitle;
1881  }
1882  if( i_rHelpIds.hasElements() )
1883  {
1884  aCtrl[nUsed ].Name = "HelpId";
1885  aCtrl[nUsed++].Value <<= i_rHelpIds;
1886  }
1887  aCtrl[nUsed ].Name = "ControlType";
1888  aCtrl[nUsed++].Value <<= i_rType;
1889  aCtrl[nUsed ].Name = "ID";
1890  aCtrl[nUsed++].Value <<= i_rIDs;
1891  if( i_pVal )
1892  {
1893  aCtrl[nUsed ].Name = "Property";
1894  aCtrl[nUsed++].Value <<= *i_pVal;
1895  }
1896  if( !i_rControlOptions.maDependsOnName.isEmpty() )
1897  {
1898  aCtrl[nUsed ].Name = "DependsOnName";
1899  aCtrl[nUsed++].Value <<= i_rControlOptions.maDependsOnName;
1900  if( i_rControlOptions.mnDependsOnEntry != -1 )
1901  {
1902  aCtrl[nUsed ].Name = "DependsOnEntry";
1903  aCtrl[nUsed++].Value <<= i_rControlOptions.mnDependsOnEntry;
1904  }
1905  if( i_rControlOptions.mbAttachToDependency )
1906  {
1907  aCtrl[nUsed ].Name = "AttachToDependency";
1908  aCtrl[nUsed++].Value <<= i_rControlOptions.mbAttachToDependency;
1909  }
1910  }
1911  if( !i_rControlOptions.maGroupHint.isEmpty() )
1912  {
1913  aCtrl[nUsed ].Name = "GroupingHint";
1914  aCtrl[nUsed++].Value <<= i_rControlOptions.maGroupHint;
1915  }
1916  if( i_rControlOptions.mbInternalOnly )
1917  {
1918  aCtrl[nUsed ].Name = "InternalUIOnly";
1919  aCtrl[nUsed++].Value <<= true;
1920  }
1921  if( ! i_rControlOptions.mbEnabled )
1922  {
1923  aCtrl[nUsed ].Name = "Enabled";
1924  aCtrl[nUsed++].Value <<= false;
1925  }
1926 
1927  sal_Int32 nAddProps = i_rControlOptions.maAddProps.size();
1928  for( sal_Int32 i = 0; i < nAddProps; i++ )
1929  aCtrl[ nUsed++ ] = i_rControlOptions.maAddProps[i];
1930 
1931  SAL_WARN_IF( nUsed != nElements, "vcl.gdi", "nUsed != nElements, probable heap corruption" );
1932 
1933  return css::uno::makeAny( aCtrl );
1934 }
1935 
1936 css::uno::Any PrinterOptionsHelper::setGroupControlOpt(const OUString& i_rID,
1937  const OUString& i_rTitle,
1938  const OUString& i_rHelpId)
1939 {
1940  css::uno::Sequence< OUString > aHelpId;
1941  if( !i_rHelpId.isEmpty() )
1942  {
1943  aHelpId.realloc( 1 );
1944  *aHelpId.getArray() = i_rHelpId;
1945  }
1946  css::uno::Sequence< OUString > aIds { i_rID };
1947  return setUIControlOpt(aIds, i_rTitle, aHelpId, "Group");
1948 }
1949 
1950 css::uno::Any PrinterOptionsHelper::setSubgroupControlOpt(const OUString& i_rID,
1951  const OUString& i_rTitle,
1952  const OUString& i_rHelpId,
1953  const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
1954 {
1955  css::uno::Sequence< OUString > aHelpId;
1956  if( !i_rHelpId.isEmpty() )
1957  {
1958  aHelpId.realloc( 1 );
1959  *aHelpId.getArray() = i_rHelpId;
1960  }
1961  css::uno::Sequence< OUString > aIds { i_rID };
1962  return setUIControlOpt(aIds, i_rTitle, aHelpId, "Subgroup", nullptr, i_rControlOptions);
1963 }
1964 
1965 css::uno::Any PrinterOptionsHelper::setBoolControlOpt(const OUString& i_rID,
1966  const OUString& i_rTitle,
1967  const OUString& i_rHelpId,
1968  const OUString& i_rProperty,
1969  bool i_bValue,
1970  const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
1971 {
1972  css::uno::Sequence< OUString > aHelpId;
1973  if( !i_rHelpId.isEmpty() )
1974  {
1975  aHelpId.realloc( 1 );
1976  *aHelpId.getArray() = i_rHelpId;
1977  }
1978  css::beans::PropertyValue aVal;
1979  aVal.Name = i_rProperty;
1980  aVal.Value <<= i_bValue;
1981  css::uno::Sequence< OUString > aIds { i_rID };
1982  return setUIControlOpt(aIds, i_rTitle, aHelpId, "Bool", &aVal, i_rControlOptions);
1983 }
1984 
1985 css::uno::Any PrinterOptionsHelper::setChoiceRadiosControlOpt(const css::uno::Sequence< OUString >& i_rIDs,
1986  const OUString& i_rTitle,
1987  const css::uno::Sequence< OUString >& i_rHelpId,
1988  const OUString& i_rProperty,
1989  const css::uno::Sequence< OUString >& i_rChoices,
1990  sal_Int32 i_nValue,
1991  const css::uno::Sequence< sal_Bool >& i_rDisabledChoices,
1992  const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
1993 {
1994  UIControlOptions aOpt( i_rControlOptions );
1995  sal_Int32 nUsed = aOpt.maAddProps.size();
1996  aOpt.maAddProps.resize( nUsed + 1 + (i_rDisabledChoices.hasElements() ? 1 : 0) );
1997  aOpt.maAddProps[nUsed].Name = "Choices";
1998  aOpt.maAddProps[nUsed].Value <<= i_rChoices;
1999  if( i_rDisabledChoices.hasElements() )
2000  {
2001  aOpt.maAddProps[nUsed+1].Name = "ChoicesDisabled";
2002  aOpt.maAddProps[nUsed+1].Value <<= i_rDisabledChoices;
2003  }
2004 
2005  css::beans::PropertyValue aVal;
2006  aVal.Name = i_rProperty;
2007  aVal.Value <<= i_nValue;
2008  return setUIControlOpt(i_rIDs, i_rTitle, i_rHelpId, "Radio", &aVal, aOpt);
2009 }
2010 
2011 css::uno::Any PrinterOptionsHelper::setChoiceListControlOpt(const OUString& i_rID,
2012  const OUString& i_rTitle,
2013  const css::uno::Sequence< OUString >& i_rHelpId,
2014  const OUString& i_rProperty,
2015  const css::uno::Sequence< OUString >& i_rChoices,
2016  sal_Int32 i_nValue,
2017  const css::uno::Sequence< sal_Bool >& i_rDisabledChoices,
2018  const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
2019 {
2020  UIControlOptions aOpt( i_rControlOptions );
2021  sal_Int32 nUsed = aOpt.maAddProps.size();
2022  aOpt.maAddProps.resize( nUsed + 1 + (i_rDisabledChoices.hasElements() ? 1 : 0) );
2023  aOpt.maAddProps[nUsed].Name = "Choices";
2024  aOpt.maAddProps[nUsed].Value <<= i_rChoices;
2025  if( i_rDisabledChoices.hasElements() )
2026  {
2027  aOpt.maAddProps[nUsed+1].Name = "ChoicesDisabled";
2028  aOpt.maAddProps[nUsed+1].Value <<= i_rDisabledChoices;
2029  }
2030 
2031  css::beans::PropertyValue aVal;
2032  aVal.Name = i_rProperty;
2033  aVal.Value <<= i_nValue;
2034  css::uno::Sequence< OUString > aIds { i_rID };
2035  return setUIControlOpt(aIds, i_rTitle, i_rHelpId, "List", &aVal, aOpt);
2036 }
2037 
2038 css::uno::Any PrinterOptionsHelper::setRangeControlOpt(const OUString& i_rID,
2039  const OUString& i_rTitle,
2040  const OUString& i_rHelpId,
2041  const OUString& i_rProperty,
2042  sal_Int32 i_nValue,
2043  sal_Int32 i_nMinValue,
2044  sal_Int32 i_nMaxValue,
2045  const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
2046 {
2047  UIControlOptions aOpt( i_rControlOptions );
2048  if( i_nMaxValue >= i_nMinValue )
2049  {
2050  sal_Int32 nUsed = aOpt.maAddProps.size();
2051  aOpt.maAddProps.resize( nUsed + 2 );
2052  aOpt.maAddProps[nUsed ].Name = "MinValue";
2053  aOpt.maAddProps[nUsed++].Value <<= i_nMinValue;
2054  aOpt.maAddProps[nUsed ].Name = "MaxValue";
2055  aOpt.maAddProps[nUsed++].Value <<= i_nMaxValue;
2056  }
2057 
2058  css::uno::Sequence< OUString > aHelpId;
2059  if( !i_rHelpId.isEmpty() )
2060  {
2061  aHelpId.realloc( 1 );
2062  *aHelpId.getArray() = i_rHelpId;
2063  }
2064  css::beans::PropertyValue aVal;
2065  aVal.Name = i_rProperty;
2066  aVal.Value <<= i_nValue;
2067  css::uno::Sequence< OUString > aIds { i_rID };
2068  return setUIControlOpt(aIds, i_rTitle, aHelpId, "Range", &aVal, aOpt);
2069 }
2070 
2071 css::uno::Any PrinterOptionsHelper::setEditControlOpt(const OUString& i_rID,
2072  const OUString& i_rTitle,
2073  const OUString& i_rHelpId,
2074  const OUString& i_rProperty,
2075  const OUString& i_rValue,
2076  const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
2077 {
2078  css::uno::Sequence< OUString > aHelpId;
2079  if( !i_rHelpId.isEmpty() )
2080  {
2081  aHelpId.realloc( 1 );
2082  *aHelpId.getArray() = i_rHelpId;
2083  }
2084  css::beans::PropertyValue aVal;
2085  aVal.Name = i_rProperty;
2086  aVal.Value <<= i_rValue;
2087  css::uno::Sequence< OUString > aIds { i_rID };
2088  return setUIControlOpt(aIds, i_rTitle, aHelpId, "Edit", &aVal, i_rControlOptions);
2089 }
2090 
2091 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static OUString GetDisplayName()
Get the default name of the application for message dialogs and printing.
Definition: svapp.cxx:1173
static css::uno::Any setChoiceRadiosControlOpt(const css::uno::Sequence< OUString > &i_rIDs, const OUString &i_rTitle, const css::uno::Sequence< OUString > &i_rHelpId, const OUString &i_rProperty, const css::uno::Sequence< OUString > &i_rChoices, sal_Int32 i_nValue, const css::uno::Sequence< sal_Bool > &i_rDisabledChoices=css::uno::Sequence< sal_Bool >(), const UIControlOptions &i_rControlOptions=UIControlOptions())
Show a set of choices as radio buttons.
Definition: print3.cxx:1985
static void PrintJob(const std::shared_ptr< vcl::PrinterController > &i_pController, const JobSetup &i_rInitSetup)
Execute a print job.
Definition: print3.cxx:295
VCL_DLLPRIVATE void setPrinter(const VclPtr< Printer > &)
Definition: print3.cxx:781
long Width() const
bool isDirectPrint() const
Definition: print3.cxx:1759
bool getBoolValue(const OUString &i_rPropertyName, bool i_bDefault) const
Definition: print3.cxx:1796
const css::uno::Sequence< css::beans::PropertyValue > & getUIOptions() const
Definition: print3.cxx:1459
const OUString & GetName() const
Definition: print.hxx:276
Orientation
Definition: Exif.hxx:25
Size aSize
In 100th mm.
Definition: print.hxx:426
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
std::vector< css::beans::PropertyValue > maUIProperties
Definition: print3.cxx:143
std::unordered_map< OUString, css::uno::Sequence< sal_Bool > > ChoiceDisableMap
Definition: print3.cxx:138
PrintJobAsync(const std::shared_ptr< PrinterController > &i_xController, const JobSetup &i_rInitSetup)
Definition: print3.cxx:279
VCL_DLLPRIVATE bool isPaperSizeFromUser() const
Definition: print3.cxx:1401
DrawModeFlags
Definition: outdev.hxx:200
std::unordered_map< OUString, css::uno::Any > m_aPropertyMap
Definition: print.hxx:569
JobSetup const maInitSetup
Definition: print3.cxx:277
sal_uInt16 GetPaperBin() const
Definition: print.cxx:1188
VCL_DLLPRIVATE void setupPrinter(weld::Window *i_pDlgParent)
Definition: print3.cxx:802
long Height() const
vcl::PrinterController::MultiPageSetup maMultiPage
Definition: print3.cxx:156
void setJobState(css::view::PrintableState)
Definition: print3.cxx:766
VCL_DLLPRIVATE bool getPapersizeFromSetup() const
Definition: print3.cxx:1377
std::vector< css::beans::PropertyValue > m_aUIProperties
Definition: print.hxx:571
VCL_DLLPRIVATE Size & getPaperSizeFromUser() const
Definition: print3.cxx:1396
VCL_DLLPRIVATE DrawModeFlags removeTransparencies(GDIMetaFile const &i_rIn, GDIMetaFile &o_rOut)
Definition: print3.cxx:1218
bool isProgressCanceled() const
Definition: print3.cxx:1705
void SetPrefSize(const Size &rSize)
Definition: gdimtf.hxx:174
aBuf
void Clear()
Definition: gdimtf.cxx:244
PrinterController::PageSize aSize
Definition: print3.cxx:55
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
Post a user event to the default window.
Definition: svapp.cxx:996
PrinterTransparencyMode GetReducedTransparencyMode() const
Definition: print.hxx:130
static bool ExecutePrintJob(const std::shared_ptr< vcl::PrinterController > &i_pController)
Definition: print3.cxx:518
std::vector< sal_Int32 > maPageNumbers
Definition: print3.cxx:59
VCL_DLLPRIVATE bool StartJob(const OUString &rJobName, std::shared_ptr< vcl::PrinterController > const &)
Definition: print3.cxx:544
void printFilteredPage(int i_nPage)
Definition: print3.cxx:1280
VCL_DLLPRIVATE Size & getPaperSizeSetup() const
Definition: print3.cxx:1382
std::vector< sal_Int32 > maCacheRanking
Definition: print3.cxx:60
bool IsReduceBitmaps() const
Definition: print.hxx:144
static void FinishPrintJob(const std::shared_ptr< vcl::PrinterController > &i_pController)
Definition: print3.cxx:528
void Clip(const tools::Rectangle &)
Definition: gdimtf.cxx:711
Orientation GetOrientation() const
Definition: print.cxx:1147
void SetMapMode()
Definition: map.cxx:655
PrinterController(const VclPtr< Printer > &, weld::Window *)
Definition: print3.cxx:223
VCL_DLLPRIVATE const MultiPageSetup & getMultipage() const
Definition: print3.cxx:1715
void updateRanking(sal_Int32 nLastHit)
Definition: print3.cxx:64
bool IsReducedBitmapIncludesTransparency() const
Definition: print.hxx:154
std::unordered_map< OUString, size_t > PropertyToIndexMap
Definition: print3.cxx:136
virtual css::uno::Sequence< css::beans::PropertyValue > getPageParameters(int i_nPage) const =0
Get the page parameters.
static bool runAsync(const std::shared_ptr< DialogController > &rController, const std::function< void(sal_Int32)> &)
Definition: weldutils.cxx:32
css::view::PrintableState meJobState
Definition: print3.cxx:154
std::vector< css::beans::PropertyValue > maAddProps
Definition: print.hxx:619
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
VCL_DLLPRIVATE css::uno::Sequence< css::beans::PropertyValue > getPageParametersProtected(int i_nPage) const
Definition: print3.cxx:963
VCL_DLLPRIVATE void resetPaperToLastConfigured()
Definition: print3.cxx:1720
std::vector< CacheEntry > maPages
Definition: print3.cxx:58
void Record(OutputDevice *pOutDev)
Definition: gdimtf.cxx:285
VCL_DLLPRIVATE void pushPropertiesToPrinter()
Definition: print3.cxx:1725
css::uno::Sequence< css::beans::PropertyValue > maUIOptions
Definition: print3.cxx:142
OUString makeEnabled(const OUString &rPropName)
MakeEnabled will change the property rPropName depends on to the value.
Definition: print3.cxx:1633
int getFilteredPageCount() const
Definition: print3.cxx:1210
static css::uno::Any setSubgroupControlOpt(const OUString &i_rID, const OUString &i_rTitle, const OUString &i_rHelpId, const UIControlOptions &i_rControlOptions=UIControlOptions())
Show and set the label of a VclFrame of id i_rID.
Definition: print3.cxx:1950
VCL_DLLPRIVATE void setPaperSizeFromUser(Size i_aUserSize)
Definition: print3.cxx:1387
#define PRINTER_GENERALERROR
Definition: errcode.hxx:268
static css::uno::Any setRangeControlOpt(const OUString &i_rID, const OUString &i_rTitle, const OUString &i_rHelpId, const OUString &i_rProperty, sal_Int32 i_nValue, sal_Int32 i_nMinValue, sal_Int32 i_nMaxValue, const UIControlOptions &i_rControlOptions)
Show an integer range (e.g.
Definition: print3.cxx:2038
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:296
std::unique_ptr< ImplPrinterControllerData > mpImplData
Definition: print.hxx:395
void ReadFromConfig(bool bFile)
Read printer options from configuration.
Definition: print.cxx:107
sal_Int32 nElements
void setLastPage(bool i_bLastPage)
Definition: print3.cxx:1359
virtual int getPageCount() const =0
App must override this.
bool getBoolProperty(const OUString &i_rPropertyName, bool i_bFallback) const
Get a bool property.
Definition: print3.cxx:1765
bool SetPaperSizeUser(const Size &rSize)
Definition: print.cxx:1347
static bool PreparePrintJob(std::shared_ptr< vcl::PrinterController > i_pController, const JobSetup &i_rInitSetup)
Definition: print3.cxx:312
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:67
VCL_DLLPRIVATE void setPapersizeFromSetup(bool i_bPapersizeFromSetup)
Definition: print3.cxx:1369
static void VCL_DLLPRIVATE ImplPrintJob(const std::shared_ptr< vcl::PrinterController > &i_pController, const JobSetup &i_rInitSetup)
Implementation detail of PrintJob being asynchronous.
Definition: print3.cxx:534
css::beans::PropertyValue * getValue(const OUString &i_rPropertyName)
Get the PropertyValue of a Property.
Definition: print3.cxx:1464
static bool Reschedule(bool bHandleAllCurrentEvents=false)
Attempt to process current pending event(s)
Definition: svapp.cxx:456
#define DBG_ASSERT(sCon, aError)
sal_uInt16 GetReducedBitmapResolution() const
Definition: print.hxx:150
void setValue(const OUString &rGroup, const OUString &rKey, const OUString &rValue)
static css::uno::Any setEditControlOpt(const OUString &i_rID, const OUString &i_rTitle, const OUString &i_rHelpId, const OUString &i_rProperty, const OUString &i_rValue, const UIControlOptions &i_rControlOptions)
Show a string field.
Definition: print3.cxx:2071
void insert(sal_Int32 i_nPageNo, const GDIMetaFile &i_rPage, const PrinterController::PageSize &i_rSize)
Definition: print3.cxx:85
int i
void setPrinterModified(bool i_bPapersizeFromSetup)
Definition: print3.cxx:1406
virtual void jobFinished(css::view::PrintableState)
Definition: print3.cxx:1338
void appendPrintUIOptions(css::uno::Sequence< css::beans::PropertyValue > &io_rProps) const
Append to a sequence of property values the ui property sequence passed at creation.
Definition: print3.cxx:1836
ControlDependencyMap maControlDependencies
Definition: print3.cxx:146
PrinterController::PageSize modifyJobSetup(const css::uno::Sequence< css::beans::PropertyValue > &i_rProps)
Definition: print3.cxx:872
virtual void printPage(int i_nPage) const =0
App must override this.
void WindStart()
Definition: gdimtf.cxx:527
std::shared_ptr< vcl::PrintProgressDialog > mxProgress
Definition: print3.cxx:158
PrinterBitmapMode GetReducedBitmapMode() const
Definition: print.hxx:147
static void appendSubPage(GDIMetaFile &o_rMtf, const tools::Rectangle &i_rClipRect, GDIMetaFile &io_rSubPage, bool i_bDrawBorder)
Definition: print3.cxx:1031
bool isShowDialogs() const
Definition: print3.cxx:1753
PageSize getFilteredPageFile(int i_nFilteredPage, GDIMetaFile &o_rMtf, bool i_bMayUseCache=false)
Definition: print3.cxx:1067
OUString getStringValue(const OUString &i_rPropertyName) const
Definition: print3.cxx:1810
VCL_DLLPRIVATE int getPageCountProtected() const
Definition: print3.cxx:952
void Stop()
Definition: gdimtf.cxx:514
A construction helper for a temporary VclPtr.
Definition: vclptr.hxx:275
static css::uno::Any setGroupControlOpt(const OUString &i_rID, const OUString &i_rTitle, const OUString &i_rHelpId)
Show and set the title of a TagPage of id i_rID.
Definition: print3.cxx:1936
bool isFixedPageSize() const
Definition: print3.cxx:217
weld::Window * getWindow() const
Definition: print3.cxx:776
const Size & getRealPaperSize(const Size &i_rPageSize, bool bNoNUP) const
Definition: print3.cxx:207
bool isUIOptionEnabled(const OUString &rPropName) const
Enable/disable an option; this can be used to implement dialog logic.
Definition: print3.cxx:1565
OUString const & GetPrinterName() const
Definition: jobset.cxx:216
bool Setup(weld::Window *pWindow, PrinterSetupMode eMode=PrinterSetupMode::DocumentGlobal)
Definition: print.cxx:993
#define PRINTER_ABORT
Definition: errcode.hxx:267
static OUString queryFile(Printer const *pPrinter)
Definition: print3.cxx:230
static bool IsHeadlessModeEnabled()
Determines if headless mode is enabled.
Definition: svapp.cxx:1498
ChoiceDisableMap maChoiceDisableMap
Definition: print3.cxx:147
#define SAL_WARN_IF(condition, area, stream)
#define ERRCODE_NONE
Definition: errcode.hxx:198
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:540
bool SetOrientation(Orientation eOrient)
Definition: print.cxx:1111
void Move(long nX, long nY)
Definition: gdimtf.cxx:608
const VclPtr< Printer > & getPrinter() const
Definition: print3.cxx:771
virtual void jobStarted()
Will be called after a possible dialog has been shown and the real printjob starts.
Definition: print3.cxx:1334
virtual std::unique_ptr< SalPrinter > CreatePrinter(SalInfoPrinter *pInfoPrinter)=0
VCL_DLLPRIVATE void resetPrinterOptions(bool i_bFileOutput)
Definition: print3.cxx:795
void invalidate()
Definition: print3.cxx:114
void Scale(double fScaleX, double fScaleY)
Definition: gdimtf.cxx:685
sal_Int32 getIntProperty(const OUString &i_rPropertyName, sal_Int32 i_nFallback) const
Get an int property.
Definition: print3.cxx:1774
VCL_DLLPRIVATE PageSize getPageFile(int i_inUnfilteredPage, GDIMetaFile &rMtf, bool i_bMayUseCache=false)
Definition: print3.cxx:974
bool processProperties(const css::uno::Sequence< css::beans::PropertyValue > &i_rNewProp)
Process a new set of properties.
Definition: print3.cxx:1817
Reference< XComponentContext > getProcessComponentContext()
VCL_DLLPRIVATE void setMultipage(const MultiPageSetup &)
Definition: print3.cxx:1710
css::uno::Any getValue(const OUString &i_rPropertyName) const
Definition: print3.cxx:1786
virtual ~PrinterController()
Definition: print3.cxx:757
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
bool GetPrinterSettingsPreferred() const
Definition: print.cxx:1193
PropertyToIndexMap maPropertyToIndex
Definition: print3.cxx:145
static css::uno::Any setBoolControlOpt(const OUString &i_rID, const OUString &i_rTitle, const OUString &i_rHelpId, const OUString &i_rProperty, bool i_bValue, const UIControlOptions &i_rControlOptions=UIControlOptions())
Show a bool option as a checkbox.
Definition: print3.cxx:1965
bool isUIChoiceEnabled(const OUString &rPropName, sal_Int32 nChoice) const
Definition: print3.cxx:1619
bool getPrinterModified() const
Definition: print3.cxx:1411
VCL_DLLPRIVATE void setReversePrint(bool i_bReverse)
Definition: print3.cxx:1364
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
static weld::Builder * CreateBuilder(weld::Widget *pParent, const OUString &rUIFile)
Definition: builder.cxx:148
#define SAL_WARN(area, stream)
OUString VclResId(const char *pId)
Definition: svdata.cxx:258
std::unordered_map< OUString, ControlDependency > ControlDependencyMap
Definition: print3.cxx:137
VclPtr< Printer > mxPrinter
Definition: print3.cxx:140
std::vector< bool > maUIPropertyEnabled
Definition: print3.cxx:144
css::uno::Sequence< css::beans::PropertyValue > getJobProperties(const css::uno::Sequence< css::beans::PropertyValue > &i_rMergeList) const
For implementations: get current job properties as changed by e.g.
Definition: print3.cxx:1416
NupOrderType
Definition: print.hxx:387
bool bFullPaper
Full paper, not only imageable area is printed.
Definition: print.hxx:429
static SettingsConfigItem * get()
static css::uno::Any setChoiceListControlOpt(const OUString &i_rID, const OUString &i_rTitle, const css::uno::Sequence< OUString > &i_rHelpId, const OUString &i_rProperty, const css::uno::Sequence< OUString > &i_rChoices, sal_Int32 i_nValue, const css::uno::Sequence< sal_Bool > &i_rDisabledChoices=css::uno::Sequence< sal_Bool >(), const UIControlOptions &i_rControlOptions=UIControlOptions())
Show a set of choices in a list box.
Definition: print3.cxx:2011
bool IsReduceTransparency() const
Definition: print.hxx:127
sal_uInt32 GetCapabilities(PrinterCapType nType) const
Definition: print.cxx:942
IMPL_LINK_NOARG(QuickSelectionEngine_Data, SearchStringTimeout, Timer *, void)
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:60
void setWidth(long nWidth)
std::shared_ptr< PrinterController > mxController
Definition: print3.cxx:276
SalInstance * mpDefInst
Definition: svdata.hxx:336
static css::uno::Any setUIControlOpt(const css::uno::Sequence< OUString > &i_rIDs, const OUString &i_rTitle, const css::uno::Sequence< OUString > &i_rHelpId, const OUString &i_rType, const css::beans::PropertyValue *i_pValue=nullptr, const UIControlOptions &i_rControlOptions=UIControlOptions())
Show general control.
Definition: print3.cxx:1849
sal_Int64 getIntValue(const OUString &i_rPropertyName, sal_Int64 i_nDefault) const
Definition: print3.cxx:1803
css::view::PrintableState getJobState() const
Definition: print3.cxx:761
void setValue(const OUString &i_rPropertyName, const css::uno::Any &i_rValue)
Set a property value - can also be used to add another UI property.
Definition: print3.cxx:1478
void SetPrefMapMode(const MapMode &rMapMode)
Definition: gdimtf.hxx:177
bool IsConvertToGreyscales() const
Definition: print.hxx:158
Size GetPaperSize() const
Definition: print.hxx:330
void setHeight(long nHeight)
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo