Add support for setting/getting the paper name on the QPrinter

This adds support for specifying a paper name which will be set on
the printer if it is available for the driver.

Change-Id: Id7fd0c8cf68745db3d7a8de7e2ac98d3e2ba9b79
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
bb10
Andy Shaw 2012-12-29 17:08:12 +01:00 committed by The Qt Project
parent 62fe32b37c
commit 39a902c008
9 changed files with 209 additions and 18 deletions

View File

@ -180,6 +180,38 @@ QPrinter::PaperSize QMacPrintEnginePrivate::paperSize() const
return QPlatformPrinterSupport::convertQSizeFToPaperSize(sizef);
}
void QMacPrintEnginePrivate::setPaperName(const QString &name)
{
Q_Q(QMacPrintEngine);
PMPrinter printer;
if (PMSessionGetCurrentPrinter(session(), &printer) == noErr) {
CFArrayRef array;
if (PMPrinterGetPaperList(printer, &array) != noErr) {
PMRelease(printer);
return;
}
int count = CFArrayGetCount(array);
for (int i = 0; i < count; ++i) {
PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(array, i)));
QCFString paperName;
if (PMPaperCreateLocalizedName(paper, printer, &paperName) == noErr) {
if (QString(paperName) == name) {
PMPageFormat tmp;
PMCreatePageFormatWithPMPaper(&tmp, paper);
PMCopyPageFormat(tmp, format());
q->setProperty(QPrintEngine::PPK_Orientation, orient);
if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr) {
// Don't know, warn for the moment.
qWarning("QMacPrintEngine, problem setting paper name");
}
}
}
}
PMRelease(printer);
}
}
QList<QVariant> QMacPrintEnginePrivate::supportedResolutions() const
{
Q_ASSERT_X(printInfo, "QMacPrinterEngine::supportedResolutions",
@ -601,6 +633,9 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
case PPK_PaperSize:
d->setPaperSize(QPrinter::PaperSize(value.toInt()));
break;
case PPK_PaperName:
d->setPaperName(value.toString());
break;
case PPK_PrinterName: {
bool printerNameSet = false;
OSStatus status = noErr;
@ -739,6 +774,9 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_PaperSize:
ret = d->paperSize();
break;
case PPK_PaperName:
ret = QCFString::toQString([d->printInfo localizedPaperName]);
break;
case PPK_PaperRect: {
QRect r;
PMRect macrect;

View File

@ -142,6 +142,7 @@ public:
bool newPage_helper();
void setPaperSize(QPrinter::PaperSize ps);
QPrinter::PaperSize paperSize() const;
void setPaperName(const QString &name);
QList<QVariant> supportedResolutions() const;
inline bool isPrintSessionInitialized() const
{

View File

@ -103,7 +103,9 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
d->cupsOptions = value.toStringList();
break;
case PPK_CupsStringPageSize:
case PPK_PaperName:
d->cupsStringPageSize = value.toString();
d->setPaperName();
break;
case PPK_PrinterName:
// prevent setting the defaults again for the same printer
@ -140,6 +142,7 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const
ret = d->cupsOptions;
break;
case PPK_CupsStringPageSize:
case PPK_PaperName:
ret = d->cupsStringPageSize;
break;
default:
@ -284,6 +287,7 @@ void QCupsPrintEnginePrivate::setPaperSize()
QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(printerPaperSize));
if (cups.currentPPD()) {
cupsStringPageSize = QLatin1String("Custom");
const ppd_option_t* pageSizes = cups.pageSizes();
for (int i = 0; i < pageSizes->num_choices; ++i) {
QByteArray cupsPageSize = pageSizes->choices[i].choice;
@ -293,7 +297,7 @@ void QCupsPrintEnginePrivate::setPaperSize()
if (qAbs(size.width - tmpCupsPaperRect.width()) < 5 && qAbs(size.height - tmpCupsPaperRect.height()) < 5) {
cupsPaperRect = tmpCupsPaperRect;
cupsPageRect = tmpCupsPageRect;
cupsStringPageSize = pageSizes->choices[i].text;
leftMargin = cupsPageRect.x() - cupsPaperRect.x();
topMargin = cupsPageRect.y() - cupsPaperRect.y();
rightMargin = cupsPaperRect.right() - cupsPageRect.right();
@ -307,6 +311,43 @@ void QCupsPrintEnginePrivate::setPaperSize()
}
}
void QCupsPrintEnginePrivate::setPaperName()
{
if (QCUPSSupport::isAvailable()) {
QCUPSSupport cups;
if (cups.currentPPD()) {
const ppd_option_t* pageSizes = cups.pageSizes();
bool foundPaperName = false;
for (int i = 0; i < pageSizes->num_choices; ++i) {
if (cupsStringPageSize == pageSizes->choices[i].text) {
foundPaperName = true;
QByteArray cupsPageSize = pageSizes->choices[i].choice;
cupsPaperRect = cups.paperRect(cupsPageSize);
cupsPageRect = cups.pageRect(cupsPageSize);
leftMargin = cupsPageRect.x() - cupsPaperRect.x();
topMargin = cupsPageRect.y() - cupsPaperRect.y();
rightMargin = cupsPaperRect.right() - cupsPageRect.right();
bottomMargin = cupsPaperRect.bottom() - cupsPageRect.bottom();
printerPaperSize = QPrinter::Custom;
customPaperSize = cupsPaperRect.size();
for (int ps = 0; ps < QPrinter::NPageSize; ++ps) {
QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
if (qAbs(size.width - cupsPaperRect.width()) < 5 && qAbs(size.height - cupsPaperRect.height()) < 5) {
printerPaperSize = static_cast<QPrinter::PaperSize>(ps);
customPaperSize = QSize();
break;
}
}
updatePaperSize();
break;
}
}
if (!foundPaperName)
cupsStringPageSize = QString();
}
}
}
void QCupsPrintEnginePrivate::setCupsDefaults()
{
if (QCUPSSupport::isAvailable()) {
@ -348,8 +389,10 @@ void QCupsPrintEnginePrivate::setCupsDefaults()
const ppd_option_t* pageSizes = cups.pageSizes();
QByteArray cupsPageSize;
for (int i = 0; i < pageSizes->num_choices; ++i) {
if (static_cast<int>(pageSizes->choices[i].marked) == 1)
if (static_cast<int>(pageSizes->choices[i].marked) == 1) {
cupsPageSize = pageSizes->choices[i].choice;
cupsStringPageSize = pageSizes->choices[i].text;
}
}
cupsOptions = cups.options();

View File

@ -97,6 +97,7 @@ public:
void updatePaperSize();
void setPaperSize();
void setPaperName();
void setCupsDefaults();
private:

View File

@ -360,7 +360,7 @@ void QPageSetupWidget::setupPrinter() const
else {
m_printer->setPaperSize(static_cast<QPrinter::PaperSize>(ps));
}
m_printer->setPaperName(widget.paperSize->currentText());
#ifdef PSD_ENABLE_PAPERSOURCE
m_printer->setPaperSource((QPrinter::PaperSource)widget.paperSource->currentIndex());
#endif
@ -380,16 +380,22 @@ void QPageSetupWidget::selectPrinter()
int cupsDefaultSize = 0;
QSize qtPreferredSize = m_printer->paperSize(QPrinter::Point).toSize();
QString qtPaperName = m_printer->paperName();
bool preferredSizeMatched = false;
for (int i = 0; i < numChoices; ++i) {
widget.paperSize->addItem(QString::fromLocal8Bit(pageSizes->choices[i].text), QByteArray(pageSizes->choices[i].choice));
if (static_cast<int>(pageSizes->choices[i].marked) == 1)
cupsDefaultSize = i;
QRect cupsPaperSize = cups.paperRect(pageSizes->choices[i].choice);
QSize diff = cupsPaperSize.size() - qtPreferredSize;
if (qAbs(diff.width()) < 5 && qAbs(diff.height()) < 5) {
if (qtPaperName == QString::fromLocal8Bit(pageSizes->choices[i].text)) {
widget.paperSize->setCurrentIndex(i);
preferredSizeMatched = true;
} else {
QRect cupsPaperSize = cups.paperRect(pageSizes->choices[i].choice);
QSize diff = cupsPaperSize.size() - qtPreferredSize;
if (qAbs(diff.width()) < 5 && qAbs(diff.height()) < 5) {
widget.paperSize->setCurrentIndex(i);
preferredSizeMatched = true;
}
}
}
if (!preferredSizeMatched)
@ -452,7 +458,7 @@ void QPageSetupWidget::_q_paperSizeChanged()
bool custom = size == QPrinter::Custom;
#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
custom = custom ? m_cups : custom;
custom = custom && m_cups && (m_printer->paperName() == QLatin1String("Custom"));
#endif
widget.paperWidth->setEnabled(custom);

View File

@ -84,6 +84,7 @@ public:
PPK_PageMargins,
PPK_CopyCount,
PPK_SupportsMultipleCopies,
PPK_PaperName,
PPK_PaperSize = PPK_PageSize,
PPK_CustomBase = 0xff00

View File

@ -167,6 +167,16 @@ static int mapPaperSourceDevmode(QPrinter::PaperSource s)
return sources[i].winSourceName ? sources[i].winSourceName : s;
}
static inline uint qwcsnlen(const wchar_t *str, uint maxlen)
{
uint length = 0;
if (str) {
while (length < maxlen && *str++)
length++;
}
return length;
}
QWin32PrintEngine::QWin32PrintEngine(QPrinter::PrinterMode mode)
: QAlphaPaintEngine(*(new QWin32PrintEnginePrivate),
PaintEngineFeatures(PrimitiveTransform
@ -1285,7 +1295,39 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
d->has_custom_paper_size = (QPrinter::PaperSize(value.toInt()) == QPrinter::Custom);
d->doReinit();
break;
case PPK_PaperName:
{
if (!d->devMode)
break;
DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
NULL, DC_PAPERNAMES, NULL, NULL);
if ((int)size > 0) {
wchar_t *paperNames = new wchar_t[size*64];
size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
NULL, DC_PAPERNAMES, paperNames, NULL);
int paperPos = -1;
for (int i=0;i<(int)size;i++) {
wchar_t *copyOfPaper = paperNames + (i * 64);
if (value.toString() == QString::fromWCharArray(copyOfPaper, qwcsnlen(copyOfPaper, 64))) {
paperPos = i;
break;
}
}
delete [] paperNames;
size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
NULL, DC_PAPERS, NULL, NULL);
if ((int)size > 0) {
wchar_t *papers = new wchar_t[size];
size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
NULL, DC_PAPERS, papers, NULL);
d->has_custom_paper_size = false;
d->devMode->dmPaperSize = papers[paperPos];
d->doReinit();
delete [] papers;
}
}
}
break;
case PPK_PaperSource:
{
if (!d->devMode)
@ -1479,7 +1521,40 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0).mapRect(d->devPaperRect);
}
break;
case PPK_PaperName:
if (!d->devMode) {
value = QLatin1String("A4");
} else {
DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
NULL, DC_PAPERS, NULL, NULL);
int paperSizePos = -1;
if ((int)size > 0) {
wchar_t *papers = new wchar_t[size];
size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
NULL, DC_PAPERS, papers, NULL);
for (int i=0;i<(int)size;i++) {
if (papers[i] == d->devMode->dmPaperSize) {
paperSizePos = i;
break;
}
}
delete [] papers;
}
if (paperSizePos != -1) {
size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
NULL, DC_PAPERNAMES, NULL, NULL);
if ((int)size > 0) {
wchar_t *papers = new wchar_t[size*64];
size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
NULL, DC_PAPERNAMES, papers, NULL);
wchar_t *copyOfPaper = papers + (paperSizePos * 64);
value = QString::fromWCharArray(copyOfPaper, qwcsnlen(copyOfPaper, 64));
delete [] papers;
}
}
}
break;
case PPK_PaperSource:
if (!d->devMode) {
value = QPrinter::Auto;
@ -1596,16 +1671,6 @@ QList<QPrinter::PaperSize> QWin32PrintEngine::supportedPaperSizes(const QPrinter
return returnList;
}
static inline uint qwcsnlen(const wchar_t *str, uint maxlen)
{
uint length = 0;
if (str) {
while (length < maxlen && *str++)
length++;
}
return length;
}
QList<QPair<QString, QSizeF> > QWin32PrintEngine::supportedSizesWithNames(const QPrinterInfo &printerInfo)
{
QList<QPair<QString, QSizeF> > paperSizes;

View File

@ -1022,6 +1022,37 @@ QSizeF QPrinter::paperSize(Unit unit) const
}
}
/*!
\since 5.1
Sets the paper used by the printer to \a paperName.
\sa paperName()
*/
void QPrinter::setPaperName(const QString &paperName)
{
Q_D(QPrinter);
if (d->paintEngine->type() != QPaintEngine::Pdf)
ABORT_IF_ACTIVE("QPrinter::setPaperName");
d->printEngine->setProperty(QPrintEngine::PPK_PaperName, paperName);
d->addToManualSetList(QPrintEngine::PPK_PaperName);
}
/*!
\since 5.1
Returns the paper name of the paper set on the printer.
The default value for this is driver-dependent.
*/
QString QPrinter::paperName() const
{
Q_D(const QPrinter);
return d->printEngine->property(QPrintEngine::PPK_PaperName).toString();
}
/*!
Sets the page order to \a pageOrder.
@ -1959,6 +1990,8 @@ QPrinter::PrintRange QPrinter::printRange() const
\value PPK_PaperSources Specifies more than one QPrinter::PaperSource value.
\value PPK_PaperName A string specifying the name of the paper.
\value PPK_PaperSize Specifies a QPrinter::PaperSize value.
\value PPK_PrinterName A string specifying the name of the printer.

View File

@ -167,6 +167,9 @@ public:
void setPaperSize(const QSizeF &paperSize, Unit unit);
QSizeF paperSize(Unit unit) const;
void setPaperName(const QString &paperName);
QString paperName() const;
void setPageOrder(PageOrder);
PageOrder pageOrder() const;