Make ippdiscovery a QQuickImageProvider...
...so that SSL errors can be ignored, and .local-addresses can be resolved
This commit is contained in:
parent
3e8da3f488
commit
684eb9669b
4 changed files with 122 additions and 28 deletions
|
@ -14,10 +14,6 @@ Page {
|
||||||
property string selectedFile: ""
|
property string selectedFile: ""
|
||||||
property string selectedFileType
|
property string selectedFileType
|
||||||
|
|
||||||
IppDiscovery {
|
|
||||||
id: discovery
|
|
||||||
}
|
|
||||||
|
|
||||||
WifiChecker {
|
WifiChecker {
|
||||||
id: wifi
|
id: wifi
|
||||||
onConnectedChanged: {
|
onConnectedChanged: {
|
||||||
|
@ -25,10 +21,10 @@ Page {
|
||||||
if(connected) {
|
if(connected) {
|
||||||
var favourites = db.getFavourites(ssid);
|
var favourites = db.getFavourites(ssid);
|
||||||
console.log(favourites);
|
console.log(favourites);
|
||||||
discovery.favourites = favourites;
|
IppDiscovery.favourites = favourites;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
discovery.favourites = []
|
IppDiscovery.favourites = []
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,7 +35,7 @@ Page {
|
||||||
console.log("ssid changed", ssid);
|
console.log("ssid changed", ssid);
|
||||||
if(!initialSSIDchange)
|
if(!initialSSIDchange)
|
||||||
{
|
{
|
||||||
discovery.reset();
|
IppDiscovery.reset();
|
||||||
}
|
}
|
||||||
initialSSIDchange = false;
|
initialSSIDchange = false;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +44,7 @@ Page {
|
||||||
signal refreshed()
|
signal refreshed()
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
discovery.discover();
|
IppDiscovery.discover();
|
||||||
if(selectedFile != "")
|
if(selectedFile != "")
|
||||||
{ // Until i can convince FilePickerPage to do its magic without user interaction
|
{ // Until i can convince FilePickerPage to do its magic without user interaction
|
||||||
if(Utils.endsWith(".pdf", selectedFile))
|
if(Utils.endsWith(".pdf", selectedFile))
|
||||||
|
@ -85,14 +81,14 @@ Page {
|
||||||
dialog.accepted.connect(function() {
|
dialog.accepted.connect(function() {
|
||||||
console.log("add", wifi.ssid, dialog.value);
|
console.log("add", wifi.ssid, dialog.value);
|
||||||
db.addFavourite(wifi.ssid, dialog.value);
|
db.addFavourite(wifi.ssid, dialog.value);
|
||||||
discovery.favourites = db.getFavourites(wifi.ssid);
|
IppDiscovery.favourites = db.getFavourites(wifi.ssid);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("Refresh")
|
text: qsTr("Refresh")
|
||||||
onClicked: {
|
onClicked: {
|
||||||
discovery.discover();
|
IppDiscovery.discover();
|
||||||
page.refreshed();
|
page.refreshed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +97,7 @@ Page {
|
||||||
SilicaListView {
|
SilicaListView {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
id: listView
|
id: listView
|
||||||
model: discovery
|
model: IppDiscovery
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,7 +158,7 @@ Page {
|
||||||
|
|
||||||
height: Theme.itemSizeLarge
|
height: Theme.itemSizeLarge
|
||||||
width: Theme.itemSizeLarge
|
width: Theme.itemSizeLarge
|
||||||
source: printer.attrs["printer-icons"] ? printer.attrs["printer-icons"].value[0] : "icon-seaprint-nobg.svg"
|
source: printer.attrs["printer-icons"] ? "image://ippdiscovery/"+printer.attrs["printer-icons"].value[0] : "icon-seaprint-nobg.svg"
|
||||||
// Some printers serve their icons over https with invalid certs...
|
// Some printers serve their icons over https with invalid certs...
|
||||||
onStatusChanged: if (status == Image.Error) source = "icon-seaprint-nobg.svg"
|
onStatusChanged: if (status == Image.Error) source = "icon-seaprint-nobg.svg"
|
||||||
}
|
}
|
||||||
|
@ -215,7 +211,7 @@ Page {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
removeRemorse.execute(delegate, qsTr("Removing printer"),
|
removeRemorse.execute(delegate, qsTr("Removing printer"),
|
||||||
function() {db.removeFavourite(wifi.ssid, model.display);
|
function() {db.removeFavourite(wifi.ssid, model.display);
|
||||||
discovery.favourites = db.getFavourites()})
|
IppDiscovery.favourites = db.getFavourites()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,24 +5,32 @@
|
||||||
#include <src/ippdiscovery.h>
|
#include <src/ippdiscovery.h>
|
||||||
#include <src/ippprinter.h>
|
#include <src/ippprinter.h>
|
||||||
|
|
||||||
|
static QObject* ippdiscovery_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||||
|
{
|
||||||
|
Q_UNUSED(engine)
|
||||||
|
Q_UNUSED(scriptEngine)
|
||||||
|
|
||||||
|
IppDiscovery *ippdiscovery = IppDiscovery::instance();
|
||||||
|
return ippdiscovery;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QGuiApplication* app = SailfishApp::application(argc, argv);
|
QGuiApplication* app = SailfishApp::application(argc, argv);
|
||||||
|
|
||||||
app->setApplicationVersion(QStringLiteral(SEAPRINT_VERSION));
|
app->setApplicationVersion(QStringLiteral(SEAPRINT_VERSION));
|
||||||
|
|
||||||
qmlRegisterType<IppDiscovery>("seaprint.ippdiscovery", 1, 0, "IppDiscovery");
|
qmlRegisterSingletonType<IppDiscovery>("seaprint.ippdiscovery", 1, 0, "IppDiscovery", ippdiscovery_singletontype_provider);
|
||||||
qmlRegisterType<IppPrinter>("seaprint.ippprinter", 1, 0, "IppPrinter");
|
qmlRegisterType<IppPrinter>("seaprint.ippprinter", 1, 0, "IppPrinter");
|
||||||
|
|
||||||
// SailfishApp::main() will display "qml/harbour-printtool.qml", if you need more
|
QQuickView* view = SailfishApp::createView();
|
||||||
// control over initialization, you can use:
|
|
||||||
//
|
view->engine()->addImportPath(SailfishApp::pathTo("qml/pages").toString());
|
||||||
// - SailfishApp::application(int, char *[]) to get the QGuiApplication *
|
view->engine()->addImageProvider(QLatin1String("ippdiscovery"), IppDiscovery::instance());
|
||||||
// - SailfishApp::createView() to get a new QQuickView * instance
|
|
||||||
// - SailfishApp::pathTo(QString) to get a QUrl to a resource file
|
view->setSource(SailfishApp::pathToMainQml());
|
||||||
// - SailfishApp::pathToMainQml() to get a QUrl to the main QML file
|
view->show();
|
||||||
//
|
return app->exec();
|
||||||
// To display the view, call "show()" (will show fullscreen on device).
|
|
||||||
|
|
||||||
return SailfishApp::main(argc, argv);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ QStringList get_addr(Bytestream& bts)
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
IppDiscovery::IppDiscovery() : QStringListModel()
|
IppDiscovery::IppDiscovery() : QStringListModel(), QQuickImageProvider(QQuickImageProvider::Image)
|
||||||
{
|
{
|
||||||
socket = new QUdpSocket(this);
|
socket = new QUdpSocket(this);
|
||||||
connect(socket, SIGNAL(readyRead()),
|
connect(socket, SIGNAL(readyRead()),
|
||||||
|
@ -57,6 +57,24 @@ IppDiscovery::~IppDiscovery() {
|
||||||
delete socket;
|
delete socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IppDiscovery* IppDiscovery::m_Instance = 0;
|
||||||
|
|
||||||
|
IppDiscovery* IppDiscovery::instance()
|
||||||
|
{
|
||||||
|
static QMutex mutex;
|
||||||
|
if (!m_Instance)
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
|
||||||
|
if (!m_Instance)
|
||||||
|
m_Instance = new IppDiscovery;
|
||||||
|
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_Instance;
|
||||||
|
}
|
||||||
|
|
||||||
void IppDiscovery::discover() {
|
void IppDiscovery::discover() {
|
||||||
sendQuery(PTR, {"_ipp","_tcp","local"});
|
sendQuery(PTR, {"_ipp","_tcp","local"});
|
||||||
}
|
}
|
||||||
|
@ -231,3 +249,59 @@ void IppDiscovery::readPendingDatagrams()
|
||||||
this->update();
|
this->update();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IppDiscovery::ignoreKnownSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
||||||
|
{
|
||||||
|
QList<QSslError> IgnoredSslErrors = {QSslError::NoError,
|
||||||
|
QSslError::SelfSignedCertificate,
|
||||||
|
QSslError::HostNameMismatch,
|
||||||
|
QSslError::UnableToGetLocalIssuerCertificate,
|
||||||
|
QSslError::UnableToVerifyFirstCertificate
|
||||||
|
};
|
||||||
|
|
||||||
|
qDebug() << errors;
|
||||||
|
for (QList<QSslError>::const_iterator it = errors.constBegin(); it != errors.constEnd(); it++) {
|
||||||
|
if(!IgnoredSslErrors.contains(it->error())) {
|
||||||
|
qDebug() << "Bad error: " << int(it->error()) << it->error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For whatever reason, it doesn't work to pass IgnoredSslErrors here
|
||||||
|
reply->ignoreSslErrors(errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage IppDiscovery::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
|
||||||
|
{ //TODO: consider caching images (doesn't appear to be needed currently)
|
||||||
|
Q_UNUSED(size);
|
||||||
|
Q_UNUSED(requestedSize);
|
||||||
|
qDebug() << "requesting image" << id;
|
||||||
|
|
||||||
|
QImage img;
|
||||||
|
|
||||||
|
QNetworkAccessManager* nam = new QNetworkAccessManager(this);
|
||||||
|
QUrl url(id);
|
||||||
|
qDebug() << url.host() << _AAs;
|
||||||
|
// TODO IPv6
|
||||||
|
if(_AAs.contains(url.host()))
|
||||||
|
{ // TODO: retry potential other IPs
|
||||||
|
url.setHost(_AAs.value(url.host()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkReply* reply = nam->get(QNetworkRequest(url));
|
||||||
|
|
||||||
|
QEventLoop el;
|
||||||
|
connect(reply, SIGNAL(finished()),&el,SLOT(quit()));
|
||||||
|
connect(nam, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||||
|
this, SLOT(ignoreKnownSslErrors(QNetworkReply*, const QList<QSslError>&)));
|
||||||
|
el.exec();
|
||||||
|
|
||||||
|
if (reply->error() == QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
QImageReader imageReader(reply);
|
||||||
|
img = imageReader.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete nam;
|
||||||
|
return img;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
#ifndef IPPDISCOVERY_H
|
#ifndef IPPDISCOVERY_H
|
||||||
#define IPPDISCOVERY_H
|
#define IPPDISCOVERY_H
|
||||||
#include <QStringListModel>
|
#include <QStringListModel>
|
||||||
|
#include <QQuickImageProvider>
|
||||||
#include <QUdpSocket>
|
#include <QUdpSocket>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QImageReader>
|
||||||
|
#include <QtNetwork>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QEventLoop>
|
||||||
#include "bytestream.h"
|
#include "bytestream.h"
|
||||||
|
|
||||||
class IppDiscovery : public QStringListModel
|
class IppDiscovery : public QStringListModel, public QQuickImageProvider
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
IppDiscovery();
|
static IppDiscovery* instance();
|
||||||
~IppDiscovery();
|
|
||||||
Q_PROPERTY(QStringList favourites MEMBER _favourites NOTIFY favouritesChanged)
|
Q_PROPERTY(QStringList favourites MEMBER _favourites NOTIFY favouritesChanged)
|
||||||
Q_INVOKABLE void discover();
|
Q_INVOKABLE void discover();
|
||||||
Q_INVOKABLE void reset();
|
Q_INVOKABLE void reset();
|
||||||
|
@ -20,11 +26,21 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
void readPendingDatagrams();
|
void readPendingDatagrams();
|
||||||
void update();
|
void update();
|
||||||
|
void ignoreKnownSslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
|
static IppDiscovery* m_Instance;
|
||||||
|
|
||||||
|
IppDiscovery();
|
||||||
|
~IppDiscovery();
|
||||||
|
IppDiscovery(const IppDiscovery &);
|
||||||
|
IppDiscovery& operator=(const IppDiscovery &);
|
||||||
|
|
||||||
void sendQuery(quint16 qtype, QStringList addr);
|
void sendQuery(quint16 qtype, QStringList addr);
|
||||||
|
|
||||||
|
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
|
||||||
|
|
||||||
QStringList _ipp;
|
QStringList _ipp;
|
||||||
QMap<QString,QString> _rps;
|
QMap<QString,QString> _rps;
|
||||||
QMap<QString,quint16> _ports;
|
QMap<QString,quint16> _ports;
|
||||||
|
|
Loading…
Reference in a new issue