diff --git a/aegisub/src/dialog_style_editor.cpp b/aegisub/src/dialog_style_editor.cpp index 75276d051..ba61719e1 100644 --- a/aegisub/src/dialog_style_editor.cpp +++ b/aegisub/src/dialog_style_editor.cpp @@ -65,6 +65,73 @@ #include "utils.h" #include "validators.h" +/// Style rename helper that walks a file searching for a style and optionally +/// updating references to it +class StyleRenamer { + agi::Context *c; + bool found_any; + bool do_replace; + wxString source_name; + wxString new_name; + + /// Process a single override parameter to check if it's \r with this style name + static void ProcessTag(wxString tag, int, AssOverrideParameter* param, void *userData) { + StyleRenamer *self = static_cast(userData); + if (tag == "\\r" && param->GetType() == VARDATA_TEXT && param->Get() == self->source_name) { + if (self->do_replace) + param->Set(self->new_name); + else + self->found_any = true; + } + } + + void Walk(bool replace) { + found_any = false; + do_replace = replace; + + for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ++it) { + AssDialogue *diag = dynamic_cast(*it); + if (!diag) continue; + + if (diag->Style == source_name) { + if (replace) + diag->Style = new_name; + else + found_any = true; + } + + diag->ParseASSTags(); + diag->ProcessParameters(&StyleRenamer::ProcessTag, this); + if (replace) + diag->UpdateText(); + diag->ClearBlocks(); + + if (found_any) return; + } + } + +public: + StyleRenamer(agi::Context *c, wxString const& source_name, wxString const& new_name) + : c(c) + , found_any(false) + , do_replace(false) + , source_name(source_name) + , new_name(new_name) + { + } + + /// Check if there are any uses of the original style name in the file + bool NeedsReplace() { + Walk(false); + return found_any; + } + + /// Replace all uses of the original style name with the new one + void Replace() { + Walk(true); + } +}; + static void add_with_label(wxSizer *sizer, wxWindow *parent, wxString const& label, wxWindow *ctrl) { sizer->Add(new wxStaticText(parent, -1, label), wxSizerFlags().Center().Right().Border(wxLEFT | wxRIGHT)); sizer->Add(ctrl, wxSizerFlags(1).Left().Expand()); @@ -350,14 +417,6 @@ wxString DialogStyleEditor::GetStyleName() const { return style->name; } -/// @brief Update appearances of a renamed style in \r tags -static void ReplaceStyle(wxString tag, int, AssOverrideParameter* param, void *userData) { - wxArrayString strings = *((wxArrayString*)userData); - if (tag == "\\r" && param->GetType() == VARDATA_TEXT && param->Get() == strings[0]) { - param->Set(strings[1]); - } -} - void DialogStyleEditor::Apply(bool apply, bool close) { if (apply) { wxString newStyleName = StyleName->GetValue(); @@ -379,24 +438,19 @@ void DialogStyleEditor::Apply(bool apply, bool close) { bool did_rename = false; if (work->name != newStyleName) { if (!store && !is_new) { - // See if user wants to update style name through script - int answer = wxMessageBox(_("Do you want to change all instances of this style in the script to this new name?"), _("Update script?"), wxYES_NO | wxCANCEL); + StyleRenamer renamer(c, work->name, newStyleName); + if (renamer.NeedsReplace()) { + // See if user wants to update style name through script + int answer = wxMessageBox( + _("Do you want to change all instances of this style in the script to this new name?"), + _("Update script?"), + wxYES_NO | wxCANCEL); - if (answer == wxCANCEL) return; + if (answer == wxCANCEL) return; - if (answer == wxYES) { - did_rename = true; - int n = c->subsGrid->GetRows(); - wxArrayString strings; - strings.Add(work->name); - strings.Add(newStyleName); - for (int i=0;isubsGrid->GetDialogue(i); - if (curDiag->Style == work->name) curDiag->Style = newStyleName; - curDiag->ParseASSTags(); - curDiag->ProcessParameters(ReplaceStyle, &strings); - curDiag->UpdateText(); - curDiag->ClearBlocks(); + if (answer == wxYES) { + did_rename = true; + renamer.Replace(); } } }