Add plaintext support
This commit is contained in:
parent
76fdbb987f
commit
4e8692c431
17 changed files with 267 additions and 5 deletions
|
@ -12,6 +12,11 @@ GalleryFilterUnion {
|
|||
value: ".ps"
|
||||
}
|
||||
|
||||
GalleryEndsWithFilter {
|
||||
property: "fileName"
|
||||
value: ".txt"
|
||||
}
|
||||
|
||||
GalleryEndsWithFilter {
|
||||
property: "fileName"
|
||||
value: ".PDF"
|
||||
|
@ -22,4 +27,9 @@ GalleryFilterUnion {
|
|||
value: ".PS"
|
||||
}
|
||||
|
||||
GalleryEndsWithFilter {
|
||||
property: "fileName"
|
||||
value: ".TXT"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,11 @@ GalleryFilterUnion {
|
|||
value: ".ps"
|
||||
}
|
||||
|
||||
GalleryEndsWithFilter {
|
||||
property: "fileName"
|
||||
value: ".txt"
|
||||
}
|
||||
|
||||
GalleryEndsWithFilter {
|
||||
property: "fileName"
|
||||
value: ".PDF"
|
||||
|
@ -22,6 +27,11 @@ GalleryFilterUnion {
|
|||
value: ".PS"
|
||||
}
|
||||
|
||||
GalleryEndsWithFilter {
|
||||
property: "fileName"
|
||||
value: ".TXT"
|
||||
}
|
||||
|
||||
GalleryEndsWithFilter {
|
||||
property: "fileName"
|
||||
value: ".odt"
|
||||
|
|
|
@ -276,7 +276,8 @@ Page {
|
|||
spacing: Theme.paddingMedium
|
||||
Label {
|
||||
id: format_unsupported_label
|
||||
visible: !supported_formats.pdf && !supported_formats.postscript && !supported_formats.office && !supported_formats.images
|
||||
visible: !supported_formats.pdf && !supported_formats.postscript && !supported_formats.plaintext
|
||||
&& !supported_formats.office && !supported_formats.images
|
||||
color: "red"
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
text: qsTr("No compatible formats supported")
|
||||
|
@ -299,6 +300,14 @@ Page {
|
|||
source: "image://theme/icon-m-file-other"
|
||||
|
||||
}
|
||||
HighlightImage {
|
||||
height: Theme.itemSizeExtraSmall/2
|
||||
width: Theme.itemSizeExtraSmall/2
|
||||
visible: supported_formats.plaintext
|
||||
highlightColor: "red"
|
||||
highlighted: !(selectedFile == "" || canPrint)
|
||||
source: "image://theme/icon-m-file-document"
|
||||
}
|
||||
HighlightImage {
|
||||
height: Theme.itemSizeExtraSmall/2
|
||||
width: Theme.itemSizeExtraSmall/2
|
||||
|
@ -441,7 +450,7 @@ Page {
|
|||
|
||||
onSelectedContentPropertiesChanged: {
|
||||
var mimeType = Mimer.get_type(selectedContentProperties.filePath)
|
||||
if(mimeType == "application/pdf" || mimeType == "application/postscript" || Mimer.isOffice(mimeType))
|
||||
if(mimeType == Mimer.PDF || mimeType == Mimer.Postscript || mimeType == Mimer.Plaintext || Mimer.isOffice(mimeType))
|
||||
{
|
||||
page.selectedFile = selectedContentProperties.filePath
|
||||
page.selectedFileType = mimeType
|
||||
|
|
|
@ -15,12 +15,15 @@ function supported_formats(printer, ConvertChecker, considerAdditionalFormats)
|
|||
var postscript = false;
|
||||
var office = false;
|
||||
var images = false;
|
||||
var plaintext = false;
|
||||
|
||||
if(has(formats, Mimer.PDF) ||
|
||||
(ConvertChecker.pdf && ( has(formats, Mimer.Postscript) || raster )))
|
||||
{
|
||||
pdf = true;
|
||||
mimetypes.push(Mimer.PDF);
|
||||
plaintext = true;
|
||||
mimetypes.push(Mimer.Plaintext);
|
||||
}
|
||||
if(has(formats, Mimer.Postscript))
|
||||
{
|
||||
|
@ -44,7 +47,7 @@ function supported_formats(printer, ConvertChecker, considerAdditionalFormats)
|
|||
mimetypes.push(Mimer.GIF);
|
||||
}
|
||||
|
||||
return {pdf: pdf, postscript: postscript, office: office, images: images, mimetypes: mimetypes};
|
||||
return {pdf: pdf, postscript: postscript, plaintext: plaintext, office: office, images: images, mimetypes: mimetypes};
|
||||
}
|
||||
|
||||
function has(arrayish, what)
|
||||
|
@ -316,6 +319,18 @@ function limitChoices(name, choices, mimeType, ConvertChecker)
|
|||
}
|
||||
|
||||
}
|
||||
else if(mimeType == Mimer.Plaintext)
|
||||
{
|
||||
// We convert plaintext to PDF internally
|
||||
if(ConvertChecker.pdf)
|
||||
{
|
||||
return choices.filter(canConvertPdfTo)
|
||||
}
|
||||
else
|
||||
{
|
||||
return choices.filter(canTransferPdfAs)
|
||||
}
|
||||
}
|
||||
else if(mimeType == Mimer.Postscript)
|
||||
{
|
||||
return choices.filter(canTransferPostscriptAs)
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <QImage>
|
||||
#include <QMatrix>
|
||||
#include <QPainter>
|
||||
#include <QTextDocument>
|
||||
#include <QPdfWriter>
|
||||
|
||||
void ppm2PwgEnv(QStringList& env, bool urf, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||
|
@ -379,6 +381,171 @@ catch(const ConvertFailedException& e)
|
|||
}
|
||||
}
|
||||
|
||||
void ConvertWorker::convertPlaintext(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble)
|
||||
{
|
||||
try {
|
||||
|
||||
if(!PaperSizes.contains(PaperSize))
|
||||
{
|
||||
qDebug() << "Unsupported paper size" << PaperSize;
|
||||
throw ConvertFailedException(tr("Unsupported paper size"));
|
||||
}
|
||||
QPair<float,float> wh = PaperSizes[PaperSize];
|
||||
|
||||
QFile inFile(filename);
|
||||
if(!inFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
throw ConvertFailedException(tr("Failed to open file"));
|
||||
}
|
||||
|
||||
quint32 resolution = std::min(HwResX, HwResY);
|
||||
|
||||
QTemporaryFile tmpPdfFile;
|
||||
tmpPdfFile.open();
|
||||
|
||||
QPdfWriter pdfWriter(tmpPdfFile.fileName());
|
||||
QPageSize pageSize(QSizeF {wh.first, wh.second}, QPageSize::Millimeter);
|
||||
pdfWriter.setPageSize(pageSize);
|
||||
pdfWriter.setResolution(resolution);
|
||||
|
||||
qreal docHeight = pageSize.sizePixels(resolution).height();
|
||||
|
||||
QTextDocument doc;
|
||||
|
||||
QFont font = QFont("Courier");
|
||||
font.setPointSizeF(1);
|
||||
|
||||
qreal charHeight = 0;
|
||||
|
||||
// Find the optimal font size
|
||||
while(true) {
|
||||
QFont tmpFont = font;
|
||||
tmpFont.setPointSizeF(font.pointSizeF()+0.5);
|
||||
QFontMetricsF qfm(tmpFont, &pdfWriter);
|
||||
|
||||
charHeight = qfm.lineSpacing();
|
||||
|
||||
if(charHeight*66 > docHeight)
|
||||
{
|
||||
break;
|
||||
}
|
||||
font=tmpFont;
|
||||
}
|
||||
|
||||
QFontMetricsF qfm(font, &pdfWriter);
|
||||
|
||||
charHeight = qfm.height();
|
||||
|
||||
int textHeight = 60*charHeight;
|
||||
qreal margin = ((docHeight-textHeight)/2);
|
||||
|
||||
doc.setDefaultFont(font);
|
||||
(void)doc.documentLayout(); // wat
|
||||
|
||||
// Needs to be before painter
|
||||
pdfWriter.setMargins({0, 0, 0, 0});
|
||||
|
||||
QPainter painter(&pdfWriter);
|
||||
|
||||
doc.documentLayout()->setPaintDevice(painter.device());
|
||||
doc.setDocumentMargin(margin);
|
||||
|
||||
QRectF body = QRectF(0, 0, pdfWriter.width(), pdfWriter.height());
|
||||
doc.setPageSize(body.size());
|
||||
|
||||
QString allText = inFile.readAll();
|
||||
if(allText.startsWith("\f"))
|
||||
{
|
||||
allText.remove(0, 1);
|
||||
}
|
||||
|
||||
if(allText.endsWith("\f"))
|
||||
{
|
||||
allText.chop(1);
|
||||
}
|
||||
else if(allText.endsWith("\f\n"))
|
||||
{
|
||||
allText.chop(2);
|
||||
}
|
||||
|
||||
QStringList pages = allText.split('\f');
|
||||
|
||||
bool first = true;
|
||||
int pageCount = 0;
|
||||
|
||||
foreach(QString page, pages)
|
||||
{
|
||||
if(!first)
|
||||
{
|
||||
pdfWriter.newPage();
|
||||
}
|
||||
first = false;
|
||||
|
||||
if(page.endsWith("\n"))
|
||||
{
|
||||
page.chop(1);
|
||||
}
|
||||
doc.setPlainText(page);
|
||||
|
||||
int p = 0; // Page number in this document, starting from 0
|
||||
|
||||
while(true)
|
||||
{
|
||||
painter.translate(body.left(), body.top() - p*body.height());
|
||||
QRectF view(0, p*body.height(), body.width(), body.height());
|
||||
painter.setClipRect(view);
|
||||
|
||||
QAbstractTextDocumentLayout::PaintContext context;
|
||||
context.clip = view;
|
||||
context.palette.setColor(QPalette::Text, Qt::black);
|
||||
doc.documentLayout()->draw(&painter, context);
|
||||
|
||||
p++;
|
||||
pageCount++;
|
||||
|
||||
if(p >= doc.pageCount())
|
||||
break;
|
||||
|
||||
pdfWriter.newPage();
|
||||
}
|
||||
}
|
||||
|
||||
painter.end();
|
||||
|
||||
|
||||
if(targetFormat == Mimer::PDF)
|
||||
{
|
||||
QFile tempfileAsFile(tempfile->fileName());
|
||||
tempfileAsFile.open(QIODevice::Append);
|
||||
tempfileAsFile.write(tmpPdfFile.readAll());
|
||||
tempfileAsFile.close();
|
||||
}
|
||||
else if(targetFormat == Mimer::Postscript)
|
||||
{
|
||||
pdftoPs(PaperSize, TwoSided, 0, 0, tmpPdfFile.fileName(), tempfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdfToRaster(targetFormat, Colors, Quality, PaperSize,
|
||||
HwResX, HwResY, TwoSided, Tumble,
|
||||
0, 0, pageCount,
|
||||
tmpPdfFile.fileName(), tempfile, false);
|
||||
}
|
||||
|
||||
qDebug() << "Finished";
|
||||
|
||||
emit done(request, tempfile);
|
||||
|
||||
}
|
||||
catch(const ConvertFailedException& e)
|
||||
{
|
||||
tempfile->deleteLater();
|
||||
emit failed(e.what() == QString("") ? tr("Conversion error") : e.what());
|
||||
}
|
||||
}
|
||||
|
||||
QString ConvertWorker::getPopplerShortPaperSize(QString PaperSize)
|
||||
{
|
||||
QString ShortPaperSize;
|
||||
|
@ -456,7 +623,10 @@ void ConvertWorker::pdftoPs(QString PaperSize, bool TwoSided, quint32 PageRangeL
|
|||
|
||||
QString ShortPaperSize = getPopplerShortPaperSize(PaperSize);
|
||||
|
||||
PdfToPsArgs << QStringList {"-f", QString::number(PageRangeLow), "-l", QString::number(PageRangeHigh)};
|
||||
if(PageRangeLow != 0 && PageRangeHigh != 0)
|
||||
{
|
||||
PdfToPsArgs << QStringList {"-f", QString::number(PageRangeLow), "-l", QString::number(PageRangeHigh)};
|
||||
}
|
||||
|
||||
PdfToPsArgs << QStringList {"-paper", ShortPaperSize, pdfFileName, "-"};
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@ public slots:
|
|||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||
quint32 PageRangeLow, quint32 PageRangeHigh);
|
||||
|
||||
void convertPlaintext(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble);
|
||||
|
||||
signals:
|
||||
void done(QNetworkRequest request, QTemporaryFile* data);
|
||||
void progress(qint64 done, qint64 pages);
|
||||
|
|
|
@ -34,6 +34,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(this, &IppPrinter::doConvertPlaintext, _worker, &ConvertWorker::convertPlaintext);
|
||||
connect(_worker, &ConvertWorker::done, this, &IppPrinter::convertDone);
|
||||
connect(_worker, &ConvertWorker::progress, this, &IppPrinter::setProgress);
|
||||
connect(_worker, &ConvertWorker::failed, this, &IppPrinter::convertFailed);
|
||||
|
@ -310,7 +311,7 @@ QString targetFormatIfAuto(QString documentFormat, QString mimeType, QJsonArray
|
|||
{
|
||||
if(documentFormat == Mimer::OctetStream)
|
||||
{
|
||||
if(mimeType == Mimer::PDF)
|
||||
if(mimeType == Mimer::PDF || mimeType == Mimer::Plaintext)
|
||||
{
|
||||
return firstMatch(supportedMimeTypes, {Mimer::PDF, Mimer::Postscript, Mimer::PWG, Mimer::URF });
|
||||
}
|
||||
|
@ -534,6 +535,11 @@ void IppPrinter::print(QJsonObject attrs, QString filename, bool alwaysUseMediaC
|
|||
emit doConvertPdf(request, filename, tempfile, documentFormat, Colors, Quality,
|
||||
PaperSize, HwResX, HwResY, TwoSided, Tumble, PageRangeLow, PageRangeHigh);
|
||||
}
|
||||
else if(mimeType == Mimer::Plaintext)
|
||||
{
|
||||
emit doConvertPlaintext(request, filename, tempfile, documentFormat, Colors, Quality,
|
||||
PaperSize, HwResX, HwResY, TwoSided, Tumble);
|
||||
}
|
||||
else if (Mimer::isImage(mimeType))
|
||||
{
|
||||
emit doConvertImage(request, filename, tempfile, documentFormat, Colors, Quality,
|
||||
|
|
|
@ -54,6 +54,10 @@ signals:
|
|||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble,
|
||||
quint32 PageRangeLow, quint32 PageRangeHigh);
|
||||
|
||||
void doConvertPlaintext(QNetworkRequest request, QString filename, QTemporaryFile* tempfile,
|
||||
QString targetFormat, quint32 Colors, quint32 Quality, QString PaperSize,
|
||||
quint32 HwResX, quint32 HwResY, bool TwoSided, bool Tumble);
|
||||
|
||||
void additionalDocumentFormatsChanged();
|
||||
void busyMessageChanged();
|
||||
void progressChanged();
|
||||
|
|
|
@ -18,6 +18,8 @@ const QString Mimer::RTF = "text/rtf";
|
|||
const QString Mimer::RTF_APP = "application/rtf";
|
||||
const QString Mimer::ODT = "application/vnd.oasis.opendocument.text";
|
||||
|
||||
const QString Mimer::Plaintext = "text/plain";
|
||||
|
||||
const QStringList Mimer::OfficeFormats = {DOC, DOCX, RTF, RTF_APP, ODT};
|
||||
|
||||
Mimer::Mimer()
|
||||
|
|
|
@ -30,6 +30,8 @@ public:
|
|||
Q_PROPERTY(const QString RTF MEMBER RTF CONSTANT);
|
||||
Q_PROPERTY(const QString ODT MEMBER ODT CONSTANT);
|
||||
|
||||
Q_PROPERTY(const QString Plaintext MEMBER Plaintext CONSTANT);
|
||||
|
||||
Q_PROPERTY(const QStringList OfficeFormats MEMBER OfficeFormats CONSTANT);
|
||||
|
||||
static const QString OctetStream;
|
||||
|
@ -50,6 +52,8 @@ public:
|
|||
static const QString RTF_APP;
|
||||
static const QString ODT;
|
||||
|
||||
static const QString Plaintext;
|
||||
|
||||
static const QStringList OfficeFormats;
|
||||
|
||||
Q_INVOKABLE static bool isImage(QString mimeType)
|
||||
|
|
|
@ -171,6 +171,10 @@
|
|||
<source>Failed to get info about PDF file</source>
|
||||
<translation>PDF Info nicht abrufbar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to open file</source>
|
||||
<translation>Öffnen der Datei fehlgeschlagen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoverPage</name>
|
||||
|
|
|
@ -171,6 +171,10 @@
|
|||
<source>Failed to get info about PDF file</source>
|
||||
<translation>Error al obtener info de archivo PDF</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to open file</source>
|
||||
<translation>Error al abrir archivo</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoverPage</name>
|
||||
|
|
|
@ -171,6 +171,10 @@
|
|||
<source>Failed to get info about PDF file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to open file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoverPage</name>
|
||||
|
|
|
@ -171,6 +171,10 @@
|
|||
<source>Failed to get info about PDF file</source>
|
||||
<translation>Informatie over het PDF-bestand ophalen mislukt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to open file</source>
|
||||
<translation>Bestand openen mislukt</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoverPage</name>
|
||||
|
|
|
@ -171,6 +171,10 @@
|
|||
<source>Failed to load image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to open file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoverPage</name>
|
||||
|
|
|
@ -171,6 +171,10 @@
|
|||
<source>Failed to get info about PDF file</source>
|
||||
<translation>获取PDF文件信息错误</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to open file</source>
|
||||
<translation>打开文件失败</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoverPage</name>
|
||||
|
|
|
@ -171,6 +171,10 @@
|
|||
<source>Failed to get info about PDF file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Failed to open file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CoverPage</name>
|
||||
|
|
Loading…
Reference in a new issue