From 0903ec652a3f48bb05603b021341582c27a5fcb1 Mon Sep 17 00:00:00 2001 From: cg2121 Date: Sat, 15 Apr 2023 21:43:37 -0500 Subject: [PATCH] UI: Delete selection dialogs when parent is deleted In the source context bar, when an user opens a selection dialog (font, color or file), and they switch scenes (causing the source toolbar to be deleted), OBS would crash, as the dialog is no longer valid. This is fixed by deleting the dialog when the toolbar is deleted. --- UI/context-bar-controls.cpp | 163 +++++++++++++++++++++++------------- UI/context-bar-controls.hpp | 7 ++ 2 files changed, 111 insertions(+), 59 deletions(-) diff --git a/UI/context-bar-controls.cpp b/UI/context-bar-controls.cpp index 55fe2049550cbf..b8f7eb8c0dea7c 100644 --- a/UI/context-bar-controls.cpp +++ b/UI/context-bar-controls.cpp @@ -4,8 +4,6 @@ #include "obs-app.hpp" #include -#include -#include #include "ui_browser-source-toolbar.h" #include "ui_device-select-toolbar.h" @@ -498,18 +496,28 @@ void ImageSourceToolbar::on_browse_clicked() const char *filter = obs_property_path_filter(p); const char *default_path = obs_property_path_default_path(p); - QString path = OpenFile(this, desc, default_path, filter); - if (path.isEmpty()) { - return; - } + fileDialog.reset(new QFileDialog(this, desc, default_path, filter)); - ui->path->setText(path); + auto finished = [this, source]() { + QStringList paths = fileDialog->selectedFiles(); + fileDialog.reset(); - SaveOldProperties(source); - OBSDataAutoRelease settings = obs_data_create(); - obs_data_set_string(settings, "file", QT_TO_UTF8(path)); - obs_source_update(source, settings); - SetUndoProperties(source); + if (!paths.count()) { + return; + } + + ui->path->setText(paths[0]); + + SaveOldProperties(source); + OBSDataAutoRelease settings = obs_data_create(); + obs_data_set_string(settings, "file", QT_TO_UTF8(paths[0])); + obs_source_update(source, settings); + SetUndoProperties(source); + }; + + connect(fileDialog.data(), &QDialog::finished, this, finished); + + fileDialog->open(); } /* ========================================================================= */ @@ -578,21 +586,32 @@ void ColorSourceToolbar::on_choose_clicked() options |= QColorDialog::DontUseNativeDialog; #endif - QColor newColor = QColorDialog::getColor(color, this, desc, options); - if (!newColor.isValid()) { - return; - } + colorDialog.reset(new QColorDialog(color, this)); + colorDialog->setOptions(options); + colorDialog->setWindowTitle(QT_UTF8(desc)); - color = newColor; - UpdateColor(); + auto finished = [this, source]() { + QColor newColor = colorDialog->selectedColor(); + colorDialog.reset(); - SaveOldProperties(source); + if (!newColor.isValid()) + return; - OBSDataAutoRelease settings = obs_data_create(); - obs_data_set_int(settings, "color", color_to_int(color)); - obs_source_update(source, settings); + color = newColor; + UpdateColor(); - SetUndoProperties(source); + SaveOldProperties(source); + + OBSDataAutoRelease settings = obs_data_create(); + obs_data_set_int(settings, "color", color_to_int(color)); + obs_source_update(source, settings); + + SetUndoProperties(source); + }; + + connect(colorDialog.data(), &QDialog::finished, this, finished); + + colorDialog->open(); } /* ========================================================================= */ @@ -643,39 +662,51 @@ void TextSourceToolbar::on_selectFont_clicked() } QFontDialog::FontDialogOptions options; - uint32_t flags; - bool success; #ifndef _WIN32 options = QFontDialog::DontUseNativeDialog; #endif - font = QFontDialog::getFont(&success, font, this, "Pick a Font", - options); - if (!success) { - return; - } + fontDialog.reset(new QFontDialog(font, this)); + fontDialog->setOptions(options); + fontDialog->setWindowTitle("Pick a Font"); - OBSDataAutoRelease font_obj = obs_data_create(); + auto accepted = [this, source]() { + font = fontDialog->selectedFont(); + fontDialog.reset(); - obs_data_set_string(font_obj, "face", QT_TO_UTF8(font.family())); - obs_data_set_string(font_obj, "style", QT_TO_UTF8(font.styleName())); - obs_data_set_int(font_obj, "size", font.pointSize()); - flags = font.bold() ? OBS_FONT_BOLD : 0; - flags |= font.italic() ? OBS_FONT_ITALIC : 0; - flags |= font.underline() ? OBS_FONT_UNDERLINE : 0; - flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0; - obs_data_set_int(font_obj, "flags", flags); + uint32_t flags; - SaveOldProperties(source); + OBSDataAutoRelease font_obj = obs_data_create(); - OBSDataAutoRelease settings = obs_data_create(); + obs_data_set_string(font_obj, "face", + QT_TO_UTF8(font.family())); + obs_data_set_string(font_obj, "style", + QT_TO_UTF8(font.styleName())); + obs_data_set_int(font_obj, "size", font.pointSize()); + flags = font.bold() ? OBS_FONT_BOLD : 0; + flags |= font.italic() ? OBS_FONT_ITALIC : 0; + flags |= font.underline() ? OBS_FONT_UNDERLINE : 0; + flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0; + obs_data_set_int(font_obj, "flags", flags); - obs_data_set_obj(settings, "font", font_obj); + SaveOldProperties(source); - obs_source_update(source, settings); + OBSDataAutoRelease settings = obs_data_create(); - SetUndoProperties(source); + obs_data_set_obj(settings, "font", font_obj); + + obs_source_update(source, settings); + + SetUndoProperties(source); + }; + + auto rejected = [this]() { fontDialog.reset(); }; + + connect(fontDialog.data(), &QDialog::accepted, this, accepted); + connect(fontDialog.data(), &QDialog::rejected, this, rejected); + + fontDialog->open(); } void TextSourceToolbar::on_selectColor_clicked() @@ -701,25 +732,39 @@ void TextSourceToolbar::on_selectColor_clicked() options |= QColorDialog::DontUseNativeDialog; #endif - QColor newColor = QColorDialog::getColor(color, this, desc, options); - if (!newColor.isValid()) { - return; - } + colorDialog.reset(new QColorDialog(color, this)); + colorDialog->setOptions(options); + colorDialog->setWindowTitle(QT_UTF8(desc)); - color = newColor; + auto finished = [this, source, freetype]() { + QColor newColor = colorDialog->selectedColor(); + colorDialog.reset(); - SaveOldProperties(source); + if (!newColor.isValid()) + return; - OBSDataAutoRelease settings = obs_data_create(); - if (freetype) { - obs_data_set_int(settings, "color1", color_to_int(color)); - obs_data_set_int(settings, "color2", color_to_int(color)); - } else { - obs_data_set_int(settings, "color", color_to_int(color)); - } - obs_source_update(source, settings); + color = newColor; - SetUndoProperties(source); + SaveOldProperties(source); + + OBSDataAutoRelease settings = obs_data_create(); + if (freetype) { + obs_data_set_int(settings, "color1", + color_to_int(color)); + obs_data_set_int(settings, "color2", + color_to_int(color)); + } else { + obs_data_set_int(settings, "color", + color_to_int(color)); + } + obs_source_update(source, settings); + + SetUndoProperties(source); + }; + + connect(colorDialog.data(), &QDialog::finished, this, finished); + + colorDialog->open(); } void TextSourceToolbar::on_text_textChanged() diff --git a/UI/context-bar-controls.hpp b/UI/context-bar-controls.hpp index 48c743afb93746..5ddcd29550491a 100644 --- a/UI/context-bar-controls.hpp +++ b/UI/context-bar-controls.hpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include class Ui_BrowserSourceToolbar; class Ui_DeviceSelectToolbar; @@ -136,6 +139,7 @@ class ImageSourceToolbar : public SourceToolbar { Q_OBJECT std::unique_ptr ui; + QScopedPointer fileDialog; public: ImageSourceToolbar(QWidget *parent, OBSSource source); @@ -149,6 +153,7 @@ class ColorSourceToolbar : public SourceToolbar { Q_OBJECT std::unique_ptr ui; + QScopedPointer colorDialog; QColor color; void UpdateColor(); @@ -165,6 +170,8 @@ class TextSourceToolbar : public SourceToolbar { Q_OBJECT std::unique_ptr ui; + QScopedPointer fontDialog; + QScopedPointer colorDialog; QFont font; QColor color;