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