Add calligraconverter support
This commit is contained in:
parent
d16562900f
commit
43373d159e
10 changed files with 332 additions and 26 deletions
|
@ -76,6 +76,7 @@ Page {
|
|||
if(status==PageStatus.Active && !nagged && nagScreenSetting.value != nagScreenSetting.expectedValue)
|
||||
{
|
||||
console.log("Can convert from PDF:", ConvertChecker.pdf)
|
||||
console.log("Can convert from Office:", ConvertChecker.calligra)
|
||||
if(!ConvertChecker.pdf)
|
||||
{
|
||||
nagged=true
|
||||
|
@ -345,24 +346,25 @@ Page {
|
|||
DocumentPickerPage {
|
||||
allowedOrientations: Orientation.All
|
||||
|
||||
Component.onCompleted: {
|
||||
var thingy = Qt.createComponent("../components/DocumentFilter.notqml");
|
||||
if (thingy.status == Component.Ready) {
|
||||
_contentModel.contentFilter = thingy.createObject(this);
|
||||
}
|
||||
}
|
||||
// Component.onCompleted: {
|
||||
// var thingy = Qt.createComponent("../components/DocumentFilter.notqml");
|
||||
// if (thingy.status == Component.Ready) {
|
||||
// _contentModel.contentFilter = thingy.createObject(this);
|
||||
// }
|
||||
// }
|
||||
|
||||
title: qsTr("Choose file")
|
||||
|
||||
onSelectedContentPropertiesChanged: {
|
||||
var mimeType = Mimer.get_type(selectedContentProperties.filePath)
|
||||
if(mimeType == "application/pdf" || mimeType == "application/postscript")
|
||||
if(mimeType == "application/pdf" || mimeType == "application/postscript" || Mimer.isOffice(mimeType))
|
||||
{
|
||||
page.selectedFile = selectedContentProperties.filePath
|
||||
page.selectedFileType = mimeType
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("UNSUPPORTED", mimeType);
|
||||
notifier.notify(qsTr("Unsupported document format"))
|
||||
page.selectedFile = ""
|
||||
page.selectedFileType = ""
|
||||
|
|
|
@ -22,6 +22,12 @@ function supported_formats(printer, ConvertChecker, considerAdditionalFormats)
|
|||
supported.push("Postscript");
|
||||
}
|
||||
|
||||
if((ConvertChecker.pdf && ConvertChecker.calligra) &&
|
||||
( has(formats, Mimer.PDF) || has(formats, Mimer.Postscript) || raster ))
|
||||
{
|
||||
mimetypes = mimetypes.concat(Mimer.OfficeFormats);
|
||||
}
|
||||
|
||||
if (raster || has(formats, Mimer.JPEG) || has(formats, Mimer.PNG))
|
||||
{
|
||||
mimetypes.push(Mimer.JPEG);
|
||||
|
@ -266,6 +272,12 @@ function canTransferPostscriptAs(type)
|
|||
return has(targets, type)
|
||||
}
|
||||
|
||||
function canConvertOfficeDocumentTo(type)
|
||||
{
|
||||
var targets = [Mimer.OctetStream, Mimer.PDF, Mimer.Postscript, Mimer.PWG, Mimer.URF];
|
||||
return has(targets, type)
|
||||
}
|
||||
|
||||
function canConvertImageTo(type)
|
||||
{
|
||||
var targets = [Mimer.OctetStream, Mimer.JPEG, Mimer.PNG, Mimer.PWG, Mimer.URF];
|
||||
|
@ -298,7 +310,11 @@ function limitChoices(name, choices, mimeType, ConvertChecker)
|
|||
{
|
||||
return choices.filter(canTransferPostscriptAs)
|
||||
}
|
||||
else if(mimeType.indexOf("image") != -1)
|
||||
else if(Mimer.isOffice(mimeType))
|
||||
{
|
||||
return choices.filter(canConvertOfficeDocumentTo)
|
||||
}
|
||||
else if(Mimer.isImage(mimeType))
|
||||
{
|
||||
return choices.filter(canConvertImageTo);
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ class ConvertChecker : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
static ConvertChecker* instance();
|
||||
Q_PROPERTY(bool pdf MEMBER _pdf)
|
||||
Q_PROPERTY(bool calligra MEMBER _calligra)
|
||||
Q_PROPERTY(bool pdf MEMBER _pdf CONSTANT)
|
||||
Q_PROPERTY(bool calligra MEMBER _calligra CONSTANT)
|
||||
|
||||
Q_INVOKABLE quint32 pdfPages(QString pdf);
|
||||
|
||||
|
|
|
@ -430,3 +430,232 @@ catch(const ConvertFailedException& e)
|
|||
emit failed(e.what() == QString("") ? tr("Conversion error") : e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertWorker::convertOfficeDocument(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||
quint32 PageRangeLow, quint32 PageRangeHigh)
|
||||
{
|
||||
try {
|
||||
|
||||
if(targetFormat == Mimer::URF && (HwResX != HwResY))
|
||||
{ // URF only supports symmetric resolutions
|
||||
qDebug() << "Unsupported URF resolution" << PaperSize;
|
||||
throw ConvertFailedException(tr("Unsupported resolution (dpi)"));
|
||||
}
|
||||
|
||||
QString ShortPaperSize;
|
||||
if(CalligraPaperSizes.contains(PaperSize))
|
||||
{
|
||||
ShortPaperSize = CalligraPaperSizes[PaperSize];
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Unsupported PDF paper size" << PaperSize;
|
||||
throw ConvertFailedException(tr("Unsupported PDF paper size"));
|
||||
}
|
||||
|
||||
QProcess* CalligraConverter = new QProcess(this);
|
||||
CalligraConverter->setProgram("calligraconverter");
|
||||
QStringList CalligraConverterArgs = {"--batch", "--mimetype", Mimer::PDF, "--print-orientation", "Portrait", "--print-papersize", ShortPaperSize};
|
||||
|
||||
CalligraConverterArgs << filename;
|
||||
|
||||
QTemporaryFile tmpPdfFile;
|
||||
tmpPdfFile.open();
|
||||
CalligraConverterArgs << tmpPdfFile.fileName();
|
||||
|
||||
qDebug() << "CalligraConverteArgs is" << CalligraConverterArgs;
|
||||
CalligraConverter->setArguments(CalligraConverterArgs);
|
||||
|
||||
connect(CalligraConverter, SIGNAL(finished(int, QProcess::ExitStatus)), CalligraConverter, SLOT(deleteLater()));
|
||||
|
||||
CalligraConverter->start();
|
||||
|
||||
qDebug() << "CalligraConverter Starting";
|
||||
|
||||
if(!CalligraConverter->waitForStarted())
|
||||
{
|
||||
qDebug() << "CalligraConverter died";
|
||||
throw ConvertFailedException();
|
||||
}
|
||||
|
||||
qDebug() << "CalligraConverter Started";
|
||||
|
||||
if(!CalligraConverter->waitForFinished(-1))
|
||||
{
|
||||
qDebug() << "CalligraConverter failed";
|
||||
throw ConvertFailedException();
|
||||
}
|
||||
|
||||
// qDebug() << CalligraConverter->readAllStandardError();
|
||||
|
||||
quint32 pages = ConvertChecker::instance()->pdfPages(tmpPdfFile.fileName());
|
||||
if (!pages)
|
||||
{
|
||||
qDebug() << "pdfinfo returned 0 pages";
|
||||
throw ConvertFailedException(tr("Failed to get info about PDF file"));
|
||||
}
|
||||
|
||||
if(PageRangeLow==0)
|
||||
{
|
||||
PageRangeLow=1;
|
||||
}
|
||||
|
||||
if(PageRangeHigh==0)
|
||||
{
|
||||
PageRangeHigh=pages;
|
||||
}
|
||||
|
||||
// Actual number of pages to print
|
||||
pages = PageRangeHigh-PageRangeLow+1;
|
||||
|
||||
qDebug() << "PageRangeLow" << PageRangeLow << "PageRangeHigh" << PageRangeHigh << "pages" << pages;
|
||||
|
||||
if(targetFormat == Mimer::PDF)
|
||||
{
|
||||
|
||||
// TODO Page ranges
|
||||
|
||||
QFile tempfileAsFile(tempfile->fileName());
|
||||
tempfileAsFile.open(QIODevice::Append);
|
||||
tempfileAsFile.write(tmpPdfFile.readAll());
|
||||
tempfileAsFile.close();
|
||||
|
||||
}
|
||||
else if(targetFormat == Mimer::Postscript)
|
||||
{
|
||||
QProcess* PdfToPs = new QProcess(this);
|
||||
PdfToPs->setProgram("pdftops");
|
||||
QStringList PdfToPsArgs;
|
||||
if(TwoSided)
|
||||
{
|
||||
PdfToPsArgs.append("-duplex");
|
||||
}
|
||||
|
||||
PdfToPsArgs << QStringList {"-f", QString::number(PageRangeLow), "-l", QString::number(PageRangeHigh)};
|
||||
PdfToPsArgs << QStringList {tmpPdfFile.fileName(), "-"};
|
||||
|
||||
|
||||
qDebug() << "pdftops args is " << PdfToPsArgs;
|
||||
PdfToPs->setArguments(PdfToPsArgs);
|
||||
|
||||
|
||||
PdfToPs->setStandardOutputFile(tempfile->fileName(), QIODevice::Append);
|
||||
connect(PdfToPs, SIGNAL(finished(int, QProcess::ExitStatus)), PdfToPs, SLOT(deleteLater()));
|
||||
|
||||
PdfToPs->start();
|
||||
|
||||
qDebug() << "PdfToPs Starting";
|
||||
|
||||
if(!PdfToPs->waitForStarted())
|
||||
{
|
||||
qDebug() << "PdfToPs died";
|
||||
throw ConvertFailedException();
|
||||
}
|
||||
|
||||
qDebug() << "PdfToPs Started";
|
||||
|
||||
if(!PdfToPs->waitForFinished(-1))
|
||||
{
|
||||
qDebug() << "PdfToPs failed";
|
||||
throw ConvertFailedException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
QProcess* pdftoppm = new QProcess(this);
|
||||
pdftoppm->setProgram("pdftoppm");
|
||||
QStringList Pdf2PpmArgs = {"-rx", QString::number(HwResX), "-ry", QString::number(HwResY)};
|
||||
Pdf2PpmArgs << QStringList {"-f", QString::number(PageRangeLow), "-l", QString::number(PageRangeHigh)};
|
||||
|
||||
if(Colors == 1)
|
||||
{
|
||||
Pdf2PpmArgs.append("-gray");
|
||||
}
|
||||
qDebug() << "pdf2ppm args is " << Pdf2PpmArgs;
|
||||
pdftoppm->setArguments(Pdf2PpmArgs);
|
||||
|
||||
|
||||
QProcess* ppm2pwg = new QProcess(this);
|
||||
// Yo dawg, I heard you like programs...
|
||||
ppm2pwg->setProgram("harbour-seaprint");
|
||||
ppm2pwg->setArguments({"ppm2pwg"});
|
||||
|
||||
bool urf = targetFormat == Mimer::URF;
|
||||
|
||||
QStringList env;
|
||||
ppm2PwgEnv(env, urf, Quality, PaperSize, HwResX, HwResY, TwoSided, Tumble, true, pages);
|
||||
qDebug() << "ppm2pwg env is " << env;
|
||||
|
||||
ppm2pwg->setEnvironment(env);
|
||||
|
||||
pdftoppm->setStandardInputFile(tmpPdfFile.fileName());
|
||||
pdftoppm->setStandardOutputProcess(ppm2pwg);
|
||||
ppm2pwg->setStandardOutputFile(tempfile->fileName(), QIODevice::Append);
|
||||
|
||||
connect(pdftoppm, SIGNAL(finished(int, QProcess::ExitStatus)), pdftoppm, SLOT(deleteLater()));
|
||||
connect(ppm2pwg, SIGNAL(finished(int, QProcess::ExitStatus)), ppm2pwg, SLOT(deleteLater()));
|
||||
|
||||
qDebug() << "All connected";
|
||||
|
||||
pdftoppm->start();
|
||||
ppm2pwg->start();
|
||||
|
||||
qDebug() << "Starting";
|
||||
|
||||
if(!pdftoppm->waitForStarted())
|
||||
{
|
||||
qDebug() << "pdftoppm died";
|
||||
throw ConvertFailedException();
|
||||
}
|
||||
if(!ppm2pwg->waitForStarted())
|
||||
{
|
||||
qDebug() << "ppm2pwg died";
|
||||
throw ConvertFailedException();
|
||||
}
|
||||
qDebug() << "All started";
|
||||
|
||||
bool ppm2pwgSuccess = false;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(ppm2pwg->waitForFinished(1000))
|
||||
{
|
||||
ppm2pwgSuccess = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
QList<QByteArray> ppm2pwgOutput = ppm2pwg->readAllStandardError().split('\n');
|
||||
for(QList<QByteArray>::iterator it = ppm2pwgOutput.begin(); it != ppm2pwgOutput.end(); it++)
|
||||
{
|
||||
if(it->startsWith("Page"))
|
||||
{
|
||||
QList<QByteArray> ppm2pwgTokens = it->split(' ');
|
||||
emit progress(ppm2pwgTokens.last().toInt()-1, pages);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!ppm2pwgSuccess)
|
||||
{
|
||||
qDebug() << "ppm2pwg failed";
|
||||
throw ConvertFailedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qDebug() << "Finished";
|
||||
|
||||
emit done(request, tempfile);
|
||||
qDebug() << "posted";
|
||||
|
||||
}
|
||||
catch(const ConvertFailedException& e)
|
||||
{
|
||||
tempfile->deleteLater();
|
||||
emit failed(e.what() == QString("") ? tr("Conversion error") : e.what());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@ public slots:
|
|||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY);
|
||||
|
||||
void convertOfficeDocument(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||
quint32 PageRangeLow, quint32 PageRangeHigh);
|
||||
|
||||
signals:
|
||||
void done(QNetworkRequest request, QTemporaryFile* data);
|
||||
void progress(qint64 done, qint64 pages);
|
||||
|
|
|
@ -32,6 +32,7 @@ IppPrinter::IppPrinter()
|
|||
|
||||
connect(this, &IppPrinter::doConvertPdf, _worker, &ConvertWorker::convertPdf);
|
||||
connect(this, &IppPrinter::doConvertImage, _worker, &ConvertWorker::convertImage);
|
||||
connect(this, &IppPrinter::doConvertOfficeDocument, _worker, &ConvertWorker::convertOfficeDocument);
|
||||
connect(_worker, &ConvertWorker::done, this, &IppPrinter::convertDone);
|
||||
connect(_worker, &ConvertWorker::progress, this, &IppPrinter::setProgress);
|
||||
connect(_worker, &ConvertWorker::failed, this, &IppPrinter::convertFailed);
|
||||
|
@ -503,22 +504,22 @@ void IppPrinter::print(QJsonObject attrs, QString filename, bool alwaysConvert,
|
|||
qDebug() << tempfile->fileName();
|
||||
tempfile->close();
|
||||
|
||||
bool TwoSided = false;
|
||||
bool Tumble = false;
|
||||
if(Sides=="two-sided-long-edge")
|
||||
{
|
||||
TwoSided = true;
|
||||
}
|
||||
else if(Sides=="two-sided-short-edge")
|
||||
{
|
||||
TwoSided = true;
|
||||
Tumble = true;
|
||||
}
|
||||
|
||||
setBusyMessage("Converting");
|
||||
|
||||
if(mimeType == Mimer::PDF)
|
||||
{
|
||||
bool TwoSided = false;
|
||||
bool Tumble = false;
|
||||
if(Sides=="two-sided-long-edge")
|
||||
{
|
||||
TwoSided = true;
|
||||
}
|
||||
else if(Sides=="two-sided-short-edge")
|
||||
{
|
||||
TwoSided = true;
|
||||
Tumble = true;
|
||||
}
|
||||
|
||||
emit doConvertPdf(request, filename, tempfile, documentFormat, Colors, Quality,
|
||||
PaperSize, HwResX, HwResY, TwoSided, Tumble, PageRangeLow, PageRangeHigh);
|
||||
}
|
||||
|
@ -527,6 +528,11 @@ void IppPrinter::print(QJsonObject attrs, QString filename, bool alwaysConvert,
|
|||
emit doConvertImage(request, filename, tempfile, documentFormat, Colors, Quality,
|
||||
PaperSize, HwResX, HwResY);
|
||||
}
|
||||
else if(Mimer::isOffice(mimeType))
|
||||
{
|
||||
emit doConvertOfficeDocument(request, filename, tempfile, documentFormat, Colors, Quality,
|
||||
PaperSize, HwResX, HwResY, TwoSided, Tumble, PageRangeLow, PageRangeHigh);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit convertFailed(tr("Cannot convert this file format"));
|
||||
|
|
|
@ -49,6 +49,11 @@ signals:
|
|||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY);
|
||||
|
||||
void doConvertOfficeDocument(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||
quint32 PageRangeLow, quint32 PageRangeHigh);
|
||||
|
||||
void additionalDocumentFormatsChanged();
|
||||
void busyMessageChanged();
|
||||
void progressChanged();
|
||||
|
|
|
@ -15,8 +15,10 @@ const QString Mimer::TIFF = "image/tiff";
|
|||
const QString Mimer::DOC = "application/msword";
|
||||
const QString Mimer::DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
||||
const QString Mimer::RTF = "text/rtf";
|
||||
const QString Mimer::RTF_APP = "application/rtf";
|
||||
const QString Mimer::ODT = "application/vnd.oasis.opendocument.text";
|
||||
|
||||
const QStringList Mimer::OfficeFormats = {DOC, DOCX, RTF, RTF_APP, ODT};
|
||||
|
||||
Mimer::Mimer()
|
||||
{
|
||||
|
|
15
src/mimer.h
15
src/mimer.h
|
@ -25,6 +25,13 @@ public:
|
|||
Q_PROPERTY(const QString JPEG MEMBER JPEG CONSTANT);
|
||||
Q_PROPERTY(const QString TIFF MEMBER TIFF CONSTANT);
|
||||
|
||||
Q_PROPERTY(const QString DOC MEMBER DOC CONSTANT);
|
||||
Q_PROPERTY(const QString DOCX MEMBER DOCX CONSTANT);
|
||||
Q_PROPERTY(const QString RTF MEMBER RTF CONSTANT);
|
||||
Q_PROPERTY(const QString ODT MEMBER ODT CONSTANT);
|
||||
|
||||
Q_PROPERTY(const QStringList OfficeFormats MEMBER OfficeFormats CONSTANT);
|
||||
|
||||
static const QString OctetStream;
|
||||
|
||||
static const QString PDF;
|
||||
|
@ -40,20 +47,20 @@ public:
|
|||
static const QString DOC;
|
||||
static const QString DOCX;
|
||||
static const QString RTF;
|
||||
static const QString RTF_APP;
|
||||
static const QString ODT;
|
||||
|
||||
static const QStringList OfficeFormats;
|
||||
|
||||
Q_INVOKABLE static bool isImage(QString mimeType)
|
||||
{
|
||||
return mimeType.startsWith("image/");
|
||||
}
|
||||
Q_INVOKABLE static bool isOffice(QString mimeType)
|
||||
{
|
||||
static QStringList OfficeForamts {DOC, DOCX, RTF, ODT};
|
||||
return OfficeForamts.contains(mimeType);
|
||||
return OfficeFormats.contains(mimeType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Mimer();
|
||||
static Mimer* m_Instance;
|
||||
|
|
|
@ -205,5 +205,39 @@ static QMap<QString, QPair<float,float>> PaperSizes =
|
|||
{"roc_16k_7.75x10.75in", {196.85, 273.05}},
|
||||
{"roc_8k_10.75x15.5in", {273.05, 393.70}}};
|
||||
|
||||
static QMap<QString, QString> CalligraPaperSizes =
|
||||
{{"iso_a0_841x1189mm", "A0"},
|
||||
{"iso_a1_594x841mm", "A1"},
|
||||
{"iso_a2_420x594mm", "A2"},
|
||||
{"iso_a3_297x420mm", "A3"},
|
||||
{"iso_a4_210x297mm", "A4"},
|
||||
{"iso_a5_148x210mm", "A5"},
|
||||
{"iso_a6_105x148mm", "A6"},
|
||||
{"iso_a7_74x105mm", "A7"},
|
||||
{"iso_a8_52x74mm", "A8"},
|
||||
{"iso_a9_37x52mm", "A9"},
|
||||
{"iso_b0_1000x1414mm", "B0"},
|
||||
{"iso_b1_707x1000mm", "B1"},
|
||||
{"iso_b2_500x707mm", "B2"},
|
||||
{"iso_b3_353x500mm", "B3"},
|
||||
{"iso_b4_250x353mm", "B4"},
|
||||
{"iso_b5_176x250mm", "B5"},
|
||||
{"iso_b6_125x176mm", "B6"},
|
||||
{"iso_b7_88x125mm", "B7"},
|
||||
{"iso_b8_62x88mm", "B8"},
|
||||
{"iso_b9_44x62mm", "B9"},
|
||||
{"iso_b10_31x44mm", "B10"},
|
||||
{"iso_c5_162x229mm", "C5E"},
|
||||
{"na_number-10_4.125x9.5in", "Comm10E"},
|
||||
{"iso_dl_110x220mm", "DLE"},
|
||||
{"na_executive_7.25x10.5in", "Executive"},
|
||||
{"om_folio_210x330mm", "Folio"},
|
||||
{"na_ledger_11x17in", "Ledger"},
|
||||
{"na_legal_8.5x14in", "Legal"},
|
||||
{"na_letter_8.5x11in", "Letter"},
|
||||
{"na_ledger_11x17in", "Tabloid"} // Dimension match
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // PAPERSIZES_H
|
||||
|
|
Loading…
Reference in a new issue