Add page range support

This commit is contained in:
Anton Thomasson 2020-08-01 20:18:47 +02:00
parent eb58606250
commit e1d34a4d1d
13 changed files with 221 additions and 36 deletions

View file

@ -3,25 +3,103 @@ import Sailfish.Silica 1.0
Setting { Setting {
//TODO
property int low
property int high property int high
property int choice_low property int choice_low: 1
property int choice_high property int choice_high: 0
function update_choice() {
choice = new Object({low: choice_low, high: choice_high});
}
onChoice_highChanged: {
if(choice_high < choice_low)
{
low_slider.value = choice_high > 0 ? choice_high : 1;
}
else
{
update_choice()
}
}
onChoice_lowChanged: {
if(choice_low > choice_high)
{
high_slider.value = choice_low
}
else
{
update_choice()
}
}
ValueButton { ValueButton {
enabled: valid enabled: valid
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
label: prettyName label: prettyName
value: choice ? choice : default_choice value: choice_high==0 ? qsTr("all") : ""+choice_low+" - "+choice_high
onClicked: parent.clicked() onClicked: parent.clicked()
} }
property var menu: ContextMenu { property var menu: ContextMenu {
id: menu id: menu
enabled: valid enabled: valid
MenuItem { MenuItem {
Slider
{
id: low_slider
minimumValue: 1
maximumValue: high
width: parent.width
stepSize: 1
value: choice_low
onValueChanged:
{
choice_low = value;
}
}
IconButton
{
anchors.right: parent.right
icon.source: "image://theme/icon-s-edit"
onClicked: {var dialog = pageStack.push(Qt.resolvedUrl("IntegerInputDialog.qml"),
{value: choice, title: prettyName,
min: 1, max: high});
dialog.accepted.connect(function() {
choice_low = dialog.value;
})
}
}
}
MenuItem {
Slider
{
id: high_slider
minimumValue: 0
maximumValue: high
width: parent.width
stepSize: 1
value: choice_high
onValueChanged:
{
choice_high = value;
}
}
IconButton
{
anchors.right: parent.right
icon.source: "image://theme/icon-s-edit"
onClicked: {var dialog = pageStack.push(Qt.resolvedUrl("IntegerInputDialog.qml"),
{value: choice, title: prettyName,
min: 1, max: high});
dialog.accepted.connect(function() {
choice_high = dialog.value;
})
}
}
} }

View file

@ -2,6 +2,7 @@ import QtQuick 2.0
import Sailfish.Silica 1.0 import Sailfish.Silica 1.0
import seaprint.mimer 1.0 import seaprint.mimer 1.0
import seaprint.ippmsg 1.0 import seaprint.ippmsg 1.0
import seaprint.convertchecker 1.0
import "utils.js" as Utils import "utils.js" as Utils
Page { Page {
@ -39,7 +40,7 @@ Page {
ListElement {name: "sides"; prettyName: qsTr("Sides"); tag: IppMsg.Enum} ListElement {name: "sides"; prettyName: qsTr("Sides"); tag: IppMsg.Enum}
ListElement {name: "media"; prettyName: qsTr("Print media"); tag: IppMsg.Keyword} ListElement {name: "media"; prettyName: qsTr("Print media"); tag: IppMsg.Keyword}
ListElement {name: "copies"; prettyName: qsTr("Copies"); tag: IppMsg.Integer} ListElement {name: "copies"; prettyName: qsTr("Copies"); tag: IppMsg.Integer}
// ListElement {name: "page-ranges"; prettyName: qsTr("Page range"); tag: IppMsg.IntegerRange} ListElement {name: "page-ranges"; prettyName: qsTr("Page range"); tag: IppMsg.IntegerRange}
ListElement {name: "print-color-mode"; prettyName: qsTr("Color mode"); tag: IppMsg.Enum} ListElement {name: "print-color-mode"; prettyName: qsTr("Color mode"); tag: IppMsg.Enum}
// ListElement {name: "orientation-requested"; prettyName: qsTr("Orientation"); tag: IppMsg.Enum} // ListElement {name: "orientation-requested"; prettyName: qsTr("Orientation"); tag: IppMsg.Enum}
ListElement {name: "print-quality"; prettyName: qsTr("Quality"); tag: IppMsg.Enum} ListElement {name: "print-quality"; prettyName: qsTr("Quality"); tag: IppMsg.Enum}
@ -111,11 +112,14 @@ Page {
}) })
break break
case IppMsg.IntegerRange: case IppMsg.IntegerRange:
var valid = printer.attrs.hasOwnProperty(name+"-supported") &&
name=="page-ranges" && Mimer.get_type(selectedFile) == "application/pdf";
loader.setSource("../components/RangeSetting.qml", loader.setSource("../components/RangeSetting.qml",
{name: name, {name: name,
prettyName: prettyName, prettyName: prettyName,
tag: tag, tag: tag,
valid: false //TODO printer.attrs.hasOwnProperty(name+"-supported"), valid: valid,
high: name=="page-ranges" ? ConvertChecker.pdfPages(selectedFile) : 0
}) })
break break
case IppMsg.Resolution: case IppMsg.Resolution:

View file

@ -1,5 +1,6 @@
#include "convertchecker.h" #include "convertchecker.h"
#include <QProcess> #include <QProcess>
#include <QtDebug>
ConvertChecker::ConvertChecker() ConvertChecker::ConvertChecker()
{ {
@ -38,3 +39,36 @@ ConvertChecker* ConvertChecker::instance()
return m_Instance; return m_Instance;
} }
quint32 ConvertChecker::pdfPages(QString filename)
{
quint32 pages = 0;
if(!_pdf)
{
return pages;
}
QProcess* pdfinfo = new QProcess(this);
pdfinfo->setProgram("pdfinfo");
pdfinfo->setArguments({filename});
pdfinfo->start();
if(!pdfinfo->waitForStarted(1000) || !pdfinfo->waitForFinished(1000))
{
pdfinfo->deleteLater();
return pages;
}
QByteArray pdfInfoOutput = pdfinfo->readAllStandardOutput();
pdfinfo->deleteLater();
qDebug() << pdfInfoOutput;
QList<QByteArray> pdfInfoOutputLines = pdfInfoOutput.split('\n');
for(QList<QByteArray>::iterator it = pdfInfoOutputLines.begin(); it != pdfInfoOutputLines.end(); it++)
{
if(it->startsWith("Pages"))
{
QList<QByteArray> pagesTokens = it->split(' ');
pages = pagesTokens.last().toInt();
}
}
return pages;
}

View file

@ -10,6 +10,8 @@ public:
static ConvertChecker* instance(); static ConvertChecker* instance();
Q_PROPERTY(bool pdf MEMBER _pdf) Q_PROPERTY(bool pdf MEMBER _pdf)
Q_INVOKABLE quint32 pdfPages(QString pdf);
signals: signals:
protected: protected:
private: private:

View file

@ -1,6 +1,7 @@
#include "convertworker.h" #include "convertworker.h"
#include <sailfishapp.h> #include <sailfishapp.h>
#include "papersizes.h" #include "papersizes.h"
#include "convertchecker.h"
#include <QImage> #include <QImage>
#include <QMatrix> #include <QMatrix>
#include <QPainter> #include <QPainter>
@ -44,34 +45,20 @@ void ppm2PwgEnv(QStringList& env, bool urf, quint32 Quality, QString PaperSize,
void ConvertWorker::convertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile, void ConvertWorker::convertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize, QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble) quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
quint32 PageRangeLow, quint32 PageRangeHigh)
{ {
quint32 pages = ConvertChecker::instance()->pdfPages(filename);
QProcess* pdfinfo = new QProcess(this); if (!pages)
pdfinfo->setProgram("pdfinfo");
pdfinfo->setArguments({filename});
pdfinfo->start();
if(!pdfinfo->waitForStarted() || !pdfinfo->waitForFinished())
{ {
qDebug() << "pdfinfo died"; qDebug() << "pdfinfo returned 0 pages";
pdfinfo->deleteLater();
tempfile->deleteLater(); tempfile->deleteLater();
emit failed(tr("Failed to get info about PDF file")); emit failed(tr("Failed to get info about PDF file"));
return;
} }
QByteArray pdfInfoOutput = pdfinfo->readAllStandardOutput();
pdfinfo->deleteLater(); if(PageRangeHigh==0)
qDebug() << pdfInfoOutput;
QList<QByteArray> pdfInfoOutputLines = pdfInfoOutput.split('\n');
quint32 pages = 0;
for(QList<QByteArray>::iterator it = pdfInfoOutputLines.begin(); it != pdfInfoOutputLines.end(); it++)
{ {
if(it->startsWith("Pages")) PageRangeHigh=pages;
{
QList<QByteArray> pagesTokens = it->split(' ');
pages = pagesTokens.last().toInt();
}
} }
bool urf = false; bool urf = false;
@ -132,11 +119,17 @@ void ConvertWorker::convertPdf(QNetworkRequest request, QString filename, QTempo
{ {
QProcess* pdftops = new QProcess(this); QProcess* pdftops = new QProcess(this);
pdftops->setProgram("pdftops"); pdftops->setProgram("pdftops");
QStringList PdfToPsArgs = {"-paper", ShortPaperSize, filename, "-"}; QStringList PdfToPsArgs;
if(TwoSided) if(TwoSided)
{ {
PdfToPsArgs.prepend("-duplex"); PdfToPsArgs.append("-duplex");
} }
if(PageRangeLow != 0)
{
PdfToPsArgs << QStringList {"-f", QString::number(PageRangeLow), "-l", QString::number(PageRangeHigh)};
}
PdfToPsArgs << QStringList {"-paper", ShortPaperSize, filename, "-"};
pdftops->setArguments(PdfToPsArgs); pdftops->setArguments(PdfToPsArgs);
pdftops->setStandardOutputFile(tempfile->fileName(), QIODevice::Append); pdftops->setStandardOutputFile(tempfile->fileName(), QIODevice::Append);
@ -169,7 +162,13 @@ void ConvertWorker::convertPdf(QNetworkRequest request, QString filename, QTempo
QProcess* pdftocairo = new QProcess(this); QProcess* pdftocairo = new QProcess(this);
pdftocairo->setProgram("pdftocairo"); pdftocairo->setProgram("pdftocairo");
pdftocairo->setArguments({"-pdf", "-paper", ShortPaperSize, filename, "-"}); QStringList PdfToCairoArgs;
if(PageRangeLow != 0)
{
PdfToCairoArgs << QStringList {"-f", QString::number(PageRangeLow), "-l", QString::number(PageRangeHigh)};
}
PdfToCairoArgs << QStringList {"-pdf", "-paper", ShortPaperSize, filename, "-"};
pdftocairo->setArguments(PdfToCairoArgs);
QProcess* pdftoppm = new QProcess(this); QProcess* pdftoppm = new QProcess(this);
pdftoppm->setProgram("pdftoppm"); pdftoppm->setProgram("pdftoppm");

View file

@ -10,7 +10,8 @@ class ConvertWorker : public QObject
public slots: public slots:
void convertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile, void convertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize, QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble); quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
quint32 PageRangeLow, quint32 PageRangeHigh);
void convertImage(QNetworkRequest request, QString filename, QTemporaryFile* tempfile, void convertImage(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize, QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,

View file

@ -432,6 +432,17 @@ void IppPrinter::print(QJsonObject attrs, QString filename,
{ {
attrs.remove("sides"); attrs.remove("sides");
} }
quint32 PageRangeLow = 0;
quint32 PageRangeHigh = 0;
if(mimeType == "application/pdf" && documentFormat != "application/pdf")
{
if(attrs.contains("page-ranges"))
{
QJsonObject PageRanges = getAttrOrDefault(attrs, "page-ranges").toObject();
PageRangeLow = PageRanges["low"].toInt();
PageRangeHigh = PageRanges["high"].toInt();
}
}
qDebug() << "Final op attributes:" << o; qDebug() << "Final op attributes:" << o;
qDebug() << "Final job attributes:" << attrs; qDebug() << "Final job attributes:" << attrs;
@ -476,7 +487,7 @@ void IppPrinter::print(QJsonObject attrs, QString filename,
} }
emit doConvertPdf(request, filename, tempfile, documentFormat, Colors, Quality, emit doConvertPdf(request, filename, tempfile, documentFormat, Colors, Quality,
PaperSize, HwResX, HwResY, TwoSided, Tumble); PaperSize, HwResX, HwResY, TwoSided, Tumble, PageRangeLow, PageRangeHigh);
} }
else if (mimeType.contains("image")) else if (mimeType.contains("image"))
{ {

View file

@ -42,7 +42,8 @@ signals:
void doConvertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile, void doConvertPdf(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize, QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble); quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
quint32 PageRangeLow, quint32 PageRangeHigh);
void doConvertImage(QNetworkRequest request, QString filename, QTemporaryFile* tempfile, void doConvertImage(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize, QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,

View file

@ -349,6 +349,17 @@
<source>Zero margins</source> <source>Zero margins</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Page range</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
<message>
<source>all</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>SettingsPage</name> <name>SettingsPage</name>

View file

@ -349,6 +349,17 @@
<source>Zero margins</source> <source>Zero margins</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Page range</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
<message>
<source>all</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>SettingsPage</name> <name>SettingsPage</name>

View file

@ -349,6 +349,17 @@
<source>Zero margins</source> <source>Zero margins</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Page range</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
<message>
<source>all</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>SettingsPage</name> <name>SettingsPage</name>

View file

@ -349,6 +349,17 @@
<source>Zero margins</source> <source>Zero margins</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Page range</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
<message>
<source>all</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>SettingsPage</name> <name>SettingsPage</name>

View file

@ -349,6 +349,17 @@
<source>Zero margins</source> <source>Zero margins</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Page range</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RangeSetting</name>
<message>
<source>all</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>SettingsPage</name> <name>SettingsPage</name>