Commit 222ed1fa authored by Ahmad Samir's avatar Ahmad Samir
Browse files

Use QDialog::show() instead of exec()

QDialog::exec() starts a nested eventloop, which could cause all sort of
issues; better use show() and make the code async.
parent b9a21ed5
......@@ -36,7 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA
#include <KLocalizedString>
// Local
#include "dialogguard.h"
#include "gwenview_app_debug.h"
#include "renamedialog.h"
#include <lib/contextmanager.h>
......@@ -52,8 +51,10 @@ static void copyMoveOrLink(Operation operation, const QList<QUrl> &urlList, QWid
Q_ASSERT(!urlList.isEmpty());
const int numberOfImages = urlList.count();
DialogGuard<QFileDialog> dialog(parent->nativeParentWidget(), QString());
auto *dialog = new QFileDialog(parent->nativeParentWidget(), QString());
dialog->setAcceptMode(QFileDialog::AcceptSave);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
// Figure out what the window title and buttons should say,
// depending on the operation and how many images are selected
......@@ -100,33 +101,33 @@ static void copyMoveOrLink(Operation operation, const QList<QUrl> &urlList, QWid
}
dialog->setDirectoryUrl(dirUrl);
if (!dialog->exec()) {
return;
}
QUrl destUrl = dialog->selectedUrls().first();
QObject::connect(dialog, &QDialog::accepted, parent, [=]() {
QUrl destUrl = dialog->selectedUrls().at(0);
KIO::CopyJob* job = nullptr;
switch (operation) {
case COPY:
job = KIO::copy(urlList, destUrl);
break;
case MOVE:
job = KIO::move(urlList, destUrl);
break;
case LINK:
job = KIO::link(urlList, destUrl);
break;
default:
Q_ASSERT(0);
}
KJobWidgets::setWindow(job, parent);
job->uiDelegate()->setAutoErrorHandlingEnabled(true);
KIO::CopyJob *job = nullptr;
switch (operation) {
case COPY:
job = KIO::copy(urlList, destUrl);
break;
case MOVE:
job = KIO::move(urlList, destUrl);
break;
case LINK:
job = KIO::link(urlList, destUrl);
break;
default:
Q_ASSERT(0);
}
KJobWidgets::setWindow(job, parent);
job->uiDelegate()->setAutoErrorHandlingEnabled(true);
if (numberOfImages == 1) {
destUrl = destUrl.adjusted(QUrl::RemoveFilename|QUrl::StripTrailingSlash);
}
contextManager->setTargetDirUrl(destUrl);
});
if (numberOfImages == 1) {
destUrl = destUrl.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash);
}
contextManager->setTargetDirUrl(destUrl);
dialog->show();
}
static void delOrTrash(KIO::JobUiDelegate::DeletionType deletionType, const QList<QUrl> &urlList, QWidget *parent)
......@@ -219,28 +220,32 @@ void showMenuForDroppedUrls(QWidget *parent, const QList<QUrl> &urlList, const Q
void rename(const QUrl &oldUrl, QWidget *parent, ContextManager *contextManager)
{
const DialogGuard<RenameDialog> dialog(parent);
auto *dialog = new RenameDialog(parent);
dialog->setFilename(oldUrl.fileName());
if (!dialog->exec()) {
return;
}
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
const QString name = dialog->filename();
if (name.isEmpty() || name == oldUrl.fileName()) {
return;
}
QObject::connect(dialog, &QDialog::accepted, parent, [=]() {
const QString name = dialog->filename();
if (name.isEmpty() || name == oldUrl.fileName()) {
return;
}
QUrl newUrl = oldUrl;
newUrl = newUrl.adjusted(QUrl::RemoveFilename);
newUrl.setPath(newUrl.path() + name);
KIO::SimpleJob *job = KIO::rename(oldUrl, newUrl, KIO::HideProgressInfo);
KJobWidgets::setWindow(job, parent);
job->uiDelegate()->setAutoErrorHandlingEnabled(true);
if (!job->exec()) {
return;
}
contextManager->setCurrentUrl(newUrl);
ThumbnailProvider::moveThumbnail(oldUrl, newUrl);
QUrl newUrl = oldUrl;
newUrl = newUrl.adjusted(QUrl::RemoveFilename);
newUrl.setPath(newUrl.path() + name);
KIO::SimpleJob* job = KIO::rename(oldUrl, newUrl, KIO::HideProgressInfo);
KJobWidgets::setWindow(job, parent);
job->uiDelegate()->setAutoErrorHandlingEnabled(true);
QObject::connect(job, &KJob::result, parent, [contextManager, job, oldUrl, newUrl]() {
if (!job->error()) {
contextManager->setCurrentUrl(newUrl);
ThumbnailProvider::moveThumbnail(oldUrl, newUrl);
}
});
});
dialog->show();
}
} // namespace
......
......@@ -56,7 +56,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#endif
// Local
#include "dialogguard.h"
#include "fileoperations.h"
#include "sidebar.h"
#include <lib/contextmanager.h>
......@@ -400,26 +399,28 @@ void FileOpsContextManagerItem::openWith(QAction *action)
job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, mGroup));
job->start();
#else
if (idx == -1) {
// Other Application...
DialogGuard<KOpenWithDialog> dlg(list, mGroup);
if (!dlg->exec()) {
return;
}
service = dlg->service();
if (idx != -1) {
service = mServiceList.at(idx);
Q_ASSERT(service);
KRun::runService(*service, list, mGroup);
return;
}
if (!service) {
// Other Application...
auto *dlg = new KOpenWithDialog(list, mGroup);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setModal(true);
connect(dlg, &QDialog::accepted, this, [this, dlg, list]() {
KService::Ptr servicePtr = dlg->service();
if (servicePtr) {
KRun::runService(*servicePtr, list, mGroup);
} else {
// User entered a custom command
Q_ASSERT(!dlg->text().isEmpty());
KRun::run(dlg->text(), list, mGroup);
return;
}
} else {
service = mServiceList.at(idx);
}
});
Q_ASSERT(service);
KRun::runService(*service, list, mGroup);
dlg->show();
#endif
}
......
......@@ -40,7 +40,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA
#include <KMessageBox>
// Local
#include "dialogguard.h"
#include "gwenview_app_debug.h"
#include <lib/backgroundcolorwidget/backgroundcolorwidget.h>
#include <lib/binder.h>
......@@ -72,7 +71,7 @@ struct GvCorePrivate {
QString mFullScreenPaletteName;
int configFileJPEGQualityValue = GwenviewConfig::jPEGQuality();
bool showSaveAsDialog(const QUrl &url, QUrl *outUrl, QByteArray *format)
KFileCustomDialog *createSaveAsDialog(const QUrl &url)
{
// Build the JPEG quality chooser custom widget
auto *JPEGQualityChooserWidget = new QWidget;
......@@ -104,7 +103,9 @@ struct GvCorePrivate {
JPEGQualityChooserLayout->addItem(horizontalSpacer);
// Set up the dialog
DialogGuard<KFileCustomDialog> dialog(mMainWindow);
auto *dialog = new KFileCustomDialog(mMainWindow);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
KFileWidget *fileWidget = dialog->fileWidget();
dialog->setCustomWidget(JPEGQualityChooserWidget);
fileWidget->setConfirmOverwrite(true);
......@@ -129,29 +130,7 @@ struct GvCorePrivate {
|| filter.contains(QLatin1String("heif")) || filter.contains(QLatin1String("heic")));
});
// Show dialog
do {
if (!dialog->exec()) {
return false;
}
QList<QUrl> files = fileWidget->selectedUrls();
if (files.isEmpty()) {
return false;
}
QString filename = files.first().fileName();
const QMimeType mimeType = QMimeDatabase().mimeTypeForFile(filename, QMimeDatabase::MatchExtension);
if (mimeType.isValid()) {
*format = mimeType.preferredSuffix().toLocal8Bit();
break;
}
KMessageBox::sorry(mMainWindow, i18nc("@info", "Gwenview cannot save images as %1.", QFileInfo(filename).suffix()));
} while (true);
*outUrl = fileWidget->selectedUrls().first();
return true;
return dialog;
}
void setupPalettes()
......@@ -441,35 +420,57 @@ void GvCore::save(const QUrl &url)
void GvCore::saveAs(const QUrl &url)
{
QByteArray format;
QUrl saveAsUrl;
if (!d->showSaveAsDialog(url, &saveAsUrl, &format)) {
return;
}
KFileCustomDialog *dialog = d->createSaveAsDialog(url);
if (format == "jpg") {
// Gwenview code assumes JPEG images have "jpeg" format, so if the
// dialog returned the format "jpg", use "jpeg" instead
// This does not affect the actual filename extension
format = "jpeg";
}
connect(dialog, &QDialog::accepted, this, [=]() {
KFileWidget *fileWidget = dialog->fileWidget();
// Start save
Document::Ptr doc = DocumentFactory::instance()->load(url);
KJob *job = doc->save(saveAsUrl, format);
if (!job) {
const QString name = saveAsUrl.fileName().isEmpty() ? saveAsUrl.toDisplayString() : saveAsUrl.fileName();
const QString msg = xi18nc("@info", "<emphasis strong='true'>Saving <filename>%1</filename> failed:</emphasis><nl />%2", name, doc->errorString());
KMessageBox::sorry(QApplication::activeWindow(), msg);
} else {
// Regardless of job result, reset JPEG config value if it was changed by
// the Save As dialog
connect(job, &KJob::result, [=]() {
if (GwenviewConfig::jPEGQuality() != d->configFileJPEGQualityValue)
GwenviewConfig::setJPEGQuality(d->configFileJPEGQualityValue);
});
connect(job, SIGNAL(result(KJob *)), SLOT(slotSaveResult(KJob *)));
}
const QList<QUrl> files = fileWidget->selectedUrls();
if (files.isEmpty()) {
return;
}
const QString filename = files.at(0).fileName();
const QMimeType mimeType = QMimeDatabase().mimeTypeForFile(filename, QMimeDatabase::MatchExtension);
QByteArray format;
if (mimeType.isValid()) {
format = mimeType.preferredSuffix().toLocal8Bit();
} else {
KMessageBox::sorry(d->mMainWindow, i18nc("@info", "Gwenview cannot save images as %1.", QFileInfo(filename).suffix()));
}
QUrl saveAsUrl = fileWidget->selectedUrls().constFirst();
if (format == "jpg") {
// Gwenview code assumes JPEG images have "jpeg" format, so if the
// dialog returned the format "jpg", use "jpeg" instead
// This does not affect the actual filename extension
format = "jpeg";
}
// Start save
Document::Ptr doc = DocumentFactory::instance()->load(url);
KJob *job = doc->save(saveAsUrl, format);
if (!job) {
const QString saveName = saveAsUrl.fileName();
const QString name = !saveName.isEmpty() ? saveName : saveAsUrl.toDisplayString();
const QString msg = xi18nc("@info", "<emphasis strong='true'>Saving <filename>%1</filename> failed:</emphasis><nl />%2", name, doc->errorString());
KMessageBox::sorry(QApplication::activeWindow(), msg);
} else {
// Regardless of job result, reset JPEG config value if it was changed by
// the Save As dialog
connect(job, &KJob::result, this, [=]() {
if (GwenviewConfig::jPEGQuality() != d->configFileJPEGQualityValue) {
GwenviewConfig::setJPEGQuality(d->configFileJPEGQualityValue);
}
});
connect(job, &KJob::result, this, &GvCore::slotSaveResult);
}
});
dialog->show();
}
static void applyTransform(const QUrl &url, Orientation orientation)
......
......@@ -33,7 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <KMessageBox>
// Local
#include "dialogguard.h"
#include "gwenview_app_debug.h"
#include "viewmainpage.h"
#include "gvcore.h"
#include "gwenview_app_debug.h"
#include "mainwindow.h"
......@@ -225,13 +226,16 @@ void ImageOpsContextManagerItem::resizeImage()
}
Document::Ptr doc = DocumentFactory::instance()->load(contextManager()->currentUrl());
doc->startLoadingFullImage();
DialogGuard<ResizeImageDialog> dialog(d->mMainWindow);
auto *dialog = new ResizeImageDialog(d->mMainWindow);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
dialog->setOriginalSize(doc->size());
if (!dialog->exec()) {
return;
}
auto *op = new ResizeImageOperation(dialog->size());
applyImageOperation(op);
connect(dialog, &QDialog::accepted, this, [this, dialog]() {
applyImageOperation(new ResizeImageOperation(dialog->size()));
});
dialog->show();
}
void ImageOpsContextManagerItem::crop()
......
......@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <QApplication>
#include <QClipboard>
#include <QDateTime>
#include <QDialog>
#include <QFileDialog>
#include <QLineEdit>
#include <QMenuBar>
......@@ -74,6 +75,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#endif
// Local
#include "gwenview_app_debug.h"
#include "alignwithsidebarwidgetaction.h"
#include "configdialog.h"
#include "dialogguard.h"
......@@ -1583,21 +1585,22 @@ void MainWindow::reload()
void MainWindow::openFile()
{
QUrl dirUrl = d->mContextManager->currentDirUrl();
const QUrl dirUrl = d->mContextManager->currentDirUrl();
DialogGuard<QFileDialog> dialog(this);
auto *dialog = new QFileDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
dialog->setDirectoryUrl(dirUrl);
dialog->setWindowTitle(i18nc("@title:window", "Open Image"));
const QStringList mimeFilter = MimeTypeUtils::imageMimeTypes();
dialog->setMimeTypeFilters(mimeFilter);
dialog->setMimeTypeFilters(MimeTypeUtils::imageMimeTypes());
dialog->setAcceptMode(QFileDialog::AcceptOpen);
if (!dialog->exec()) {
return;
}
connect(dialog, &QDialog::accepted, this, [this, dialog]() {
if (!dialog->selectedUrls().isEmpty()) {
openUrl(dialog->selectedUrls().at(0));
}
});
if (!dialog->selectedUrls().isEmpty()) {
openUrl(dialog->selectedUrls().first());
}
dialog->show();
}
void MainWindow::openUrl(const QUrl &url)
......@@ -1691,9 +1694,11 @@ void MainWindow::showConfigDialog()
// Save first so changes like thumbnail zoom level are not lost when reloading config
saveConfig();
DialogGuard<ConfigDialog> dialog(this);
connect(dialog.data(), &KConfigDialog::settingsChanged, this, &MainWindow::loadConfig);
dialog->exec();
auto *dialog = new ConfigDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
connect(dialog, &KConfigDialog::settingsChanged, this, &MainWindow::loadConfig);
dialog->show();
}
void MainWindow::configureShortcuts()
......
......@@ -37,7 +37,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA
#include <kio/global.h>
// Local
#include "dialogguard.h"
#include "gwenview_importer_debug.h"
#include <documentdirfinder.h>
#include <importerconfigdialog.h>
......@@ -330,8 +329,10 @@ void ThumbnailPage::updateImportButtons()
void ThumbnailPage::showConfigDialog()
{
DialogGuard<ImporterConfigDialog> dialog(this);
dialog->exec();
auto *dialog = new ImporterConfigDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
dialog->show();
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment