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 "qprinterinfo.h"
41 #include "qprinterinfo_p.h"
42 #include "qprintdevice_p.h"
43 
44 #ifndef QT_NO_PRINTER
45 
46 #include <QtCore/qdebug.h>
47 
48 #include <qpa/qplatformprintplugin.h>
49 #include <qpa/qplatformprintersupport.h>
50 
51 QT_BEGIN_NAMESPACE
52 
53 Q_GLOBAL_STATIC(QPrinterInfoPrivate, shared_null);
54 
55 class QPrinterInfoPrivateDeleter
56 {
57 public:
cleanup(QPrinterInfoPrivate * d)58     static inline void cleanup(QPrinterInfoPrivate *d)
59     {
60         if (d != shared_null)
61             delete d;
62     }
63 };
64 
QPrinterInfoPrivate(const QString & id)65 QPrinterInfoPrivate::QPrinterInfoPrivate(const QString &id)
66 {
67     if (!id.isEmpty()) {
68         QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
69         if (ps)
70             m_printDevice = ps->createPrintDevice(id);
71     }
72 }
73 
~QPrinterInfoPrivate()74 QPrinterInfoPrivate::~QPrinterInfoPrivate()
75 {
76 }
77 
78 /*!
79     \class QPrinterInfo
80 
81     \brief The QPrinterInfo class gives access to information about
82     existing printers.
83 
84     \ingroup printing
85     \inmodule QtPrintSupport
86 
87     Use the static functions to generate a list of QPrinterInfo
88     objects. Each QPrinterInfo object in the list represents a single
89     printer and can be queried for name, supported paper sizes, and
90     whether or not it is the default printer.
91 
92     \since 4.4
93 */
94 
95 /*!
96     Constructs an empty QPrinterInfo object.
97 
98     \sa isNull()
99 */
QPrinterInfo()100 QPrinterInfo::QPrinterInfo()
101     : d_ptr(shared_null)
102 {
103 }
104 
105 /*!
106     Constructs a copy of \a other.
107 */
QPrinterInfo(const QPrinterInfo & other)108 QPrinterInfo::QPrinterInfo(const QPrinterInfo &other)
109     : d_ptr((other.d_ptr.data() == shared_null) ? shared_null : new QPrinterInfoPrivate(*other.d_ptr))
110 {
111 }
112 
113 /*!
114     Constructs a QPrinterInfo object from \a printer.
115 */
QPrinterInfo(const QPrinter & printer)116 QPrinterInfo::QPrinterInfo(const QPrinter &printer)
117     : d_ptr(shared_null)
118 {
119     QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
120     if (ps) {
121         QPrinterInfo pi(printer.printerName());
122         if (pi.d_ptr.data() == shared_null)
123             d_ptr.reset(shared_null);
124         else
125             d_ptr.reset(new QPrinterInfoPrivate(*pi.d_ptr));
126     }
127 }
128 
129 /*!
130     \internal
131 */
QPrinterInfo(const QString & name)132 QPrinterInfo::QPrinterInfo(const QString &name)
133     : d_ptr(new QPrinterInfoPrivate(name))
134 {
135 }
136 
137 /*!
138     Destroys the QPrinterInfo object. References to the values in the
139     object become invalid.
140 */
~QPrinterInfo()141 QPrinterInfo::~QPrinterInfo()
142 {
143 }
144 
145 /*!
146     Sets the QPrinterInfo object to be equal to \a other.
147 */
operator =(const QPrinterInfo & other)148 QPrinterInfo &QPrinterInfo::operator=(const QPrinterInfo &other)
149 {
150     Q_ASSERT(d_ptr);
151     if (other.d_ptr.data() == shared_null)
152         d_ptr.reset(shared_null);
153     else
154         d_ptr.reset(new QPrinterInfoPrivate(*other.d_ptr));
155     return *this;
156 }
157 
158 /*!
159     Returns the name of the printer.
160 
161     This is a unique id to identify the printer and may not be human-readable.
162 
163     \sa QPrinterInfo::description()
164     \sa QPrinter::setPrinterName()
165 */
printerName() const166 QString QPrinterInfo::printerName() const
167 {
168     const Q_D(QPrinterInfo);
169     return d->m_printDevice.id();
170 }
171 
172 /*!
173     Returns the human-readable description of the printer.
174 
175     \since 5.0
176     \sa QPrinterInfo::printerName()
177 */
description() const178 QString QPrinterInfo::description() const
179 {
180     const Q_D(QPrinterInfo);
181     return d->m_printDevice.name();
182 }
183 
184 /*!
185     Returns the human-readable location of the printer.
186 
187     \since 5.0
188 */
location() const189 QString QPrinterInfo::location() const
190 {
191     const Q_D(QPrinterInfo);
192     return d->m_printDevice.location();
193 }
194 
195 /*!
196     Returns the human-readable make and model of the printer.
197 
198     \since 5.0
199 */
makeAndModel() const200 QString QPrinterInfo::makeAndModel() const
201 {
202     const Q_D(QPrinterInfo);
203     return d->m_printDevice.makeAndModel();
204 }
205 
206 /*!
207     Returns whether this QPrinterInfo object holds a printer definition.
208 
209     An empty QPrinterInfo object could result for example from calling
210     defaultPrinter() when there are no printers on the system.
211 */
isNull() const212 bool QPrinterInfo::isNull() const
213 {
214     Q_D(const QPrinterInfo);
215     return d == shared_null || !d->m_printDevice.isValid();
216 }
217 
218 /*!
219     Returns whether this printer is currently the default printer.
220 */
isDefault() const221 bool QPrinterInfo::isDefault() const
222 {
223     Q_D(const QPrinterInfo);
224     return d->m_printDevice.isDefault();
225 }
226 
227 /*!
228     Returns whether this printer is a remote network printer.
229 
230     \since 5.3
231 */
isRemote() const232 bool QPrinterInfo::isRemote() const
233 {
234     Q_D(const QPrinterInfo);
235     return d->m_printDevice.isRemote();
236 }
237 
238 /*!
239     Returns the current state of this printer.
240 
241     This state may not always be accurate, depending on the platform, printer
242     driver, or printer itself.
243 
244     \since 5.3
245 */
state() const246 QPrinter::PrinterState QPrinterInfo::state() const
247 {
248     Q_D(const QPrinterInfo);
249     return QPrinter::PrinterState(d->m_printDevice.state());
250 }
251 
252 /*!
253     Returns a list of Page Sizes supported by this printer.
254 
255     \since 5.3
256 */
257 
supportedPageSizes() const258 QList<QPageSize> QPrinterInfo::supportedPageSizes() const
259 {
260     Q_D(const QPrinterInfo);
261     return d->m_printDevice.supportedPageSizes();
262 }
263 
264 /*!
265     Returns the current default Page Size for this printer.
266 
267     \since 5.3
268 */
269 
defaultPageSize() const270 QPageSize QPrinterInfo::defaultPageSize() const
271 {
272     Q_D(const QPrinterInfo);
273     return d->m_printDevice.defaultPageSize();
274 }
275 
276 /*!
277     Returns whether this printer supports custom page sizes.
278 
279     \since 5.3
280 */
281 
supportsCustomPageSizes() const282 bool QPrinterInfo::supportsCustomPageSizes() const
283 {
284     Q_D(const QPrinterInfo);
285     return d->m_printDevice.supportsCustomPageSizes();
286 }
287 
288 /*!
289     Returns the minimum physical page size supported by this printer.
290 
291     \sa maximumPhysicalPageSize()
292 
293     \since 5.3
294 */
295 
minimumPhysicalPageSize() const296 QPageSize QPrinterInfo::minimumPhysicalPageSize() const
297 {
298     Q_D(const QPrinterInfo);
299     return QPageSize(d->m_printDevice.minimumPhysicalPageSize(), QString(), QPageSize::ExactMatch);
300 }
301 
302 /*!
303     Returns the maximum physical page size supported by this printer.
304 
305     \sa minimumPhysicalPageSize()
306 
307     \since 5.3
308 */
309 
maximumPhysicalPageSize() const310 QPageSize QPrinterInfo::maximumPhysicalPageSize() const
311 {
312     Q_D(const QPrinterInfo);
313     return QPageSize(d->m_printDevice.maximumPhysicalPageSize(), QString(), QPageSize::ExactMatch);
314 }
315 
316 #if QT_DEPRECATED_SINCE(5,3)
317 /*!
318     \obsolete Use supportedPageSizes() instead.
319 
320     Returns a list of supported paper sizes by the printer.
321 
322     Not all printer drivers support this query, so the list may be empty.
323 
324     \since 4.4
325 */
326 
supportedPaperSizes() const327 QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
328 {
329     Q_D(const QPrinterInfo);
330     QList<QPrinter::PaperSize> list;
331     const QList<QPageSize> supportedPageSizes = d->m_printDevice.supportedPageSizes();
332     list.reserve(supportedPageSizes.size());
333     for (const QPageSize &pageSize : supportedPageSizes)
334         list.append(QPrinter::PaperSize(pageSize.id()));
335     return list;
336 }
337 
338 /*!
339     \obsolete Use supportedPageSizes() instead.
340 
341     Returns a list of all the paper names supported by the driver with the
342     corresponding size in millimeters.
343 
344     Not all printer drivers support this query, so the list may be empty.
345 
346     \since 5.1
347 */
348 
supportedSizesWithNames() const349 QList<QPair<QString, QSizeF> > QPrinterInfo::supportedSizesWithNames() const
350 {
351     Q_D(const QPrinterInfo);
352     QList<QPair<QString, QSizeF> > list;
353     const QList<QPageSize> supportedPageSizes = d->m_printDevice.supportedPageSizes();
354     list.reserve(supportedPageSizes.size());
355     for (const QPageSize &pageSize : supportedPageSizes)
356         list.append(qMakePair(pageSize.name(), pageSize.size(QPageSize::Millimeter)));
357     return list;
358 }
359 #endif // QT_DEPRECATED_SINCE(5,3)
360 
361 /*!
362     Returns a list of resolutions supported by this printer.
363 
364     \since 5.3
365 */
366 
supportedResolutions() const367 QList<int> QPrinterInfo::supportedResolutions() const
368 {
369     Q_D(const QPrinterInfo);
370     return d->m_printDevice.supportedResolutions();
371 }
372 
373 /*!
374     Returns the default duplex mode of this printer.
375 
376     \since 5.4
377 */
378 
defaultDuplexMode() const379 QPrinter::DuplexMode QPrinterInfo::defaultDuplexMode() const
380 {
381     Q_D(const QPrinterInfo);
382     return QPrinter::DuplexMode(d->m_printDevice.defaultDuplexMode());
383 }
384 
385 /*!
386     Returns a list of duplex modes supported by this printer.
387 
388     \since 5.4
389 */
390 
supportedDuplexModes() const391 QList<QPrinter::DuplexMode> QPrinterInfo::supportedDuplexModes() const
392 {
393     Q_D(const QPrinterInfo);
394     QList<QPrinter::DuplexMode> list;
395     const auto supportedDuplexModes = d->m_printDevice.supportedDuplexModes();
396     list.reserve(supportedDuplexModes.size());
397     for (QPrint::DuplexMode mode : supportedDuplexModes)
398         list << QPrinter::DuplexMode(mode);
399     return list;
400 }
401 
402 /*!
403     Returns the default color mode of this printer.
404 
405     \since 5.13
406 */
407 
defaultColorMode() const408 QPrinter::ColorMode QPrinterInfo::defaultColorMode() const
409 {
410     Q_D(const QPrinterInfo);
411     return QPrinter::ColorMode(d->m_printDevice.defaultColorMode());
412 }
413 
414 /*!
415     Returns the supported color modes of this printer.
416 
417     \since 5.13
418 */
419 
supportedColorModes() const420 QList<QPrinter::ColorMode> QPrinterInfo::supportedColorModes() const
421 {
422     Q_D(const QPrinterInfo);
423     QList<QPrinter::ColorMode> list;
424     const auto supportedColorModes = d->m_printDevice.supportedColorModes();
425     list.reserve(supportedColorModes.size());
426     for (QPrint::ColorMode mode : supportedColorModes)
427         list << QPrinter::ColorMode(mode);
428     return list;
429 }
430 
431 /*!
432     Returns a list of all the available Printer Names on this system.
433 
434     It is recommended to use this instead of availablePrinters() as
435     it will be faster on most systems.
436 
437     Note that the list may become outdated if changes are made on the local
438     system or remote print server. Only instantiate required QPrinterInfo
439     instances when needed, and always check for validity before calling.
440 
441     \since 5.3
442 */
availablePrinterNames()443 QStringList QPrinterInfo::availablePrinterNames()
444 {
445     QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
446     if (ps)
447         return ps->availablePrintDeviceIds();
448     return QStringList();
449 }
450 
451 /*!
452     Returns a list of QPrinterInfo objects for all the available printers
453     on this system.
454 
455     It is NOT recommended to use this as creating each printer instance may
456     take a long time, especially if there are remote networked printers, and
457     retained instances may become outdated if changes are made on the local
458     system or remote print server. Use availablePrinterNames() instead and
459     only instantiate printer instances as you need them.
460 */
availablePrinters()461 QList<QPrinterInfo> QPrinterInfo::availablePrinters()
462 {
463     QList<QPrinterInfo> list;
464     QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
465     if (ps) {
466         const QStringList availablePrintDeviceIds = ps->availablePrintDeviceIds();
467         list.reserve(availablePrintDeviceIds.size());
468         for (const QString &id : availablePrintDeviceIds)
469             list.append(QPrinterInfo(id));
470     }
471     return list;
472 }
473 
474 /*!
475     Returns the current default printer name.
476 
477     \since 5.3
478 */
defaultPrinterName()479 QString QPrinterInfo::defaultPrinterName()
480 {
481     QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
482     if (ps)
483         return ps->defaultPrintDeviceId();
484     return QString();
485 }
486 
487 /*!
488     Returns the default printer on the system.
489 
490     The return value should be checked using isNull() before being
491     used, in case there is no default printer.
492 
493     On some systems it is possible for there to be available printers
494     but none of them set to be the default printer.
495 
496     \sa isNull()
497     \sa isDefault()
498     \sa availablePrinters()
499 */
500 
defaultPrinter()501 QPrinterInfo QPrinterInfo::defaultPrinter()
502 {
503     QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
504     if (ps)
505         return QPrinterInfo(ps->defaultPrintDeviceId());
506     return QPrinterInfo();
507 }
508 
509 /*!
510     Returns the printer \a printerName.
511 
512     The return value should be checked using isNull() before being
513     used, in case the named printer does not exist.
514 
515     \since 5.0
516     \sa isNull()
517 */
printerInfo(const QString & printerName)518 QPrinterInfo QPrinterInfo::printerInfo(const QString &printerName)
519 {
520     return QPrinterInfo(printerName);
521 }
522 
523 #  ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug debug,const QPrinterInfo & p)524 QDebug operator<<(QDebug debug, const QPrinterInfo &p)
525 {
526     QDebugStateSaver saver(debug);
527     debug.nospace();
528     debug << "QPrinterInfo(";
529     if (p.isNull())
530         debug << "null";
531     else
532         p.d_ptr->m_printDevice.format(debug);
533     debug << ')';
534     return debug;
535 }
536 #  endif // !QT_NO_DEBUG_STREAM
537 
538 QT_END_NAMESPACE
539 
540 #endif // QT_NO_PRINTER
541