From 9ee8807af7276ee8a910561f671a8cd1936babf9 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Fri, 30 Apr 2021 15:51:13 +0200 Subject: [PATCH] export: show progress dialog for TeX exports The TeX exports may hang the UI for a long time. Show a progress-dialog that is updated after every exported dive and allows the user to cancel the export. This is pretty lame, because it is synchronous (export still runs in UI thread) and therefore the UI still is sluggish. But it is an improvement. Since the TeX-exporting code is in a shared directory (desktop and mobile), this uses a slim interface class. Mobile does not yet use TeX export, but you never know. Better than #ifdefs sprinkled all around, I reckon. Signed-off-by: Berthold Stoeger --- CHANGELOG.md | 1 + backend-shared/exportfuncs.cpp | 22 +++++++++++++--- backend-shared/exportfuncs.h | 8 +++++- desktop-widgets/divelogexportdialog.cpp | 34 +++++++++++++++++++++++-- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 412303665..5270b9abc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +export: show progress dialog when exporting to TeX printing: use sensible font size even for strange window size --- diff --git a/backend-shared/exportfuncs.cpp b/backend-shared/exportfuncs.cpp index 24f133377..af6379001 100644 --- a/backend-shared/exportfuncs.cpp +++ b/backend-shared/exportfuncs.cpp @@ -15,8 +15,19 @@ #include "core/picture.h" #include "core/pref.h" #include "core/sample.h" +#include "core/selection.h" #include "exportfuncs.h" +// Default implementation of the export callback: do nothing / never cancel +void ExportCallback::setProgress(int) +{ +} + +bool ExportCallback::canceled() const +{ + return false; +} + #if !defined(SUBSURFACE_MOBILE) void exportProfile(QString filename, bool selected_only) { @@ -38,7 +49,7 @@ void exportProfile(QString filename, bool selected_only) } } -void export_TeX(const char *filename, bool selected_only, bool plain) +void export_TeX(const char *filename, bool selected_only, bool plain, ExportCallback &cb) { FILE *f; QDir texdir = QFileInfo(filename).dir(); @@ -91,10 +102,14 @@ void export_TeX(const char *filename, bool selected_only, bool plain) put_format(&buf, "\n%%%%%%%%%% Begin Dive Data: %%%%%%%%%%\n"); + int todo = selected_only ? amount_selected : dive_table.nr; + int done = 0; for_each_dive (i, dive) { + if (cb.canceled()) + return; if (selected_only && !dive->selected) continue; - + cb.setProgress(done++ * 1000 / todo); exportProfile(dive, texdir.filePath(QString("profile%1.png").arg(dive->number))); struct tm tm; utc_mkdate(dive->when, &tm); @@ -219,7 +234,6 @@ void export_TeX(const char *filename, bool selected_only, bool plain) dive->maxdepth.mm ? put_format(&buf, "\\def\\%sdepth{%.1f\\%sdepthunit}\n", ssrf, get_depth_units(dive->maxdepth.mm, NULL, &unit), ssrf) : put_format(&buf, "\\def\\%sdepth{}\n", ssrf); put_format(&buf, "\\%spage\n", ssrf); - } if (plain) @@ -235,7 +249,7 @@ void export_TeX(const char *filename, bool selected_only, bool plain) fclose(f); } free_buffer(&buf); - + cb.setProgress(1000); } void export_depths(const char *filename, bool selected_only) diff --git a/backend-shared/exportfuncs.h b/backend-shared/exportfuncs.h index 250e8e60f..3eb83c9b1 100644 --- a/backend-shared/exportfuncs.h +++ b/backend-shared/exportfuncs.h @@ -7,8 +7,14 @@ struct dive_site; +// A synchrounous callback interface to signal progress / check for user abort +struct ExportCallback { + virtual void setProgress(int progress); // 0-1000 + virtual bool canceled() const; +}; + void exportProfile(QString filename, bool selected_only); -void export_TeX(const char *filename, bool selected_only, bool plain); +void export_TeX(const char *filename, bool selected_only, bool plain, ExportCallback &cb); void export_depths(const char *filename, bool selected_only); std::vector getDiveSitesToExport(bool selectedOnly); QFuture exportUsingStyleSheet(QString filename, bool doExport, int units, QString stylesheet, bool anonymize); diff --git a/desktop-widgets/divelogexportdialog.cpp b/desktop-widgets/divelogexportdialog.cpp index f0ee82337..7d9a6d6ca 100644 --- a/desktop-widgets/divelogexportdialog.cpp +++ b/desktop-widgets/divelogexportdialog.cpp @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include #include // Allows string comparisons and substitutions in TeX export @@ -14,6 +15,7 @@ #include "core/divesite.h" #include "core/errorhelper.h" #include "core/file.h" +#include "core/gettextfromc.h" #include "core/tag.h" #include "backend-shared/exportfuncs.h" #include "desktop-widgets/mainwindow.h" @@ -131,6 +133,32 @@ void DiveLogExportDialog::on_exportGroup_buttonClicked(QAbstractButton*) showExplanation(); } +// Use a QProgressDialog to show export-progress +// Default implementation of the export callback: do nothing / never cancel +struct ProgressDialogCallback : public ExportCallback { + ProgressDialogCallback(); + QProgressDialog dialog; + virtual void setProgress(int progress) override; + virtual bool canceled() const override; +}; + +ProgressDialogCallback::ProgressDialogCallback() : + dialog(gettextFromC::tr("Exporting..."), gettextFromC::tr("Cancel"), 0, 1000, MainWindow::instance()) +{ + dialog.setWindowModality(Qt::WindowModal); + dialog.setMinimumDuration(0); // Show dialog immediately +} + +void ProgressDialogCallback::setProgress(int progress) +{ + dialog.setValue(progress); +} + +bool ProgressDialogCallback::canceled() const +{ + return dialog.wasCanceled(); +} + void DiveLogExportDialog::on_buttonBox_accepted() { QString filename; @@ -188,8 +216,10 @@ void DiveLogExportDialog::on_buttonBox_accepted() export_depths(qPrintable(filename), ui->exportSelected->isChecked()); } else if (ui->exportTeX->isChecked() || ui->exportLaTeX->isChecked()) { filename = QFileDialog::getSaveFileName(this, tr("Export to TeX file"), lastDir, tr("TeX files") + " (*.tex)"); - if (!filename.isEmpty()) - export_TeX(qPrintable(filename), ui->exportSelected->isChecked(), ui->exportTeX->isChecked()); + if (!filename.isEmpty()) { + ProgressDialogCallback cb; + export_TeX(qPrintable(filename), ui->exportSelected->isChecked(), ui->exportTeX->isChecked(), cb); + } } else if (ui->exportProfile->isChecked()) { filename = QFileDialog::getSaveFileName(this, tr("Save profile image"), lastDir); if (!filename.isEmpty())