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( "-" + OUString::number( nPages ) );
428 }
429 xController->setValue("PageRange", css::uno::Any(aBuf.makeStringAndClear()));
430 }
431 }
432 }
433 }
434 }
435
436 css::beans::PropertyValue* pReverseVal = xController->getValue("PrintReverse");
437 if( pReverseVal )
438 {
439 bool bReverse = false;
440 pReverseVal->Value >>= bReverse;
441 xController->setReversePrint( bReverse );
442 }
443
444 css::beans::PropertyValue* pPapersizeFromSetupVal = xController->getValue("PapersizeFromSetup");
445 if( pPapersizeFromSetupVal )
446 {
447 bool bPapersizeFromSetup = false;
448 pPapersizeFromSetupVal->Value >>= bPapersizeFromSetup;
449 xController->setPapersizeFromSetup(bPapersizeFromSetup);
450 }
451
452 // setup NUp printing from properties
453 sal_Int32 nRows = xController->getIntProperty("NUpRows", 1);
454 sal_Int32 nCols = xController->getIntProperty("NUpColumns", 1);
455 if( nRows > 1 || nCols > 1 )
456 {
458 aMPS.nRows = std::max<sal_Int32>(nRows, 1);
459 aMPS.nColumns = std::max<sal_Int32>(nCols, 1);
460 sal_Int32 nValue = xController->getIntProperty("NUpPageMarginLeft", aMPS.nLeftMargin);
461 if( nValue >= 0 )
462 aMPS.nLeftMargin = nValue;
463 nValue = xController->getIntProperty("NUpPageMarginRight", aMPS.nRightMargin);
464 if( nValue >= 0 )
465 aMPS.nRightMargin = nValue;
466 nValue = xController->getIntProperty( "NUpPageMarginTop", aMPS.nTopMargin );
467 if( nValue >= 0 )
468 aMPS.nTopMargin = nValue;
469 nValue = xController->getIntProperty( "NUpPageMarginBottom", aMPS.nBottomMargin );
470 if( nValue >= 0 )
471 aMPS.nBottomMargin = nValue;
472 nValue = xController->getIntProperty( "NUpHorizontalSpacing", aMPS.nHorizontalSpacing );
473 if( nValue >= 0 )
475 nValue = xController->getIntProperty( "NUpVerticalSpacing", aMPS.nVerticalSpacing );
476 if( nValue >= 0 )
478 aMPS.bDrawBorder = xController->getBoolProperty( "NUpDrawBorder", aMPS.bDrawBorder );
479 aMPS.nOrder = static_cast<NupOrderType>(xController->getIntProperty( "NUpSubPageOrder", static_cast<sal_Int32>(aMPS.nOrder) ));
480 aMPS.aPaperSize = xController->getPrinter()->PixelToLogic( xController->getPrinter()->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) );
481 css::beans::PropertyValue* pPgSizeVal = xController->getValue( "NUpPaperSize" );
482 css::awt::Size aSizeVal;
483 if( pPgSizeVal && (pPgSizeVal->Value >>= aSizeVal) )
484 {
485 aMPS.aPaperSize.setWidth( aSizeVal.Width );
486 aMPS.aPaperSize.setHeight( aSizeVal.Height );
487 }
488
489 xController->setMultipage( aMPS );
490 }
491
492 // in direct print case check whether there is anything to print.
493 // if not, show an errorbox (if appropriate)
494 if( xController->isShowDialogs() && xController->isDirectPrint() )
495 {
496 if( xController->getFilteredPageCount() == 0 )
497 {
498 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(xController->getWindow(), "vcl/ui/errornocontentdialog.ui"));
499 std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("ErrorNoContentDialog"));
500 xBox->run();
501 return false;
502 }
503 }
504
505 // check if the printer brings up its own dialog
506 // in that case leave the work to that dialog
507 if( ! xController->getPrinter()->GetCapabilities( PrinterCapType::ExternalDialog ) &&
508 ! xController->isDirectPrint() &&
509 xController->isShowDialogs()
510 )
511 {
512 try
513 {
514 PrintDialog aDlg(xController->getWindow(), xController);
515 if (!aDlg.run())
516 {
517 xController->abortJob();
518 return false;
519 }
520 if (aDlg.isPrintToFile())
521 {
522 OUString aFile = queryFile( xController->getPrinter().get() );
523 if( aFile.isEmpty() )
524 {
525 xController->abortJob();
526 return false;
527 }
528 xController->setValue( "LocalFileName",
529 css::uno::Any( aFile ) );
530 }
531 else if (aDlg.isSingleJobs())
532 {
533 xController->getPrinter()->SetSinglePrintJobs(true);
534 }
535 }
536 catch (const std::bad_alloc&)
537 {
538 }
539 }
540#ifdef MACOSX
541 else
542 {
543 // The PrintDialog updates the printer list in its constructor so do
544 // the same for printers that bring up their own dialog since. Not
545 // sure if this is needed or not on Windows or X11, so limit only to
546 // macOS for now.
548 }
549#endif
550
551 xController->pushPropertiesToPrinter();
552 return true;
553}
554
555bool Printer::ExecutePrintJob(const std::shared_ptr<PrinterController>& xController)
556{
557 OUString aJobName;
558 css::beans::PropertyValue* pJobNameVal = xController->getValue( "JobName" );
559 if( pJobNameVal )
560 pJobNameVal->Value >>= aJobName;
561
562 return xController->getPrinter()->StartJob( aJobName, xController );
563}
564
565void Printer::FinishPrintJob(const std::shared_ptr<PrinterController>& xController)
566{
567 xController->resetPaperToLastConfigured();
568 xController->jobFinished( xController->getJobState() );
569}
570
571void Printer::ImplPrintJob(const std::shared_ptr<PrinterController>& xController,
572 const JobSetup& i_rInitSetup)
573{
574 if (PreparePrintJob(xController, i_rInitSetup))
575 {
576 ExecutePrintJob(xController);
577 }
578 FinishPrintJob(xController);
579}
580
581bool Printer::StartJob( const OUString& i_rJobName, std::shared_ptr<vcl::PrinterController> const & i_xController)
582{
583 mnError = ERRCODE_NONE;
584
585 if ( IsDisplayPrinter() )
586 return false;
587
588 if ( IsJobActive() || IsPrinting() )
589 return false;
590
591 sal_uInt32 nCopies = mnCopyCount;
592 bool bCollateCopy = mbCollateCopy;
593 bool bUserCopy = false;
594
595 if ( nCopies > 1 )
596 {
597 const sal_uInt32 nDevCopy = GetCapabilities( bCollateCopy
600
601 // need to do copies by hand ?
602 if ( nCopies > nDevCopy )
603 {
604 bUserCopy = true;
605 nCopies = 1;
606 bCollateCopy = false;
607 }
608 }
609 else
610 bCollateCopy = false;
611
612 ImplSVData* pSVData = ImplGetSVData();
613 mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
614
615 if (!mpPrinter)
616 return false;
617
618 bool bSinglePrintJobs = i_xController->getPrinter()->IsSinglePrintJobs();
619
620 css::beans::PropertyValue* pFileValue = i_xController->getValue("LocalFileName");
621 if( pFileValue )
622 {
623 OUString aFile;
624 pFileValue->Value >>= aFile;
625 if( !aFile.isEmpty() )
626 {
627 mbPrintFile = true;
628 maPrintFile = aFile;
629 bSinglePrintJobs = false;
630 }
631 }
632
633 OUString* pPrintFile = nullptr;
634 if ( mbPrintFile )
635 pPrintFile = &maPrintFile;
636 mpPrinterOptions->ReadFromConfig( mbPrintFile );
637
638 mbPrinting = true;
639 if( GetCapabilities( PrinterCapType::UsePullModel ) )
640 {
641 mbJobActive = true;
642 // SAL layer does all necessary page printing
643 // and also handles showing a dialog
644 // that also means it must call jobStarted when the dialog is finished
645 // it also must set the JobState of the Controller
646 if( mpPrinter->StartJob( pPrintFile,
647 i_rJobName,
649 &maJobSetup.ImplGetData(),
650 *i_xController) )
651 {
652 EndJob();
653 }
654 else
655 {
656 mnError = ImplSalPrinterErrorCodeToVCL(mpPrinter->GetErrorCode());
657 if ( !mnError )
658 mnError = PRINTER_GENERALERROR;
659 mbPrinting = false;
660 mpPrinter.reset();
661 mbJobActive = false;
662
663 GDIMetaFile aDummyFile;
664 i_xController->setLastPage(true);
665 i_xController->getFilteredPageFile(0, aDummyFile);
666
667 return false;
668 }
669 }
670 else
671 {
672 // possibly a dialog has been shown
673 // now the real job starts
674 i_xController->setJobState( css::view::PrintableState_JOB_STARTED );
675 i_xController->jobStarted();
676
677 int nJobs = 1;
678 int nOuterRepeatCount = 1;
679 int nInnerRepeatCount = 1;
680 if( bUserCopy )
681 {
682 if( mbCollateCopy )
683 nOuterRepeatCount = mnCopyCount;
684 else
685 nInnerRepeatCount = mnCopyCount;
686 }
687 if( bSinglePrintJobs )
688 {
689 nJobs = mnCopyCount;
690 nCopies = 1;
691 nOuterRepeatCount = nInnerRepeatCount = 1;
692 }
693
694 for( int nJobIteration = 0; nJobIteration < nJobs; nJobIteration++ )
695 {
696 bool bError = false;
697 if( mpPrinter->StartJob( pPrintFile,
698 i_rJobName,
700 nCopies,
701 bCollateCopy,
702 i_xController->isDirectPrint(),
703 &maJobSetup.ImplGetData() ) )
704 {
705 bool bAborted = false;
706 mbJobActive = true;
707 i_xController->createProgressDialog();
708 const int nPages = i_xController->getFilteredPageCount();
709 // abort job, if no pages will be printed.
710 if ( nPages == 0 )
711 {
712 i_xController->abortJob();
713 bAborted = true;
714 }
715 for( int nOuterIteration = 0; nOuterIteration < nOuterRepeatCount && ! bAborted; nOuterIteration++ )
716 {
717 for( int nPage = 0; nPage < nPages && ! bAborted; nPage++ )
718 {
719 for( int nInnerIteration = 0; nInnerIteration < nInnerRepeatCount && ! bAborted; nInnerIteration++ )
720 {
721 if( nPage == nPages-1 &&
722 nOuterIteration == nOuterRepeatCount-1 &&
723 nInnerIteration == nInnerRepeatCount-1 &&
724 nJobIteration == nJobs-1 )
725 {
726 i_xController->setLastPage(true);
727 }
728 i_xController->printFilteredPage(nPage);
729 if (i_xController->isProgressCanceled())
730 {
731 i_xController->abortJob();
732 }
733 if (i_xController->getJobState() ==
734 css::view::PrintableState_JOB_ABORTED)
735 {
736 bAborted = true;
737 }
738 }
739 }
740 // FIXME: duplex ?
741 }
742 EndJob();
743
744 if( nJobIteration < nJobs-1 )
745 {
746 mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter );
747
748 if ( mpPrinter )
749 mbPrinting = true;
750 else
751 bError = true;
752 }
753 }
754 else
755 bError = true;
756
757 if( bError )
758 {
759 mnError = mpPrinter ? ImplSalPrinterErrorCodeToVCL(mpPrinter->GetErrorCode()) : ERRCODE_NONE;
760 if ( !mnError )
761 mnError = PRINTER_GENERALERROR;
762 i_xController->setJobState( mnError == PRINTER_ABORT
763 ? css::view::PrintableState_JOB_ABORTED
764 : css::view::PrintableState_JOB_FAILED );
765 mbPrinting = false;
766 mpPrinter.reset();
767
768 return false;
769 }
770 }
771
772 if (i_xController->getJobState() == css::view::PrintableState_JOB_STARTED)
773 i_xController->setJobState(css::view::PrintableState_JOB_SPOOLED);
774 }
775
776 // make last used printer persistent for UI jobs
777 if (i_xController->isShowDialogs() && !i_xController->isDirectPrint())
778 {
780 pItem->setValue( "PrintDialog",
781 "LastPrinterUsed",
782 GetName()
783 );
784 }
785
786 return true;
787}
788
790{
791}
792
793css::view::PrintableState PrinterController::getJobState() const
794{
795 return mpImplData->meJobState;
796}
797
798void PrinterController::setJobState( css::view::PrintableState i_eState )
799{
800 mpImplData->meJobState = i_eState;
801}
802
804{
805 return mpImplData->mxPrinter;
806}
807
809{
810 return mpImplData->mpWindow;
811}
812
814{
815 mpImplData->mpWindow = nullptr;
816 if (mpImplData->mxProgress)
817 {
818 // close the dialog without doing anything, just get rid of it
819 mpImplData->mxProgress->response(RET_OK);
820 mpImplData->mxProgress.reset();
821 }
822}
823
825{
826 VclPtr<Printer> xPrinter = mpImplData->mxPrinter;
827
828 Size aPaperSize; // Save current paper size
829 Orientation eOrientation = Orientation::Portrait; // Save current paper orientation
830 bool bSavedSizeOrientation = false;
831
832 // #tdf 126744 Transfer paper size and orientation settings to newly selected printer
833 if ( xPrinter )
834 {
835 aPaperSize = xPrinter->GetPaperSize();
836 eOrientation = xPrinter->GetOrientation();
837 bSavedSizeOrientation = true;
838 }
839
840 mpImplData->mxPrinter = i_rPrinter;
841 setValue( "Name",
842 css::uno::Any( i_rPrinter->GetName() ) );
843 mpImplData->mnDefaultPaperBin = mpImplData->mxPrinter->GetPaperBin();
844 mpImplData->mxPrinter->Push();
845 mpImplData->mxPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
846 mpImplData->maDefaultPageSize = mpImplData->mxPrinter->GetPaperSize();
847
848 if ( bSavedSizeOrientation )
849 {
850 mpImplData->mxPrinter->SetPaperSizeUser(aPaperSize);
851 mpImplData->mxPrinter->SetOrientation(eOrientation);
852 }
853
854 mpImplData->mbPapersizeFromUser = false;
855 mpImplData->mbOrientationFromUser = false;
856 mpImplData->mxPrinter->Pop();
857 mpImplData->mnFixedPaperBin = -1;
858}
859
861{
862 vcl::printer::Options aOpt;
863 aOpt.ReadFromConfig( i_bFileOutput );
864 mpImplData->mxPrinter->SetPrinterOptions( aOpt );
865}
866
868{
869 bool bRet = false;
870
871 // Important to hold printer alive while doing setup etc.
872 VclPtr< Printer > xPrinter = mpImplData->mxPrinter;
873
874 if( !xPrinter )
875 return;
876
877 xPrinter->Push();
878 xPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
879
880 // get current data
881 Size aPaperSize(xPrinter->GetPaperSize());
882 Orientation eOrientation = xPrinter->GetOrientation();
883 sal_uInt16 nPaperBin = xPrinter->GetPaperBin();
884
885 // reset paper size back to last configured size, not
886 // whatever happens to be the current page
887 // (but only if the printer config has changed, otherwise
888 // don't override printer page auto-detection - tdf#91362)
890 {
892 }
893
894 // call driver setup
895 bRet = xPrinter->Setup( i_pParent, PrinterSetupMode::SingleJob );
896 SAL_WARN_IF(xPrinter != mpImplData->mxPrinter, "vcl.gdi",
897 "Printer changed underneath us during setup");
898 xPrinter = mpImplData->mxPrinter;
899
900 Size aNewPaperSize(xPrinter->GetPaperSize());
901 if (bRet)
902 {
903 bool bInvalidateCache = false;
905
906 // was papersize overridden ? if so we need to take action if we're
907 // configured to use the driver papersize
908 if (aNewPaperSize != mpImplData->maDefaultPageSize)
909 {
910 mpImplData->maDefaultPageSize = aNewPaperSize;
911 bInvalidateCache = getPapersizeFromSetup();
912 }
913
914 // was bin overridden ? if so we need to take action
915 sal_uInt16 nNewPaperBin = xPrinter->GetPaperBin();
916 if (nNewPaperBin != nPaperBin)
917 {
918 mpImplData->mnFixedPaperBin = nNewPaperBin;
919 bInvalidateCache = true;
920 }
921
922 if (bInvalidateCache)
923 {
924 mpImplData->maPageCache.invalidate();
925 }
926 }
927 else
928 {
929 //restore to whatever it was before we entered this method
930 xPrinter->SetOrientation( eOrientation );
931 if (aPaperSize != aNewPaperSize)
932 xPrinter->SetPaperSizeUser(aPaperSize);
933 }
934 xPrinter->Pop();
935}
936
937PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( const css::uno::Sequence< css::beans::PropertyValue >& i_rProps )
938{
940 aPageSize.aSize = mxPrinter->GetPaperSize();
941 css::awt::Size aSetSize, aIsSize;
942 sal_Int32 nPaperBin = mnDefaultPaperBin;
943 for( const auto& rProp : i_rProps )
944 {
945 if ( rProp.Name == "PreferredPageSize" )
946 {
947 rProp.Value >>= aSetSize;
948 }
949 else if ( rProp.Name == "PageSize" )
950 {
951 rProp.Value >>= aIsSize;
952 }
953 else if ( rProp.Name == "PageIncludesNonprintableArea" )
954 {
955 bool bVal = false;
956 rProp.Value >>= bVal;
957 aPageSize.bFullPaper = bVal;
958 }
959 else if ( rProp.Name == "PrinterPaperTray" )
960 {
961 sal_Int32 nBin = -1;
962 rProp.Value >>= nBin;
963 if( nBin >= 0 && o3tl::make_unsigned(nBin) < mxPrinter->GetPaperBinCount() )
964 nPaperBin = nBin;
965 }
966 }
967
968 Size aCurSize( mxPrinter->GetPaperSize() );
969 if( aSetSize.Width && aSetSize.Height )
970 {
971 Size aSetPaperSize( aSetSize.Width, aSetSize.Height );
972 Size aRealPaperSize( getRealPaperSize( aSetPaperSize, true/*bNoNUP*/ ) );
973 if( aRealPaperSize != aCurSize )
974 aIsSize = aSetSize;
975 }
976
977 if( aIsSize.Width && aIsSize.Height )
978 {
979 aPageSize.aSize.setWidth( aIsSize.Width );
980 aPageSize.aSize.setHeight( aIsSize.Height );
981
982 Size aRealPaperSize( getRealPaperSize( aPageSize.aSize, true/*bNoNUP*/ ) );
983 if( aRealPaperSize != aCurSize )
984 mxPrinter->SetPaperSizeUser( aRealPaperSize );
985 }
986
987 // paper bin set from properties in print dialog overrides
988 // application default for a page
989 if ( mnFixedPaperBin != -1 )
990 nPaperBin = mnFixedPaperBin;
991
992 if( nPaperBin != -1 && nPaperBin != mxPrinter->GetPaperBin() )
993 mxPrinter->SetPaperBin( nPaperBin );
994
995 return aPageSize;
996}
997
998//fdo#61886
999
1000//when printing is finished, set the paper size of the printer to either what
1001//the user explicitly set as the desired paper size, or fallback to whatever
1002//the printer had before printing started. That way it doesn't contain the last
1003//paper size of a multiple paper size using document when we are in our normal
1004//auto accept document paper size mode and end up overwriting the original
1005//paper size setting for file->printer_settings just by pressing "ok" in the
1006//print dialog
1008{
1009 mxPrinter->Push();
1010 mxPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
1011 Size aCurSize(mxPrinter->GetPaperSize());
1012 if (aCurSize != maDefaultPageSize)
1013 mxPrinter->SetPaperSizeUser(maDefaultPageSize);
1014 mxPrinter->Pop();
1015}
1016
1018{
1019 const MapMode aMapMode( MapUnit::Map100thMM );
1020
1021 mpImplData->mxPrinter->Push();
1022 mpImplData->mxPrinter->SetMapMode( aMapMode );
1023 int nPages = getPageCount();
1024 mpImplData->mxPrinter->Pop();
1025 return nPages;
1026}
1027
1028css::uno::Sequence< css::beans::PropertyValue > PrinterController::getPageParametersProtected( int i_nPage ) const
1029{
1030 const MapMode aMapMode( MapUnit::Map100thMM );
1031
1032 mpImplData->mxPrinter->Push();
1033 mpImplData->mxPrinter->SetMapMode( aMapMode );
1034 css::uno::Sequence< css::beans::PropertyValue > aResult( getPageParameters( i_nPage ) );
1035 mpImplData->mxPrinter->Pop();
1036 return aResult;
1037}
1038
1039PrinterController::PageSize PrinterController::getPageFile( int i_nUnfilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache )
1040{
1041 // update progress if necessary
1042 if( mpImplData->mxProgress )
1043 {
1044 // do nothing if printing is canceled
1045 if( mpImplData->mxProgress->isCanceled() )
1047 mpImplData->mxProgress->tick();
1049 }
1050
1051 if( i_bMayUseCache )
1052 {
1054 if( mpImplData->maPageCache.get( i_nUnfilteredPage, o_rMtf, aPageSize ) )
1055 {
1056 return aPageSize;
1057 }
1058 }
1059 else
1060 mpImplData->maPageCache.invalidate();
1061
1062 o_rMtf.Clear();
1063
1064 // get page parameters
1065 css::uno::Sequence< css::beans::PropertyValue > aPageParm( getPageParametersProtected( i_nUnfilteredPage ) );
1066 const MapMode aMapMode( MapUnit::Map100thMM );
1067
1068 mpImplData->mxPrinter->Push();
1069 mpImplData->mxPrinter->SetMapMode( aMapMode );
1070
1071 // modify job setup if necessary
1072 PrinterController::PageSize aPageSize = mpImplData->modifyJobSetup( aPageParm );
1073
1074 o_rMtf.SetPrefSize( aPageSize.aSize );
1075 o_rMtf.SetPrefMapMode( aMapMode );
1076
1077 mpImplData->mxPrinter->EnableOutput( false );
1078
1079 o_rMtf.Record( mpImplData->mxPrinter.get() );
1080
1081 printPage( i_nUnfilteredPage );
1082
1083 o_rMtf.Stop();
1084 o_rMtf.WindStart();
1085 mpImplData->mxPrinter->Pop();
1086
1087 if( i_bMayUseCache )
1088 mpImplData->maPageCache.insert( i_nUnfilteredPage, o_rMtf, aPageSize );
1089
1090 // reset "FirstPage" property to false now we've gotten at least our first one
1091 mpImplData->mbFirstPage = false;
1092
1093 return aPageSize;
1094}
1095
1096static void appendSubPage( GDIMetaFile& o_rMtf, const tools::Rectangle& i_rClipRect, GDIMetaFile& io_rSubPage, bool i_bDrawBorder )
1097{
1098 // intersect all clipregion actions with our clip rect
1099 io_rSubPage.WindStart();
1100 io_rSubPage.Clip( i_rClipRect );
1101
1102 // save gstate
1103 o_rMtf.AddAction( new MetaPushAction( PushFlags::ALL ) );
1104
1105 // clip to page rect
1106 o_rMtf.AddAction( new MetaClipRegionAction( vcl::Region( i_rClipRect ), true ) );
1107
1108 // append the subpage
1109 io_rSubPage.WindStart();
1110 io_rSubPage.Play( o_rMtf );
1111
1112 // restore gstate
1113 o_rMtf.AddAction( new MetaPopAction() );
1114
1115 // draw a border
1116 if( !i_bDrawBorder )
1117 return;
1118
1119 // save gstate
1121 o_rMtf.AddAction( new MetaMapModeAction( MapMode( MapUnit::Map100thMM ) ) );
1122
1123 tools::Rectangle aBorderRect( i_rClipRect );
1124 o_rMtf.AddAction( new MetaLineColorAction( COL_BLACK, true ) );
1125 o_rMtf.AddAction( new MetaFillColorAction( COL_TRANSPARENT, false ) );
1126 o_rMtf.AddAction( new MetaRectAction( aBorderRect ) );
1127
1128 // restore gstate
1129 o_rMtf.AddAction( new MetaPopAction() );
1130}
1131
1132PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache )
1133{
1134 const MultiPageSetup& rMPS( mpImplData->maMultiPage );
1135 int nSubPages = rMPS.nRows * rMPS.nColumns;
1136 if( nSubPages < 1 )
1137 nSubPages = 1;
1138
1139 // reverse sheet order
1140 if( mpImplData->mbReversePageOrder )
1141 {
1142 int nDocPages = getFilteredPageCount();
1143 i_nFilteredPage = nDocPages - 1 - i_nFilteredPage;
1144 }
1145
1146 // there is no filtering to be done (and possibly the page size of the
1147 // original page is to be set), when N-Up is "neutral" that is there is
1148 // only one subpage and the margins are 0
1149 if( nSubPages == 1 &&
1150 rMPS.nLeftMargin == 0 && rMPS.nRightMargin == 0 &&
1151 rMPS.nTopMargin == 0 && rMPS.nBottomMargin == 0 )
1152 {
1153 PrinterController::PageSize aPageSize = getPageFile( i_nFilteredPage, o_rMtf, i_bMayUseCache );
1154 if (mpImplData->meJobState != css::view::PrintableState_JOB_STARTED)
1155 { // rhbz#657394: check that we are still printing...
1157 }
1158 Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize, true );
1159 mpImplData->mxPrinter->SetMapMode( MapMode( MapUnit::Map100thMM ) );
1160 mpImplData->mxPrinter->SetPaperSizeUser( aPaperSize );
1161 if( aPaperSize != aPageSize.aSize )
1162 {
1163 // user overridden page size, center Metafile
1164 o_rMtf.WindStart();
1165 tools::Long nDX = (aPaperSize.Width() - aPageSize.aSize.Width()) / 2;
1166 tools::Long nDY = (aPaperSize.Height() - aPageSize.aSize.Height()) / 2;
1167 o_rMtf.Move( nDX, nDY, mpImplData->mxPrinter->GetDPIX(), mpImplData->mxPrinter->GetDPIY() );
1168 o_rMtf.WindStart();
1169 o_rMtf.SetPrefSize( aPaperSize );
1170 aPageSize.aSize = aPaperSize;
1171 }
1172 return aPageSize;
1173 }
1174
1175 // set last page property really only on the very last page to be rendered
1176 // that is on the last subpage of a NUp run
1177 bool bIsLastPage = mpImplData->mbLastPage;
1178 mpImplData->mbLastPage = false;
1179
1180 Size aPaperSize( mpImplData->getRealPaperSize( mpImplData->maMultiPage.aPaperSize, false ) );
1181
1182 // multi page area: page size minus margins + one time spacing right and down
1183 // the added spacing is so each subpage can be calculated including its spacing
1184 Size aMPArea( aPaperSize );
1185 aMPArea.AdjustWidth( -(rMPS.nLeftMargin + rMPS.nRightMargin) );
1186 aMPArea.AdjustWidth(rMPS.nHorizontalSpacing );
1187 aMPArea.AdjustHeight( -(rMPS.nTopMargin + rMPS.nBottomMargin) );
1188 aMPArea.AdjustHeight(rMPS.nVerticalSpacing );
1189
1190 // determine offsets
1191 tools::Long nAdvX = aMPArea.Width() / rMPS.nColumns;
1192 tools::Long nAdvY = aMPArea.Height() / rMPS.nRows;
1193
1194 // determine size of a "cell" subpage, leave a little space around pages
1195 Size aSubPageSize( nAdvX - rMPS.nHorizontalSpacing, nAdvY - rMPS.nVerticalSpacing );
1196
1197 o_rMtf.Clear();
1198 o_rMtf.SetPrefSize( aPaperSize );
1199 o_rMtf.SetPrefMapMode( MapMode( MapUnit::Map100thMM ) );
1200 o_rMtf.AddAction( new MetaMapModeAction( MapMode( MapUnit::Map100thMM ) ) );
1201
1202 int nDocPages = getPageCountProtected();
1203 if (mpImplData->meJobState != css::view::PrintableState_JOB_STARTED)
1204 { // rhbz#657394: check that we are still printing...
1206 }
1207 for( int nSubPage = 0; nSubPage < nSubPages; nSubPage++ )
1208 {
1209 // map current sub page to real page
1210 int nPage = i_nFilteredPage * nSubPages + nSubPage;
1211 if( nSubPage == nSubPages-1 ||
1212 nPage == nDocPages-1 )
1213 {
1214 mpImplData->mbLastPage = bIsLastPage;
1215 }
1216 if( nPage >= 0 && nPage < nDocPages )
1217 {
1218 GDIMetaFile aPageFile;
1219 PrinterController::PageSize aPageSize = getPageFile( nPage, aPageFile, i_bMayUseCache );
1220 if( aPageSize.aSize.Width() && aPageSize.aSize.Height() )
1221 {
1222 tools::Long nCellX = 0, nCellY = 0;
1223 switch( rMPS.nOrder )
1224 {
1225 case NupOrderType::LRTB:
1226 nCellX = (nSubPage % rMPS.nColumns);
1227 nCellY = (nSubPage / rMPS.nColumns);
1228 break;
1229 case NupOrderType::TBLR:
1230 nCellX = (nSubPage / rMPS.nRows);
1231 nCellY = (nSubPage % rMPS.nRows);
1232 break;
1233 case NupOrderType::RLTB:
1234 nCellX = rMPS.nColumns - 1 - (nSubPage % rMPS.nColumns);
1235 nCellY = (nSubPage / rMPS.nColumns);
1236 break;
1237 case NupOrderType::TBRL:
1238 nCellX = rMPS.nColumns - 1 - (nSubPage / rMPS.nRows);
1239 nCellY = (nSubPage % rMPS.nRows);
1240 break;
1241 }
1242 // scale the metafile down to a sub page size
1243 double fScaleX = double(aSubPageSize.Width())/double(aPageSize.aSize.Width());
1244 double fScaleY = double(aSubPageSize.Height())/double(aPageSize.aSize.Height());
1245 double fScale = std::min( fScaleX, fScaleY );
1246 aPageFile.Scale( fScale, fScale );
1247 aPageFile.WindStart();
1248
1249 // move the subpage so it is centered in its "cell"
1250 tools::Long nOffX = (aSubPageSize.Width() - tools::Long(double(aPageSize.aSize.Width()) * fScale)) / 2;
1251 tools::Long nOffY = (aSubPageSize.Height() - tools::Long(double(aPageSize.aSize.Height()) * fScale)) / 2;
1252 tools::Long nX = rMPS.nLeftMargin + nOffX + nAdvX * nCellX;
1253 tools::Long nY = rMPS.nTopMargin + nOffY + nAdvY * nCellY;
1254 aPageFile.Move( nX, nY, mpImplData->mxPrinter->GetDPIX(), mpImplData->mxPrinter->GetDPIY() );
1255 aPageFile.WindStart();
1256 // calculate border rectangle
1257 tools::Rectangle aSubPageRect( Point( nX, nY ),
1258 Size( tools::Long(double(aPageSize.aSize.Width())*fScale),
1259 tools::Long(double(aPageSize.aSize.Height())*fScale) ) );
1260
1261 // append subpage to page
1262 appendSubPage( o_rMtf, aSubPageRect, aPageFile, rMPS.bDrawBorder );
1263 }
1264 }
1265 }
1266 o_rMtf.WindStart();
1267
1268 // subsequent getPageFile calls have changed the paper, reset it to current value
1269 mpImplData->mxPrinter->SetMapMode( MapMode( MapUnit::Map100thMM ) );
1270 mpImplData->mxPrinter->SetPaperSizeUser( aPaperSize );
1271
1272 return PrinterController::PageSize( aPaperSize, true );
1273}
1274
1276{
1277 int nDiv = mpImplData->maMultiPage.nRows * mpImplData->maMultiPage.nColumns;
1278 if( nDiv < 1 )
1279 nDiv = 1;
1280 return (getPageCountProtected() + (nDiv-1)) / nDiv;
1281}
1282
1284{
1285 DrawModeFlags nRestoreDrawMode = mpImplData->mxPrinter->GetDrawMode();
1286 sal_Int32 nMaxBmpDPIX = mpImplData->mxPrinter->GetDPIX();
1287 sal_Int32 nMaxBmpDPIY = mpImplData->mxPrinter->GetDPIY();
1288
1289 const vcl::printer::Options& rPrinterOptions = mpImplData->mxPrinter->GetPrinterOptions();
1290
1291 static const sal_Int32 OPTIMAL_BMP_RESOLUTION = 300;
1292 static const sal_Int32 NORMAL_BMP_RESOLUTION = 200;
1293
1294 if( rPrinterOptions.IsReduceBitmaps() )
1295 {
1296 // calculate maximum resolution for bitmap graphics
1297 if( printer::BitmapMode::Optimal == rPrinterOptions.GetReducedBitmapMode() )
1298 {
1299 nMaxBmpDPIX = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIX );
1300 nMaxBmpDPIY = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIY );
1301 }
1302 else if( printer::BitmapMode::Normal == rPrinterOptions.GetReducedBitmapMode() )
1303 {
1304 nMaxBmpDPIX = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIX );
1305 nMaxBmpDPIY = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIY );
1306 }
1307 else
1308 {
1309 nMaxBmpDPIX = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIX );
1310 nMaxBmpDPIY = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIY );
1311 }
1312 }
1313
1314 // convert to greyscales
1315 if( rPrinterOptions.IsConvertToGreyscales() )
1316 {
1317 mpImplData->mxPrinter->SetDrawMode( mpImplData->mxPrinter->GetDrawMode() |
1320 }
1321
1322 // disable transparency output
1323 if( rPrinterOptions.IsReduceTransparency() && ( vcl::printer::TransparencyMode::NONE == rPrinterOptions.GetReducedTransparencyMode() ) )
1324 {
1325 mpImplData->mxPrinter->SetDrawMode( mpImplData->mxPrinter->GetDrawMode() | DrawModeFlags::NoTransparency );
1326 }
1327
1328 Color aBg( COL_TRANSPARENT ); // default: let RemoveTransparenciesFromMetaFile do its own background logic
1329 if( mpImplData->maMultiPage.nRows * mpImplData->maMultiPage.nColumns > 1 )
1330 {
1331 // in N-Up printing we have no "page" background operation
1332 // we also have no way to determine the paper color
1333 // so let's go for white, which will kill 99.9% of the real cases
1334 aBg = COL_WHITE;
1335 }
1336 mpImplData->mxPrinter->RemoveTransparenciesFromMetaFile( i_rIn, o_rOut, nMaxBmpDPIX, nMaxBmpDPIY,
1337 rPrinterOptions.IsReduceTransparency(),
1338 rPrinterOptions.GetReducedTransparencyMode() == vcl::printer::TransparencyMode::Auto,
1339 rPrinterOptions.IsReduceBitmaps() && rPrinterOptions.IsReducedBitmapIncludesTransparency(),
1340 aBg
1341 );
1342 return nRestoreDrawMode;
1343}
1344
1346{
1347 if( mpImplData->meJobState != css::view::PrintableState_JOB_STARTED )
1348 return; // rhbz#657394: check that we are still printing...
1349
1350 GDIMetaFile aPageFile;
1351 PrinterController::PageSize aPageSize = getFilteredPageFile( i_nPage, aPageFile );
1352
1353 if( mpImplData->mxProgress )
1354 {
1355 // do nothing if printing is canceled
1356 if( mpImplData->mxProgress->isCanceled() )
1357 {
1358 setJobState( css::view::PrintableState_JOB_ABORTED );
1359 return;
1360 }
1361 }
1362
1363 // in N-Up printing set the correct page size
1364 mpImplData->mxPrinter->SetMapMode(MapMode(MapUnit::Map100thMM));
1365 // aPageSize was filtered through mpImplData->getRealPaperSize already by getFilteredPageFile()
1366 mpImplData->mxPrinter->SetPaperSizeUser( aPageSize.aSize );
1367 if( mpImplData->mnFixedPaperBin != -1 &&
1368 mpImplData->mxPrinter->GetPaperBin() != mpImplData->mnFixedPaperBin )
1369 {
1370 mpImplData->mxPrinter->SetPaperBin( mpImplData->mnFixedPaperBin );
1371 }
1372
1373 // if full paper is meant to be used, move the output to accommodate for pageoffset
1374 if( aPageSize.bFullPaper )
1375 {
1376 Point aPageOffset( mpImplData->mxPrinter->GetPageOffset() );
1377 aPageFile.WindStart();
1378 aPageFile.Move( -aPageOffset.X(), -aPageOffset.Y(), mpImplData->mxPrinter->GetDPIX(), mpImplData->mxPrinter->GetDPIY() );
1379 }
1380
1381 GDIMetaFile aCleanedFile;
1382 DrawModeFlags nRestoreDrawMode = removeTransparencies( aPageFile, aCleanedFile );
1383
1384 mpImplData->mxPrinter->EnableOutput();
1385
1386 // actually print the page
1387 mpImplData->mxPrinter->ImplStartPage();
1388
1389 mpImplData->mxPrinter->Push();
1390 aCleanedFile.WindStart();
1391 aCleanedFile.Play(*mpImplData->mxPrinter);
1392 mpImplData->mxPrinter->Pop();
1393
1394 mpImplData->mxPrinter->ImplEndPage();
1395
1396 mpImplData->mxPrinter->SetDrawMode( nRestoreDrawMode );
1397}
1398
1400{
1401}
1402
1403void PrinterController::jobFinished( css::view::PrintableState )
1404{
1405}
1406
1408{
1409 setJobState( css::view::PrintableState_JOB_ABORTED );
1410 // applications (well, sw) depend on a page request with "IsLastPage" = true
1411 // to free resources, else they (well, sw) will crash eventually
1412 setLastPage( true );
1413
1414 if (mpImplData->mxProgress)
1415 {
1416 mpImplData->mxProgress->response(RET_CANCEL);
1417 mpImplData->mxProgress.reset();
1418 }
1419
1420 GDIMetaFile aMtf;
1421 getPageFile( 0, aMtf );
1422}
1423
1424void PrinterController::setLastPage( bool i_bLastPage )
1425{
1426 mpImplData->mbLastPage = i_bLastPage;
1427}
1428
1430{
1431 mpImplData->mbReversePageOrder = i_bReverse;
1432}
1433
1434void PrinterController::setPapersizeFromSetup( bool i_bPapersizeFromSetup )
1435{
1436 mpImplData->mbPapersizeFromSetup = i_bPapersizeFromSetup;
1437 mpImplData->mxPrinter->SetPrinterSettingsPreferred( i_bPapersizeFromSetup );
1438 if ( i_bPapersizeFromSetup )
1439 {
1440 mpImplData->mbPapersizeFromUser = false;
1441 mpImplData->mbOrientationFromUser = false;
1442 }
1443}
1444
1446{
1447 return mpImplData->mbPapersizeFromSetup;
1448}
1449
1451{
1452 mpImplData->mbPapersizeFromUser = true;
1453 mpImplData->mbPapersizeFromSetup = false;
1454 mpImplData->mxPrinter->SetPrinterSettingsPreferred( false );
1455
1456 mpImplData->maUserPageSize = i_aUserSize;
1457}
1458
1460{
1461 mpImplData->mbOrientationFromUser = set;
1462 mpImplData->meUserOrientation = eOrientation;
1463}
1464
1465void PrinterController::setPrinterModified( bool i_bPrinterModified )
1466{
1467 mpImplData->mbPrinterModified = i_bPrinterModified;
1468}
1469
1471{
1472 return mpImplData->mbPrinterModified;
1473}
1474
1475css::uno::Sequence< css::beans::PropertyValue > PrinterController::getJobProperties( const css::uno::Sequence< css::beans::PropertyValue >& i_rMergeList ) const
1476{
1477 std::unordered_set< OUString > aMergeSet;
1478 size_t nResultLen = size_t(i_rMergeList.getLength()) + mpImplData->maUIProperties.size() + 3;
1479 for( const auto& rPropVal : i_rMergeList )
1480 aMergeSet.insert( rPropVal.Name );
1481
1482 css::uno::Sequence< css::beans::PropertyValue > aResult( nResultLen );
1483 auto pResult = aResult.getArray();
1484 std::copy(i_rMergeList.begin(), i_rMergeList.end(), pResult);
1485 int nCur = i_rMergeList.getLength();
1486 for(const css::beans::PropertyValue & rPropVal : mpImplData->maUIProperties)
1487 {
1488 if( aMergeSet.find( rPropVal.Name ) == aMergeSet.end() )
1489 pResult[nCur++] = rPropVal;
1490 }
1491 // append IsFirstPage
1492 if( aMergeSet.find( "IsFirstPage" ) == aMergeSet.end() )
1493 {
1494 css::beans::PropertyValue aVal;
1495 aVal.Name = "IsFirstPage";
1496 aVal.Value <<= mpImplData->mbFirstPage;
1497 pResult[nCur++] = aVal;
1498 }
1499 // append IsLastPage
1500 if( aMergeSet.find( "IsLastPage" ) == aMergeSet.end() )
1501 {
1502 css::beans::PropertyValue aVal;
1503 aVal.Name = "IsLastPage";
1504 aVal.Value <<= mpImplData->mbLastPage;
1505 pResult[nCur++] = aVal;
1506 }
1507 // append IsPrinter
1508 if( aMergeSet.find( "IsPrinter" ) == aMergeSet.end() )
1509 {
1510 css::beans::PropertyValue aVal;
1511 aVal.Name = "IsPrinter";
1512 aVal.Value <<= true;
1513 pResult[nCur++] = aVal;
1514 }
1515 aResult.realloc( nCur );
1516 return aResult;
1517}
1518
1519const css::uno::Sequence< css::beans::PropertyValue >& PrinterController::getUIOptions() const
1520{
1521 return mpImplData->maUIOptions;
1522}
1523
1524css::beans::PropertyValue* PrinterController::getValue( const OUString& i_rProperty )
1525{
1526 std::unordered_map< OUString, size_t >::const_iterator it =
1527 mpImplData->maPropertyToIndex.find( i_rProperty );
1528 return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : nullptr;
1529}
1530
1531const css::beans::PropertyValue* PrinterController::getValue( const OUString& i_rProperty ) const
1532{
1533 std::unordered_map< OUString, size_t >::const_iterator it =
1534 mpImplData->maPropertyToIndex.find( i_rProperty );
1535 return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : nullptr;
1536}
1537
1538void PrinterController::setValue( const OUString& i_rPropertyName, const css::uno::Any& i_rValue )
1539{
1540 css::beans::PropertyValue aVal;
1541 aVal.Name = i_rPropertyName;
1542 aVal.Value = i_rValue;
1543
1544 setValue( aVal );
1545}
1546
1547void PrinterController::setValue( const css::beans::PropertyValue& i_rPropertyValue )
1548{
1549 std::unordered_map< OUString, size_t >::const_iterator it =
1550 mpImplData->maPropertyToIndex.find( i_rPropertyValue.Name );
1551 if( it != mpImplData->maPropertyToIndex.end() )
1552 mpImplData->maUIProperties[ it->second ] = i_rPropertyValue;
1553 else
1554 {
1555 // insert correct index into property map
1556 mpImplData->maPropertyToIndex[ i_rPropertyValue.Name ] = mpImplData->maUIProperties.size();
1557 mpImplData->maUIProperties.push_back( i_rPropertyValue );
1558 mpImplData->maUIPropertyEnabled.push_back( true );
1559 }
1560}
1561
1562void PrinterController::setUIOptions( const css::uno::Sequence< css::beans::PropertyValue >& i_rOptions )
1563{
1564 SAL_WARN_IF( mpImplData->maUIOptions.hasElements(), "vcl.gdi", "setUIOptions called twice !" );
1565
1566 mpImplData->maUIOptions = i_rOptions;
1567
1568 for( const auto& rOpt : i_rOptions )
1569 {
1570 css::uno::Sequence< css::beans::PropertyValue > aOptProp;
1571 rOpt.Value >>= aOptProp;
1572 bool bIsEnabled = true;
1573 bool bHaveProperty = false;
1574 OUString aPropName;
1576 css::uno::Sequence< sal_Bool > aChoicesDisabled;
1577 for( const css::beans::PropertyValue& rEntry : std::as_const(aOptProp) )
1578 {
1579 if ( rEntry.Name == "Property" )
1580 {
1581 css::beans::PropertyValue aVal;
1582 rEntry.Value >>= aVal;
1583 DBG_ASSERT( mpImplData->maPropertyToIndex.find( aVal.Name )
1584 == mpImplData->maPropertyToIndex.end(), "duplicate property entry" );
1585 setValue( aVal );
1586 aPropName = aVal.Name;
1587 bHaveProperty = true;
1588 }
1589 else if ( rEntry.Name == "Enabled" )
1590 {
1591 bool bValue = true;
1592 rEntry.Value >>= bValue;
1593 bIsEnabled = bValue;
1594 }
1595 else if ( rEntry.Name == "DependsOnName" )
1596 {
1597 rEntry.Value >>= aDep.maDependsOnName;
1598 }
1599 else if ( rEntry.Name == "DependsOnEntry" )
1600 {
1601 rEntry.Value >>= aDep.mnDependsOnEntry;
1602 }
1603 else if ( rEntry.Name == "ChoicesDisabled" )
1604 {
1605 rEntry.Value >>= aChoicesDisabled;
1606 }
1607 }
1608 if( bHaveProperty )
1609 {
1610 vcl::ImplPrinterControllerData::PropertyToIndexMap::const_iterator it =
1611 mpImplData->maPropertyToIndex.find( aPropName );
1612 // sanity check
1613 if( it != mpImplData->maPropertyToIndex.end() )
1614 {
1615 mpImplData->maUIPropertyEnabled[ it->second ] = bIsEnabled;
1616 }
1617 if( !aDep.maDependsOnName.isEmpty() )
1618 mpImplData->maControlDependencies[ aPropName ] = aDep;
1619 if( aChoicesDisabled.hasElements() )
1620 mpImplData->maChoiceDisableMap[ aPropName ] = aChoicesDisabled;
1621 }
1622 }
1623}
1624
1625bool PrinterController::isUIOptionEnabled( const OUString& i_rProperty ) const
1626{
1627 bool bEnabled = false;
1628 std::unordered_map< OUString, size_t >::const_iterator prop_it =
1629 mpImplData->maPropertyToIndex.find( i_rProperty );
1630 if( prop_it != mpImplData->maPropertyToIndex.end() )
1631 {
1632 bEnabled = mpImplData->maUIPropertyEnabled[prop_it->second];
1633
1634 if( bEnabled )
1635 {
1636 // check control dependencies
1637 vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
1638 mpImplData->maControlDependencies.find( i_rProperty );
1639 if( it != mpImplData->maControlDependencies.end() )
1640 {
1641 // check if the dependency is enabled
1642 // if the dependency is disabled, we are too
1643 bEnabled = isUIOptionEnabled( it->second.maDependsOnName );
1644
1645 if( bEnabled )
1646 {
1647 // does the dependency have the correct value ?
1648 const css::beans::PropertyValue* pVal = getValue( it->second.maDependsOnName );
1649 OSL_ENSURE( pVal, "unknown property in dependency" );
1650 if( pVal )
1651 {
1652 sal_Int32 nDepVal = 0;
1653 bool bDepVal = false;
1654 if( pVal->Value >>= nDepVal )
1655 {
1656 bEnabled = (nDepVal == it->second.mnDependsOnEntry) || (it->second.mnDependsOnEntry == -1);
1657 }
1658 else if( pVal->Value >>= bDepVal )
1659 {
1660 // could be a dependency on a checked boolean
1661 // in this case the dependency is on a non zero for checked value
1662 bEnabled = ( bDepVal && it->second.mnDependsOnEntry != 0) ||
1663 ( ! bDepVal && it->second.mnDependsOnEntry == 0);
1664 }
1665 else
1666 {
1667 // if the type does not match something is awry
1668 OSL_FAIL( "strange type in control dependency" );
1669 bEnabled = false;
1670 }
1671 }
1672 }
1673 }
1674 }
1675 }
1676 return bEnabled;
1677}
1678
1679bool PrinterController::isUIChoiceEnabled( const OUString& i_rProperty, sal_Int32 i_nValue ) const
1680{
1681 bool bEnabled = true;
1682 ImplPrinterControllerData::ChoiceDisableMap::const_iterator it =
1683 mpImplData->maChoiceDisableMap.find( i_rProperty );
1684 if(it != mpImplData->maChoiceDisableMap.end() )
1685 {
1686 const css::uno::Sequence< sal_Bool >& rDisabled( it->second );
1687 if( i_nValue >= 0 && i_nValue < rDisabled.getLength() )
1688 bEnabled = ! rDisabled[i_nValue];
1689 }
1690 return bEnabled;
1691}
1692
1693OUString PrinterController::makeEnabled( const OUString& i_rProperty )
1694{
1695 OUString aDependency;
1696
1697 vcl::ImplPrinterControllerData::ControlDependencyMap::const_iterator it =
1698 mpImplData->maControlDependencies.find( i_rProperty );
1699 if( it != mpImplData->maControlDependencies.end() )
1700 {
1701 if( isUIOptionEnabled( it->second.maDependsOnName ) )
1702 {
1703 aDependency = it->second.maDependsOnName;
1704 const css::beans::PropertyValue* pVal = getValue( aDependency );
1705 OSL_ENSURE( pVal, "unknown property in dependency" );
1706 if( pVal )
1707 {
1708 sal_Int32 nDepVal = 0;
1709 bool bDepVal = false;
1710 if( pVal->Value >>= nDepVal )
1711 {
1712 if( it->second.mnDependsOnEntry != -1 )
1713 {
1714 setValue( aDependency, css::uno::Any( sal_Int32( it->second.mnDependsOnEntry ) ) );
1715 }
1716 }
1717 else if( pVal->Value >>= bDepVal )
1718 {
1719 setValue( aDependency, css::uno::Any( it->second.mnDependsOnEntry != 0 ) );
1720 }
1721 else
1722 {
1723 // if the type does not match something is awry
1724 OSL_FAIL( "strange type in control dependency" );
1725 }
1726 }
1727 }
1728 }
1729
1730 return aDependency;
1731}
1732
1734{
1735 if (!mpImplData->mxProgress)
1736 {
1737 bool bShow = true;
1738 css::beans::PropertyValue* pMonitor = getValue( "MonitorVisible" );
1739 if( pMonitor )
1740 pMonitor->Value >>= bShow;
1741 else
1742 {
1743 const css::beans::PropertyValue* pVal = getValue( "IsApi" );
1744 if( pVal )
1745 {
1746 bool bApi = false;
1747 pVal->Value >>= bApi;
1748 bShow = ! bApi;
1749 }
1750 }
1751
1752 if( bShow && ! Application::IsHeadlessModeEnabled() )
1753 {
1754 mpImplData->mxProgress = std::make_shared<PrintProgressDialog>(getWindow(), getPageCountProtected());
1755 weld::DialogController::runAsync(mpImplData->mxProgress, [](sal_Int32 /*nResult*/){});
1756 }
1757 }
1758 else
1759 {
1760 mpImplData->mxProgress->response(RET_CANCEL);
1761 mpImplData->mxProgress.reset();
1762 }
1763}
1764
1766{
1767 return mpImplData->mxProgress && mpImplData->mxProgress->isCanceled();
1768}
1769
1771{
1772 mpImplData->maMultiPage = i_rMPS;
1773}
1774
1776{
1777 return mpImplData->maMultiPage;
1778}
1779
1781{
1782 mpImplData->resetPaperToLastConfigured();
1783}
1784
1786{
1787 sal_Int32 nCopyCount = 1;
1788 // set copycount and collate
1789 const css::beans::PropertyValue* pVal = getValue( "CopyCount" );
1790 if( pVal )
1791 pVal->Value >>= nCopyCount;
1792 bool bCollate = false;
1793 pVal = getValue( "Collate" );
1794 if( pVal )
1795 pVal->Value >>= bCollate;
1796 mpImplData->mxPrinter->SetCopyCount( static_cast<sal_uInt16>(nCopyCount), bCollate );
1797
1798 pVal = getValue("SinglePrintJobs");
1799 bool bSinglePrintJobs = false;
1800 if (pVal)
1801 pVal->Value >>= bSinglePrintJobs;
1802 mpImplData->mxPrinter->SetSinglePrintJobs(bSinglePrintJobs);
1803
1804 // duplex mode
1805 pVal = getValue( "DuplexMode" );
1806 if( pVal )
1807 {
1808 sal_Int16 nDuplex = css::view::DuplexMode::UNKNOWN;
1809 pVal->Value >>= nDuplex;
1810 switch( nDuplex )
1811 {
1812 case css::view::DuplexMode::OFF: mpImplData->mxPrinter->SetDuplexMode( DuplexMode::Off ); break;
1813 case css::view::DuplexMode::LONGEDGE: mpImplData->mxPrinter->SetDuplexMode( DuplexMode::LongEdge ); break;
1814 case css::view::DuplexMode::SHORTEDGE: mpImplData->mxPrinter->SetDuplexMode( DuplexMode::ShortEdge ); break;
1815 }
1816 }
1817}
1818
1820{
1821 bool bApi = getBoolProperty( "IsApi", false );
1822 return ! bApi && ! Application::IsHeadlessModeEnabled();
1823}
1824
1826{
1827 bool bDirect = getBoolProperty( "IsDirect", false );
1828 return bDirect;
1829}
1830
1831bool PrinterController::getBoolProperty( const OUString& i_rProperty, bool i_bFallback ) const
1832{
1833 bool bRet = i_bFallback;
1834 const css::beans::PropertyValue* pVal = getValue( i_rProperty );
1835 if( pVal )
1836 pVal->Value >>= bRet;
1837 return bRet;
1838}
1839
1840sal_Int32 PrinterController::getIntProperty( const OUString& i_rProperty, sal_Int32 i_nFallback ) const
1841{
1842 sal_Int32 nRet = i_nFallback;
1843 const css::beans::PropertyValue* pVal = getValue( i_rProperty );
1844 if( pVal )
1845 pVal->Value >>= nRet;
1846 return nRet;
1847}
1848
1849/*
1850 * PrinterOptionsHelper
1851**/
1852css::uno::Any PrinterOptionsHelper::getValue( const OUString& i_rPropertyName ) const
1853{
1854 css::uno::Any aRet;
1855 std::unordered_map< OUString, css::uno::Any >::const_iterator it =
1856 m_aPropertyMap.find( i_rPropertyName );
1857 if( it != m_aPropertyMap.end() )
1858 aRet = it->second;
1859 return aRet;
1860}
1861
1862bool PrinterOptionsHelper::getBoolValue( const OUString& i_rPropertyName, bool i_bDefault ) const
1863{
1864 bool bRet = false;
1865 css::uno::Any aVal( getValue( i_rPropertyName ) );
1866 return (aVal >>= bRet) ? bRet : i_bDefault;
1867}
1868
1869sal_Int64 PrinterOptionsHelper::getIntValue( const OUString& i_rPropertyName, sal_Int64 i_nDefault ) const
1870{
1871 sal_Int64 nRet = 0;
1872 css::uno::Any aVal( getValue( i_rPropertyName ) );
1873 return (aVal >>= nRet) ? nRet : i_nDefault;
1874}
1875
1876OUString PrinterOptionsHelper::getStringValue( const OUString& i_rPropertyName ) const
1877{
1878 OUString aRet;
1879 css::uno::Any aVal( getValue( i_rPropertyName ) );
1880 return (aVal >>= aRet) ? aRet : OUString();
1881}
1882
1883bool PrinterOptionsHelper::processProperties( const css::uno::Sequence< css::beans::PropertyValue >& i_rNewProp )
1884{
1885 bool bChanged = false;
1886
1887 for( const auto& rVal : i_rNewProp )
1888 {
1889 std::unordered_map< OUString, css::uno::Any >::iterator it =
1890 m_aPropertyMap.find( rVal.Name );
1891
1892 bool bElementChanged = (it == m_aPropertyMap.end()) || (it->second != rVal.Value);
1893 if( bElementChanged )
1894 {
1895 m_aPropertyMap[ rVal.Name ] = rVal.Value;
1896 bChanged = true;
1897 }
1898 }
1899 return bChanged;
1900}
1901
1902void PrinterOptionsHelper::appendPrintUIOptions( css::uno::Sequence< css::beans::PropertyValue >& io_rProps ) const
1903{
1904 if( !m_aUIProperties.empty() )
1905 {
1906 sal_Int32 nIndex = io_rProps.getLength();
1907 io_rProps.realloc( nIndex+1 );
1908 io_rProps.getArray()[ nIndex ] = comphelper::makePropertyValue(
1909 "ExtraPrintUIOptions", comphelper::containerToSequence(m_aUIProperties));
1910 }
1911}
1912
1913css::uno::Any PrinterOptionsHelper::setUIControlOpt(const css::uno::Sequence< OUString >& i_rIDs,
1914 const OUString& i_rTitle,
1915 const css::uno::Sequence< OUString >& i_rHelpIds,
1916 const OUString& i_rType,
1917 const css::beans::PropertyValue* i_pVal,
1918 const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
1919{
1920 sal_Int32 nElements =
1921 2 // ControlType + ID
1922 + (i_rTitle.isEmpty() ? 0 : 1) // Text
1923 + (i_rHelpIds.hasElements() ? 1 : 0) // HelpId
1924 + (i_pVal ? 1 : 0) // Property
1925 + i_rControlOptions.maAddProps.size() // additional props
1926 + (i_rControlOptions.maGroupHint.isEmpty() ? 0 : 1) // grouping
1927 + (i_rControlOptions.mbInternalOnly ? 1 : 0) // internal hint
1928 + (i_rControlOptions.mbEnabled ? 0 : 1) // enabled
1929 ;
1930 if( !i_rControlOptions.maDependsOnName.isEmpty() )
1931 {
1932 nElements += 1;
1933 if( i_rControlOptions.mnDependsOnEntry != -1 )
1934 nElements += 1;
1935 if( i_rControlOptions.mbAttachToDependency )
1936 nElements += 1;
1937 }
1938
1939 css::uno::Sequence< css::beans::PropertyValue > aCtrl( nElements );
1940 auto pCtrl = aCtrl.getArray();
1941 sal_Int32 nUsed = 0;
1942 if( !i_rTitle.isEmpty() )
1943 {
1944 pCtrl[nUsed ].Name = "Text";
1945 pCtrl[nUsed++].Value <<= i_rTitle;
1946 }
1947 if( i_rHelpIds.hasElements() )
1948 {
1949 pCtrl[nUsed ].Name = "HelpId";
1950 pCtrl[nUsed++].Value <<= i_rHelpIds;
1951 }
1952 pCtrl[nUsed ].Name = "ControlType";
1953 pCtrl[nUsed++].Value <<= i_rType;
1954 pCtrl[nUsed ].Name = "ID";
1955 pCtrl[nUsed++].Value <<= i_rIDs;
1956 if( i_pVal )
1957 {
1958 pCtrl[nUsed ].Name = "Property";
1959 pCtrl[nUsed++].Value <<= *i_pVal;
1960 }
1961 if( !i_rControlOptions.maDependsOnName.isEmpty() )
1962 {
1963 pCtrl[nUsed ].Name = "DependsOnName";
1964 pCtrl[nUsed++].Value <<= i_rControlOptions.maDependsOnName;
1965 if( i_rControlOptions.mnDependsOnEntry != -1 )
1966 {
1967 pCtrl[nUsed ].Name = "DependsOnEntry";
1968 pCtrl[nUsed++].Value <<= i_rControlOptions.mnDependsOnEntry;
1969 }
1970 if( i_rControlOptions.mbAttachToDependency )
1971 {
1972 pCtrl[nUsed ].Name = "AttachToDependency";
1973 pCtrl[nUsed++].Value <<= i_rControlOptions.mbAttachToDependency;
1974 }
1975 }
1976 if( !i_rControlOptions.maGroupHint.isEmpty() )
1977 {
1978 pCtrl[nUsed ].Name = "GroupingHint";
1979 pCtrl[nUsed++].Value <<= i_rControlOptions.maGroupHint;
1980 }
1981 if( i_rControlOptions.mbInternalOnly )
1982 {
1983 pCtrl[nUsed ].Name = "InternalUIOnly";
1984 pCtrl[nUsed++].Value <<= true;
1985 }
1986 if( ! i_rControlOptions.mbEnabled )
1987 {
1988 pCtrl[nUsed ].Name = "Enabled";
1989 pCtrl[nUsed++].Value <<= false;
1990 }
1991
1992 sal_Int32 nAddProps = i_rControlOptions.maAddProps.size();
1993 for( sal_Int32 i = 0; i < nAddProps; i++ )
1994 pCtrl[ nUsed++ ] = i_rControlOptions.maAddProps[i];
1995
1996 SAL_WARN_IF( nUsed != nElements, "vcl.gdi", "nUsed != nElements, probable heap corruption" );
1997
1998 return css::uno::Any( aCtrl );
1999}
2000
2001css::uno::Any PrinterOptionsHelper::setGroupControlOpt(const OUString& i_rID,
2002 const OUString& i_rTitle,
2003 const OUString& i_rHelpId)
2004{
2005 css::uno::Sequence< OUString > aHelpId;
2006 if( !i_rHelpId.isEmpty() )
2007 {
2008 aHelpId.realloc( 1 );
2009 *aHelpId.getArray() = i_rHelpId;
2010 }
2011 css::uno::Sequence< OUString > aIds { i_rID };
2012 return setUIControlOpt(aIds, i_rTitle, aHelpId, "Group");
2013}
2014
2015css::uno::Any PrinterOptionsHelper::setSubgroupControlOpt(const OUString& i_rID,
2016 const OUString& i_rTitle,
2017 const OUString& i_rHelpId,
2018 const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
2019{
2020 css::uno::Sequence< OUString > aHelpId;
2021 if( !i_rHelpId.isEmpty() )
2022 {
2023 aHelpId.realloc( 1 );
2024 *aHelpId.getArray() = i_rHelpId;
2025 }
2026 css::uno::Sequence< OUString > aIds { i_rID };
2027 return setUIControlOpt(aIds, i_rTitle, aHelpId, "Subgroup", nullptr, i_rControlOptions);
2028}
2029
2030css::uno::Any PrinterOptionsHelper::setBoolControlOpt(const OUString& i_rID,
2031 const OUString& i_rTitle,
2032 const OUString& i_rHelpId,
2033 const OUString& i_rProperty,
2034 bool i_bValue,
2035 const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
2036{
2037 css::uno::Sequence< OUString > aHelpId;
2038 if( !i_rHelpId.isEmpty() )
2039 {
2040 aHelpId.realloc( 1 );
2041 *aHelpId.getArray() = i_rHelpId;
2042 }
2043 css::beans::PropertyValue aVal;
2044 aVal.Name = i_rProperty;
2045 aVal.Value <<= i_bValue;
2046 css::uno::Sequence< OUString > aIds { i_rID };
2047 return setUIControlOpt(aIds, i_rTitle, aHelpId, "Bool", &aVal, i_rControlOptions);
2048}
2049
2050css::uno::Any PrinterOptionsHelper::setChoiceRadiosControlOpt(const css::uno::Sequence< OUString >& i_rIDs,
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 return setUIControlOpt(i_rIDs, i_rTitle, i_rHelpId, "Radio", &aVal, aOpt);
2074}
2075
2076css::uno::Any PrinterOptionsHelper::setChoiceListControlOpt(const OUString& i_rID,
2077 const OUString& i_rTitle,
2078 const css::uno::Sequence< OUString >& i_rHelpId,
2079 const OUString& i_rProperty,
2080 const css::uno::Sequence< OUString >& i_rChoices,
2081 sal_Int32 i_nValue,
2082 const css::uno::Sequence< sal_Bool >& i_rDisabledChoices,
2083 const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
2084{
2085 UIControlOptions aOpt( i_rControlOptions );
2086 sal_Int32 nUsed = aOpt.maAddProps.size();
2087 aOpt.maAddProps.resize( nUsed + 1 + (i_rDisabledChoices.hasElements() ? 1 : 0) );
2088 aOpt.maAddProps[nUsed].Name = "Choices";
2089 aOpt.maAddProps[nUsed].Value <<= i_rChoices;
2090 if( i_rDisabledChoices.hasElements() )
2091 {
2092 aOpt.maAddProps[nUsed+1].Name = "ChoicesDisabled";
2093 aOpt.maAddProps[nUsed+1].Value <<= i_rDisabledChoices;
2094 }
2095
2096 css::beans::PropertyValue aVal;
2097 aVal.Name = i_rProperty;
2098 aVal.Value <<= i_nValue;
2099 css::uno::Sequence< OUString > aIds { i_rID };
2100 return setUIControlOpt(aIds, i_rTitle, i_rHelpId, "List", &aVal, aOpt);
2101}
2102
2103css::uno::Any PrinterOptionsHelper::setRangeControlOpt(const OUString& i_rID,
2104 const OUString& i_rTitle,
2105 const OUString& i_rHelpId,
2106 const OUString& i_rProperty,
2107 sal_Int32 i_nValue,
2108 sal_Int32 i_nMinValue,
2109 sal_Int32 i_nMaxValue,
2110 const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
2111{
2112 UIControlOptions aOpt( i_rControlOptions );
2113 if( i_nMaxValue >= i_nMinValue )
2114 {
2115 sal_Int32 nUsed = aOpt.maAddProps.size();
2116 aOpt.maAddProps.resize( nUsed + 2 );
2117 aOpt.maAddProps[nUsed ].Name = "MinValue";
2118 aOpt.maAddProps[nUsed++].Value <<= i_nMinValue;
2119 aOpt.maAddProps[nUsed ].Name = "MaxValue";
2120 aOpt.maAddProps[nUsed++].Value <<= i_nMaxValue;
2121 }
2122
2123 css::uno::Sequence< OUString > aHelpId;
2124 if( !i_rHelpId.isEmpty() )
2125 {
2126 aHelpId.realloc( 1 );
2127 *aHelpId.getArray() = i_rHelpId;
2128 }
2129 css::beans::PropertyValue aVal;
2130 aVal.Name = i_rProperty;
2131 aVal.Value <<= i_nValue;
2132 css::uno::Sequence< OUString > aIds { i_rID };
2133 return setUIControlOpt(aIds, i_rTitle, aHelpId, "Range", &aVal, aOpt);
2134}
2135
2136css::uno::Any PrinterOptionsHelper::setEditControlOpt(const OUString& i_rID,
2137 const OUString& i_rTitle,
2138 const OUString& i_rHelpId,
2139 const OUString& i_rProperty,
2140 const OUString& i_rValue,
2141 const PrinterOptionsHelper::UIControlOptions& i_rControlOptions)
2142{
2143 css::uno::Sequence< OUString > aHelpId;
2144 if( !i_rHelpId.isEmpty() )
2145 {
2146 aHelpId.realloc( 1 );
2147 *aHelpId.getArray() = i_rHelpId;
2148 }
2149 css::beans::PropertyValue aVal;
2150 aVal.Name = i_rProperty;
2151 aVal.Value <<= i_rValue;
2152 css::uno::Sequence< OUString > aIds { i_rID };
2153 return setUIControlOpt(aIds, i_rTitle, aHelpId, "Edit", &aVal, i_rControlOptions);
2154}
2155
2156/* 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:1208
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:999
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:363
static bool IsHeadlessModeEnabled()
Determines if headless mode is enabled.
Definition: svapp.cxx:1539
void Move(tools::Long nX, tools::Long nY)
Definition: gdimtf.cxx:653
void WindStart()
Definition: gdimtf.cxx:572
void Scale(double fScaleX, double fScaleY)
Definition: gdimtf.cxx:748
void Stop()
Definition: gdimtf.cxx:559
void Clip(const tools::Rectangle &)
Definition: gdimtf.cxx:761
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:585
void Clear()
Definition: gdimtf.cxx:273
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:325
void SetPrefMapMode(const MapMode &rMapMode)
Definition: gdimtf.hxx:180
void Record(OutputDevice *pOutDev)
Definition: gdimtf.cxx:314
void SetPrefSize(const Size &rSize)
Definition: gdimtf.hxx:177
OUString PathToFileName() const
OUString const & GetPrinterName() const
Definition: jobset.cxx:225
void SetMapMode()
Definition: map.cxx:597
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:32
void Pop()
Definition: stack.cxx:91
constexpr tools::Long Y() const
constexpr tools::Long X() const
static void FinishPrintJob(const std::shared_ptr< vcl::PrinterController > &i_pController)
Definition: print3.cxx:565
bool SetOrientation(Orientation eOrient)
Definition: print.cxx:1110
bool GetPrinterSettingsPreferred() const
Definition: print.cxx:1192
bool Setup(weld::Window *pWindow, PrinterSetupMode eMode=PrinterSetupMode::DocumentGlobal)
Definition: print.cxx:994
sal_uInt32 GetCapabilities(PrinterCapType nType) const
Definition: print.cxx:943
Size GetPaperSize() const
Definition: print.hxx:250
static void updatePrinters()
Checks the printer list and updates it necessary.
Definition: print.cxx:1570
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:571
bool SetPaperSizeUser(const Size &rSize)
Definition: print.cxx:1303
VCL_DLLPRIVATE bool StartJob(const OUString &rJobName, std::shared_ptr< vcl::PrinterController > const &)
Definition: print3.cxx:581
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:1187
Orientation GetOrientation() const
Definition: print.cxx:1146
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:555
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:277
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:937
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:1779
bool isPrintToFile() const
Definition: printdlg.cxx:1769
VCL_DLLPRIVATE css::uno::Sequence< css::beans::PropertyValue > getPageParametersProtected(int i_nPage) const
Definition: print3.cxx:1028
PageSize getFilteredPageFile(int i_nFilteredPage, GDIMetaFile &o_rMtf, bool i_bMayUseCache=false)
Definition: print3.cxx:1132
void setLastPage(bool i_bLastPage)
Definition: print3.cxx:1424
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:1831
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:1538
VCL_DLLPRIVATE const MultiPageSetup & getMultipage() const
Definition: print3.cxx:1775
void printFilteredPage(int i_nPage)
Definition: print3.cxx:1345
void dialogsParentClosing()
Definition: print3.cxx:813
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:1475
std::unique_ptr< ImplPrinterControllerData > mpImplData
Definition: print.hxx:319
VCL_DLLPRIVATE void pushPropertiesToPrinter()
Definition: print3.cxx:1785
void setUIOptions(const css::uno::Sequence< css::beans::PropertyValue > &)
Set possible UI options.
Definition: print3.cxx:1562
VCL_DLLPRIVATE int getPageCountProtected() const
Definition: print3.cxx:1017
const css::uno::Sequence< css::beans::PropertyValue > & getUIOptions() const
Definition: print3.cxx:1519
VCL_DLLPRIVATE DrawModeFlags removeTransparencies(GDIMetaFile const &i_rIn, GDIMetaFile &o_rOut)
Definition: print3.cxx:1283
bool isUIChoiceEnabled(const OUString &rPropName, sal_Int32 nChoice) const
Definition: print3.cxx:1679
VCL_DLLPRIVATE void setupPrinter(weld::Window *i_pDlgParent)
Definition: print3.cxx:867
virtual void jobStarted()
Will be called after a possible dialog has been shown and the real printjob starts.
Definition: print3.cxx:1399
VCL_DLLPRIVATE void resetPaperToLastConfigured()
Definition: print3.cxx:1780
bool isShowDialogs() const
Definition: print3.cxx:1819
VCL_DLLPRIVATE void setPapersizeFromSetup(bool i_bPapersizeFromSetup)
Definition: print3.cxx:1434
int getFilteredPageCount() const
Definition: print3.cxx:1275
weld::Window * getWindow() const
Definition: print3.cxx:808
virtual void jobFinished(css::view::PrintableState)
Definition: print3.cxx:1403
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:1693
css::beans::PropertyValue * getValue(const OUString &i_rPropertyName)
Get the PropertyValue of a Property.
Definition: print3.cxx:1524
bool isDirectPrint() const
Definition: print3.cxx:1825
void setPrinterModified(bool i_bPapersizeFromSetup)
Definition: print3.cxx:1465
css::view::PrintableState getJobState() const
Definition: print3.cxx:793
VCL_DLLPRIVATE void setReversePrint(bool i_bReverse)
Definition: print3.cxx:1429
bool isUIOptionEnabled(const OUString &rPropName) const
Enable/disable an option; this can be used to implement dialog logic.
Definition: print3.cxx:1625
virtual void printPage(int i_nPage) const =0
App must override this.
bool getPrinterModified() const
Definition: print3.cxx:1470
bool isProgressCanceled() const
Definition: print3.cxx:1765
sal_Int32 getIntProperty(const OUString &i_rPropertyName, sal_Int32 i_nFallback) const
Get an int property.
Definition: print3.cxx:1840
const VclPtr< Printer > & getPrinter() const
Definition: print3.cxx:803
VCL_DLLPRIVATE void setPaperSizeFromUser(Size i_aUserSize)
Definition: print3.cxx:1450
VCL_DLLPRIVATE void resetPrinterOptions(bool i_bFileOutput)
Definition: print3.cxx:860
VCL_DLLPRIVATE bool getPapersizeFromSetup() const
Definition: print3.cxx:1445
VCL_DLLPRIVATE void setMultipage(const MultiPageSetup &)
Definition: print3.cxx:1770
void setJobState(css::view::PrintableState)
Definition: print3.cxx:798
VCL_DLLPRIVATE PageSize getPageFile(int i_inUnfilteredPage, GDIMetaFile &rMtf, bool i_bMayUseCache=false)
Definition: print3.cxx:1039
virtual ~PrinterController()
Definition: print3.cxx:789
VCL_DLLPRIVATE void setOrientationFromUser(Orientation eOrientation, bool set)
Definition: print3.cxx:1459
VCL_DLLPRIVATE void setPrinter(const VclPtr< Printer > &)
Definition: print3.cxx:824
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:2001
bool getBoolValue(const OUString &i_rPropertyName, bool i_bDefault) const
Definition: print3.cxx:1862
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:2050
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:1913
OUString getStringValue(const OUString &i_rPropertyName) const
Definition: print3.cxx:1876
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:1869
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:2030
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:2015
css::uno::Any getValue(const OUString &i_rPropertyName) const
Definition: print3.cxx:1852
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:2103
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:2076
bool processProperties(const css::uno::Sequence< css::beans::PropertyValue > &i_rNewProp)
Process a new set of properties.
Definition: print3.cxx:1883
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:2136
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:1902
static SettingsConfigItem * get()
void setValue(const OUString &rGroup, const OUString &rKey, const OUString &rValue)
virtual short run()
Definition: weld.hxx:2659
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:1096
Orientation
Definition: prntypes.hxx:31
SalInstance * mpDefInst
Definition: svdata.hxx:389
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:77
OUString VclResId(TranslateId aId)
Definition: svdata.cxx:261
bool bIsEnabled
constexpr auto nCacheSize
@ RET_OK
Definition: vclenum.hxx:206
@ RET_CANCEL
Definition: vclenum.hxx:205