33#include " settings.h"
44#include < QDir>
55#include < QMessageBox>
6+ #include < QJsonDocument>
7+ #include < QJsonObject>
68
79#ifdef Q_OS_WINDOWS
810#define WIN32_LEAN_AND_MEAN
@@ -89,7 +91,7 @@ CreateProgress::CreateProgress(QWidget *parent) :
8991 // TODO: consider adding decimal percentage bar: https://www.qtcentre.org/threads/70885-QProgressBar-with-in-decimal?s=bdfd413197898978b8ef6ea933c3e67e&p=307578#post307578
9092}
9193
92- void CreateProgress::run (QStringList args, const QByteArray& inFiles, const QString& baseOutput_, const QString& outDir_, const QStringList& outFiles_)
94+ void CreateProgress::run (QStringList args, const QHash<QString, QString>& env, const QByteArray& inFiles, const QString& baseOutput_, const QString& outDir_, const QStringList& outFiles_)
9395{
9496 baseOutput = baseOutput_;
9597 outDir = outDir_;
@@ -100,17 +102,25 @@ void CreateProgress::run(QStringList args, const QByteArray& inFiles, const QStr
100102 if (cmd.length () > 1 )
101103 args.prepend (cmd[1 ]);
102104
103- args << " --quiet" << " --progress" << " stdout" << " --input-file0" << " -" ;
105+ args << " --quiet" << " --json " << " -- progress" << " stdout" << " --input-file0" << " -" ;
104106 parpar.setArguments (args);
105107
108+ if (!env.empty ()) {
109+ auto procEnv = QProcessEnvironment::systemEnvironment ();
110+ auto it = QHashIterator<QString, QString>(env);
111+ while (it.hasNext ()) {
112+ it.next ();
113+ procEnv.insert (it.key (), it.value ());
114+ }
115+ parpar.setProcessEnvironment (procEnv);
116+ }
117+
106118 this ->setWindowTitle (tr (" ParPar - Creating %2" )
107119 .arg (baseOutput));
108120
109121 // send stdin when process starts
110122 connect (&parpar, &QProcess::started, this , [=]() {
111123 ui->lblStatus ->setText (" " );
112- ui->btnBackground ->setEnabled (true );
113- ui->btnNotify ->setEnabled (true );
114124 ui->btnPause ->setEnabled (true );
115125
116126 if (ui->btnBackground ->isChecked ())
@@ -142,36 +152,32 @@ void CreateProgress::run(QStringList args, const QByteArray& inFiles, const QStr
142152
143153void CreateProgress::gotStdout ()
144154{
145- stdoutBuffer += QString::fromUtf8 (parpar.readAllStandardOutput ());
146-
147- // find last % and update display
148- int p = stdoutBuffer.lastIndexOf (' %' );
149- if (p > 0 ) {
150- // extract percentage
151- int i = p;
152- while (i--) {
153- auto c = stdoutBuffer.at (i);
154- if (c != ' .' && !c.isDigit ())
155- break ;
155+ stdoutBuffer.append (parpar.readAllStandardOutput ());
156+
157+ // find end of JSON message
158+ int p = stdoutBuffer.indexOf (" \n }" );
159+ while (p > 0 ) {
160+ // extract message
161+ const auto doc = QJsonDocument::fromJson (stdoutBuffer.left (p + 2 ));
162+ stdoutBuffer = stdoutBuffer.mid (p + 2 );
163+ p = stdoutBuffer.indexOf (" \n }" );
164+
165+ if (!doc.isNull () && !doc.isEmpty ()) {
166+ const auto msg = doc.object ().toVariantHash ();
167+ const auto type = msg.value (" type" , " " ).toString ();
168+ if (type == " progress" ) {
169+ bool ok;
170+ float progress = msg.value (" progress_percent" , -1 ).toFloat (&ok);
171+ if (progress >= 0 && ok) {
172+ ui->progressBar ->setMaximum (10000 );
173+ ui->progressBar ->setValue (progress * 100 );
174+ WIN_PROGRESS (SetProgressState, TBPF_NORMAL);
175+ WIN_PROGRESS (SetProgressValue, progress, 10000 );
176+
177+ updateTitlePerc ();
178+ }
179+ }
156180 }
157- i++;
158- if (i == p) return ; // got a % without a preceeding number
159-
160- bool ok;
161- #if QT_VERSION >= 0x060000
162- int progress = QStringView{stdoutBuffer}.mid (i, p-i).toFloat (&ok) * 100 ;
163- #else
164- int progress = stdoutBuffer.midRef (i, p-i).toFloat (&ok) * 100 ;
165- #endif
166- if (!ok) return ; // why oh why???
167-
168- ui->progressBar ->setMaximum (10000 );
169- ui->progressBar ->setValue (progress);
170- WIN_PROGRESS (SetProgressState, TBPF_NORMAL);
171- WIN_PROGRESS (SetProgressValue, progress, 10000 );
172-
173- updateTitlePerc ();
174- stdoutBuffer = stdoutBuffer.mid (p+1 );
175181 }
176182}
177183
@@ -202,20 +208,22 @@ void CreateProgress::finished(int exitCode, QProcess::ExitStatus exitStatus)
202208 } else if (exitCode != 0 ) {
203209 ended (tr (" PAR2 creation failed (exit code: %1)" ).arg (exitCode), true );
204210 } else {
205- ended (" " , false );
211+ ended (" " , true );
206212 }
207213}
208214
209215void CreateProgress::ended (const QString &error, bool showOutput)
210216{
217+ // gotStdout(); // flush remaining stdout
218+
211219 bool success = error.isEmpty ();
212220 ui->progressBar ->setEnabled (false );
213221 ui->lblTime ->setEnabled (false );
214- ui->btnBackground ->setEnabled (false );
215- ui->btnNotify ->setEnabled (false );
216222 ui->btnPause ->setEnabled (false );
217223 if (success) {
218224 ui->lblStatus ->setText (tr (" PAR2 successfully created" ));
225+ ui->progressBar ->setMaximum (10000 );
226+ ui->progressBar ->setValue (10000 );
219227 this ->setWindowTitle (tr (" ParPar - Finished creating %1" ).arg (baseOutput));
220228 WIN_PROGRESS (SetProgressState, TBPF_NOPROGRESS);
221229 } else {
@@ -246,9 +254,11 @@ void CreateProgress::ended(const QString &error, bool showOutput)
246254
247255 if (isCancelled) return ;
248256
257+ bool hasOutput = false ;
249258 if (showOutput) {
250259 auto output = QString::fromUtf8 (parpar.readAllStandardError ()).trimmed ();
251260 if (!output.isEmpty ()) {
261+ hasOutput = true ;
252262 ui->txtMessage ->setPlainText (output);
253263 ui->txtMessage ->show ();
254264
@@ -257,6 +267,9 @@ void CreateProgress::ended(const QString &error, bool showOutput)
257267 this ->resize (this ->width (), this ->layout ()->sizeHint ().height ());
258268
259269 this ->setSizeGripEnabled (true );
270+
271+ if (success)
272+ ui->lblStatus ->setText (tr (" PAR2 created with warnings" ));
260273 }
261274 }
262275
@@ -272,6 +285,9 @@ void CreateProgress::ended(const QString &error, bool showOutput)
272285 }
273286 QApplication::alert (this );
274287 }
288+
289+ if (!hasOutput && success && Settings::getInstance ().runClose ())
290+ this ->close ();
275291}
276292
277293void CreateProgress::deleteOutput ()
@@ -308,6 +324,9 @@ void CreateProgress::on_CreateProgress_rejected()
308324 ended (tr (" Cancelled" ), false );
309325 parpar.waitForFinished (1000 ); // try to avoid warning of destroying QProcess whilst still active
310326 deleteOutput ();
327+
328+ if (Settings::getInstance ().runClose ())
329+ this ->close ();
311330 }
312331}
313332
@@ -316,61 +335,63 @@ void CreateProgress::on_btnBackground_clicked()
316335{
317336 bool isBackground = ui->btnBackground ->isChecked ();
318337
338+ if (parpar.state () == QProcess::Running) {
319339#ifdef Q_OS_WINDOWS
320- static DWORD normPrio = 0x7fff ;
321- HANDLE hPP = OpenProcess (PROCESS_SET_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION, FALSE , parpar.processId ());
322- if (hPP == NULL ) {
323- ui->btnBackground ->setEnabled (false );
324- ui->btnBackground ->setChecked (!isBackground);
325- return ;
326- }
327- if (normPrio == 0x7fff ) {
328- normPrio = GetPriorityClass (hPP);
329- if (!normPrio) {
330- // failed to retrieve, disable option
340+ static DWORD normPrio = 0x7fff ;
341+ HANDLE hPP = OpenProcess (PROCESS_SET_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION, FALSE , parpar.processId ());
342+ if (hPP == NULL ) {
331343 ui->btnBackground ->setEnabled (false );
332- ui->btnBackground ->setChecked (false );
333- CloseHandle (hPP);
344+ ui->btnBackground ->setChecked (!isBackground);
334345 return ;
335346 }
336- if (normPrio == IDLE_PRIORITY_CLASS) {
337- // already at low priority
338- ui->btnBackground ->setEnabled (false );
339- ui->btnBackground ->setChecked (true );
340- CloseHandle (hPP);
341- return ;
347+ if (normPrio == 0x7fff ) {
348+ normPrio = GetPriorityClass (hPP);
349+ if (!normPrio) {
350+ // failed to retrieve, disable option
351+ ui->btnBackground ->setEnabled (false );
352+ ui->btnBackground ->setChecked (false );
353+ CloseHandle (hPP);
354+ return ;
355+ }
356+ if (normPrio == IDLE_PRIORITY_CLASS) {
357+ // already at low priority
358+ ui->btnBackground ->setEnabled (false );
359+ ui->btnBackground ->setChecked (true );
360+ CloseHandle (hPP);
361+ return ;
362+ }
342363 }
343- }
344- if (!SetPriorityClass (hPP, isBackground ? IDLE_PRIORITY_CLASS : normPrio)) {
345- ui->btnBackground ->setChecked (!isBackground);
346- }
347- CloseHandle (hPP);
348- #elif defined(Q_OS_UNIX)
349- static int normPrio = 0x7fff ;
350- if (normPrio == 0x7fff ) {
351- // get the normal priority level (assume we start there)
352- errno = 0 ;
353- normPrio = getpriority (PRIO_PROCESS, parpar.processId ());
354- if (normPrio == -1 && errno) {
355- // failed to retrieve, disable option
356- ui->btnBackground ->setEnabled (false );
357- ui->btnBackground ->setChecked (false );
358- return ;
364+ if (!SetPriorityClass (hPP, isBackground ? IDLE_PRIORITY_CLASS : normPrio)) {
365+ ui->btnBackground ->setChecked (!isBackground);
359366 }
360- if (normPrio >= 19 ) {
361- // already at low priority
362- ui->btnBackground ->setEnabled (false );
363- ui->btnBackground ->setChecked (true );
364- return ;
367+ CloseHandle (hPP);
368+ #elif defined(Q_OS_UNIX)
369+ static int normPrio = 0x7fff ;
370+ if (normPrio == 0x7fff ) {
371+ // get the normal priority level (assume we start there)
372+ errno = 0 ;
373+ normPrio = getpriority (PRIO_PROCESS, parpar.processId ());
374+ if (normPrio == -1 && errno) {
375+ // failed to retrieve, disable option
376+ ui->btnBackground ->setEnabled (false );
377+ ui->btnBackground ->setChecked (false );
378+ return ;
379+ }
380+ if (normPrio >= 19 ) {
381+ // already at low priority
382+ ui->btnBackground ->setEnabled (false );
383+ ui->btnBackground ->setChecked (true );
384+ return ;
385+ }
365386 }
366- }
367387
368- if (setpriority (PRIO_PROCESS, parpar.processId (), isBackground ? 19 : normPrio)) {
369- ui->btnBackground ->setChecked (!isBackground);
370- // TODO: it seems like you can't increase priority back to normal on Linux
371- // TODO: if failed, the settings change is still persisted
372- }
388+ if (setpriority (PRIO_PROCESS, parpar.processId (), isBackground ? 19 : normPrio)) {
389+ ui->btnBackground ->setChecked (!isBackground);
390+ // TODO: it seems like you can't increase priority back to normal on Linux
391+ // TODO: if failed, the settings change is still persisted
392+ }
373393#endif
394+ }
374395
375396 Settings::getInstance ().setRunBackground (isBackground);
376397}
0 commit comments