Merge pull request #1 from attah/master

Updated from original project
This commit is contained in:
Carmen F. B 2020-01-13 13:29:45 +01:00 committed by GitHub
commit 7d6323168d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 258 additions and 136 deletions

View file

@ -6,7 +6,7 @@ import "pages"
ApplicationWindow
{
initialPage: Component { FirstPage { } }
initialPage: Component { FirstPage { selectedFile: Qt.application.arguments[1] ? Qt.application.arguments[1] : "" } }
cover: Qt.resolvedUrl("cover/CoverPage.qml")
allowedOrientations: defaultAllowedOrientations

View file

@ -14,10 +14,6 @@ Page {
property string selectedFile: ""
property string selectedFileType
IppDiscovery {
id: discovery
}
WifiChecker {
id: wifi
onConnectedChanged: {
@ -25,10 +21,10 @@ Page {
if(connected) {
var favourites = db.getFavourites(ssid);
console.log(favourites);
discovery.favourites = favourites;
IppDiscovery.favourites = favourites;
}
else {
discovery.favourites = []
IppDiscovery.favourites = []
}
}
@ -39,7 +35,7 @@ Page {
console.log("ssid changed", ssid);
if(!initialSSIDchange)
{
discovery.reset();
IppDiscovery.reset();
}
initialSSIDchange = false;
}
@ -48,7 +44,22 @@ Page {
signal refreshed()
Component.onCompleted: {
discovery.discover();
IppDiscovery.discover();
if(selectedFile != "")
{ // Until i can convince FilePickerPage to do its magic without user interaction
if(Utils.endsWith(".pdf", selectedFile))
{
selectedFileType = "application/pdf"
}
else if(Utils.endsWith(".jpg", selectedFile) || Utils.endsWith(".jpeg", selectedFile))
{
selectedFileType = "image/jpeg"
}
else
{
selectedFile = ""
}
}
}
// To enable PullDownMenu, place our content in a SilicaFlickable
@ -70,14 +81,14 @@ Page {
dialog.accepted.connect(function() {
console.log("add", wifi.ssid, dialog.value);
db.addFavourite(wifi.ssid, dialog.value);
discovery.favourites = db.getFavourites(wifi.ssid);
IppDiscovery.favourites = db.getFavourites(wifi.ssid);
})
}
}
MenuItem {
text: qsTr("Refresh")
onClicked: {
discovery.discover();
IppDiscovery.discover();
page.refreshed();
}
}
@ -86,7 +97,7 @@ Page {
SilicaListView {
anchors.fill: parent
id: listView
model: discovery
model: IppDiscovery
spacing: Theme.paddingSmall
@ -147,7 +158,7 @@ Page {
height: 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...
onStatusChanged: if (status == Image.Error) source = "icon-seaprint-nobg.svg"
}
@ -200,7 +211,7 @@ Page {
onClicked: {
removeRemorse.execute(delegate, qsTr("Removing printer"),
function() {db.removeFavourite(wifi.ssid, model.display);
discovery.favourites = db.getFavourites()})
IppDiscovery.favourites = db.getFavourites()})
}
}
}

View file

@ -13,7 +13,7 @@ function supported_formats(printer)
if(supported.length == 0)
{
supported.push(qsTr("No relevant formats supported"))
supported.push(qsTr("No compatible formats supported"))
}
return supported.join(" ");
@ -86,3 +86,8 @@ function ippName(name, value)
}
return value;
}
function endsWith(ending, string)
{
return string.lastIndexOf(ending) == (string.length - ending.length);
}

View file

@ -9,8 +9,8 @@ Name: harbour-seaprint
# << macros
Summary: SeaPrint
Version: 0.3.1
Release: 1
Version: 0.4
Release: 3
Group: Qt/Qt
License: LICENSE
URL: http://example.org/

View file

@ -1,7 +1,7 @@
Name: harbour-seaprint
Summary: SeaPrint
Version: 0.3.1
Release: 1
Version: 0.4
Release: 3
# The contents of the Group field should be one of the groups listed here:
# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
Group: Qt/Qt

View file

@ -5,24 +5,32 @@
#include <src/ippdiscovery.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[])
{
QGuiApplication* app = SailfishApp::application(argc, argv);
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");
// SailfishApp::main() will display "qml/harbour-printtool.qml", if you need more
// control over initialization, you can use:
//
// - SailfishApp::application(int, char *[]) to get the QGuiApplication *
// - SailfishApp::createView() to get a new QQuickView * instance
// - SailfishApp::pathTo(QString) to get a QUrl to a resource file
// - SailfishApp::pathToMainQml() to get a QUrl to the main QML file
//
// To display the view, call "show()" (will show fullscreen on device).
QQuickView* view = SailfishApp::createView();
view->engine()->addImportPath(SailfishApp::pathTo("qml/pages").toString());
view->engine()->addImageProvider(QLatin1String("ippdiscovery"), IppDiscovery::instance());
view->setSource(SailfishApp::pathToMainQml());
view->show();
return app->exec();
return SailfishApp::main(argc, argv);
}

View file

@ -44,7 +44,7 @@ QStringList get_addr(Bytestream& bts)
return addr;
}
IppDiscovery::IppDiscovery() : QStringListModel()
IppDiscovery::IppDiscovery() : QStringListModel(), QQuickImageProvider(QQuickImageProvider::Image)
{
socket = new QUdpSocket(this);
connect(socket, SIGNAL(readyRead()),
@ -57,6 +57,24 @@ IppDiscovery::~IppDiscovery() {
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() {
sendQuery(PTR, {"_ipp","_tcp","local"});
}
@ -136,69 +154,77 @@ void IppDiscovery::readPendingDatagrams()
sender = QHostAddress(sender.toIPv4Address());
quint16 transactionid, flags, questions, answerRRs, authRRs, addRRs;
resp >> transactionid >> flags >> questions >> answerRRs >> authRRs >> addRRs;
for(quint16 i = 0; i < questions; i++)
{
quint16 qtype, qflags;
QString qaddr = get_addr(resp).join('.');
resp >> qtype >> qflags;
}
try {
for(quint16 i = 0; i < answerRRs; i++)
{
quint16 atype, aflags, len;
quint32 ttl;
resp >> transactionid >> flags >> questions >> answerRRs >> authRRs >> addRRs;
QString aaddr = get_addr(resp).join('.');
resp >> atype >> aflags >> ttl >> len;
quint16 pos_before = resp.pos();
if (atype == PTR)
for(quint16 i = 0; i < questions; i++)
{
QString tmpname = get_addr(resp).join(".");
if(aaddr.endsWith("_ipp._tcp.local"))
{
ipp_ptrs.append(tmpname);
}
quint16 qtype, qflags;
QString qaddr = get_addr(resp).join('.');
resp >> qtype >> qflags;
}
else if(atype == TXT)
for(quint16 i = 0; i < answerRRs; i++)
{
Bytestream tmp;
while(resp.pos() < pos_before+len)
quint16 atype, aflags, len;
quint32 ttl;
QString aaddr = get_addr(resp).join('.');
resp >> atype >> aflags >> ttl >> len;
quint16 pos_before = resp.pos();
if (atype == PTR)
{
resp/resp.getU8() >> tmp;
if(tmp >>= "rp=")
QString tmpname = get_addr(resp).join(".");
if(aaddr.endsWith("_ipp._tcp.local"))
{
std::string tmprp;
tmp/tmp.remaining() >> tmprp;
_rps[aaddr] = tmprp.c_str();
ipp_ptrs.append(tmpname);
}
}
}
else if (atype == SRV)
{
quint16 prio, w, port;
resp >> prio >> w >> port;
QString target = get_addr(resp).join(".");
_ports[aaddr] = port;
_targets[aaddr] = target;
}
else if(atype == A)
{
quint32 addr;
resp >> addr;
QHostAddress haddr(addr);
_AAs.insert(aaddr, haddr.toString());
}
else
{
resp += len;
}
Q_ASSERT(resp.pos() == pos_before+len);
else if(atype == TXT)
{
Bytestream tmp;
while(resp.pos() < pos_before+len)
{
resp/resp.getU8() >> tmp;
if(tmp >>= "rp=")
{
std::string tmprp;
tmp/tmp.remaining() >> tmprp;
_rps[aaddr] = tmprp.c_str();
}
}
}
else if (atype == SRV)
{
quint16 prio, w, port;
resp >> prio >> w >> port;
QString target = get_addr(resp).join(".");
_ports[aaddr] = port;
_targets[aaddr] = target;
}
else if(atype == A)
{
quint32 addr;
resp >> addr;
QHostAddress haddr(addr);
_AAs.insert(aaddr, haddr.toString());
}
else
{
resp += len;
}
Q_ASSERT(resp.pos() == pos_before+len);
}
}
catch(std::exception e)
{
qDebug() << e.what();
return;
}
qDebug() << "new ipp ptrs" << ipp_ptrs;
qDebug() << "ipp ptrs" << _ipp;
qDebug() << "rps" << _rps;
@ -223,3 +249,59 @@ void IppDiscovery::readPendingDatagrams()
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;
}

View file

@ -1,15 +1,21 @@
#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
class IppDiscovery : public QStringListModel, public QQuickImageProvider
{
Q_OBJECT
public:
IppDiscovery();
~IppDiscovery();
static IppDiscovery* instance();
Q_PROPERTY(QStringList favourites MEMBER _favourites NOTIFY favouritesChanged)
Q_INVOKABLE void discover();
Q_INVOKABLE void reset();
@ -20,11 +26,21 @@ signals:
public slots:
void readPendingDatagrams();
void update();
void ignoreKnownSslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
protected:
private:
static IppDiscovery* m_Instance;
IppDiscovery();
~IppDiscovery();
IppDiscovery(const IppDiscovery &);
IppDiscovery& operator=(const IppDiscovery &);
void sendQuery(quint16 qtype, QStringList addr);
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
QStringList _ipp;
QMap<QString,QString> _rps;
QMap<QString,quint16> _ports;

View file

@ -282,7 +282,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<source>No relevant formats supported</source>
<source>No compatible formats supported</source>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -282,8 +282,8 @@
<translation>ppp</translation>
</message>
<message>
<source>No relevant formats supported</source>
<translation>No hay formatos relevantes compatibles</translation>
<source>No compatible formats supported</source>
<translation type="unfinished">No hay formatos compatibles</translation>
</message>
</context>
</TS>

View file

@ -57,11 +57,11 @@
</message>
<message>
<source>Code and Testing - Rudi Timmermans</source>
<translation type="unfinished">Rudi Timmermans - Code et test</translation>
<translation>Rudi Timmermans - Code et test</translation>
</message>
<message>
<source>Spanish</source>
<translation type="unfinished"></translation>
<translation>Espagnol</translation>
</message>
</context>
<context>
@ -84,7 +84,7 @@
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Inconnu</translation>
<translation>Inconnu</translation>
</message>
</context>
<context>
@ -138,7 +138,7 @@
</message>
<message>
<source>Unknown</source>
<translation type="unfinished">Inconnu</translation>
<translation>Inconnu</translation>
</message>
</context>
<context>
@ -215,74 +215,74 @@
</message>
<message>
<source>processing</source>
<translation type="unfinished"></translation>
<translation>traitement</translation>
</message>
<message>
<source>processing-stopped</source>
<translation type="unfinished"></translation>
<translation>traitement-arrêt</translation>
</message>
<message>
<source>canceled</source>
<translation type="unfinished"></translation>
<translation>annulé</translation>
</message>
<message>
<source>aborted</source>
<translation type="unfinished"></translation>
<translation>abandonné</translation>
</message>
<message>
<source>completed</source>
<translation type="unfinished"></translation>
<translation>terminé</translation>
</message>
<message>
<source>unknown state </source>
<translation type="unfinished"></translation>
<translation>état inconnu</translation>
</message>
<message>
<source>draft</source>
<translation type="unfinished">brouillon</translation>
<translation>brouillon</translation>
</message>
<message>
<source>normal</source>
<translation type="unfinished">normale</translation>
<translation>normale</translation>
</message>
<message>
<source>high</source>
<translation type="unfinished">haute</translation>
<translation>haute</translation>
</message>
<message>
<source>unknown quality </source>
<translation type="unfinished">qualité inconnue</translation>
<translation>qualité inconnue</translation>
</message>
<message>
<source>portrait</source>
<translation type="unfinished">portrait</translation>
<translation>portrait</translation>
</message>
<message>
<source>landscape</source>
<translation type="unfinished">paysage</translation>
<translation>paysage</translation>
</message>
<message>
<source>reverse landscape</source>
<translation type="unfinished">paysage inversé</translation>
<translation>paysage inversé</translation>
</message>
<message>
<source>reverse portrait</source>
<translation type="unfinished">portrait inversé</translation>
<translation>portrait inversé</translation>
</message>
<message>
<source>unknown orientation </source>
<translation type="unfinished">orientation inconnue</translation>
<translation>orientation inconnue</translation>
</message>
<message>
<source>dpi</source>
<translation type="unfinished">dpi</translation>
<translation>dpi</translation>
</message>
<message>
<source>dots/cm</source>
<translation type="unfinished">pts/cm</translation>
<translation>pts/cm</translation>
</message>
<message>
<source>No relevant formats supported</source>
<source>No compatible formats supported</source>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -45,7 +45,7 @@
</message>
<message>
<source>Source code is available at GitHub. Translations, bug reports and other contributions are welcome!</source>
<translation> Github </translation>
<translation> Github </translation>
</message>
<message>
<source>SeaPrint licencing is still TBD, but will be some flavor of open.</source>
@ -57,11 +57,11 @@
</message>
<message>
<source>Code and Testing - Rudi Timmermans</source>
<translation type="unfinished"> - Rudi Timmermans</translation>
<translation> - Rudi Timmermans</translation>
</message>
<message>
<source>Spanish</source>
<translation type="unfinished"></translation>
<translation>西</translation>
</message>
</context>
<context>
@ -84,7 +84,7 @@
</message>
<message>
<source>Unknown</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
</context>
<context>
@ -207,83 +207,83 @@
<name>utils</name>
<message>
<source>pending</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>pending-held</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>processing</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>processing-stopped</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>canceled</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>aborted</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>completed</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>unknown state </source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>draft</source>
<translation type="unfinished">稿</translation>
<translation>稿</translation>
</message>
<message>
<source>normal</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>high</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>unknown quality </source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>portrait</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>landscape</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>reverse landscape</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>reverse portrait</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>unknown orientation </source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>dpi</source>
<translation type="unfinished">dpi</translation>
<translation>dpi</translation>
</message>
<message>
<source>dots/cm</source>
<translation type="unfinished">/</translation>
<translation>/</translation>
</message>
<message>
<source>No relevant formats supported</source>
<translation type="unfinished"></translation>
<source>No compatible formats supported</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

View file

@ -282,7 +282,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<source>No relevant formats supported</source>
<source>No compatible formats supported</source>
<translation type="unfinished"></translation>
</message>
</context>