Qt 4.8
qprintengine_mac.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <private/qprintengine_mac_p.h>
43 #include <qthread.h>
44 #include <quuid.h>
45 #include <QtCore/qcoreapplication.h>
46 
47 #ifndef QT_NO_PRINTER
48 
50 
52 
54 {
56  d->mode = mode;
57  d->initialize();
58 }
59 
61 {
63 
64  Q_ASSERT(dev && dev->devType() == QInternal::Printer);
65  if (!static_cast<QPrinter *>(dev)->isValid())
66  return false;
67 
68  if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized()) // Need to reinitialize
69  d->initialize();
70 
71  d->paintEngine->state = state;
72  d->paintEngine->begin(dev);
73  Q_ASSERT_X(d->state == QPrinter::Idle, "QMacPrintEngine", "printer already active");
74 
75  if (PMSessionValidatePrintSettings(d->session, d->settings, kPMDontWantBoolean) != noErr
76  || PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean) != noErr) {
77  d->state = QPrinter::Error;
78  return false;
79  }
80 
81  if (!d->outputFilename.isEmpty()) {
82  QCFType<CFURLRef> outFile = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault,
83  QCFString(d->outputFilename),
84  kCFURLPOSIXPathStyle,
85  false);
86  if (PMSessionSetDestination(d->session, d->settings, kPMDestinationFile,
87  kPMDocumentFormatPDF, outFile) != noErr) {
88  qWarning("QMacPrintEngine::begin: Problem setting file [%s]", d->outputFilename.toUtf8().constData());
89  return false;
90  }
91  }
92  OSStatus status = noErr;
93 #ifndef QT_MAC_USE_COCOA
94  status = d->shouldSuppressStatus() ? PMSessionBeginCGDocumentNoDialog(d->session, d->settings, d->format)
95  : PMSessionBeginCGDocument(d->session, d->settings, d->format);
96 #else
97  status = PMSessionBeginCGDocumentNoDialog(d->session, d->settings, d->format);
98 #endif
99 
100  if (status != noErr) {
101  d->state = QPrinter::Error;
102  return false;
103  }
104 
105  d->state = QPrinter::Active;
106  setActive(true);
107  d->newPage_helper();
108  return true;
109 }
110 
112 {
114  if (d->state == QPrinter::Aborted)
115  return true; // I was just here a function call ago :)
116  if(d->paintEngine->type() == QPaintEngine::CoreGraphics) {
117  // We dont need the paint engine to call restoreGraphicsState()
118  static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->stackCount = 0;
119  static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = 0;
120  }
121  d->paintEngine->end();
122  if (d->state != QPrinter::Idle)
123  d->releaseSession();
124  d->state = QPrinter::Idle;
125  return true;
126 }
127 
128 QPaintEngine *
130 {
131  return d_func()->paintEngine;
132 }
133 
135 {
137  return cgEngine->d_func()->hd;
138 }
139 
141 {
142 #ifdef QT_MAC_USE_COCOA
143  [printInfo release];
144 #endif
145  delete paintEngine;
146 }
147 
149 {
151  if (hasCustomPaperSize) {
152  PMRelease(customPaper);
153  customPaper = 0;
154  }
155  hasCustomPaperSize = (ps == QPrinter::Custom);
156  PMPrinter printer;
157 
158  if (PMSessionGetCurrentPrinter(session, &printer) == noErr) {
159  if (ps != QPrinter::Custom) {
160  QSize newSize = qt_paperSizeToQSizeF(ps).toSize();
161  QCFType<CFArrayRef> formats;
162  if (PMSessionCreatePageFormatList(session, printer, &formats) == noErr) {
163  CFIndex total = CFArrayGetCount(formats);
164  PMPageFormat tmp;
165  PMRect paper;
166  for (CFIndex idx = 0; idx < total; ++idx) {
167  tmp = static_cast<PMPageFormat>(const_cast<void *>(CFArrayGetValueAtIndex(formats, idx)));
168  PMGetUnadjustedPaperRect(tmp, &paper);
169  int wMM = int((paper.right - paper.left) / 72 * 25.4 + 0.5);
170  int hMM = int((paper.bottom - paper.top) / 72 * 25.4 + 0.5);
171  if (newSize.width() == wMM && newSize.height() == hMM) {
172  PMCopyPageFormat(tmp, format);
173  // reset the orientation and resolution as they are lost in the copy.
174  q->setProperty(QPrintEngine::PPK_Orientation, orient);
175  if (PMSessionValidatePageFormat(session, format, kPMDontWantBoolean) != noErr) {
176  // Don't know, warn for the moment.
177  qWarning("QMacPrintEngine, problem setting format and resolution for this page size");
178  }
179  break;
180  }
181  }
182  }
183  } else {
185  PMPaperMargins paperMargins;
186  paperMargins.left = leftMargin;
187  paperMargins.top = topMargin;
188  paperMargins.right = rightMargin;
189  paperMargins.bottom = bottomMargin;
190  PMPaperCreateCustom(printer, paperId, QCFString("Custom size"), customSize.width(), customSize.height(), &paperMargins, &customPaper);
191  PMPageFormat tmp;
192  PMCreatePageFormatWithPMPaper(&tmp, customPaper);
193  PMCopyPageFormat(tmp, format);
194  if (PMSessionValidatePageFormat(session, format, kPMDontWantBoolean) != noErr) {
195  // Don't know, warn for the moment.
196  qWarning("QMacPrintEngine, problem setting paper name");
197  }
198  }
199  }
200 }
201 
203 {
204  if (hasCustomPaperSize)
205  return QPrinter::Custom;
206  PMRect paper;
207  PMGetUnadjustedPaperRect(format, &paper);
208  int wMM = int((paper.right - paper.left) / 72 * 25.4 + 0.5);
209  int hMM = int((paper.bottom - paper.top) / 72 * 25.4 + 0.5);
210  for (int i = QPrinter::A4; i < QPrinter::NPaperSize; ++i) {
212  if (s.width() == wMM && s.height() == hMM)
213  return (QPrinter::PaperSize)i;
214  }
215  return QPrinter::Custom;
216 }
217 
219 {
220  Q_ASSERT_X(session, "QMacPrinterEngine::supportedResolutions",
221  "must have a valid printer session");
222  UInt32 resCount;
223  QList<QVariant> resolutions;
224  PMPrinter printer;
225  if (PMSessionGetCurrentPrinter(session, &printer) == noErr) {
226  PMResolution res;
227  OSStatus status = PMPrinterGetPrinterResolutionCount(printer, &resCount);
228  if (status == kPMNotImplemented) {
229 #if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
230  // *Sigh* we have to use the non-indexed version.
231  if (PMPrinterGetPrinterResolution(printer, kPMMinSquareResolution, &res) == noErr)
232  resolutions.append(int(res.hRes));
233  if (PMPrinterGetPrinterResolution(printer, kPMMaxSquareResolution, &res) == noErr) {
234  QVariant var(int(res.hRes));
235  if (!resolutions.contains(var))
236  resolutions.append(var);
237  }
238  if (PMPrinterGetPrinterResolution(printer, kPMDefaultResolution, &res) == noErr) {
239  QVariant var(int(res.hRes));
240  if (!resolutions.contains(var))
241  resolutions.append(var);
242  }
243 #endif
244  } else if (status == noErr) {
245  // According to the docs, index start at 1.
246  for (UInt32 i = 1; i <= resCount; ++i) {
247  if (PMPrinterGetIndexedPrinterResolution(printer, i, &res) == noErr)
248  resolutions.append(QVariant(int(res.hRes)));
249  }
250  } else {
251  qWarning("QMacPrintEngine::supportedResolutions: Unexpected error: %ld", long(status));
252  }
253  }
254  return resolutions;
255 }
256 
258 {
259  if (suppressStatus == true)
260  return true;
261 
262  // Supress displaying the automatic progress dialog if we are printing
263  // from a non-gui thread.
264  return (qApp->thread() != QThread::currentThread());
265 }
266 
268 {
269  return d_func()->state;
270 }
271 
273 {
275  Q_ASSERT(d->state == QPrinter::Active);
276  OSStatus err =
277 #ifndef QT_MAC_USE_COCOA
278  d->shouldSuppressStatus() ? PMSessionEndPageNoDialog(d->session)
279  : PMSessionEndPage(d->session);
280 #else
281  PMSessionEndPageNoDialog(d->session);
282 #endif
283  if (err != noErr) {
284  if (err == kPMCancel) {
285  // User canceled, we need to abort!
286  abort();
287  } else {
288  // Not sure what the problem is...
289  qWarning("QMacPrintEngine::newPage: Cannot end current page. %ld", long(err));
290  d->state = QPrinter::Error;
291  }
292  return false;
293  }
294  return d->newPage_helper();
295 }
296 
298 {
300  if (d->state != QPrinter::Active)
301  return false;
302  bool ret = end();
303  d->state = QPrinter::Aborted;
304  return ret;
305 }
306 
307 static inline int qt_get_PDMWidth(PMPageFormat pformat, bool fullPage,
308  const PMResolution &resolution)
309 {
310  int val = 0;
311  PMRect r;
312  qreal hRatio = resolution.hRes / 72;
313  if (fullPage) {
314  if (PMGetAdjustedPaperRect(pformat, &r) == noErr)
315  val = qRound((r.right - r.left) * hRatio);
316  } else {
317  if (PMGetAdjustedPageRect(pformat, &r) == noErr)
318  val = qRound((r.right - r.left) * hRatio);
319  }
320  return val;
321 }
322 
323 static inline int qt_get_PDMHeight(PMPageFormat pformat, bool fullPage,
324  const PMResolution &resolution)
325 {
326  int val = 0;
327  PMRect r;
328  qreal vRatio = resolution.vRes / 72;
329  if (fullPage) {
330  if (PMGetAdjustedPaperRect(pformat, &r) == noErr)
331  val = qRound((r.bottom - r.top) * vRatio);
332  } else {
333  if (PMGetAdjustedPageRect(pformat, &r) == noErr)
334  val = qRound((r.bottom - r.top) * vRatio);
335  }
336  return val;
337 }
338 
339 
341 {
342  Q_D(const QMacPrintEngine);
343  int val = 1;
344  switch (m) {
346  if (d->hasCustomPaperSize) {
347  val = qRound(d->customSize.width());
348  if (d->hasCustomPageMargins) {
349  val -= qRound(d->leftMargin + d->rightMargin);
350  } else {
352  val -= qRound(margins.at(0).toDouble() + margins.at(2).toDouble());
353  }
354  } else {
355  val = qt_get_PDMWidth(d->format, property(PPK_FullPage).toBool(), d->resolution);
356  }
357  break;
359  if (d->hasCustomPaperSize) {
360  val = qRound(d->customSize.height());
361  if (d->hasCustomPageMargins) {
362  val -= qRound(d->topMargin + d->bottomMargin);
363  } else {
365  val -= qRound(margins.at(1).toDouble() + margins.at(3).toDouble());
366  }
367  } else {
368  val = qt_get_PDMHeight(d->format, property(PPK_FullPage).toBool(), d->resolution);
369  }
370  break;
373  val = int((val * 254 + 5 * d->resolution.hRes) / (10 * d->resolution.hRes));
374  break;
377  val = int((val * 254 + 5 * d->resolution.vRes) / (10 * d->resolution.vRes));
378  break;
381  PMPrinter printer;
382  if(PMSessionGetCurrentPrinter(d->session, &printer) == noErr) {
383  PMResolution resolution;
384 #ifndef QT_MAC_USE_COCOA
385 # if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
387  PMPrinterGetOutputResolution(printer, d->settings, &resolution);
388  } else
389 # endif
390  {
391  PMPrinterGetPrinterResolution(printer, kPMCurrentValue, &resolution);
392  }
393 #else
394  PMPrinterGetOutputResolution(printer, d->settings, &resolution);
395 #endif
396  val = (int)resolution.vRes;
397  break;
398  }
399  //otherwise fall through
400  }
402  val = (int)d->resolution.vRes;
403  break;
405  val = (int)d->resolution.hRes;
406  break;
408  val = (1 << metric(QPaintDevice::PdmDepth));
409  break;
411  val = 24;
412  break;
413  default:
414  val = 0;
415  qWarning("QPrinter::metric: Invalid metric command");
416  }
417  return val;
418 }
419 
421 {
423 
424 #ifndef QT_MAC_USE_COCOA
425  Q_ASSERT(!session);
426 #else
427  Q_ASSERT(!printInfo);
428 #endif
429 
430  if (!paintEngine)
432 
433  q->gccaps = paintEngine->gccaps;
434 
435  fullPage = false;
436 
437 #ifndef QT_MAC_USE_COCOA
438  if (PMCreateSession(&session) != 0)
439  session = 0;
440 #else
442  printInfo = [[NSPrintInfo alloc] initWithDictionary:[NSDictionary dictionary]];
443  session = static_cast<PMPrintSession>([printInfo PMPrintSession]);
444 #endif
445 
446  PMPrinter printer;
447  if (session && PMSessionGetCurrentPrinter(session, &printer) == noErr) {
448  QList<QVariant> resolutions = supportedResolutions();
449  if (!resolutions.isEmpty() && mode != QPrinter::ScreenResolution) {
450  if (resolutions.count() > 1 && mode == QPrinter::HighResolution) {
451  int max = 0;
452  for (int i = 0; i < resolutions.count(); ++i) {
453  int value = resolutions.at(i).toInt();
454  if (value > max)
455  max = value;
456  }
457  resolution.hRes = resolution.vRes = max;
458  } else {
459  resolution.hRes = resolution.vRes = resolutions.at(0).toInt();
460  }
461  if(resolution.hRes == 0)
462  resolution.hRes = resolution.vRes = 600;
463  } else {
464  resolution.hRes = resolution.vRes = qt_defaultDpi();
465  }
466  }
467 
468 #ifndef QT_MAC_USE_COCOA
469  bool settingsInitialized = (settings != 0);
470  bool settingsOK = !settingsInitialized ? PMCreatePrintSettings(&settings) == noErr : true;
471  if (settingsOK && !settingsInitialized)
472  settingsOK = PMSessionDefaultPrintSettings(session, settings) == noErr;
473 
474 
475  bool formatInitialized = (format != 0);
476  bool formatOK = !formatInitialized ? PMCreatePageFormat(&format) == noErr : true;
477  if (formatOK) {
478  if (!formatInitialized) {
479  formatOK = PMSessionDefaultPageFormat(session, format) == noErr;
480  }
481  formatOK = PMSessionValidatePageFormat(session, format, kPMDontWantBoolean) == noErr;
482  }
483 #else
484  settings = static_cast<PMPrintSettings>([printInfo PMPrintSettings]);
485  format = static_cast<PMPageFormat>([printInfo PMPageFormat]);
486 #endif
487 
488 #ifndef QT_MAC_USE_COCOA
489  if (!settingsOK || !formatOK) {
490  qWarning("QMacPrintEngine::initialize: Unable to initialize QPainter");
492  }
493 #endif
494 
496  for (propC = valueCache.constBegin(); propC != valueCache.constEnd(); propC++) {
497  q->setProperty(propC.key(), propC.value());
498  }
499 }
500 
502 {
503 #ifndef QT_MAC_USE_COCOA
504  if (shouldSuppressStatus()) {
505  PMSessionEndPageNoDialog(session);
506  PMSessionEndDocumentNoDialog(session);
507  } else {
508  PMSessionEndPage(session);
509  PMSessionEndDocument(session);
510  }
511  PMRelease(session);
512 #else
513  PMSessionEndPageNoDialog(session);
514  PMSessionEndDocumentNoDialog(session);
515  [printInfo release];
516 #endif
517  if (hasCustomPaperSize)
518  PMRelease(customPaper);
519  printInfo = 0;
520  session = 0;
521 }
522 
524 {
527 
528  if (PMSessionError(session) != noErr) {
529  q->abort();
530  return false;
531  }
532 
533  // pop the stack of saved graphic states, in case we get the same
534  // context back - either way, the stack count should be 0 when we
535  // get the new one
537  while (cgEngine->d_func()->stackCount > 0)
538  cgEngine->d_func()->restoreGraphicsState();
539 
540  OSStatus status =
541 #ifndef QT_MAC_USE_COCOA
542  shouldSuppressStatus() ? PMSessionBeginPageNoDialog(session, format, 0)
543  : PMSessionBeginPage(session, format, 0);
544 #else
545  PMSessionBeginPageNoDialog(session, format, 0);
546 #endif
547  if(status != noErr) {
549  return false;
550  }
551 
552  QRect page = q->property(QPrintEngine::PPK_PageRect).toRect();
553  QRect paper = q->property(QPrintEngine::PPK_PaperRect).toRect();
554 
555  CGContextRef cgContext;
556  OSStatus err = noErr;
557  err = PMSessionGetCGGraphicsContext(session, &cgContext);
558  if(err != noErr) {
559  qWarning("QMacPrintEngine::newPage: Cannot retrieve CoreGraphics context: %ld", long(err));
561  return false;
562  }
563  cgEngine->d_func()->hd = cgContext;
564 
565  // Set the resolution as a scaling ration of 72 (the default).
566  CGContextScaleCTM(cgContext, 72 / resolution.hRes, 72 / resolution.vRes);
567 
568  CGContextScaleCTM(cgContext, 1, -1);
569  CGContextTranslateCTM(cgContext, 0, -paper.height());
570  if (!fullPage)
571  CGContextTranslateCTM(cgContext, page.x() - paper.x(), page.y() - paper.y());
572  cgEngine->d_func()->orig_xform = CGContextGetCTM(cgContext);
573  cgEngine->d_func()->setClip(0);
578  if (cgEngine->painter()->hasClipping())
580  cgEngine->syncState();
581  return true;
582 }
583 
584 
586 {
587  d_func()->paintEngine->updateState(state);
588 }
589 
590 void QMacPrintEngine::drawRects(const QRectF *r, int num)
591 {
593  Q_ASSERT(d->state == QPrinter::Active);
594  d->paintEngine->drawRects(r, num);
595 }
596 
597 void QMacPrintEngine::drawPoints(const QPointF *points, int pointCount)
598 {
600  Q_ASSERT(d->state == QPrinter::Active);
601  d->paintEngine->drawPoints(points, pointCount);
602 }
603 
605 {
607  Q_ASSERT(d->state == QPrinter::Active);
608  d->paintEngine->drawEllipse(r);
609 }
610 
611 void QMacPrintEngine::drawLines(const QLineF *lines, int lineCount)
612 {
614  Q_ASSERT(d->state == QPrinter::Active);
615  d->paintEngine->drawLines(lines, lineCount);
616 }
617 
618 void QMacPrintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
619 {
621  Q_ASSERT(d->state == QPrinter::Active);
622  d->paintEngine->drawPolygon(points, pointCount, mode);
623 }
624 
625 void QMacPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
626 {
628  Q_ASSERT(d->state == QPrinter::Active);
629  d->paintEngine->drawPixmap(r, pm, sr);
630 }
631 
632 void QMacPrintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags)
633 {
635  Q_ASSERT(d->state == QPrinter::Active);
636  d->paintEngine->drawImage(r, pm, sr, flags);
637 }
638 
640 {
642  Q_ASSERT(d->state == QPrinter::Active);
643  d->paintEngine->drawTextItem(p, ti);
644 }
645 
646 void QMacPrintEngine::drawTiledPixmap(const QRectF &dr, const QPixmap &pixmap, const QPointF &sr)
647 {
649  Q_ASSERT(d->state == QPrinter::Active);
650  d->paintEngine->drawTiledPixmap(dr, pixmap, sr);
651 }
652 
654 {
656  Q_ASSERT(d->state == QPrinter::Active);
657  d->paintEngine->drawPath(path);
658 }
659 
660 
662 {
664 
665  d->valueCache.insert(key, value);
666  if (!d->session)
667  return;
668 
669  switch (key) {
670  case PPK_CollateCopies:
671  break;
672  case PPK_ColorMode:
673  break;
674  case PPK_Creator:
675  break;
676  case PPK_DocumentName:
677  break;
678  case PPK_PageOrder:
679  break;
680  case PPK_PaperSource:
681  break;
682  case PPK_SelectionOption:
683  break;
684  case PPK_Resolution: {
685  PMPrinter printer;
686  UInt32 count;
687  if (PMSessionGetCurrentPrinter(d->session, &printer) != noErr)
688  break;
689  if (PMPrinterGetPrinterResolutionCount(printer, &count) != noErr)
690  break;
691  PMResolution resolution = { 0.0, 0.0 };
692  PMResolution bestResolution = { 0.0, 0.0 };
693  int dpi = value.toInt();
694  int bestDistance = INT_MAX;
695  for (UInt32 i = 1; i <= count; ++i) { // Yes, it starts at 1
696  if (PMPrinterGetIndexedPrinterResolution(printer, i, &resolution) == noErr) {
697  if (dpi == int(resolution.hRes)) {
698  bestResolution = resolution;
699  break;
700  } else {
701  int distance = qAbs(dpi - int(resolution.hRes));
702  if (distance < bestDistance) {
703  bestDistance = distance;
704  bestResolution = resolution;
705  }
706  }
707  }
708  }
709  PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean);
710  break;
711  }
712 
713  case PPK_FullPage:
714  d->fullPage = value.toBool();
715  break;
716  case PPK_CopyCount: // fallthrough
717  case PPK_NumberOfCopies:
718  PMSetCopies(d->settings, value.toInt(), false);
719  break;
720  case PPK_Orientation: {
721  if (d->state == QPrinter::Active) {
722  qWarning("QMacPrintEngine::setOrientation: Orientation cannot be changed during a print job, ignoring change");
723  } else {
724  QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt());
725  if (d->hasCustomPaperSize && (d->orient != newOrientation))
726  d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
727  d->orient = newOrientation;
728  PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape;
729  PMSetOrientation(d->format, o, false);
730  PMSessionValidatePageFormat(d->session, d->format, kPMDontWantBoolean);
731  }
732  break; }
733  case PPK_OutputFileName:
734  d->outputFilename = value.toString();
735  break;
736  case PPK_PaperSize:
737  d->setPaperSize(QPrinter::PaperSize(value.toInt()));
738  break;
739  case PPK_PrinterName: {
740  bool printerNameSet = false;
741  OSStatus status = noErr;
742  QCFType<CFArrayRef> printerList;
743  status = PMServerCreatePrinterList(kPMServerLocal, &printerList);
744  if (status == noErr) {
745  CFIndex count = CFArrayGetCount(printerList);
746  for (CFIndex i=0; i<count; ++i) {
747  PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i)));
748  QString name = QCFString::toQString(PMPrinterGetName(printer));
749  if (name == value.toString()) {
750  status = PMSessionSetCurrentPMPrinter(d->session, printer);
751  printerNameSet = true;
752  break;
753  }
754  }
755  }
756  if (status != noErr)
757  qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status));
758  if (!printerNameSet) {
759  qWarning("QMacPrintEngine::setPrinterName: Failed to set printer named '%s'.", qPrintable(value.toString()));
760  d->releaseSession();
761  d->state = QPrinter::Idle;
762  }
763  break; }
765  d->suppressStatus = value.toBool();
766  break;
767  case PPK_CustomPaperSize:
768  {
769  PMOrientation orientation;
770  PMGetOrientation(d->format, &orientation);
771  d->customSize = value.toSizeF();
772  if (orientation != kPMPortrait)
773  d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
774  d->setPaperSize(QPrinter::Custom);
775  break;
776  }
777  case PPK_PageMargins:
778  {
779  QList<QVariant> margins(value.toList());
780  Q_ASSERT(margins.size() == 4);
781  d->leftMargin = margins.at(0).toDouble();
782  d->topMargin = margins.at(1).toDouble();
783  d->rightMargin = margins.at(2).toDouble();
784  d->bottomMargin = margins.at(3).toDouble();
785  d->hasCustomPageMargins = true;
786  break;
787  }
788 
789  default:
790  break;
791  }
792 }
793 
795 {
796  Q_D(const QMacPrintEngine);
797  QVariant ret;
798 
799  if (!d->session && d->valueCache.contains(key))
800  return *d->valueCache.find(key);
801 
802  switch (key) {
803  case PPK_CollateCopies:
804  ret = false;
805  break;
806  case PPK_ColorMode:
807  ret = QPrinter::Color;
808  break;
809  case PPK_Creator:
810  break;
811  case PPK_DocumentName:
812  break;
813  case PPK_FullPage:
814  ret = d->fullPage;
815  break;
816  case PPK_NumberOfCopies:
817  ret = 1;
818  break;
819  case PPK_CopyCount: {
820  UInt32 copies = 1;
821  PMGetCopies(d->settings, &copies);
822  ret = (uint) copies;
823  break;
824  }
826  ret = true;
827  break;
828  case PPK_Orientation:
829  PMOrientation orientation;
830  PMGetOrientation(d->format, &orientation);
831  ret = orientation == kPMPortrait ? QPrinter::Portrait : QPrinter::Landscape;
832  break;
833  case PPK_OutputFileName:
834  ret = d->outputFilename;
835  break;
836  case PPK_PageOrder:
837  break;
838  case PPK_PaperSource:
839  break;
840  case PPK_PageRect: {
841  // PageRect is returned in device pixels
842  QRect r;
843  PMRect macrect, macpaper;
844  qreal hRatio = d->resolution.hRes / 72;
845  qreal vRatio = d->resolution.vRes / 72;
846  if (d->hasCustomPaperSize) {
847  r = QRect(0, 0, qRound(d->customSize.width() * hRatio), qRound(d->customSize.height() * vRatio));
848  if (d->hasCustomPageMargins) {
849  r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio),
850  -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio));
851  } else {
853  r.adjust(qRound(margins.at(0).toDouble() * hRatio),
854  qRound(margins.at(1).toDouble() * vRatio),
855  -qRound(margins.at(2).toDouble() * hRatio),
856  -qRound(margins.at(3).toDouble()) * vRatio);
857  }
858  } else if (PMGetAdjustedPageRect(d->format, &macrect) == noErr
859  && PMGetAdjustedPaperRect(d->format, &macpaper) == noErr)
860  {
861  if (d->fullPage || d->hasCustomPageMargins) {
862  r.setCoords(int(macpaper.left * hRatio), int(macpaper.top * vRatio),
863  int(macpaper.right * hRatio), int(macpaper.bottom * vRatio));
864  r.translate(-r.x(), -r.y());
865  if (d->hasCustomPageMargins) {
866  r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio),
867  -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio));
868  }
869  } else {
870  r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio),
871  int(macrect.right * hRatio), int(macrect.bottom * vRatio));
872  r.translate(int(-macpaper.left * hRatio), int(-macpaper.top * vRatio));
873  }
874  }
875  ret = r;
876  break; }
877  case PPK_PaperSize:
878  ret = d->paperSize();
879  break;
880  case PPK_PaperRect: {
881  QRect r;
882  PMRect macrect;
883  qreal hRatio = d->resolution.hRes / 72;
884  qreal vRatio = d->resolution.vRes / 72;
885  if (d->hasCustomPaperSize) {
886  r = QRect(0, 0, qRound(d->customSize.width() * hRatio), qRound(d->customSize.height() * vRatio));
887  } else if (PMGetAdjustedPaperRect(d->format, &macrect) == noErr) {
888  r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio),
889  int(macrect.right * hRatio), int(macrect.bottom * vRatio));
890  r.translate(-r.x(), -r.y());
891  }
892  ret = r;
893  break; }
894  case PPK_PrinterName: {
895  PMPrinter printer;
896  OSStatus status = PMSessionGetCurrentPrinter(d->session, &printer);
897  if (status != noErr)
898  qWarning("QMacPrintEngine::printerName: Failed getting current PMPrinter: %ld", long(status));
899  if (printer)
900  ret = QCFString::toQString(PMPrinterGetName(printer));
901  break; }
902  case PPK_Resolution: {
903  ret = d->resolution.hRes;
904  break;
905  }
907  ret = d->supportedResolutions();
908  break;
909  case PPK_CustomPaperSize:
910  ret = d->customSize;
911  break;
912  case PPK_PageMargins:
913  {
914  QList<QVariant> margins;
915  if (d->hasCustomPageMargins) {
916  margins << d->leftMargin << d->topMargin
917  << d->rightMargin << d->bottomMargin;
918  } else {
919  PMPaperMargins paperMargins;
920  PMPaper paper;
921  PMGetPageFormatPaper(d->format, &paper);
922  PMPaperGetMargins(paper, &paperMargins);
923  margins << paperMargins.left << paperMargins.top
924  << paperMargins.right << paperMargins.bottom;
925  }
926  ret = margins;
927  break;
928  }
929  default:
930  break;
931  }
932  return ret;
933 }
934 
936 
937 #endif // QT_NO_PRINTER
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
double d
Definition: qnumeric_p.h:62
double qreal
Definition: qglobal.h:1193
PrinterState
Definition: qprinter.h:119
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void syncState()
Updates all dirty states in this engine.
PaintEngineFeatures gccaps
Definition: qpaintengine.h:240
QSize toSize() const
Returns an integer based copy of this size.
Definition: qsize.h:355
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:67
static int qt_get_PDMWidth(PMPageFormat pformat, bool fullPage, const PMResolution &resolution)
QPaintEngineState * state
Definition: qpaintengine.h:239
static QUuid createUuid()
On any platform other than Windows, this function returns a new UUID with variant QUuid::DCE and vers...
Definition: quuid.cpp:897
PrinterMode
This enum describes the mode the printer should work in.
Definition: qprinter.h:70
void setProperty(PrintEnginePropertyKey key, const QVariant &value)
Sets the print engine&#39;s property specified by key to the given value.
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
bool begin(QPaintDevice *dev)
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
Reimplement this virtual function to draw the polygon defined by the pointCount first points in point...
Orientation
This enum type (not to be confused with Orientation) is used to specify each page&#39;s orientation...
Definition: qprinter.h:78
static CFStringRef toCFStringRef(const QString &str)
Definition: qcore_mac.cpp:69
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
static QString toQString(CFStringRef cfstr)
Definition: qcore_mac.cpp:47
static int qt_get_PDMHeight(PMPageFormat pformat, bool fullPage, const PMResolution &resolution)
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has type() List or StringList ; otherwise return...
Definition: qvariant.cpp:2751
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
bool toBool() const
Returns the variant as a bool if the variant has type() Bool.
Definition: qvariant.cpp:2691
QPaintEngine::DirtyFlags dirtyFlags
Definition: qpaintengine.h:325
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
The QString class provides a Unicode character string.
Definition: qstring.h:83
void updateState(const QPaintEngineState &state)
Reimplement this function to update the state of a paint engine.
QPrinter::PrinterState printerState() const
Returns the current state of the printer being used by the print engine.
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
virtual void drawPoints(const QPointF *p, int pointCount)
Draws the first pointCount points in the buffer points.
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define Q_D(Class)
Definition: qglobal.h:2482
virtual int devType() const
Definition: qpaintdevice.h:167
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
DirtyFlag
QPaintEngine::updateState().
Definition: qpaintengine.h:125
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
QPaintEngine * paintEngine() const
#define Q_Q(Class)
Definition: qglobal.h:2483
The QLineF class provides a two-dimensional vector using floating point precision.
Definition: qline.h:212
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
virtual void drawRects(const QRectF *r, int num)
Draws the first rectCount rectangles in the buffer rects.
static bool toBool(Register *reg, int type, bool *ok=0)
QPrinter::PaperSize paperSize() const
int width() const
Returns the width.
Definition: qsize.h:126
static QThread * currentThread()
Returns a pointer to a QThread which manages the currently executing thread.
Definition: qthread.cpp:419
static QString toString(Register *reg, int type, bool *ok=0)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QPainter * painter() const
Returns the paint engine&#39;s painter.
void NSPrintInfo
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
bool hasClipping() const
Returns true if clipping has been set; otherwise returns false.
Definition: qpainter.cpp:2499
#define qApp
void setActive(bool newState)
Sets the active state of the paint engine to state.
Definition: qpaintengine.h:155
QVariant property(PrintEnginePropertyKey key) const
Returns the print engine&#39;s property specified by key.
const char * name
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
void setPaperSize(QPrinter::PaperSize ps)
void adjust(int x1, int y1, int x2, int y2)
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition: qrect.h:434
Q_CORE_EXPORT void qWarning(const char *,...)
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
unsigned int uint
Definition: qglobal.h:996
static int distance(QWidget *source, QWidget *target, QAccessible::RelationFlag relation)
virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
Reimplement this function to draw the pixmap in the given rect, starting at the given p...
virtual void drawLines(const QLineF *lines, int lineCount)
The default implementation splits the list of lines in lines into lineCount separate calls to drawPat...
void * HANDLE
Definition: qnamespace.h:1671
void setCoords(int x1, int y1, int x2, int y2)
Sets the coordinates of the rectangle&#39;s top-left corner to (x1, y1), and the coordinates of its botto...
Definition: qrect.h:416
virtual void drawPath(const QPainterPath &)
The default implementation ignores the path and does nothing.
signed long OSStatus
virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags)
Reimplement this function to draw the part of the image specified by the sr rectangle in the given re...
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
bool shouldSuppressStatus() const
QSizeF toSizeF() const
Returns the variant as a QSizeF if the variant has type() SizeF ; otherwise returns an invalid QSizeF...
Definition: qvariant.cpp:2447
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r...
bool end()
Reimplement this function to finish painting on the current paint device.
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
Qt::HANDLE handle() const
Q_GUI_EXPORT int qt_defaultDpi()
Definition: qfont.cpp:240
PaperSize
This enum type specifies what paper size QPrinter should use.
Definition: qprinter.h:91
const Key key(const T &value) const
Returns the first key mapped to value.
Definition: qhash.h:674
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
int key
QMacPrintEngine(QPrinter::PrinterMode mode)
int metric(QPaintDevice::PaintDeviceMetric) const
Returns the metric for the given id.
static const char * outFile
Definition: qtestlog.cpp:93
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size)
Definition: qprinter.cpp:2615
QList< QVariant > supportedResolutions() const
double toDouble(bool *ok=0) const
Returns the variant as a double if the variant has type() Double , QMetaType::Float ...
Definition: qvariant.cpp:2710
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
The QPaintEngineState class provides information about the active paint engine&#39;s current state...
Definition: qpaintengine.h:289
static const MacVersion MacintoshVersion
the version of the Macintosh operating system on which the application is run (Mac only)...
Definition: qglobal.h:1646
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
bool abort()
Instructs the print engine to abort the printing process.
struct CGContext * CGContextRef
The QTextItem class provides all the information required to draw text in a custom paint engine...
Definition: qpaintengine.h:68
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
#define qPrintable(string)
Definition: qglobal.h:1750
bool newPage()
Instructs the print engine to start a new page.
#define INT_MAX
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
virtual void drawEllipse(const QRectF &r)
Reimplement this function to draw the largest ellipse that can be contained within rectangle rect...
virtual void drawTextItem(const QPointF &p, const QTextItem &ti)
This function draws the text item textItem at position p.
PrintEnginePropertyKey
This enum is used to communicate properties between the print engine and QPrinter.
Definition: qprintengine.h:60