From 044c16a0a32c883bcab145c87d35d7e19089ddbb Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 5 Oct 2016 16:51:26 +0200 Subject: [PATCH] Switch to helper functions for blocking dialogs (file and message) * To continue the workaround for QTBUG-56382 we need to run our own manual message loop for dialogs as well. We only use a couple so we can just run it through a handful of thin wrappers. --- qrenderdoc/Code/CaptureContext.cpp | 102 ++++++++++++++++++++++++++--- qrenderdoc/Code/CaptureContext.h | 59 +++++++++++++++++ qrenderdoc/Windows/MainWindow.cpp | 8 +-- 3 files changed, 157 insertions(+), 12 deletions(-) diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index 369895900..e6d55f34d 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -93,15 +93,15 @@ void CaptureContext::LoadLogfile(int proxyRenderer, QString replayHost, QString errmsg = status; if(proxyRenderer >= 0) - QMessageBox::critical(NULL, "Error opening log", - QString("%1\nFailed to transfer and replay on remote host %2: %3.\n\n" - "Check diagnostic log in Help menu for more details.") - .arg(logFile, replayHost, errmsg)); + RDDialog::critical(NULL, "Error opening log", + QString("%1\nFailed to transfer and replay on remote host %2: %3.\n\n" + "Check diagnostic log in Help menu for more details.") + .arg(logFile, replayHost, errmsg)); else - QMessageBox::critical(NULL, "Error opening log", - QString("%1\nFailed to open logfile for replay: %1.\n\n" - "Check diagnostic log in Help menu for more details.") - .arg(logFile, errmsg)); + RDDialog::critical(NULL, "Error opening log", + QString("%1\nFailed to open logfile for replay: %1.\n\n" + "Check diagnostic log in Help menu for more details.") + .arg(logFile, errmsg)); m_LoadInProgress = false; @@ -268,3 +268,89 @@ void GUIInvoke::blockcall(const std::function &f) invoke->moveToThread(qApp->thread()); QMetaObject::invokeMethod(invoke, "doInvoke", Qt::BlockingQueuedConnection); } + +void RDDialog::show(QDialog *dialog) +{ + dialog->setWindowModality(Qt::ApplicationModal); + dialog->show(); + QEventLoop loop; + while(dialog->isVisible()) + { + loop.processEvents(QEventLoop::WaitForMoreEvents); + QCoreApplication::sendPostedEvents(); + } +} + +QMessageBox::StandardButton RDDialog::messageBox(QMessageBox::Icon icon, QWidget *parent, + const QString &title, const QString &text, + QMessageBox::StandardButtons buttons, + QMessageBox::StandardButton defaultButton) +{ + QMessageBox mb(icon, title, text, buttons, parent); + mb.setDefaultButton(defaultButton); + show(&mb); + return mb.standardButton(mb.clickedButton()); +} + +QString RDDialog::getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, + QFileDialog::Options options) +{ + QFileDialog fd(parent, caption, dir, QString()); + fd.setAcceptMode(QFileDialog::AcceptOpen); + fd.setFileMode(QFileDialog::DirectoryOnly); + fd.setOptions(options); + show(&fd); + + if(fd.result() == QFileDialog::Accepted) + { + QStringList files = fd.selectedFiles(); + if(!files.isEmpty()) + return files[0]; + } + + return QString(); +} + +QString RDDialog::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, + const QString &filter, QString *selectedFilter, + QFileDialog::Options options) +{ + QFileDialog fd(parent, caption, dir, filter); + fd.setAcceptMode(QFileDialog::AcceptOpen); + fd.setOptions(options); + show(&fd); + + if(fd.result() == QFileDialog::Accepted) + { + if(selectedFilter) + *selectedFilter = fd.selectedNameFilter(); + + QStringList files = fd.selectedFiles(); + if(!files.isEmpty()) + return files[0]; + } + + return QString(); +} + +QString RDDialog::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, + const QString &filter, QString *selectedFilter, + QFileDialog::Options options) +{ + QFileDialog fd(parent, caption, dir, filter); + fd.setAcceptMode(QFileDialog::AcceptSave); + fd.setOptions(options); + show(&fd); + + if(fd.result() == QFileDialog::Accepted) + { + if(selectedFilter) + *selectedFilter = fd.selectedNameFilter(); + + QStringList files = fd.selectedFiles(); + if(!files.isEmpty()) + return files[0]; + } + + return QString(); +} diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index 13c15dd48..27c8cf32a 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -24,8 +24,10 @@ #pragma once +#include #include #include +#include #include #include #include "CommonPipelineState.h" @@ -243,6 +245,63 @@ public: bool isRunning() { return m_Thread->isRunning(); } }; +// helper for doing a manual blocking invoke of a dialog +struct RDDialog +{ + static void show(QDialog *dialog); + static QMessageBox::StandardButton messageBox( + QMessageBox::Icon, QWidget *parent, const QString &title, const QString &text, + QMessageBox::StandardButtons buttons = QMessageBox::Ok, + QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); + + static QMessageBox::StandardButton information( + QWidget *parent, const QString &title, const QString &text, + QMessageBox::StandardButtons buttons = QMessageBox::Ok, + QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) + { + return messageBox(QMessageBox::Information, parent, title, text, buttons, defaultButton); + } + + static QMessageBox::StandardButton question( + QWidget *parent, const QString &title, const QString &text, + QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons(QMessageBox::Yes | + QMessageBox::No), + QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) + { + return messageBox(QMessageBox::Question, parent, title, text, buttons, defaultButton); + } + + static QMessageBox::StandardButton warning( + QWidget *parent, const QString &title, const QString &text, + QMessageBox::StandardButtons buttons = QMessageBox::Ok, + QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) + { + return messageBox(QMessageBox::Warning, parent, title, text, buttons, defaultButton); + } + + static QMessageBox::StandardButton critical( + QWidget *parent, const QString &title, const QString &text, + QMessageBox::StandardButtons buttons = QMessageBox::Ok, + QMessageBox::StandardButton defaultButton = QMessageBox::NoButton) + { + return messageBox(QMessageBox::Critical, parent, title, text, buttons, defaultButton); + } + + static QString getExistingDirectory(QWidget *parent = NULL, const QString &caption = QString(), + const QString &dir = QString(), + QFileDialog::Options options = QFileDialog::ShowDirsOnly); + + static QString getOpenFileName(QWidget *parent = NULL, const QString &caption = QString(), + const QString &dir = QString(), const QString &filter = QString(), + QString *selectedFilter = NULL, + QFileDialog::Options options = QFileDialog::Options()); + + static QString getSaveFileName(QWidget *parent = NULL, const QString &caption = QString(), + const QString &dir = QString(), const QString &filter = QString(), + QString *selectedFilter = NULL, + QFileDialog::Options options = QFileDialog::Options()); +}; + // useful delegate for enforcing a given size #include diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 45e03d827..45963c58f 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -62,9 +62,9 @@ void MainWindow::on_action_Exit_triggered() void MainWindow::on_action_Open_Log_triggered() { QString filename = - QFileDialog::getOpenFileName(this, "Select Logfile to open", "", - "Log Files (*.rdc);;Image Files (*.dds *.hdr *.exr *.bmp *.jpg " - "*.jpeg *.png *.tga *.gif *.psd;;All Files (*.*)"); + RDDialog::getOpenFileName(this, "Select Logfile to open", "", + "Log Files (*.rdc);;Image Files (*.dds *.hdr *.exr *.bmp *.jpg " + "*.jpeg *.png *.tga *.gif *.psd;;All Files (*.*)"); QFileInfo checkFile(filename); if(filename != "" && checkFile.exists() && checkFile.isFile()) @@ -78,5 +78,5 @@ void MainWindow::on_action_Open_Log_triggered() void MainWindow::on_action_About_triggered() { AboutDialog about(this); - about.exec(); + RDDialog::show(&about); }