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