From 1d0087929c4c47ca8a5ca7ea669a7db3e2674585 Mon Sep 17 00:00:00 2001 From: Floris Bos Date: Wed, 9 Dec 2020 14:23:40 +0100 Subject: [PATCH] Windows: show progress in taskbar Windows: show progress in taskbar Closes #132 Implemented in ImageWriter class instead of qml for practical reasons. GUI stuff does not really belong there, but there is no easy way to have platform specific stuff in qml, lacking #ifdef --- CMakeLists.txt | 3 +- imagewriter.cpp | 65 +++++++++++++++++++++++++++++++++------ imagewriter.h | 6 ++++ windows/rpi-imager.nsi.in | 2 ++ 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f96d8415a..c54dd3eea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,8 @@ elseif (WIN32) set(DEPENDENCIES acceleratedcryptographichash.cpp dependencies/mountutils/src/windows/functions.cpp dependencies/drivelist/src/windows/list.cpp windows/winfile.cpp windows/winfile.h windows/rpi-imager.rc) - set(EXTRALIBS setupapi) + find_package(Qt5WinExtras REQUIRED) + set(EXTRALIBS setupapi Qt5::WinExtras) endif() include_directories(BEFORE .) diff --git a/imagewriter.cpp b/imagewriter.cpp index a6513f962..a6b0a9717 100644 --- a/imagewriter.cpp +++ b/imagewriter.cpp @@ -34,6 +34,8 @@ #ifdef Q_OS_WIN #include #include +#include +#include #endif ImageWriter::ImageWriter(QObject *parent) @@ -52,6 +54,7 @@ ImageWriter::ImageWriter(QObject *parent) } #ifdef Q_OS_WIN + _taskbarButton = nullptr; QProcess *p = new QProcess(this); p->start("net stop ShellHWDetection"); #endif @@ -207,8 +210,6 @@ void ImageWriter::startWrite() _thread->setInputBufferSize(IMAGEWRITER_UNCOMPRESSED_BLOCKSIZE); } - _powersave.applyBlock(tr("Downloading and writing image")); - connect(_thread, SIGNAL(success()), SLOT(onSuccess())); connect(_thread, SIGNAL(error(QString)), SLOT(onError(QString))); connect(_thread, SIGNAL(finalizing()), SLOT(onFinalizing())); @@ -264,8 +265,7 @@ void ImageWriter::startWrite() _thread->start(); } - _dlnow = 0; _verifynow = 0; - _polltimer.start(PROGRESS_UPDATE_INTERVAL); + startProgressPolling(); } void ImageWriter::onCacheFileUpdated(QByteArray sha256) @@ -359,6 +359,41 @@ DriveListModel *ImageWriter::getDriveList() return &_drivelist; } +void ImageWriter::startProgressPolling() +{ + _powersave.applyBlock(tr("Downloading and writing image")); +#ifdef Q_OS_WIN + if (!_taskbarButton && _engine) + { + QWindow* window = qobject_cast( _engine->rootObjects().at(0) ); + if (window) + { + _taskbarButton = new QWinTaskbarButton(this); + _taskbarButton->setWindow(window); + _taskbarButton->progress()->setMaximum(0); + _taskbarButton->progress()->setVisible(true); + } + } +#endif + _dlnow = 0; _verifynow = 0; + _polltimer.start(PROGRESS_UPDATE_INTERVAL); +} + +void ImageWriter::stopProgressPolling() +{ + _polltimer.stop(); + pollProgress(); +#ifdef Q_OS_WIN + if (_taskbarButton) + { + _taskbarButton->progress()->setVisible(false); + _taskbarButton->deleteLater(); + _taskbarButton = nullptr; + } +#endif + _powersave.removeBlock(); +} + void ImageWriter::pollProgress() { if (!_thread) @@ -379,6 +414,13 @@ void ImageWriter::pollProgress() if (newDlNow != _dlnow) { _dlnow = newDlNow; +#ifdef Q_OS_WIN + if (_taskbarButton) + { + _taskbarButton->progress()->setMaximum(dlTotal); + _taskbarButton->progress()->setValue(newDlNow); + } +#endif emit downloadProgress(newDlNow, dlTotal); } @@ -388,6 +430,13 @@ void ImageWriter::pollProgress() { _verifynow = newVerifyNow; quint64 verifyTotal = _thread->verifyTotal(); +#ifdef Q_OS_WIN + if (_taskbarButton) + { + _taskbarButton->progress()->setMaximum(verifyTotal); + _taskbarButton->progress()->setValue(newVerifyNow); + } +#endif emit verifyProgress(newVerifyNow, verifyTotal); } } @@ -402,17 +451,13 @@ void ImageWriter::setVerifyEnabled(bool verify) /* Relay events from download thread to QML */ void ImageWriter::onSuccess() { - _polltimer.stop(); - pollProgress(); - _powersave.removeBlock(); + stopProgressPolling(); emit success(); } void ImageWriter::onError(QString msg) { - _polltimer.stop(); - pollProgress(); - _powersave.removeBlock(); + stopProgressPolling(); emit error(msg); } diff --git a/imagewriter.h b/imagewriter.h index 8108cfe97..07c7730a7 100644 --- a/imagewriter.h +++ b/imagewriter.h @@ -18,6 +18,7 @@ class QQmlApplicationEngine; class DownloadThread; class QNetworkReply; +class QWinTaskbarButton; class ImageWriter : public QObject { @@ -106,6 +107,8 @@ class ImageWriter : public QObject protected slots: + void startProgressPolling(); + void stopProgressPolling(); void pollProgress(); void pollNetwork(); void syncTime(); @@ -130,6 +133,9 @@ protected slots: DownloadThread *_thread; bool _verifyEnabled, _multipleFilesInZip, _cachingEnabled, _embeddedMode, _online; QSettings _settings; +#ifdef Q_OS_WIN + QWinTaskbarButton *_taskbarButton; +#endif void _parseCompressedFile(); }; diff --git a/windows/rpi-imager.nsi.in b/windows/rpi-imager.nsi.in index e77d6bd7d..358033635 100644 --- a/windows/rpi-imager.nsi.in +++ b/windows/rpi-imager.nsi.in @@ -242,6 +242,7 @@ File "deploy\Qt5QuickControls2.dll" File "deploy\Qt5QuickTemplates2.dll" File "deploy\Qt5Svg.dll" File "deploy\Qt5Widgets.dll" +File "deploy\Qt5WinExtras.dll" File "deploy\rpi-imager.exe" SetOutPath "$INSTDIR\styles" File "deploy\styles\qwindowsvistastyle.dll" @@ -695,6 +696,7 @@ Delete "$INSTDIR\Qt5QuickControls2.dll" Delete "$INSTDIR\Qt5QuickTemplates2.dll" Delete "$INSTDIR\Qt5Svg.dll" Delete "$INSTDIR\Qt5Widgets.dll" +Delete "$INSTDIR\Qt5WinExtras.dll" # Old name Delete "$INSTDIR\imagingutility.exe" Delete "$INSTDIR\rpi-imager.exe"