Add support for client-side copies
This commit is contained in:
parent
b7aeb097a3
commit
6a06fa5ffd
13 changed files with 123 additions and 14 deletions
2
ppm2pwg
2
ppm2pwg
|
@ -1 +1 @@
|
||||||
Subproject commit faf26f7042928ec2cbe4b77fafb7ffb50882a0c2
|
Subproject commit 89cfaa0b424310f54355ee2415d3bee9ed786255
|
|
@ -2,8 +2,21 @@ import QtQuick 2.6
|
||||||
import Sailfish.Silica 1.0
|
import Sailfish.Silica 1.0
|
||||||
|
|
||||||
Setting {
|
Setting {
|
||||||
property int low: valid ? parent.printer.attrs[name+"-supported"].value.low : 0
|
property int minimum_high: 0
|
||||||
property int high: valid ? parent.printer.attrs[name+"-supported"].value.high : 0
|
property int low: _valid ? parent.printer.attrs[name+"-supported"].value.low : (minimum_high != 0) ? 1 : 0
|
||||||
|
property int high: _valid ? ensure_minimum(parent.printer.attrs[name+"-supported"].value.high) : minimum_high
|
||||||
|
|
||||||
|
function ensure_minimum(orig)
|
||||||
|
{
|
||||||
|
if(orig < minimum_high)
|
||||||
|
{
|
||||||
|
return minimum_high;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property bool suppressChange: false
|
property bool suppressChange: false
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,8 @@ Page {
|
||||||
tag: IppMsg.Integer
|
tag: IppMsg.Integer
|
||||||
name: "copies"
|
name: "copies"
|
||||||
prettyName: qsTr("Copies")
|
prettyName: qsTr("Copies")
|
||||||
|
valid: _valid || Utils.supports_raster(printer)
|
||||||
|
minimum_high: 99
|
||||||
}
|
}
|
||||||
ChoiceSetting {
|
ChoiceSetting {
|
||||||
tag: IppMsg.Keyword
|
tag: IppMsg.Keyword
|
||||||
|
|
|
@ -63,6 +63,16 @@ function supported_formats(printer, considerAdditionalFormats)
|
||||||
return {pdf: pdf, postscript: postscript, plaintext: plaintext, office: office, images: images, mimetypes: mimetypes};
|
return {pdf: pdf, postscript: postscript, plaintext: plaintext, office: office, images: images, mimetypes: mimetypes};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function supports_raster(printer)
|
||||||
|
{
|
||||||
|
var formats = printer.attrs["document-format-supported"].value;
|
||||||
|
if(considerAdditionalFormats)
|
||||||
|
{
|
||||||
|
formats=formats+printer.additionalDocumentFormats;
|
||||||
|
}
|
||||||
|
return (has(formats, Mimer.Mimer.PWG) || has(formats, Mimer.Mimer.URF));
|
||||||
|
}
|
||||||
|
|
||||||
function has(arrayish, what)
|
function has(arrayish, what)
|
||||||
{
|
{
|
||||||
return arrayish.indexOf(what) != -1;
|
return arrayish.indexOf(what) != -1;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "ippprinter.h"
|
#include "ippprinter.h"
|
||||||
#include "ippdiscovery.h"
|
#include "ippdiscovery.h"
|
||||||
#include "mimer.h"
|
#include "mimer.h"
|
||||||
|
#include "convertchecker.h"
|
||||||
#include "papersizes.h"
|
#include "papersizes.h"
|
||||||
#include "overrider.h"
|
#include "overrider.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
@ -542,6 +543,27 @@ void IppPrinter::adjustRasterSettings(QString documentFormat, QJsonObject& jobAt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int copies_requested = getAttrOrDefault(jobAttrs, "copies").toInt(1);
|
||||||
|
QJsonArray varying_attributes = _attrs["document-format-varying-attributes"].toObject()["value"].toArray();
|
||||||
|
bool supports_copies = _attrs.contains("copies-supported")
|
||||||
|
&& _attrs["copies-supported"].toObject()["value"].toObject()["high"].toInt(1) != 1
|
||||||
|
// assume raster formats causes the variation in supported copies
|
||||||
|
&& !(varying_attributes.contains("copies-supported") || varying_attributes.contains("copies"));
|
||||||
|
|
||||||
|
if(copies_requested > 1 && !supports_copies)
|
||||||
|
{
|
||||||
|
QString copyMode = getAttrOrDefault(jobAttrs, "multiple-document-handling").toString();
|
||||||
|
qDebug() << "Doing local copies" << copyMode << copies_requested;
|
||||||
|
if(copyMode == "separate-documents-uncollated-copies")
|
||||||
|
{ // Only do silly copies if explicitly requested
|
||||||
|
Params.pageCopies = copies_requested;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Params.documentCopies = copies_requested;
|
||||||
|
}
|
||||||
|
jobAttrs.remove("copies");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IppPrinter::print(QJsonObject jobAttrs, QString filename)
|
void IppPrinter::print(QJsonObject jobAttrs, QString filename)
|
||||||
|
@ -679,18 +701,19 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename)
|
||||||
Params.hwResW = PrinterResolutionRef.toObject()["x"].toInt(Params.hwResW);
|
Params.hwResW = PrinterResolutionRef.toObject()["x"].toInt(Params.hwResW);
|
||||||
Params.hwResH = PrinterResolutionRef.toObject()["y"].toInt(Params.hwResH);
|
Params.hwResH = PrinterResolutionRef.toObject()["y"].toInt(Params.hwResH);
|
||||||
|
|
||||||
adjustRasterSettings(targetFormat, jobAttrs, Params);
|
bool singlePageRange = false;
|
||||||
|
|
||||||
Params.quality = getAttrOrDefault(jobAttrs, "print-quality").toInt();
|
|
||||||
|
|
||||||
QString PrintColorMode = getAttrOrDefault(jobAttrs, "print-color-mode").toString();
|
|
||||||
Params.colors = PrintColorMode.contains("color") ? 3 : PrintColorMode.contains("monochrome") ? 1 : Params.colors;
|
|
||||||
|
|
||||||
if(jobAttrs.contains("page-ranges"))
|
if(jobAttrs.contains("page-ranges"))
|
||||||
{
|
{
|
||||||
QJsonObject PageRanges = getAttrOrDefault(jobAttrs, "page-ranges").toObject();
|
QJsonObject PageRanges = getAttrOrDefault(jobAttrs, "page-ranges").toObject();
|
||||||
Params.fromPage = PageRanges["low"].toInt();
|
size_t fromPage = PageRanges["low"].toInt();
|
||||||
Params.toPage = PageRanges["high"].toInt();
|
size_t toPage = PageRanges["high"].toInt();
|
||||||
|
if(fromPage != 0 || toPage != 0)
|
||||||
|
{
|
||||||
|
Params.pageRangeList = {{fromPage, toPage}};
|
||||||
|
singlePageRange = toPage == fromPage;
|
||||||
|
}
|
||||||
|
|
||||||
// Effected locally, unless it is Postscript which we cant't render
|
// Effected locally, unless it is Postscript which we cant't render
|
||||||
if(targetFormat != Mimer::Postscript)
|
if(targetFormat != Mimer::Postscript)
|
||||||
{
|
{
|
||||||
|
@ -699,6 +722,19 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Sides = getAttrOrDefault(jobAttrs, "sides").toString();
|
QString Sides = getAttrOrDefault(jobAttrs, "sides").toString();
|
||||||
|
int copies_requested = getAttrOrDefault(jobAttrs, "copies").toInt(1);
|
||||||
|
|
||||||
|
if((Params.format == PrintParameters::PWG || Params.format == PrintParameters::URF) &&
|
||||||
|
copies_requested > 1 &&
|
||||||
|
Sides != "one-sided" &&
|
||||||
|
(Mimer::instance()->isImage(mimeType) ||
|
||||||
|
(mimeType == Mimer::PDF && (singlePageRange || ConvertChecker::instance()->pdfPages(filename) == 1))))
|
||||||
|
{
|
||||||
|
jobAttrs.insert("sides", QJsonObject {{"tag", IppMsg::Keyword}, {"value", "one-sided"}});
|
||||||
|
qDebug() << "Optimizing one-page document to one-sided";
|
||||||
|
}
|
||||||
|
|
||||||
|
Sides = getAttrOrDefault(jobAttrs, "sides").toString();
|
||||||
|
|
||||||
if(Sides=="two-sided-long-edge")
|
if(Sides=="two-sided-long-edge")
|
||||||
{
|
{
|
||||||
|
@ -710,6 +746,13 @@ void IppPrinter::print(QJsonObject jobAttrs, QString filename)
|
||||||
Params.tumble = true;
|
Params.tumble = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adjustRasterSettings(targetFormat, jobAttrs, Params);
|
||||||
|
|
||||||
|
Params.quality = getAttrOrDefault(jobAttrs, "print-quality").toInt();
|
||||||
|
|
||||||
|
QString PrintColorMode = getAttrOrDefault(jobAttrs, "print-color-mode").toString();
|
||||||
|
Params.colors = PrintColorMode.contains("color") ? 3 : PrintColorMode.contains("monochrome") ? 1 : Params.colors;
|
||||||
|
|
||||||
QJsonArray supportedOperations = _attrs["operations-supported"].toObject()["value"].toArray();
|
QJsonArray supportedOperations = _attrs["operations-supported"].toObject()["value"].toArray();
|
||||||
|
|
||||||
if(supportedOperations.contains(IppMsg::CreateJob) && supportedOperations.contains(IppMsg::SendDocument))
|
if(supportedOperations.contains(IppMsg::CreateJob) && supportedOperations.contains(IppMsg::SendDocument))
|
||||||
|
|
|
@ -453,6 +453,14 @@ void PrinterWorker::convertImage(QString filename, Bytestream header, PrintParam
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
size_t total_pages = Params.documentCopies*Params.pageCopies;
|
||||||
|
|
||||||
|
if(total_pages > 1 && Params.duplex)
|
||||||
|
{ // Images are one page by definition - if we need to do client-side copies, they must be one-sided or we'd have to insert backsides
|
||||||
|
qDebug() << "Inconsistent duplex setting";
|
||||||
|
throw ConvertFailedException(tr("Inconsistent duplex setting"));
|
||||||
|
}
|
||||||
|
|
||||||
QImage outImage = QImage(Params.getPaperSizeWInPixels(), Params.getPaperSizeHInPixels(), inImage.format());
|
QImage outImage = QImage(Params.getPaperSizeWInPixels(), Params.getPaperSizeHInPixels(), inImage.format());
|
||||||
outImage.fill(Qt::white);
|
outImage.fill(Qt::white);
|
||||||
QPainter painter(&outImage);
|
QPainter painter(&outImage);
|
||||||
|
@ -463,7 +471,7 @@ void PrinterWorker::convertImage(QString filename, Bytestream header, PrintParam
|
||||||
|
|
||||||
QBuffer buf;
|
QBuffer buf;
|
||||||
buf.open(QIODevice::ReadWrite);
|
buf.open(QIODevice::ReadWrite);
|
||||||
Bytestream outBts;
|
Bytestream fileHdr, outBts;
|
||||||
|
|
||||||
|
|
||||||
if(inImage.allGray())
|
if(inImage.allGray())
|
||||||
|
@ -488,7 +496,7 @@ void PrinterWorker::convertImage(QString filename, Bytestream header, PrintParam
|
||||||
|
|
||||||
buf.read((char*)(inBts.raw()), inBts.size());
|
buf.read((char*)(inBts.raw()), inBts.size());
|
||||||
|
|
||||||
outBts << (Params.format == PrintParameters::URF ? make_urf_file_hdr(1) : make_pwg_file_hdr());
|
fileHdr << (Params.format == PrintParameters::URF ? make_urf_file_hdr(1) : make_pwg_file_hdr());
|
||||||
|
|
||||||
bool verbose = QLoggingCategory::defaultCategory()->isDebugEnabled();
|
bool verbose = QLoggingCategory::defaultCategory()->isDebugEnabled();
|
||||||
|
|
||||||
|
@ -499,7 +507,12 @@ void PrinterWorker::convertImage(QString filename, Bytestream header, PrintParam
|
||||||
emit busyMessage(tr("Printing"));
|
emit busyMessage(tr("Printing"));
|
||||||
|
|
||||||
OK(cr.write((char*)header.raw(), header.size()));
|
OK(cr.write((char*)header.raw(), header.size()));
|
||||||
OK(cr.write((char*)(outBts.raw()), outBts.size()));
|
OK(cr.write((char*)fileHdr.raw(), fileHdr.size()));
|
||||||
|
for(size_t c = 0; c < total_pages; c++)
|
||||||
|
{
|
||||||
|
OK(cr.write((char*)(outBts.raw()), outBts.size()));
|
||||||
|
emit progress(c+1, total_pages);
|
||||||
|
}
|
||||||
|
|
||||||
awaitResult(cr, "printRequestFinished");
|
awaitResult(cr, "printRequestFinished");
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,6 +520,10 @@ auf diesem Drucker</translation>
|
||||||
<source>Print error</source>
|
<source>Print error</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inconsistent duplex setting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RangeSetting</name>
|
<name>RangeSetting</name>
|
||||||
|
|
|
@ -519,6 +519,10 @@
|
||||||
<source>Print error</source>
|
<source>Print error</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inconsistent duplex setting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RangeSetting</name>
|
<name>RangeSetting</name>
|
||||||
|
|
|
@ -520,6 +520,10 @@ sur cette imprimante</translation>
|
||||||
<source>Print error</source>
|
<source>Print error</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inconsistent duplex setting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RangeSetting</name>
|
<name>RangeSetting</name>
|
||||||
|
|
|
@ -519,6 +519,10 @@
|
||||||
<source>Print error</source>
|
<source>Print error</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inconsistent duplex setting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RangeSetting</name>
|
<name>RangeSetting</name>
|
||||||
|
|
|
@ -519,6 +519,10 @@
|
||||||
<source>Print error</source>
|
<source>Print error</source>
|
||||||
<translation>Błąd drukowania</translation>
|
<translation>Błąd drukowania</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inconsistent duplex setting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RangeSetting</name>
|
<name>RangeSetting</name>
|
||||||
|
|
|
@ -519,6 +519,10 @@
|
||||||
<source>Print error</source>
|
<source>Print error</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inconsistent duplex setting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RangeSetting</name>
|
<name>RangeSetting</name>
|
||||||
|
|
|
@ -519,6 +519,10 @@
|
||||||
<source>Unknown target format</source>
|
<source>Unknown target format</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Inconsistent duplex setting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RangeSetting</name>
|
<name>RangeSetting</name>
|
||||||
|
|
Loading…
Reference in a new issue