From d185d07affa55687956d12fe74403812bb75ca3e Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Thu, 31 Oct 2024 22:13:56 +0100 Subject: [PATCH] Fix crash when using search/replace with multiple windows Have the dialog_manager manage the search/replace dialog like the other dialogs. --- src/command/edit.cpp | 2 +- src/command/subtitle.cpp | 4 +-- src/dialog_search_replace.cpp | 47 +++++++++++++++++++---------------- src/dialog_search_replace.h | 9 +++---- src/dialogs.h | 1 + 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/command/edit.cpp b/src/command/edit.cpp index 1d2881ccc4..c1778bd8fd 100644 --- a/src/command/edit.cpp +++ b/src/command/edit.cpp @@ -546,7 +546,7 @@ struct edit_find_replace final : public Command { void operator()(agi::Context *c) override { c->videoController->Stop(); - DialogSearchReplace::Show(c, true); + ShowSearchReplaceDialog(c, true); } }; diff --git a/src/command/subtitle.cpp b/src/command/subtitle.cpp index 98c278d85f..0b7cb6e6c5 100644 --- a/src/command/subtitle.cpp +++ b/src/command/subtitle.cpp @@ -95,7 +95,7 @@ struct subtitle_find final : public Command { void operator()(agi::Context *c) override { c->videoController->Stop(); - DialogSearchReplace::Show(c, false); + ShowSearchReplaceDialog(c, false); } }; @@ -109,7 +109,7 @@ struct subtitle_find_next final : public Command { void operator()(agi::Context *c) override { c->videoController->Stop(); if (!c->search->FindNext()) - DialogSearchReplace::Show(c, false); + ShowSearchReplaceDialog(c, false); } }; diff --git a/src/dialog_search_replace.cpp b/src/dialog_search_replace.cpp index ce3ea27490..3436971f1a 100644 --- a/src/dialog_search_replace.cpp +++ b/src/dialog_search_replace.cpp @@ -22,6 +22,7 @@ #include "dialog_search_replace.h" #include "compat.h" +#include "dialog_manager.h" #include "include/aegisub/context.h" #include "options.h" #include "search_replace_engine.h" @@ -41,11 +42,11 @@ #include #include -DialogSearchReplace::DialogSearchReplace(agi::Context* c, bool replace) -: wxDialog(c->parent, -1, replace ? _("Replace") : _("Find")) +template +DialogSearchReplace::DialogSearchReplace(agi::Context* c) +: wxDialog(c->parent, -1, has_replace ? _("Replace") : _("Find")) , c(c) , settings(std::make_unique()) -, has_replace(replace) { auto recent_find(lagi_MRU_wxAS("Find")); auto recent_replace(lagi_MRU_wxAS("Replace")); @@ -127,10 +128,8 @@ DialogSearchReplace::DialogSearchReplace(agi::Context* c, bool replace) replace_all->Bind(wxEVT_BUTTON, std::bind(&DialogSearchReplace::FindReplace, this, &SearchReplaceEngine::ReplaceAll)); } -DialogSearchReplace::~DialogSearchReplace() { -} - -void DialogSearchReplace::FindReplace(bool (SearchReplaceEngine::*func)()) { +template +void DialogSearchReplace::FindReplace(bool (SearchReplaceEngine::*func)()) { TransferDataFromWindow(); if (settings->find.empty()) @@ -168,27 +167,33 @@ static void update_mru(wxComboBox *cb, const char *mru_name) { cb->Thaw(); } -void DialogSearchReplace::UpdateDropDowns() { +template +void DialogSearchReplace::UpdateDropDowns() { update_mru(find_edit, "Find"); if (has_replace) update_mru(replace_edit, "Replace"); } -void DialogSearchReplace::Show(agi::Context *context, bool replace) { - static DialogSearchReplace *diag = nullptr; - - if (diag && replace != diag->has_replace) { - // Already opened, but wrong type - destroy and create the right one - diag->Destroy(); - diag = nullptr; +template +void ShowSearchReplaceDialog(agi::Context *context) { + auto other = context->dialog->Get>(); + if (other != nullptr) { + other->Close(); } - if (!diag) - diag = new DialogSearchReplace(context, replace); + context->dialog->Show>(context); + auto dialog = context->dialog->Get>(); - diag->find_edit->SetFocus(); - diag->find_edit->SelectAll(); - diag->wxDialog::Show(); - diag->Raise(); + dialog->find_edit->SetFocus(); + dialog->find_edit->SelectAll(); + dialog->Raise(); +} + +void ShowSearchReplaceDialog(agi::Context *context, bool replace) { + if (replace) { + ShowSearchReplaceDialog(context); + } else { + ShowSearchReplaceDialog(context); + } } diff --git a/src/dialog_search_replace.h b/src/dialog_search_replace.h index 2d231e7ec5..1d87eac525 100644 --- a/src/dialog_search_replace.h +++ b/src/dialog_search_replace.h @@ -28,19 +28,16 @@ class SearchReplaceEngine; struct SearchReplaceSettings; class wxComboBox; +template class DialogSearchReplace final : public wxDialog { agi::Context *c; std::unique_ptr settings; - bool has_replace; - wxComboBox *find_edit; wxComboBox *replace_edit; void UpdateDropDowns(); void FindReplace(bool (SearchReplaceEngine::*func)()); public: - static void Show(agi::Context *context, bool with_replace); - - DialogSearchReplace(agi::Context* c, bool with_replace); - ~DialogSearchReplace(); + wxComboBox *find_edit; + DialogSearchReplace(agi::Context* c); }; diff --git a/src/dialogs.h b/src/dialogs.h index 2e03d09e9e..e3ba485098 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -68,6 +68,7 @@ void ShowKanjiTimerDialog(agi::Context *c); void ShowLogWindow(agi::Context *c); void ShowPreferences(wxWindow *parent); void ShowPropertiesDialog(agi::Context *c); +void ShowSearchReplaceDialog(agi::Context *c, bool replace); void ShowSelectLinesDialog(agi::Context *c); void ShowShiftTimesDialog(agi::Context *c); void ShowSpellcheckerDialog(agi::Context *c);