KIO

standardthumbnailjob.cpp
1/*
2 SPDX-FileCopyrightText: 2024 Akseli Lahtinen <akselmo@akselmo.dev>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#include "global.h"
7#include "standardthumbnailjob_p.h"
8#include <KMacroExpander>
9#include <QImage>
10#include <QProcess>
11#include <QTemporaryFile>
12
13class ThumbnailerExpander : public KMacroExpanderBase
14{
15public:
16 explicit ThumbnailerExpander(const QString execString, const int width, const QString inputFile, const QString outputFile)
18 , m_width(width)
19 , m_execString(execString)
20 , m_inputFile(inputFile)
21 , m_outputFile(outputFile)
22 {
23 QString newString(execString);
24 expandMacros(newString);
25 auto fullCmd = QProcess::splitCommand(newString);
26 m_binary = fullCmd.first();
27 fullCmd.removeFirst();
28 m_args = fullCmd;
29 }
30
31 QString binary()
32 {
33 return m_binary;
34 }
35
36 QStringList args()
37 {
38 return m_args;
39 }
40
41private:
42 int expandEscapedMacro(const QString &str, int pos, QStringList &ret) override;
43 const int m_width;
44 const QString m_execString;
45 const QString m_inputFile;
46 const QString m_outputFile;
47 QString m_binary;
48 QStringList m_args;
49};
50
51int ThumbnailerExpander::expandEscapedMacro(const QString &str, int pos, QStringList &ret)
52{
53 uint option = str[pos + 1].unicode();
54 switch (option) {
55 case 's':
56 ret << QString::number(m_width);
57 break;
58 case 'i':
59 case 'u':
60 ret << QStringLiteral(R"("%1")").arg(m_inputFile);
61 break;
62 case 'o':
63 ret << QStringLiteral(R"("%1")").arg(m_outputFile);
64 break;
65 case '%':
66 ret = QStringList(QStringLiteral("%"));
67 break;
68 default:
69 return -2; // subst with same and skip
70 }
71 return 2;
72}
73
74class Q_DECL_HIDDEN KIO::StandardThumbnailJob::Private
75{
76public:
77 explicit Private(const QString &execString, int width, const QString &inputFile, const QString &outputFolder)
78 : m_execString(execString)
79 , m_width(width)
80 , m_inputFile(inputFile)
81 , m_outputFolder(outputFolder)
82 {
83 }
84 ~Private()
85 {
86 }
87
88 QString m_execString;
89 int m_width;
90 QString m_inputFile;
91 QString m_outputFolder;
92 QProcess *m_proc;
93 QTemporaryFile *m_tempFile;
94};
95
96KIO::StandardThumbnailJob::StandardThumbnailJob(const QString &execString, int width, const QString &inputFile, const QString &outputFolder)
97 : d(new Private(execString, width, inputFile, outputFolder))
98{
99 setAutoDelete(true);
100}
101
102KIO::StandardThumbnailJob::~StandardThumbnailJob() = default;
103
104bool KIO::StandardThumbnailJob::StandardThumbnailJob::doKill()
105{
106 d->m_proc->kill();
107 return true;
108}
109
110void KIO::StandardThumbnailJob::StandardThumbnailJob::start()
111{
112 // Prepare the command
113 d->m_tempFile = new QTemporaryFile(QStringLiteral("%1/XXXXXX.png").arg(d->m_outputFolder));
114 if (!d->m_tempFile->open()) {
115 setErrorText(QStringLiteral("Standard Thumbnail Job had an error: could not open temporary file"));
116 setError(KIO::ERR_CANNOT_OPEN_FOR_WRITING);
117 emitResult();
118 }
119 d->m_tempFile->setAutoRemove(false);
120
121 ThumbnailerExpander thumbnailer(d->m_execString, d->m_width, d->m_inputFile, d->m_tempFile->fileName());
122 // Emit data on command exit
123 d->m_proc = new QProcess();
124 connect(d->m_proc, &QProcess::finished, this, [=, this](const int exitCode, const QProcess::ExitStatus /* exitStatus */) {
125 d->m_proc->deleteLater();
126 if (exitCode != 0) {
127 setErrorText(QStringLiteral("Standard Thumbnail Job failed with exit code: %1 ").arg(exitCode));
128 setError(KIO::ERR_CANNOT_LAUNCH_PROCESS);
129 emitResult();
130
131 // clean temp file
132 d->m_tempFile->remove();
133 return;
134 }
135 Q_EMIT data(this, QImage(d->m_tempFile->fileName()));
136 emitResult();
137
138 // clean temp file
139 d->m_tempFile->remove();
140 });
141 connect(d->m_proc, &QProcess::errorOccurred, this, [=, this](const QProcess::ProcessError error) {
142 d->m_proc->deleteLater();
143 setErrorText(QStringLiteral("Standard Thumbnail Job had an error: %1").arg(error));
144 setError(KIO::ERR_CANNOT_LAUNCH_PROCESS);
145 emitResult();
146
147 // clean temp file
148 d->m_tempFile->remove();
149 });
150 d->m_proc->start(thumbnailer.binary(), thumbnailer.args());
151}
void expandMacros(QString &str)
A namespace for KIO globals.
void errorOccurred(QProcess::ProcessError error)
void finished(int exitCode, QProcess::ExitStatus exitStatus)
QStringList splitCommand(QStringView command)
QString first(qsizetype n) const const
QString number(double n, char format, int precision)
QString & removeFirst()
const QChar * unicode() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:58:45 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.