1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39
40 #include "qpagesetupdialog.h"
41
42 #include "qpagesetupdialog_unix_p.h"
43
44 #include <private/qpagesetupdialog_p.h>
45 #include <private/qprintdevice_p.h>
46 #if QT_CONFIG(cups)
47 #include <private/qcups_p.h>
48 #endif
49
50 #include "qpainter.h"
51 #include "qprintdialog.h"
52 #include "qtextcodec.h"
53 #include "qdialogbuttonbox.h"
54 #include <ui_qpagesetupwidget.h>
55
56 #include <QtPrintSupport/qprinter.h>
57
58 #include <qpa/qplatformprintplugin.h>
59 #include <qpa/qplatformprintersupport.h>
60
61 QT_BEGIN_NAMESPACE
62
63 extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits);
64
65 // Disabled until we have support for papersources on unix
66 // #define PSD_ENABLE_PAPERSOURCE
67
68 #ifdef PSD_ENABLE_PAPERSOURCE
69 static const char *paperSourceNames[] = {
70 "Only One",
71 "Lower",
72 "Middle",
73 "Manual",
74 "Envelope",
75 "Envelope manual",
76 "Auto",
77 "Tractor",
78 "Small format",
79 "Large format",
80 "Large capacity",
81 "Cassette",
82 "Form source",
83 0
84 };
85
86 struct PaperSourceNames
87 {
PaperSourceNamesPaperSourceNames88 PaperSourceNames(const char *nam, QPrinter::PaperSource ps)
89 : paperSource(ps), name(nam) {}
90 QPrinter::PaperSource paperSource;
91 const char *name;
92 };
93 #endif
94
95
96 // QPagePreview
97 // - Private widget to display preview of page layout
98 // - Embedded in QPageSetupWidget
99
100 class QPagePreview : public QWidget
101 {
102 public:
QPagePreview(QWidget * parent)103 QPagePreview(QWidget *parent) : QWidget(parent)
104 {
105 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
106 setMinimumSize(50, 50);
107 }
108
setPageLayout(const QPageLayout & layout)109 void setPageLayout(const QPageLayout &layout)
110 {
111 m_pageLayout = layout;
112 update();
113 }
114
setPagePreviewLayout(int columns,int rows)115 void setPagePreviewLayout(int columns, int rows)
116 {
117 m_pagePreviewColumns = columns;
118 m_pagePreviewRows = rows;
119 update();
120 }
121
122 protected:
paintEvent(QPaintEvent *)123 void paintEvent(QPaintEvent *) override
124 {
125 QSize pageSize = m_pageLayout.fullRectPoints().size();
126 QSizeF scaledSize = pageSize.scaled(width() - 10, height() - 10, Qt::KeepAspectRatio);
127 QRect pageRect = QRect(QPoint(0,0), scaledSize.toSize());
128 pageRect.moveCenter(rect().center());
129 qreal width_factor = scaledSize.width() / pageSize.width();
130 qreal height_factor = scaledSize.height() / pageSize.height();
131 QMarginsF margins = m_pageLayout.margins(QPageLayout::Point);
132 int left = qRound(margins.left() * width_factor);
133 int top = qRound(margins.top() * height_factor);
134 int right = qRound(margins.right() * width_factor);
135 int bottom = qRound(margins.bottom() * height_factor);
136 QRect marginRect(pageRect.x() + left, pageRect.y() + top,
137 pageRect.width() - (left + right + 1), pageRect.height() - (top + bottom + 1));
138
139 QPainter p(this);
140 QColor shadow(palette().mid().color());
141 for (int i=1; i<6; ++i) {
142 shadow.setAlpha(180-i*30);
143 QRect offset(pageRect.adjusted(i, i, i, i));
144 p.setPen(shadow);
145 p.drawLine(offset.left(), offset.bottom(), offset.right(), offset.bottom());
146 p.drawLine(offset.right(), offset.top(), offset.right(), offset.bottom()-1);
147 }
148 p.fillRect(pageRect, palette().light());
149
150 if (marginRect.isValid()) {
151 p.setPen(QPen(palette().color(QPalette::Dark), 0, Qt::DotLine));
152 p.drawRect(marginRect);
153
154 marginRect.adjust(2, 2, -1, -1);
155 p.setClipRect(marginRect);
156 QFont font;
157 font.setPointSizeF(font.pointSizeF()*0.25);
158 p.setFont(font);
159 p.setPen(palette().color(QPalette::Dark));
160 QString text(QLatin1String("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."));
161 for (int i=0; i<3; ++i)
162 text += text;
163
164 const int spacing = pageRect.width() * 0.1;
165 const int textWidth = (marginRect.width() - (spacing * (m_pagePreviewColumns-1))) / m_pagePreviewColumns;
166 const int textHeight = (marginRect.height() - (spacing * (m_pagePreviewRows-1))) / m_pagePreviewRows;
167
168 for (int x = 0 ; x < m_pagePreviewColumns; ++x) {
169 for (int y = 0 ; y < m_pagePreviewRows; ++y) {
170 QRect textRect(marginRect.left() + x * (textWidth + spacing),
171 marginRect.top() + y * (textHeight + spacing),
172 textWidth, textHeight);
173 p.drawText(textRect, Qt::TextWordWrap|Qt::AlignVCenter, text);
174 }
175 }
176 }
177 }
178
179 private:
180 // Page Layout
181 QPageLayout m_pageLayout;
182 // Pages Per Sheet / n-up layout
183 int m_pagePreviewColumns, m_pagePreviewRows;
184 };
185
186
187 // QUnixPageSetupDialogPrivate
188 // - Linux / Cups implementation of QPageSetupDialogPrivate
189 // - Embeds QPageSetupWidget
190
191 class QUnixPageSetupDialogPrivate : public QPageSetupDialogPrivate
192 {
193 Q_DECLARE_PUBLIC(QPageSetupDialog)
194
195 public:
196 QUnixPageSetupDialogPrivate(QPrinter *printer);
197 ~QUnixPageSetupDialogPrivate();
198 void init();
199
200 QPageSetupWidget *widget;
201 };
202
QUnixPageSetupDialogPrivate(QPrinter * printer)203 QUnixPageSetupDialogPrivate::QUnixPageSetupDialogPrivate(QPrinter *printer) : QPageSetupDialogPrivate(printer)
204 {
205 }
206
~QUnixPageSetupDialogPrivate()207 QUnixPageSetupDialogPrivate::~QUnixPageSetupDialogPrivate()
208 {
209 }
210
init()211 void QUnixPageSetupDialogPrivate::init()
212 {
213 Q_Q(QPageSetupDialog);
214
215 widget = new QPageSetupWidget(q);
216 widget->setPrinter(printer, nullptr, printer->outputFormat(), printer->printerName());
217
218 QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok
219 | QDialogButtonBox::Cancel,
220 Qt::Horizontal, q);
221 QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(accept()));
222 QObject::connect(buttons, SIGNAL(rejected()), q, SLOT(reject()));
223
224 QVBoxLayout *lay = new QVBoxLayout(q);
225 lay->addWidget(widget);
226 lay->addWidget(buttons);
227 }
228
229 // QPageSetupWidget
230 // - Private widget implementation for Linux / CUPS
231 // - Embeds QPagePreview
232 // - TODO Could be made public as a stand-alone widget?
233
QPageSetupWidget(QWidget * parent)234 QPageSetupWidget::QPageSetupWidget(QWidget *parent)
235 : QWidget(parent),
236 m_pagePreview(nullptr),
237 m_printer(nullptr),
238 m_printDevice(nullptr),
239 #if QT_CONFIG(cups)
240 m_pageSizePpdOption(nullptr),
241 #endif
242 m_outputFormat(QPrinter::PdfFormat),
243 m_units(QPageLayout::Point),
244 m_savedUnits(QPageLayout::Point),
245 m_savedPagesPerSheet(-1),
246 m_savedPagesPerSheetLayout(-1),
247 m_blockSignals(false),
248 m_realCustomPageSizeIndex(-1)
249 {
250 m_ui.setupUi(this);
251
252 if (!QMetaType::hasRegisteredComparators<QPageSize>())
253 QMetaType::registerEqualsComparator<QPageSize>();
254
255 QVBoxLayout *lay = new QVBoxLayout(m_ui.preview);
256 m_pagePreview = new QPagePreview(m_ui.preview);
257 m_pagePreview->setPagePreviewLayout(1, 1);
258
259 lay->addWidget(m_pagePreview);
260
261 setAttribute(Qt::WA_WState_Polished, false);
262
263 #ifdef PSD_ENABLE_PAPERSOURCE
264 for (int i=0; paperSourceNames[i]; ++i)
265 m_ui.paperSource->insertItem(paperSourceNames[i]);
266 #else
267 m_ui.paperSourceLabel->setVisible(false);
268 m_ui.paperSource->setVisible(false);
269 #endif
270
271 m_ui.reverseLandscape->setVisible(false);
272 m_ui.reversePortrait->setVisible(false);
273
274 initUnits();
275 initPagesPerSheet();
276
277 connect(m_ui.unitCombo, QOverload<int>::of(&QComboBox::activated), this, &QPageSetupWidget::unitChanged);
278
279 connect(m_ui.pageSizeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QPageSetupWidget::pageSizeChanged);
280 connect(m_ui.pageWidth, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::pageSizeChanged);
281 connect(m_ui.pageHeight, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::pageSizeChanged);
282
283 connect(m_ui.leftMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::leftMarginChanged);
284 connect(m_ui.topMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::topMarginChanged);
285 connect(m_ui.rightMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::rightMarginChanged);
286 connect(m_ui.bottomMargin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &QPageSetupWidget::bottomMarginChanged);
287
288 connect(m_ui.portrait, &QRadioButton::clicked, this, &QPageSetupWidget::pageOrientationChanged);
289 connect(m_ui.landscape, &QRadioButton::clicked, this, &QPageSetupWidget::pageOrientationChanged);
290
291 connect(m_ui.pagesPerSheetCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QPageSetupWidget::pagesPerSheetChanged);
292 }
293
294 // Init the Units combo box
initUnits()295 void QPageSetupWidget::initUnits()
296 {
297 m_ui.unitCombo->addItem(tr("Millimeters (mm)"), QVariant::fromValue(QPageLayout::Millimeter));
298 m_ui.unitCombo->addItem(tr("Inches (in)"), QVariant::fromValue(QPageLayout::Inch));
299 m_ui.unitCombo->addItem(tr("Points (pt)"), QVariant::fromValue(QPageLayout::Point));
300 m_ui.unitCombo->addItem(tr("Pica (P̸)"), QVariant::fromValue(QPageLayout::Pica));
301 m_ui.unitCombo->addItem(tr("Didot (DD)"), QVariant::fromValue(QPageLayout::Didot));
302 m_ui.unitCombo->addItem(tr("Cicero (CC)"), QVariant::fromValue(QPageLayout::Cicero));
303
304 // Initailly default to locale measurement system, mm if metric, in otherwise
305 m_ui.unitCombo->setCurrentIndex(QLocale().measurementSystem() != QLocale::MetricSystem);
306 }
307
308 // Init the Pages Per Sheet (n-up) combo boxes if using CUPS
initPagesPerSheet()309 void QPageSetupWidget::initPagesPerSheet()
310 {
311 #if QT_CONFIG(cups)
312 m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Left to Right, Top to Bottom"),
313 QVariant::fromValue(QCUPSSupport::LeftToRightTopToBottom));
314 m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Left to Right, Bottom to Top"),
315 QVariant::fromValue(QCUPSSupport::LeftToRightBottomToTop));
316 m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Right to Left, Bottom to Top"),
317 QVariant::fromValue(QCUPSSupport::RightToLeftBottomToTop));
318 m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Right to Left, Top to Bottom"),
319 QVariant::fromValue(QCUPSSupport::RightToLeftTopToBottom));
320 m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Bottom to Top, Left to Right"),
321 QVariant::fromValue(QCUPSSupport::BottomToTopLeftToRight));
322 m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Bottom to Top, Right to Left"),
323 QVariant::fromValue(QCUPSSupport::BottomToTopRightToLeft));
324 m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Top to Bottom, Left to Right"),
325 QVariant::fromValue(QCUPSSupport::TopToBottomLeftToRight));
326 m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Top to Bottom, Right to Left"),
327 QVariant::fromValue(QCUPSSupport::TopToBottomRightToLeft));
328
329 m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("1 (1x1)"),
330 QVariant::fromValue(QCUPSSupport::OnePagePerSheet));
331 m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("2 (2x1)"),
332 QVariant::fromValue(QCUPSSupport::TwoPagesPerSheet));
333 m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("4 (2x2)"),
334 QVariant::fromValue(QCUPSSupport::FourPagesPerSheet));
335 m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("6 (2x3)"),
336 QVariant::fromValue(QCUPSSupport::SixPagesPerSheet));
337 m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("9 (3x3)"),
338 QVariant::fromValue(QCUPSSupport::NinePagesPerSheet));
339 m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("16 (4x4)"),
340 QVariant::fromValue(QCUPSSupport::SixteenPagesPerSheet));
341
342 // Set to QCUPSSupport::OnePagePerSheet
343 m_ui.pagesPerSheetCombo->setCurrentIndex(0);
344 // Set to QCUPSSupport::LeftToRightTopToBottom
345 m_ui.pagesPerSheetLayoutCombo->setCurrentIndex(0);
346 #else
347 // Disable if CUPS wasn't found
348 m_ui.pagesPerSheetButtonGroup->hide();
349 #endif
350 }
351
initPageSizes()352 void QPageSetupWidget::initPageSizes()
353 {
354 m_blockSignals = true;
355
356 m_ui.pageSizeCombo->clear();
357
358 m_realCustomPageSizeIndex = -1;
359
360 if (m_outputFormat == QPrinter::NativeFormat && !m_printerName.isEmpty()) {
361 QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
362 if (ps) {
363 QPrintDevice printDevice = ps->createPrintDevice(m_printerName);
364 const QPageSize defaultSize = printDevice.defaultPageSize();
365 const auto pageSizes = printDevice.supportedPageSizes();
366 for (const QPageSize &pageSize : pageSizes)
367 m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize));
368 if (m_ui.pageSizeCombo->count() > 0) {
369 if (printDevice.supportsCustomPageSizes()) {
370 m_ui.pageSizeCombo->addItem(tr("Custom"));
371 m_realCustomPageSizeIndex = m_ui.pageSizeCombo->count() - 1;
372 }
373 m_blockSignals = false;
374
375 // If the defaultSize is index 0, setCurrentIndex won't emit the currentIndexChanged
376 // signal; workaround the issue by initially setting the currentIndex to -1
377 m_ui.pageSizeCombo->setCurrentIndex(-1);
378 m_ui.pageSizeCombo->setCurrentIndex(m_ui.pageSizeCombo->findData(QVariant::fromValue(defaultSize)));
379 return;
380 }
381 }
382 }
383
384 // If PdfFormat or no available printer page sizes, populate with all page sizes
385 for (int id = 0; id < QPageSize::LastPageSize; ++id) {
386 if (QPageSize::PageSizeId(id) == QPageSize::Custom) {
387 m_ui.pageSizeCombo->addItem(tr("Custom"));
388 m_realCustomPageSizeIndex = m_ui.pageSizeCombo->count() - 1;
389 } else {
390 QPageSize pageSize = QPageSize(QPageSize::PageSizeId(id));
391 m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize));
392 }
393 }
394
395 m_blockSignals = false;
396 }
397
398 // Set the dialog to use the given QPrinter
399 // Usually only called on first creation
setPrinter(QPrinter * printer,QPrintDevice * printDevice,QPrinter::OutputFormat outputFormat,const QString & printerName)400 void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice,
401 QPrinter::OutputFormat outputFormat, const QString &printerName)
402 {
403 m_printer = printer;
404 m_printDevice = printDevice;
405
406 #if QT_CONFIG(cups)
407 // find the PageSize cups option
408 m_pageSizePpdOption = m_printDevice ? QCUPSSupport::findPpdOption("PageSize", m_printDevice) : nullptr;
409 #endif
410
411 // Initialize the layout to the current QPrinter layout
412 m_pageLayout = m_printer->pageLayout();
413
414 // Assume if margins are Points then is by default, so set to locale default units
415 if (m_pageLayout.units() == QPageLayout::Point) {
416 if (QLocale().measurementSystem() == QLocale::MetricSystem)
417 m_pageLayout.setUnits(QPageLayout::Millimeter);
418 else
419 m_pageLayout.setUnits(QPageLayout::Inch);
420 }
421 m_units = m_pageLayout.units();
422 m_pagePreview->setPageLayout(m_pageLayout);
423
424 m_outputFormat = outputFormat;
425 m_printerName = printerName;
426 initPageSizes();
427 updateWidget();
428 updateSavedValues();
429
430 if (m_ui.pageSizeCombo->currentIndex() == -1) {
431 // This can happen in raw printers that since they don't have a default
432 // page size none will get selected so just default to the first size (A4)
433 m_ui.pageSizeCombo->setCurrentIndex(0);
434 }
435 }
436
437 // Update the widget with the current settings
438 // TODO Break up into more intelligent chunks?
updateWidget()439 void QPageSetupWidget::updateWidget()
440 {
441 m_blockSignals = true;
442
443 QString suffix;
444 switch (m_units) {
445 case QPageLayout::Millimeter:
446 //: Unit 'Millimeter'
447 suffix = tr("mm");
448 break;
449 case QPageLayout::Point:
450 //: Unit 'Points'
451 suffix = tr("pt");
452 break;
453 case QPageLayout::Inch:
454 //: Unit 'Inch'
455 suffix = tr("in");
456 break;
457 case QPageLayout::Pica:
458 //: Unit 'Pica'
459 suffix = tr("P̸");
460 break;
461 case QPageLayout::Didot:
462 //: Unit 'Didot'
463 suffix = tr("DD");
464 break;
465 case QPageLayout::Cicero:
466 //: Unit 'Cicero'
467 suffix = tr("CC");
468 break;
469 }
470
471 m_ui.unitCombo->setCurrentIndex(m_ui.unitCombo->findData(QVariant::fromValue(m_units)));
472
473 const bool isCustom = m_ui.pageSizeCombo->currentIndex() == m_realCustomPageSizeIndex && m_realCustomPageSizeIndex != -1;
474 if (!isCustom)
475 m_ui.pageSizeCombo->setCurrentIndex(m_ui.pageSizeCombo->findData(QVariant::fromValue(m_pageLayout.pageSize())));
476
477 QMarginsF min;
478 QMarginsF max;
479
480 if (m_pageLayout.mode() == QPageLayout::FullPageMode) {
481 min = QMarginsF(0.0, 0.0, 0.0, 0.0);
482 max = QMarginsF(9999.9999, 9999.9999, 9999.9999, 9999.9999);
483 } else {
484 min = m_pageLayout.minimumMargins();
485 max = m_pageLayout.maximumMargins();
486 }
487
488 m_ui.leftMargin->setSuffix(suffix);
489 m_ui.leftMargin->setMinimum(min.left());
490 m_ui.leftMargin->setMaximum(max.left());
491 m_ui.leftMargin->setValue(m_pageLayout.margins().left());
492
493 m_ui.rightMargin->setSuffix(suffix);
494 m_ui.rightMargin->setMinimum(min.right());
495 m_ui.rightMargin->setMaximum(max.right());
496 m_ui.rightMargin->setValue(m_pageLayout.margins().right());
497
498 m_ui.topMargin->setSuffix(suffix);
499 m_ui.topMargin->setMinimum(min.top());
500 m_ui.topMargin->setMaximum(max.top());
501 m_ui.topMargin->setValue(m_pageLayout.margins().top());
502
503 m_ui.bottomMargin->setSuffix(suffix);
504 m_ui.bottomMargin->setMinimum(min.bottom());
505 m_ui.bottomMargin->setMaximum(max.bottom());
506 m_ui.bottomMargin->setValue(m_pageLayout.margins().bottom());
507
508 m_ui.pageWidth->setSuffix(suffix);
509 m_ui.pageWidth->setValue(m_pageLayout.fullRect(m_units).width());
510 m_ui.pageWidth->setEnabled(isCustom);
511 m_ui.widthLabel->setEnabled(isCustom);
512
513 m_ui.pageHeight->setSuffix(suffix);
514 m_ui.pageHeight->setValue(m_pageLayout.fullRect(m_units).height());
515 m_ui.pageHeight->setEnabled(isCustom);
516 m_ui.heightLabel->setEnabled(isCustom);
517
518 m_ui.portrait->setChecked(m_pageLayout.orientation() == QPageLayout::Portrait);
519 m_ui.landscape->setChecked(m_pageLayout.orientation() == QPageLayout::Landscape);
520
521 m_ui.pagesPerSheetButtonGroup->setEnabled(m_outputFormat == QPrinter::NativeFormat);
522
523 #ifdef PSD_ENABLE_PAPERSOURCE
524 m_ui.paperSource->setCurrentItem(printer->paperSource());
525 #endif
526
527 m_blockSignals = false;
528 }
529
530 // Set the dialog chosen options on the QPrinter
531 // Normally only called when the QPrintDialog or QPageSetupDialog OK button is pressed
setupPrinter() const532 void QPageSetupWidget::setupPrinter() const
533 {
534 m_printer->setPageLayout(m_pageLayout);
535 #if QT_CONFIG(cups)
536 QCUPSSupport::PagesPerSheet pagesPerSheet = qvariant_cast<QCUPSSupport::PagesPerSheet>(m_ui.pagesPerSheetCombo->currentData()
537 );
538 QCUPSSupport::PagesPerSheetLayout pagesPerSheetLayout = qvariant_cast<QCUPSSupport::PagesPerSheetLayout>(m_ui.pagesPerSheetLayoutCombo->currentData()
539 );
540 QCUPSSupport::setPagesPerSheetLayout(m_printer, pagesPerSheet, pagesPerSheetLayout);
541 #endif
542 #ifdef PSD_ENABLE_PAPERSOURCE
543 m_printer->setPaperSource((QPrinter::PaperSource)m_ui.paperSource->currentIndex());
544 #endif
545 }
546
updateSavedValues()547 void QPageSetupWidget::updateSavedValues()
548 {
549 m_savedUnits = m_units;
550 m_savedPageLayout = m_pageLayout;
551 m_savedPagesPerSheet = m_ui.pagesPerSheetCombo->currentIndex();
552 m_savedPagesPerSheetLayout = m_ui.pagesPerSheetLayoutCombo->currentIndex();
553 }
554
revertToSavedValues()555 void QPageSetupWidget::revertToSavedValues()
556 {
557 m_units = m_savedUnits;
558 m_pageLayout = m_savedPageLayout;
559 m_pagePreview->setPageLayout(m_pageLayout);
560
561 updateWidget();
562
563 m_ui.pagesPerSheetCombo->setCurrentIndex(m_savedPagesPerSheet);
564 m_ui.pagesPerSheetLayoutCombo->setCurrentIndex(m_savedPagesPerSheetLayout);
565 }
566
567 #if QT_CONFIG(cups)
hasPpdConflict() const568 bool QPageSetupWidget::hasPpdConflict() const
569 {
570 if (m_pageSizePpdOption) {
571 if (m_pageSizePpdOption->conflicted) {
572 const QIcon warning = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, nullptr);
573 const int pixmap_size = m_ui.pageSizeCombo->sizeHint().height() * .75;
574 m_ui.pageSizeWarningLabel->setPixmap(warning.pixmap(pixmap_size, pixmap_size));
575 } else {
576 m_ui.pageSizeWarningLabel->setPixmap(QPixmap());
577 }
578 return m_pageSizePpdOption->conflicted;
579 }
580
581 return false;
582 }
583 #endif
584
585 // Updates size/preview after the combobox has been changed.
pageSizeChanged()586 void QPageSetupWidget::pageSizeChanged()
587 {
588 QPageSize pageSize;
589 if (m_ui.pageSizeCombo->currentIndex() != m_realCustomPageSizeIndex) {
590 pageSize = qvariant_cast<QPageSize>(m_ui.pageSizeCombo->currentData());
591
592 #if QT_CONFIG(cups)
593 if (m_pageSizePpdOption) {
594 ppd_file_t *ppd = qvariant_cast<ppd_file_t*>(m_printDevice->property(PDPK_PpdFile));
595 QTextCodec *cupsCodec = QTextCodec::codecForName(ppd->lang_encoding);
596 for (int i = 0; i < m_pageSizePpdOption->num_choices; ++i) {
597 const ppd_choice_t *choice = &m_pageSizePpdOption->choices[i];
598 if (cupsCodec->toUnicode(choice->text) == m_ui.pageSizeCombo->currentText()) {
599 const auto values = QStringList{} << QString::fromLatin1(m_pageSizePpdOption->keyword)
600 << QString::fromLatin1(choice->choice);
601 m_printDevice->setProperty(PDPK_PpdOption, values);
602 emit ppdOptionChanged();
603 break;
604 }
605 }
606 }
607 #endif
608
609 } else {
610 QSizeF customSize;
611 if (m_pageLayout.orientation() == QPageLayout::Landscape)
612 customSize = QSizeF(m_ui.pageHeight->value(), m_ui.pageWidth->value());
613 else
614 customSize = QSizeF(m_ui.pageWidth->value(), m_ui.pageHeight->value());
615 pageSize = QPageSize(customSize, QPageSize::Unit(m_units));
616
617 #if QT_CONFIG(cups)
618 if (m_pageSizePpdOption) {
619 const auto values = QStringList{} << QString::fromLatin1(m_pageSizePpdOption->keyword)
620 << QStringLiteral("Custom");
621 m_printDevice->setProperty(PDPK_PpdOption, values);
622 emit ppdOptionChanged();
623 }
624 #endif
625 }
626
627 // We always need to update the m_pageSizePpdOption when the page size changes
628 // even if it's from inside updateWidget, so do not move up
629 if (m_blockSignals)
630 return;
631
632 const QMarginsF printable = m_printDevice ? m_printDevice->printableMargins(pageSize, m_pageLayout.orientation(), m_printer->resolution())
633 : QMarginsF();
634 m_pageLayout.setPageSize(pageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units()));
635 m_pagePreview->setPageLayout(m_pageLayout);
636
637 updateWidget();
638 }
639
pageOrientationChanged()640 void QPageSetupWidget::pageOrientationChanged()
641 {
642 if (m_blockSignals)
643 return;
644 m_pageLayout.setOrientation(m_ui.portrait->isChecked() ? QPageLayout::Portrait : QPageLayout::Landscape);
645 m_pagePreview->setPageLayout(m_pageLayout);
646 updateWidget();
647 }
648
pagesPerSheetChanged()649 void QPageSetupWidget::pagesPerSheetChanged()
650 {
651 #if QT_CONFIG(cups)
652 switch (m_ui.pagesPerSheetCombo->currentData().toInt()) {
653 case QCUPSSupport::OnePagePerSheet:
654 m_pagePreview->setPagePreviewLayout(1, 1);
655 break;
656 case QCUPSSupport::TwoPagesPerSheet:
657 m_pagePreview->setPagePreviewLayout(1, 2);
658 break;
659 case QCUPSSupport::FourPagesPerSheet:
660 m_pagePreview->setPagePreviewLayout(2, 2);
661 break;
662 case QCUPSSupport::SixPagesPerSheet:
663 m_pagePreview->setPagePreviewLayout(3, 2);
664 break;
665 case QCUPSSupport::NinePagesPerSheet:
666 m_pagePreview->setPagePreviewLayout(3, 3);
667 break;
668 case QCUPSSupport::SixteenPagesPerSheet:
669 m_pagePreview->setPagePreviewLayout(4, 4);
670 break;
671 }
672 #endif
673 }
674
unitChanged()675 void QPageSetupWidget::unitChanged()
676 {
677 if (m_blockSignals)
678 return;
679 m_units = qvariant_cast<QPageLayout::Unit>(m_ui.unitCombo->currentData());
680 m_pageLayout.setUnits(m_units);
681 updateWidget();
682 }
683
topMarginChanged(double newValue)684 void QPageSetupWidget::topMarginChanged(double newValue)
685 {
686 if (m_blockSignals)
687 return;
688 m_pageLayout.setTopMargin(newValue);
689 m_pagePreview->setPageLayout(m_pageLayout);
690 }
691
bottomMarginChanged(double newValue)692 void QPageSetupWidget::bottomMarginChanged(double newValue)
693 {
694 if (m_blockSignals)
695 return;
696 m_pageLayout.setBottomMargin(newValue);
697 m_pagePreview->setPageLayout(m_pageLayout);
698 }
699
leftMarginChanged(double newValue)700 void QPageSetupWidget::leftMarginChanged(double newValue)
701 {
702 if (m_blockSignals)
703 return;
704 m_pageLayout.setLeftMargin(newValue);
705 m_pagePreview->setPageLayout(m_pageLayout);
706 }
707
rightMarginChanged(double newValue)708 void QPageSetupWidget::rightMarginChanged(double newValue)
709 {
710 if (m_blockSignals)
711 return;
712 m_pageLayout.setRightMargin(newValue);
713 m_pagePreview->setPageLayout(m_pageLayout);
714 }
715
716 // QPageSetupDialog
717 // - Public Linux / CUPS class implementation
718
QPageSetupDialog(QPrinter * printer,QWidget * parent)719 QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent)
720 : QDialog(*(new QUnixPageSetupDialogPrivate(printer)), parent)
721 {
722 Q_D(QPageSetupDialog);
723 setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
724 static_cast<QUnixPageSetupDialogPrivate *>(d)->init();
725 }
726
QPageSetupDialog(QWidget * parent)727 QPageSetupDialog::QPageSetupDialog(QWidget *parent)
728 : QDialog(*(new QUnixPageSetupDialogPrivate(nullptr)), parent)
729 {
730 Q_D(QPageSetupDialog);
731 setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
732 static_cast<QUnixPageSetupDialogPrivate *>(d)->init();
733 }
734
exec()735 int QPageSetupDialog::exec()
736 {
737 Q_D(QPageSetupDialog);
738
739 int ret = QDialog::exec();
740 if (ret == Accepted) {
741 static_cast <QUnixPageSetupDialogPrivate*>(d)->widget->setupPrinter();
742 static_cast <QUnixPageSetupDialogPrivate*>(d)->widget->updateSavedValues();
743 } else {
744 static_cast <QUnixPageSetupDialogPrivate*>(d)->widget->revertToSavedValues();
745 }
746 return ret;
747 }
748
749 QT_END_NAMESPACE
750
751 #include "moc_qpagesetupdialog.cpp"
752