From 776ec800cd24e7f4b30fa5e51f48cca4cc65d8bf Mon Sep 17 00:00:00 2001 From: Anton Thomasson Date: Sun, 8 Dec 2019 13:55:56 +0100 Subject: [PATCH] Start adding jobs view --- harbour-seaprint.desktop | 1 - harbour-seaprint.pro | 3 +- qml/pages/FirstPage.qml | 11 ++++- qml/pages/JobsPage.qml | 62 +++++++++++++++++++++++++++ qml/pages/utils.js | 5 +++ src/ippmsg.cpp | 51 ++++++++++++---------- src/ippmsg.h | 6 +-- src/ippprinter.cpp | 65 ++++++++++++++++++++++++++--- src/ippprinter.h | 11 ++++- translations/harbour-seaprint-de.ts | 15 +++++++ translations/harbour-seaprint.ts | 15 +++++++ 11 files changed, 208 insertions(+), 37 deletions(-) create mode 100644 qml/pages/JobsPage.qml diff --git a/harbour-seaprint.desktop b/harbour-seaprint.desktop index e9112aa..64f5665 100644 --- a/harbour-seaprint.desktop +++ b/harbour-seaprint.desktop @@ -9,4 +9,3 @@ Name=Seaprint # # Remember to comment out the following line, if you do not want to use # a different app name in German locale (de). -Name[de]=harbour-seaprint diff --git a/harbour-seaprint.pro b/harbour-seaprint.pro index a52d211..c12cbb6 100644 --- a/harbour-seaprint.pro +++ b/harbour-seaprint.pro @@ -24,8 +24,7 @@ SOURCES += src/harbour-seaprint.cpp \ DISTFILES += qml/harbour-seaprint.qml \ qml/cover/CoverPage.qml \ qml/pages/*.qml \ - qml/pages/WifiChecker.qml \ - qml/pages/utils.js \ + qml/pages/*.js \ qml/pages/printer.svg \ rpm/harbour-seaprint.changes.in \ rpm/harbour-seaprint.changes.run.in \ diff --git a/qml/pages/FirstPage.qml b/qml/pages/FirstPage.qml index 9a66ab5..072ff76 100644 --- a/qml/pages/FirstPage.qml +++ b/qml/pages/FirstPage.qml @@ -69,9 +69,9 @@ Page { spacing: Theme.paddingSmall - delegate: BackgroundItem { + delegate: ListItem { id: delegate - height: visible ? Math.max(column.implicitHeight, Theme.itemSizeLarge+2*Theme.paddingMedium) : 0 + contentItem.height: visible ? Math.max(column.implicitHeight, Theme.itemSizeLarge+2*Theme.paddingMedium) : 0 visible: printer.attrs["printer-name"] ? true : false enabled: Utils.can_print(printer, selectedFile) onClicked: { @@ -137,6 +137,13 @@ Page { } } + menu: ContextMenu { + MenuItem { + text: qsTr("View jobs") + onClicked: pageStack.push(Qt.resolvedUrl("JobsPage.qml"), {printer: printer}) + } + } + } onCountChanged: { console.log("count", count) diff --git a/qml/pages/JobsPage.qml b/qml/pages/JobsPage.qml new file mode 100644 index 0000000..7a39cf5 --- /dev/null +++ b/qml/pages/JobsPage.qml @@ -0,0 +1,62 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 + + +Page { + id: page + allowedOrientations: Orientation.All + + property var printer + + Component.onCompleted: { + printer.getJobs() + console.log(JSON.stringify(printer.jobs)) + } + + // To enable PullDownMenu, place our content in a SilicaFlickable + SilicaFlickable { + anchors.fill: parent + + // PullDownMenu and PushUpMenu must be declared in SilicaFlickable, SilicaListView or SilicaGridView + PullDownMenu { + MenuItem { + text: qsTr("Remove all") + onClicked: { + console.log("todo") + } + } + MenuItem { + text: qsTr("Refresh") + onClicked: { + console.log(JSON.stringify(printer.jobs)) + printer.getJobs(); + } + } + } + + SilicaListView { + anchors.fill: parent + id: listView + + model: printer.jobs.length + + header: PageHeader { + id: pageHeader + title: printer.name + + } + + delegate: ListItem { + + Label { + leftPadding: Theme.horizontalPageMargin + anchors.verticalCenter: parent.verticalCenter + text: printer.jobs[index]["job-id"].value + Component.onCompleted: console.log(JSON.stringify(printer.jobs)) + } + } + + } + + } +} diff --git a/qml/pages/utils.js b/qml/pages/utils.js index e7738c5..5730825 100644 --- a/qml/pages/utils.js +++ b/qml/pages/utils.js @@ -25,6 +25,11 @@ function _formats(printer) filters.push("*.jpeg"); } + if(supported.length == 0) + { + supported.push("No relevant formats supported") + } + return {supported: supported.join(" "), filters: filters}; } diff --git a/src/ippmsg.cpp b/src/ippmsg.cpp index cc8d67a..c0cf29c 100644 --- a/src/ippmsg.cpp +++ b/src/ippmsg.cpp @@ -12,7 +12,7 @@ IppMsg::IppMsg() IppMsg::IppMsg(QJsonObject opAttrs, QJsonObject jobAttrs) { _opAttrs = opAttrs; - _jobAttrs = jobAttrs; + _jobAttrs = QJsonArray {jobAttrs}; } @@ -31,24 +31,32 @@ IppMsg::IppMsg(QNetworkReply* resp) bts >> majVsn >> minVsn >> _status >> reqId; - QJsonObject* attrs = 0; + QJsonObject attrs; + IppMsg::IppTag currentAttrType = IppTag::EndAttrs; QString last_name; while(!bts.atEnd()) { - if(bts>>=(quint8)IppTag::OpAttrs) - { - attrs = &_opAttrs; - } - else if (bts>>=(quint8)IppTag::JobAttrs) { - attrs = &_jobAttrs; - } - else if (bts>>=(quint8)IppTag::EndAttrs) { - break; - } - else if (bts>>=(quint8)IppTag::PrinterAttrs) { - attrs = &_printerAttrs; + if(bts.peekU8() <= IppTag::PrinterAttrs) { + + if(currentAttrType == IppTag::OpAttrs) { + _opAttrs = attrs; + } + else if (currentAttrType == IppTag::JobAttrs) { + _jobAttrs.append(attrs); + } + else if (currentAttrType == IppTag::PrinterAttrs) { + _printerAttrs = attrs; + } + + if(bts >>= (uint8_t)IppTag::EndAttrs) { + break; + } + + currentAttrType = (IppTag)bts.getU8(); + attrs = QJsonObject(); + } else { last_name = consume_attribute(attrs, bts, last_name); @@ -56,7 +64,7 @@ IppMsg::IppMsg(QNetworkReply* resp) } } -QString IppMsg::consume_attribute(QJsonObject* attrs, Bytestream& data, QString lastName) +QString IppMsg::consume_attribute(QJsonObject& attrs, Bytestream& data, QString lastName) { quint8 tag; quint16 tmp_len; @@ -144,9 +152,9 @@ QString IppMsg::consume_attribute(QJsonObject* attrs, Bytestream& data, QString }; - if(attrs->contains(name)) + if(attrs.contains(name)) { - QJsonObject tmp = (*attrs)[name].toObject(); + QJsonObject tmp = attrs[name].toObject(); QJsonArray tmpa; if(tmp["value"].isArray()) { @@ -158,7 +166,7 @@ QString IppMsg::consume_attribute(QJsonObject* attrs, Bytestream& data, QString } tmpa.append(value); tmp["value"] = tmpa; - attrs->insert(name, tmp); + attrs.insert(name, tmp); } else { @@ -166,7 +174,7 @@ QString IppMsg::consume_attribute(QJsonObject* attrs, Bytestream& data, QString { value = QJsonArray {value}; } - attrs->insert(name, QJsonObject {{"tag", tag}, {"value", value}}); + attrs.insert(name, QJsonObject {{"tag", tag}, {"value", value}}); } return name; } @@ -189,10 +197,11 @@ QByteArray IppMsg::encode(Operation op) ipp << encode_attr(val["tag"].toInt(), it.key(), val["value"]); } } - if(!_jobAttrs.empty()) + for(QJsonArray::iterator ait = _jobAttrs.begin(); ait != _jobAttrs.begin(); ait++) { ipp << quint8(2); - for(QJsonObject::iterator it = _jobAttrs.begin(); it != _jobAttrs.end(); it++) + QJsonObject tmpObj = ait->toObject(); + for(QJsonObject::iterator it = tmpObj.begin(); it != tmpObj.end(); it++) { QJsonObject val = it.value().toObject(); ipp << encode_attr(val["tag"].toInt(), it.key(), val["value"]); diff --git a/src/ippmsg.h b/src/ippmsg.h index 0e8b016..db160a9 100644 --- a/src/ippmsg.h +++ b/src/ippmsg.h @@ -65,7 +65,7 @@ public: QByteArray encode(Operation op); QJsonObject getPrinterAttrs() {return _printerAttrs;} - QJsonObject getJobAttrs() {return _jobAttrs;} + QJsonArray getJobAttrs() {return _jobAttrs;} QJsonObject getOpAttrs() {return _opAttrs;} quint16 getStatus() {return _status;} @@ -73,11 +73,11 @@ public: protected: private: - QString consume_attribute(QJsonObject* attrs, Bytestream& data, QString lastName); + QString consume_attribute(QJsonObject& attrs, Bytestream& data, QString lastName); Bytestream encode_attr(quint8 tag, QString name, QJsonValueRef value); QJsonObject _opAttrs; - QJsonObject _jobAttrs; + QJsonArray _jobAttrs; QJsonObject _printerAttrs; quint16 _status; diff --git a/src/ippprinter.cpp b/src/ippprinter.cpp index 02f0bc2..27f4c36 100644 --- a/src/ippprinter.cpp +++ b/src/ippprinter.cpp @@ -3,15 +3,18 @@ IppPrinter::IppPrinter() { _nam = new QNetworkAccessManager(this); - _jnam = new QNetworkAccessManager(this); + _print_nam = new QNetworkAccessManager(this); + _jobs_nam = new QNetworkAccessManager(this); connect(_nam, SIGNAL(finished(QNetworkReply*)),this, SLOT(getPrinterAttributesFinished(QNetworkReply*))); - connect(_jnam, SIGNAL(finished(QNetworkReply*)),this, SLOT(jobRequestFinished(QNetworkReply*))); + connect(_print_nam, SIGNAL(finished(QNetworkReply*)),this, SLOT(printRequestFinished(QNetworkReply*))); + connect(_jobs_nam, SIGNAL(finished(QNetworkReply*)),this, SLOT(getJobsRequestFinished(QNetworkReply*))); QObject::connect(this, &IppPrinter::urlChanged, this, &IppPrinter::onUrlChanged); } IppPrinter::~IppPrinter() { delete _nam; - delete _jnam; + delete _print_nam; + delete _jobs_nam; } void IppPrinter::setUrl(QString url) @@ -52,10 +55,12 @@ void IppPrinter::onUrlChanged() void IppPrinter::getPrinterAttributesFinished(QNetworkReply *reply) { + qDebug() << reply->error() << reply->errorString() << reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString(); if(reply->error() == QNetworkReply::NoError) { try { IppMsg resp(reply); + qDebug() << resp.getStatus() << resp.getOpAttrs() << resp.getPrinterAttrs(); _attrs = resp.getPrinterAttrs(); emit attrsChanged(); } @@ -67,14 +72,14 @@ void IppPrinter::getPrinterAttributesFinished(QNetworkReply *reply) } -void IppPrinter::jobRequestFinished(QNetworkReply *reply) +void IppPrinter::printRequestFinished(QNetworkReply *reply) { if(reply->error() == QNetworkReply::NoError) { try { IppMsg resp(reply); qDebug() << resp.getStatus() << resp.getOpAttrs() << resp.getJobAttrs(); - _jobAttrs = resp.getJobAttrs(); + _jobAttrs = resp.getJobAttrs()[0].toObject(); emit jobAttrsChanged(); } catch(std::exception e) @@ -84,6 +89,23 @@ void IppPrinter::jobRequestFinished(QNetworkReply *reply) } } +void IppPrinter::getJobsRequestFinished(QNetworkReply *reply) +{ + if(reply->error() == QNetworkReply::NoError) + { + try { + IppMsg resp(reply); + qDebug() << resp.getStatus() << resp.getOpAttrs() << resp.getJobAttrs(); + _jobs = resp.getJobAttrs(); + emit jobsChanged(); + } + catch(std::exception e) + { + qDebug() << e.what(); + } + } +} + bool IppPrinter::print(QJsonObject attrs, QString filename){ qDebug() << "printing" << filename << attrs; @@ -127,7 +149,38 @@ bool IppPrinter::print(QJsonObject attrs, QString filename){ QByteArray filedata = file.readAll(); contents = contents.append(filedata); - _jnam->post(request, contents); + _print_nam->post(request, contents); file.close(); return true; } + +bool IppPrinter::getJobs() { + + qDebug() << "getting jobs"; + + QJsonObject o + { + {"attributes-charset", QJsonObject {{"tag", IppMsg::Charset}, {"value", "utf-8"}}}, + {"attributes-natural-language", QJsonObject {{"tag", IppMsg::NaturalLanguage}, {"value", "en-us"}}}, + {"printer-uri", QJsonObject {{"tag", IppMsg::Uri}, {"value", "ipp://"+_url}}}, + {"requesting-user-name", QJsonObject {{"tag", IppMsg::NameWithoutLanguage}, {"value", "nemo"}}} + }; + + IppMsg job = IppMsg(o, QJsonObject()); + + QNetworkRequest request; + QUrl url("http://"+_url); + if(url.port() == -1) { + url.setPort(631); + } + + QByteArray contents = job.encode(IppMsg::GetJobs); + + request.setUrl(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/ipp"); + _jobs_nam->post(request, contents); + + return true; +} + + diff --git a/src/ippprinter.h b/src/ippprinter.h index 51581c4..4043d8c 100644 --- a/src/ippprinter.h +++ b/src/ippprinter.h @@ -11,6 +11,8 @@ class IppPrinter : public QObject Q_PROPERTY(QString url READ getUrl WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(QJsonObject attrs MEMBER _attrs NOTIFY attrsChanged) Q_PROPERTY(QJsonObject jobAttrs MEMBER _jobAttrs NOTIFY jobAttrsChanged) + Q_PROPERTY(QJsonArray jobs MEMBER _jobs NOTIFY jobsChanged) + public: IppPrinter(); @@ -21,25 +23,30 @@ public: void setUrl(QString url); Q_INVOKABLE bool print(QJsonObject attrs, QString file); + Q_INVOKABLE bool getJobs(); signals: void urlChanged(); void attrsChanged(); void jobAttrsChanged(); + void jobsChanged(); public slots: void onUrlChanged(); void getPrinterAttributesFinished(QNetworkReply* reply); - void jobRequestFinished(QNetworkReply* reply); + void printRequestFinished(QNetworkReply* reply); + void getJobsRequestFinished(QNetworkReply* reply); private: QString _url; QNetworkAccessManager* _nam; - QNetworkAccessManager* _jnam; + QNetworkAccessManager* _jobs_nam; + QNetworkAccessManager* _print_nam; QJsonObject _attrs; QJsonObject _jobAttrs; + QJsonArray _jobs; }; diff --git a/translations/harbour-seaprint-de.ts b/translations/harbour-seaprint-de.ts index d04b99f..18aae81 100644 --- a/translations/harbour-seaprint-de.ts +++ b/translations/harbour-seaprint-de.ts @@ -100,6 +100,21 @@ None + + View jobs + + + + + JobsPage + + Refresh + + + + Remove all + + PrinterPage diff --git a/translations/harbour-seaprint.ts b/translations/harbour-seaprint.ts index a08e9f9..d61d19e 100644 --- a/translations/harbour-seaprint.ts +++ b/translations/harbour-seaprint.ts @@ -100,6 +100,21 @@ None + + View jobs + + + + + JobsPage + + Refresh + + + + Remove all + + PrinterPage