From 1b4c241b5bc1291943b12445f4189afdd436d2ee Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 6 Apr 2020 18:13:07 +1000 Subject: [PATCH] windows: implemented export progress on taskbar button --- app/dialog/export/export.cpp | 22 ++++-------- app/dialog/export/export.h | 8 ----- app/window/mainwindow/mainwindow.cpp | 54 ++++++++++++++++++++++++++++ app/window/mainwindow/mainwindow.h | 22 ++++++++++++ 4 files changed, 82 insertions(+), 24 deletions(-) diff --git a/app/dialog/export/export.cpp b/app/dialog/export/export.cpp index c1514fafa..c05ea18b4 100644 --- a/app/dialog/export/export.cpp +++ b/app/dialog/export/export.cpp @@ -30,10 +30,12 @@ #include #include +#include "core.h" #include "project/item/sequence/sequence.h" #include "project/project.h" #include "render/pixelformat.h" #include "ui/icons/icons.h" +#include "window/mainwindow/mainwindow.h" OLIVE_NAMESPACE_ENTER @@ -42,9 +44,6 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) : viewer_node_(viewer_node), previously_selected_format_(0), exporter_(nullptr), -#ifdef Q_OS_WINDOWS - taskbar_list_(nullptr), -#endif cancelled_(false) { QHBoxLayout* layout = new QHBoxLayout(this); @@ -335,8 +334,7 @@ void ExportDialog::accept() connect(exporter_, &Exporter::ProgressChanged, progress_bar_, &QProgressBar::setValue); #ifdef Q_OS_WINDOWS - CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, IID_ITaskbarList, reinterpret_cast(&taskbar_list_)); - taskbar_list_->SetProgressState(reinterpret_cast(this->winId()), TBPF_NORMAL); + Core::instance()->main_window()->SetTaskbarButtonState(TBPF_NORMAL); connect(exporter_, &Exporter::ProgressChanged, this, &ExportDialog::UpdateTaskbarProgress); #endif @@ -592,9 +590,7 @@ void ExportDialog::ExporterIsDone() } else { if (!cancelled_) { #ifdef Q_OS_WINDOWS - if (taskbar_list_) { - taskbar_list_->SetProgressState(reinterpret_cast(this->winId()), TBPF_ERROR); - } + Core::instance()->main_window()->SetTaskbarButtonState(TBPF_ERROR); #endif QMessageBox::critical(this, @@ -611,11 +607,7 @@ void ExportDialog::ExporterIsDone() cancelled_ = false; #ifdef Q_OS_WINDOWS - if (taskbar_list_) { - taskbar_list_->SetProgressState(reinterpret_cast(this->winId()), TBPF_NOPROGRESS); - taskbar_list_->Release(); - taskbar_list_ = nullptr; - } + Core::instance()->main_window()->SetTaskbarButtonState(TBPF_NOPROGRESS); #endif } @@ -630,9 +622,7 @@ void ExportDialog::CancelExport() #ifdef Q_OS_WINDOWS void ExportDialog::UpdateTaskbarProgress(int progress) { - if (taskbar_list_) { - taskbar_list_->SetProgressValue(reinterpret_cast(this->winId()), progress, 100); - } + Core::instance()->main_window()->SetTaskbarButtonProgress(progress, 100); } #endif diff --git a/app/dialog/export/export.h b/app/dialog/export/export.h index 61fb49679..ec239997d 100644 --- a/app/dialog/export/export.h +++ b/app/dialog/export/export.h @@ -27,10 +27,6 @@ #include #include -#ifdef Q_OS_WINDOWS -#include -#endif - #include "exportaudiotab.h" #include "exportcodec.h" #include "exportformat.h" @@ -90,10 +86,6 @@ private: QDialogButtonBox* buttons_; QPushButton* export_cancel_btn_; -#ifdef Q_OS_WINDOWS - ITaskbarList3* taskbar_list_; -#endif - bool cancelled_; enum Format { diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index c37da80dd..4d118687b 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -37,6 +37,10 @@ MainWindow::MainWindow(QWidget *parent) : // Qt on Windows has a bug that "de-maximizes" the window when widgets are added, resizing the window beforehand // works around that issue and we just set it to whatever size is available resize(qApp->desktop()->availableGeometry(this).size()); + + // Set up taskbar button progress bar (used for some modal tasks like exporting) + taskbar_btn_id_ = RegisterWindowMessage("TaskbarButtonCreated"); + taskbar_interface_ = nullptr; #endif // Create empty central widget - we don't actually want a central widget but some of Qt's docking/undocking fails @@ -108,6 +112,15 @@ MainWindow::MainWindow(QWidget *parent) : UpdateTitle(); } +MainWindow::~MainWindow() +{ +#ifdef Q_OS_WINDOWS + if (taskbar_interface_) { + taskbar_interface_->Release(); + } +#endif +} + void MainWindow::OpenSequence(Sequence *sequence) { // See if this sequence is already open, and switch to it if so @@ -151,6 +164,22 @@ void MainWindow::CloseSequence(Sequence *sequence) } } +#ifdef Q_OS_WINDOWS +void MainWindow::SetTaskbarButtonState(TBPFLAG flags) +{ + if (taskbar_interface_) { + taskbar_interface_->SetProgressState(reinterpret_cast(this->winId()), flags); + } +} + +void MainWindow::SetTaskbarButtonProgress(int value, int max) +{ + if (taskbar_interface_) { + taskbar_interface_->SetProgressValue(reinterpret_cast(this->winId()), value, max); + } +} +#endif + void MainWindow::SetFullscreen(bool fullscreen) { if (fullscreen) { @@ -239,6 +268,31 @@ void MainWindow::closeEvent(QCloseEvent *e) QMainWindow::closeEvent(e); } +#ifdef Q_OS_WINDOWS +bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) +{ + if (static_cast(message)->message == taskbar_btn_id_) { + // Attempt to create taskbar button progress handle + HRESULT hr = CoCreateInstance(CLSID_TaskbarList, + NULL, + CLSCTX_INPROC_SERVER, + IID_ITaskbarList3, + reinterpret_cast(&taskbar_interface_)); + + if (SUCCEEDED(hr)) { + hr = taskbar_interface_->HrInit(); + + if (FAILED(hr)) { + taskbar_interface_->Release(); + taskbar_interface_ = nullptr; + } + } + } + + return QMainWindow::nativeEvent(eventType, message, result); +} +#endif + void MainWindow::UpdateTitle() { if (project_panel_->project()) { diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index d9365978f..c3b2e69c9 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -37,6 +37,10 @@ #include "panel/pixelsampler/pixelsamplerpanel.h" #include "project/project.h" +#ifdef Q_OS_WINDOWS +#include +#endif + OLIVE_NAMESPACE_ENTER /** @@ -47,10 +51,18 @@ class MainWindow : public QMainWindow { public: MainWindow(QWidget *parent = nullptr); + virtual ~MainWindow() override; + void OpenSequence(Sequence* sequence); void CloseSequence(Sequence* sequence); +#ifdef Q_OS_WINDOWS + void SetTaskbarButtonState(TBPFLAG flags); + + void SetTaskbarButtonProgress(int value, int max); +#endif + public slots: void ProjectOpen(Project *p); void SetFullscreen(bool fullscreen); @@ -61,6 +73,10 @@ public slots: protected: virtual void closeEvent(QCloseEvent* e) override; +#ifdef Q_OS_WINDOWS + virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result) override; +#endif + private: TimelinePanel* AppendTimelinePanel(); @@ -81,6 +97,12 @@ private: CurvePanel* curve_panel_; PixelSamplerPanel* pixel_sampler_panel_; +#ifdef Q_OS_WINDOWS + unsigned int taskbar_btn_id_; + + ITaskbarList3* taskbar_interface_; +#endif + private slots: void FocusedPanelChanged(PanelWidget* panel);