Make the icon an attribute on the printer object
This allows retrying based on actual size and using cURL for getting the icon to avoid old Qt network code.
This commit is contained in:
parent
d8267db9fe
commit
0efd96c072
12 changed files with 154 additions and 75 deletions
|
@ -36,6 +36,7 @@ DEFINES += SEAPRINT_VERSION='\\"$$VERSION\\"'
|
|||
SOURCES += src/harbour-seaprint.cpp \
|
||||
src/convertchecker.cpp \
|
||||
src/curlrequester.cpp \
|
||||
src/imageitem.cpp \
|
||||
src/ippdiscovery.cpp \
|
||||
src/ippmsg.cpp \
|
||||
src/ippprinter.cpp \
|
||||
|
@ -82,6 +83,7 @@ TRANSLATIONS += translations/harbour-seaprint-de.ts \
|
|||
HEADERS += \
|
||||
src/convertchecker.h \
|
||||
src/curlrequester.h \
|
||||
src/imageitem.h \
|
||||
src/ippdiscovery.h \
|
||||
src/ippmsg.h \
|
||||
src/ippprinter.h \
|
||||
|
|
|
@ -4,6 +4,7 @@ import Sailfish.Pickers 1.0
|
|||
import seaprint.ippdiscovery 1.0
|
||||
import seaprint.convertchecker 1.0
|
||||
import seaprint.ippprinter 1.0
|
||||
import seaprint.imageitem 1.0
|
||||
import seaprint.mimer 1.0
|
||||
import "utils.js" as Utils
|
||||
|
||||
|
@ -212,7 +213,7 @@ Page {
|
|||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
ImageItem {
|
||||
id: icon
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
|
@ -221,13 +222,17 @@ Page {
|
|||
|
||||
height: Theme.itemSizeLarge
|
||||
width: Theme.itemSizeLarge
|
||||
sourceSize.height: height
|
||||
sourceSize.width: width
|
||||
source: printer.attrs["printer-icons"] ? "image://ippdiscovery/"+Utils.selectIcon(printer.attrs["printer-icons"].value)
|
||||
: "image://svg/qml/pages/icon-seaprint-nobg.svg"
|
||||
// Some printers serve their icons over https with invalid certs...
|
||||
onStatusChanged: if (status == Image.Error) source = "image://svg/qml/pages/icon-seaprint-nobg.svg"
|
||||
image: printer.icon
|
||||
|
||||
Image {
|
||||
id: placeholder
|
||||
anchors.fill: parent
|
||||
sourceSize.height: height
|
||||
sourceSize.width: width
|
||||
|
||||
visible: !parent.valid
|
||||
source: "image://svg/qml/pages/icon-seaprint-nobg.svg"
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
|
|
|
@ -461,26 +461,6 @@ function fixupChoices(name, choices, mimeType)
|
|||
}
|
||||
}
|
||||
|
||||
function selectIcon(icons)
|
||||
{
|
||||
for(var i=0; i < icons.length; i++)
|
||||
{
|
||||
if(endsWith("M.png", icons[i]) || endsWith("128.png", icons[i]) || endsWith("128.PNG", icons[i]))
|
||||
{
|
||||
return icons[i];
|
||||
}
|
||||
}
|
||||
// Icons must be 48, 128 or 256px and sorted by size, so if all 3 are provided we want the middle one
|
||||
if(icons.length == 3)
|
||||
{
|
||||
return icons[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return icons[0];
|
||||
}
|
||||
}
|
||||
|
||||
function isWaringState(printer)
|
||||
{
|
||||
if(printer.attrs["printer-state"].value > 4)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <sailfishapp.h>
|
||||
#include <src/ippdiscovery.h>
|
||||
#include <src/ippprinter.h>
|
||||
#include <src/imageitem.h>
|
||||
#include <src/mimer.h>
|
||||
#include <src/convertchecker.h>
|
||||
#include <src/svgprovider.h>
|
||||
|
@ -41,12 +42,12 @@ int main(int argc, char *argv[])
|
|||
qmlRegisterSingletonType<ConvertChecker>("seaprint.convertchecker", 1, 0, "ConvertChecker", singletontype_provider<ConvertChecker>);
|
||||
qmlRegisterSingletonType<ConvertChecker>("seaprint.settings", 1, 0, "SeaPrintSettings", singletontype_provider<Settings>);
|
||||
qmlRegisterType<IppPrinter>("seaprint.ippprinter", 1, 0, "IppPrinter");
|
||||
qmlRegisterType<ImageItem>("seaprint.imageitem", 1, 0, "ImageItem");
|
||||
qmlRegisterUncreatableType<IppMsg>("seaprint.ippmsg", 1, 0, "IppMsg", "Only used to supply an enum type");
|
||||
|
||||
QQuickView* view = SailfishApp::createView();
|
||||
|
||||
view->engine()->addImportPath(SailfishApp::pathTo("qml/pages").toString());
|
||||
view->engine()->addImageProvider(QLatin1String("ippdiscovery"), IppDiscovery::instance());
|
||||
view->engine()->addImageProvider(QLatin1String("svg"), SvgProvider::instance());
|
||||
|
||||
view->setSource(SailfishApp::pathToMainQml());
|
||||
|
|
32
src/imageitem.cpp
Normal file
32
src/imageitem.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include "imageitem.h"
|
||||
#include "svgprovider.h"
|
||||
|
||||
ImageItem::ImageItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ImageItem::paint(QPainter *painter)
|
||||
{
|
||||
|
||||
QImage scaled = _image.scaledToHeight(boundingRect().height(), Qt::SmoothTransformation);
|
||||
painter->drawImage(QPoint {0, 0}, scaled);
|
||||
}
|
||||
|
||||
QImage ImageItem::getImage() const
|
||||
{
|
||||
return _image;
|
||||
}
|
||||
|
||||
void ImageItem::setImage(const QImage &image)
|
||||
{
|
||||
_image = image;
|
||||
emit imageChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
bool ImageItem::isValid() const
|
||||
{
|
||||
return !_image.isNull();
|
||||
}
|
31
src/imageitem.h
Normal file
31
src/imageitem.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef IMAGEITEM_H
|
||||
#define IMAGEITEM_H
|
||||
|
||||
#include <QQuickPaintedItem>
|
||||
#include <QPainter>
|
||||
#include <QImage>
|
||||
|
||||
class ImageItem : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QImage image READ getImage WRITE setImage NOTIFY imageChanged)
|
||||
Q_PROPERTY(bool valid READ isValid NOTIFY imageChanged)
|
||||
public:
|
||||
ImageItem();
|
||||
|
||||
void paint(QPainter *painter);
|
||||
|
||||
signals:
|
||||
void imageChanged();
|
||||
|
||||
private:
|
||||
QImage getImage() const;
|
||||
void setImage(const QImage &image);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
QImage _image;
|
||||
};
|
||||
|
||||
#endif // IMAGEITEM_H
|
|
@ -37,7 +37,7 @@ QStringList get_addr(Bytestream& bts)
|
|||
return addr;
|
||||
}
|
||||
|
||||
IppDiscovery::IppDiscovery() : QStringListModel(), QQuickImageProvider(QQuickImageProvider::Image, ForceAsynchronousImageLoading)
|
||||
IppDiscovery::IppDiscovery() : QStringListModel()
|
||||
{
|
||||
socket = new QUdpSocket(this);
|
||||
connect(socket, &QUdpSocket::readyRead, this, &IppDiscovery::readPendingDatagrams);
|
||||
|
@ -419,37 +419,3 @@ void IppDiscovery::resolve(QUrl& url)
|
|||
url.setHost(_AAs.value(host));
|
||||
}
|
||||
}
|
||||
|
||||
QImage IppDiscovery::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
|
||||
{ //TODO: consider caching images (doesn't appear to be needed currently)
|
||||
Q_UNUSED(requestedSize);
|
||||
qDebug() << "requesting image" << id;
|
||||
|
||||
QImage img;
|
||||
|
||||
QNetworkAccessManager* nam = new QNetworkAccessManager();
|
||||
QUrl url(id);
|
||||
|
||||
resolve(url);
|
||||
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::UserAgentHeader, "SeaPrint " SEAPRINT_VERSION);
|
||||
connect(nam, &QNetworkAccessManager::sslErrors, &IppPrinter::ignoreSslErrors);
|
||||
|
||||
QNetworkReply* reply = nam->get(request);
|
||||
|
||||
QEventLoop loop;
|
||||
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||
loop.exec();
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
QImageReader imageReader(reply);
|
||||
img = imageReader.read();
|
||||
}
|
||||
|
||||
*size = img.size();
|
||||
delete nam;
|
||||
return img;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
#ifndef IPPDISCOVERY_H
|
||||
#define IPPDISCOVERY_H
|
||||
#include <QStringListModel>
|
||||
#include <QQuickImageProvider>
|
||||
#include <QUdpSocket>
|
||||
#include <QMutex>
|
||||
#include <QImageReader>
|
||||
#include <QtNetwork>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QEventLoop>
|
||||
#include "bytestream.h"
|
||||
|
||||
class IppDiscovery : public QStringListModel, public QQuickImageProvider
|
||||
class IppDiscovery : public QStringListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -49,9 +44,6 @@ private:
|
|||
|
||||
void updateAndQueryPtrs(QStringList& ptrs, QStringList new_ptrs);
|
||||
|
||||
|
||||
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
|
||||
|
||||
QStringList _ipp;
|
||||
QStringList _ipps;
|
||||
QMap<QString,QString> _rps;
|
||||
|
|
|
@ -25,6 +25,7 @@ IppPrinter::IppPrinter() : _worker(this)
|
|||
connect(this, &IppPrinter::doConvertPlaintext, &_worker, &PrinterWorker::convertPlaintext);
|
||||
|
||||
connect(this, &IppPrinter::doGetStrings, &_worker, &PrinterWorker::getStrings);
|
||||
connect(this, &IppPrinter::doGetImage, &_worker, &PrinterWorker::getImage);
|
||||
|
||||
connect(&_worker, &PrinterWorker::progress, this, &IppPrinter::setProgress);
|
||||
connect(&_worker, &PrinterWorker::busyMessage, this, &IppPrinter::setBusyMessage);
|
||||
|
@ -106,7 +107,7 @@ void IppPrinter::refresh() {
|
|||
}
|
||||
emit attrsChanged();
|
||||
|
||||
MaybeGetStrings();
|
||||
// MaybeGetStrings(); - for testing fake file-prinetrs with a strings file hosted elsewhere
|
||||
UpdateAdditionalDocumentFormats();
|
||||
}
|
||||
else
|
||||
|
@ -128,6 +129,41 @@ void IppPrinter::MaybeGetStrings()
|
|||
}
|
||||
}
|
||||
|
||||
void IppPrinter::MaybeGetIcon(bool retry)
|
||||
{
|
||||
if(_attrs.contains("printer-icons") && (_icon.isNull() || retry))
|
||||
{
|
||||
QUrl url;
|
||||
QJsonArray icons = _attrs["printer-icons"].toObject()["value"].toArray();
|
||||
|
||||
if(retry)
|
||||
{ // If there were more than one icon, try the last one on the retry
|
||||
if(icons.size() > 1)
|
||||
{
|
||||
url = icons.last().toString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(icons.size() == 3)
|
||||
{ // If there are 3 icons, the first will be the 48px one, ignore it
|
||||
url = icons.at(1).toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
url = icons.at(0).toString();
|
||||
}
|
||||
}
|
||||
|
||||
if(!url.isEmpty())
|
||||
{
|
||||
IppDiscovery::instance()->resolve(url);
|
||||
emit doGetImage(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IppPrinter::UpdateAdditionalDocumentFormats()
|
||||
{
|
||||
_additionalDocumentFormats = QStringList();
|
||||
|
@ -180,6 +216,7 @@ void IppPrinter::getPrinterAttributesFinished(CURLcode res, Bytestream data)
|
|||
emit attrsChanged();
|
||||
|
||||
MaybeGetStrings();
|
||||
MaybeGetIcon();
|
||||
UpdateAdditionalDocumentFormats();
|
||||
}
|
||||
|
||||
|
@ -272,6 +309,26 @@ void IppPrinter::getStringsFinished(CURLcode res, Bytestream data)
|
|||
}
|
||||
}
|
||||
|
||||
void IppPrinter::getImageFinished(CURLcode res, Bytestream data)
|
||||
{
|
||||
qDebug() << res << data.size();
|
||||
if(res == CURLE_OK)
|
||||
{
|
||||
QImage tmp;
|
||||
if(tmp.loadFromData(data.raw(), data.size(), "PNG"))
|
||||
{
|
||||
_icon = tmp;
|
||||
qDebug() << "image loaded" << _icon;
|
||||
emit iconChanged();
|
||||
|
||||
if(tmp.size().width() < 128)
|
||||
{
|
||||
MaybeGetIcon(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IppPrinter::ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
||||
{
|
||||
bool ignore = Settings::instance()->ignoreSslErrors();
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#ifndef IPPPRINTER_H
|
||||
#define IPPPRINTER_H
|
||||
|
||||
#include <QtNetwork>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QImage>
|
||||
#include "ippmsg.h"
|
||||
#include "printerworker.h"
|
||||
#include "curlrequester.h"
|
||||
|
@ -19,6 +18,7 @@ class IppPrinter : public QObject
|
|||
Q_PROPERTY(QJsonObject jobAttrs MEMBER _jobAttrs NOTIFY jobAttrsChanged)
|
||||
Q_PROPERTY(QJsonArray jobs MEMBER _jobs NOTIFY jobsChanged)
|
||||
Q_PROPERTY(QJsonObject strings MEMBER _strings NOTIFY stringsChanged)
|
||||
Q_PROPERTY(QImage icon MEMBER _icon NOTIFY iconChanged)
|
||||
Q_PROPERTY(QStringList additionalDocumentFormats MEMBER _additionalDocumentFormats NOTIFY additionalDocumentFormatsChanged)
|
||||
Q_PROPERTY(QString busyMessage MEMBER _busyMessage NOTIFY busyMessageChanged)
|
||||
Q_PROPERTY(QString progress MEMBER _progress NOTIFY progressChanged)
|
||||
|
@ -49,6 +49,7 @@ signals:
|
|||
void jobsChanged();
|
||||
|
||||
void stringsChanged();
|
||||
void iconChanged();
|
||||
|
||||
void jobFinished(bool status);
|
||||
void cancelStatus(bool status);
|
||||
|
@ -78,6 +79,7 @@ signals:
|
|||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble, bool BackHFlip, bool BackVFlip);
|
||||
|
||||
void doGetStrings(QUrl url);
|
||||
void doGetImage(QUrl url);
|
||||
|
||||
void additionalDocumentFormatsChanged();
|
||||
void busyMessageChanged();
|
||||
|
@ -89,6 +91,7 @@ public slots:
|
|||
|
||||
void onUrlChanged();
|
||||
void MaybeGetStrings();
|
||||
void MaybeGetIcon(bool retry=false);
|
||||
void UpdateAdditionalDocumentFormats();
|
||||
void getPrinterAttributesFinished(CURLcode res, Bytestream data);
|
||||
void printRequestFinished(CURLcode res, Bytestream data);
|
||||
|
@ -96,6 +99,7 @@ public slots:
|
|||
void cancelJobFinished(CURLcode res, Bytestream data);
|
||||
|
||||
void getStringsFinished(CURLcode res, Bytestream data);
|
||||
void getImageFinished(CURLcode res, Bytestream data);
|
||||
|
||||
static void ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
|
||||
|
||||
|
@ -122,6 +126,7 @@ private:
|
|||
QJsonArray _jobs;
|
||||
|
||||
QJsonObject _strings;
|
||||
QImage _icon;
|
||||
|
||||
QStringList _additionalDocumentFormats;
|
||||
|
||||
|
|
|
@ -26,6 +26,13 @@ void PrinterWorker::getStrings(QUrl url)
|
|||
connect(&cr, &CurlRequester::done, _printer, &IppPrinter::getStringsFinished);
|
||||
}
|
||||
|
||||
void PrinterWorker::getImage(QUrl url)
|
||||
{
|
||||
CurlRequester cr(url, CurlRequester::HttpGetRequest);
|
||||
connect(&cr, &CurlRequester::done, _printer, &IppPrinter::getImageFinished);
|
||||
}
|
||||
|
||||
|
||||
void PrinterWorker::getPrinterAttributes(Bytestream msg)
|
||||
{
|
||||
CurlRequester cr(_printer->httpUrl());
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
|
||||
public slots:
|
||||
void getStrings(QUrl url);
|
||||
void getImage(QUrl url);
|
||||
void getPrinterAttributes(Bytestream msg);
|
||||
void getJobs(Bytestream msg);
|
||||
void cancelJob(Bytestream msg);
|
||||
|
|
Loading…
Reference in a new issue