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