From 51c90e6443383c732c60bfcd7f30d91ad3b173c6 Mon Sep 17 00:00:00 2001 From: Anton Thomasson Date: Sun, 10 Jul 2022 17:06:31 +0200 Subject: [PATCH] Add two-stage create/send print job support --- src/ippmsg.cpp | 5 +++++ src/ippmsg.h | 2 ++ src/ippprinter.cpp | 43 ++++++++++++++++++++++++++++++++----------- src/ippprinter.h | 2 +- src/printerworker.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- src/printerworker.h | 1 + 6 files changed, 82 insertions(+), 14 deletions(-) diff --git a/src/ippmsg.cpp b/src/ippmsg.cpp index 15b5749..7bce38a 100644 --- a/src/ippmsg.cpp +++ b/src/ippmsg.cpp @@ -441,3 +441,8 @@ void IppMsg::encode_attr(Bytestream& msg, quint8 tag, QString name, QJsonValue v break; } } + +void IppMsg::setOpAttr(QString name, IppMsg::IppTag type, QJsonValue value) +{ + _opAttrs.insert(name, QJsonObject {{"tag", type}, {"value", value}}); +} diff --git a/src/ippmsg.h b/src/ippmsg.h index 1b33ae2..ba389a2 100644 --- a/src/ippmsg.h +++ b/src/ippmsg.h @@ -76,6 +76,8 @@ public: QJsonArray getJobAttrs() {return _jobAttrs;} QJsonObject getOpAttrs() {return _opAttrs;} + void setOpAttr(QString name, IppMsg::IppTag type, QJsonValue value); + quint16 getStatus() {return _status;} diff --git a/src/ippprinter.cpp b/src/ippprinter.cpp index 3a61913..5252052 100644 --- a/src/ippprinter.cpp +++ b/src/ippprinter.cpp @@ -21,6 +21,7 @@ IppPrinter::IppPrinter() : _worker(this) connect(this, &IppPrinter::doCancelJob, &_worker, &PrinterWorker::cancelJob); connect(this, &IppPrinter::doIdentify, &_worker, &PrinterWorker::identify); connect(this, &IppPrinter::doPrint, &_worker, &PrinterWorker::print); + connect(this, &IppPrinter::doPrint2, &_worker, &PrinterWorker::print2); connect(this, &IppPrinter::doGetStrings, &_worker, &PrinterWorker::getStrings); connect(this, &IppPrinter::doGetImage, &_worker, &PrinterWorker::getImage); @@ -574,9 +575,6 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename) qDebug() << supportedMimeTypes << supportedMimeTypes.contains(mimeType); - QJsonObject o = opAttrs(); - o.insert("job-name", QJsonObject {{"tag", IppMsg::NameWithoutLanguage}, {"value", fileinfo.fileName()}}); - Params.paperSizeName = getAttrOrDefault(jobAttrs, "media").toString(Params.paperSizeName.c_str()).toStdString(); QString targetFormat = getAttrOrDefault(jobAttrs, "document-format").toString(); @@ -638,8 +636,9 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename) jobAttrs.remove("media"); } + QJsonObject jobOpAttrs = opAttrs(); // document-format goes in the op-attrs and not the job-attrs - o.insert("document-format", QJsonObject {{"tag", IppMsg::MimeMediaType}, {"value", targetFormat}}); + jobOpAttrs.insert("document-format", QJsonObject {{"tag", IppMsg::MimeMediaType}, {"value", targetFormat}}); jobAttrs.remove("document-format"); targetFormat = targetFormatIfAuto(targetFormat, mimeType, supportedMimeTypes); @@ -677,7 +676,7 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename) Params.paperSizeW = size.width(); Params.paperSizeH = size.height(); - qDebug() << "Printing job" << o << jobAttrs; + qDebug() << "Printing job" << jobOpAttrs << jobAttrs; QJsonValue PrinterResolutionRef = getAttrOrDefault(jobAttrs, "printer-resolution"); Params.hwResW = PrinterResolutionRef.toObject()["x"].toInt(Params.hwResW); @@ -702,10 +701,6 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename) } } - qDebug() << "Final op attributes:" << o; - qDebug() << "Final job attributes:" << jobAttrs; - - QString Sides = getAttrOrDefault(jobAttrs, "sides").toString(); if(Sides=="two-sided-long-edge") @@ -718,8 +713,34 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename) Params.tumble = true; } - IppMsg job = mk_msg(IppMsg::PrintJob, o, jobAttrs); - emit doPrint(filename, mimeType, targetFormat, job, Params, margins); + QJsonArray supportedOperations = _attrs["operations-supported"].toObject()["value"].toArray(); + + if(supportedOperations.contains(IppMsg::CreateJob) && supportedOperations.contains(IppMsg::SendDocument)) + { + QJsonObject createJobOpAttrs = opAttrs(); + createJobOpAttrs.insert("job-name", QJsonObject {{"tag", IppMsg::NameWithoutLanguage}, {"value", fileinfo.fileName()}}); + + qDebug() << "Final create op attributes:" << createJobOpAttrs; + qDebug() << "Final job attributes:" << jobAttrs; + + IppMsg createJob = mk_msg(IppMsg::CreateJob, createJobOpAttrs, jobAttrs); + qDebug() << "Final job op attributes:" << jobOpAttrs; + + IppMsg sendDoc = mk_msg(IppMsg::SendDocument, jobOpAttrs); + + emit doPrint2(filename, mimeType, targetFormat, createJob, sendDoc, Params, margins); + } + else + { + jobOpAttrs.insert("job-name", QJsonObject {{"tag", IppMsg::NameWithoutLanguage}, {"value", fileinfo.fileName()}}); + + qDebug() << "Final op attributes:" << jobOpAttrs; + qDebug() << "Final job attributes:" << jobAttrs; + + IppMsg job = mk_msg(IppMsg::PrintJob, jobOpAttrs, jobAttrs); + emit doPrint(filename, mimeType, targetFormat, job, Params, margins); + } + } bool IppPrinter::getJobs() { diff --git a/src/ippprinter.h b/src/ippprinter.h index aa56741..bfb03cd 100644 --- a/src/ippprinter.h +++ b/src/ippprinter.h @@ -73,6 +73,7 @@ signals: void doConvertPlaintext(QString filename, Bytestream header, PrintParameters Params); void doPrint(QString filename, QString mimeType, QString targetFormat, IppMsg job, PrintParameters Params, QMargins margins); + void doPrint2(QString filename, QString mimeType, QString targetFormat, IppMsg createJob, IppMsg sendDocument, PrintParameters Params, QMargins margins); void doGetStrings(QUrl url); void doGetImage(QUrl url); @@ -84,7 +85,6 @@ signals: public slots: void print(QJsonObject attrs, QString file); - void onUrlChanged(); void MaybeGetStrings(); void MaybeGetIcon(bool retry=false); diff --git a/src/printerworker.cpp b/src/printerworker.cpp index 6eb2106..d7290f2 100644 --- a/src/printerworker.cpp +++ b/src/printerworker.cpp @@ -60,16 +60,55 @@ void PrinterWorker::identify(Bytestream msg) awaitResult(cr, "identifyFinished"); } +void PrinterWorker::print2(QString filename, QString mimeType, QString targetFormat, IppMsg createJob, IppMsg sendDocument, PrintParameters Params, QMargins margins) +{ + emit busyMessage(tr("Preparing")); + + Bytestream header = createJob.encode(); + + CurlRequester cr(_printer->httpUrl(), CurlRequester::IppRequest, &header); + + Bytestream resData; + CURLcode res = cr.await(&resData); + + if(res == CURLE_OK) + { + IppMsg resMsg(resData); + qDebug() << resMsg.getOpAttrs() << resMsg.getJobAttrs(); + + QJsonObject resJobAttrs = resMsg.getJobAttrs()[0].toObject(); + if(resMsg.getStatus() <= 0xff && resJobAttrs.contains("job-id")) + { + int jobId = resJobAttrs["job-id"].toObject()["value"].toInt(); + sendDocument.setOpAttr("job-id", IppMsg::Integer, jobId); + sendDocument.setOpAttr("last-document", IppMsg::Boolean, true); + print(filename, mimeType, targetFormat, sendDocument, Params, margins); + } + else + { + QMetaObject::invokeMethod(_printer, "printRequestFinished", Qt::QueuedConnection, + Q_ARG(CURLcode, res), + Q_ARG(Bytestream, resData)); + } + } + else + { + QMetaObject::invokeMethod(_printer, "printRequestFinished", Qt::QueuedConnection, + Q_ARG(CURLcode, res), + Q_ARG(Bytestream, resData)); + } +} + void PrinterWorker::print(QString filename, QString mimeType, QString targetFormat, IppMsg job, PrintParameters Params, QMargins margins) { - try { + try + { Mimer* mimer = Mimer::instance(); Bytestream contents = job.encode(); emit busyMessage(tr("Preparing")); - if((mimeType == targetFormat) && (targetFormat == Mimer::Postscript)) { // Can't process Postscript justUpload(filename, contents); diff --git a/src/printerworker.h b/src/printerworker.h index c5ac1dd..5e65824 100644 --- a/src/printerworker.h +++ b/src/printerworker.h @@ -39,6 +39,7 @@ public slots: void cancelJob(Bytestream msg); void identify(Bytestream msg); void print(QString filename, QString mimeType, QString targetFormat, IppMsg job, PrintParameters Params, QMargins margins); + void print2(QString filename, QString mimeType, QString targetFormat, IppMsg createJob, IppMsg sendDocument, PrintParameters Params, QMargins margins); signals: void progress(qint64 done, qint64 pages);