diff --git a/aegisub/src/auto4_base.cpp b/aegisub/src/auto4_base.cpp index 2b0d9b587..c37e8b8e5 100644 --- a/aegisub/src/auto4_base.cpp +++ b/aegisub/src/auto4_base.cpp @@ -62,9 +62,11 @@ #include "ass_style.h" #include "auto4_base.h" #include "compat.h" +#include "include/aegisub/context.h" #include "main.h" #include "standard_paths.h" #include "string_codec.h" +#include "utils.h" /// DOCME namespace Automation4 { @@ -912,7 +914,84 @@ namespace Automation4 { } } + LocalScriptManager::LocalScriptManager(agi::Context *c) + : context(c) + { + slots.push_back(c->ass->AddFileSaveListener(&LocalScriptManager::OnSubtitlesSave, this)); + slots.push_back(c->ass->AddFileOpenListener(&LocalScriptManager::Reload, this)); + } + void LocalScriptManager::Reload() { + RemoveAll(); + + wxString local_scripts = context->ass->GetScriptInfo("Automation Scripts"); + if (local_scripts.empty()) return; + + wxStringTokenizer tok(local_scripts, "|", wxTOKEN_STRTOK); + wxFileName assfn(context->ass->filename); + wxString autobasefn(lagi_wxString(OPT_GET("Path/Automation/Base")->GetString())); + while (tok.HasMoreTokens()) { + wxString trimmed = tok.GetNextToken().Trim(true).Trim(false); + char first_char = trimmed[0]; + trimmed.Remove(0, 1); + + wxString basepath; + if (first_char == '~') { + basepath = assfn.GetPath(); + } else if (first_char == '$') { + basepath = autobasefn; + } else if (first_char == '/') { + basepath = ""; + } else { + wxLogWarning("Automation Script referenced with unknown location specifier character.\nLocation specifier found: %c\nFilename specified: %s", + first_char, trimmed); + continue; + } + wxFileName sfname(trimmed); + sfname.MakeAbsolute(basepath); + if (sfname.FileExists()) { + wxString err; + Add(Automation4::ScriptFactory::CreateFromFile(sfname.GetFullPath(), true)); + } else { + wxLogWarning("Automation Script referenced could not be found.\nFilename specified: %c%s\nSearched relative to: %s\nResolved filename: %s", + first_char, trimmed, basepath, sfname.GetFullPath()); + } + } + } + + void LocalScriptManager::OnSubtitlesSave() { + // Store Automation script data + // Algorithm: + // 1. If script filename has Automation Base Path as a prefix, the path is relative to that (ie. "$") + // 2. Otherwise try making it relative to the ass filename + // 3. If step 2 failed, or absolute path is shorter than path relative to ass, use absolute path ("/") + // 4. Otherwise, use path relative to ass ("~") + wxString scripts_string; + wxString autobasefn(lagi_wxString(OPT_GET("Path/Automation/Base")->GetString())); + + for (size_t i = 0; i < GetScripts().size(); i++) { + Script *script = GetScripts()[i]; + + if (i != 0) + scripts_string += "|"; + + wxString autobase_rel, assfile_rel; + wxString scriptfn(script->GetFilename()); + autobase_rel = MakeRelativePath(scriptfn, autobasefn); + assfile_rel = MakeRelativePath(scriptfn, context->ass->filename); + + if (autobase_rel.size() <= scriptfn.size() && autobase_rel.size() <= assfile_rel.size()) { + scriptfn = "$" + autobase_rel; + } else if (assfile_rel.size() <= scriptfn.size() && assfile_rel.size() <= autobase_rel.size()) { + scriptfn = "~" + assfile_rel; + } else { + scriptfn = "/" + wxFileName(scriptfn).GetFullPath(wxPATH_UNIX); + } + + scripts_string += scriptfn; + } + context->ass->SetScriptInfo("Automation Scripts", scripts_string); + } // ScriptFactory diff --git a/aegisub/src/auto4_base.h b/aegisub/src/auto4_base.h index 2915dfd2b..f0475c086 100644 --- a/aegisub/src/auto4_base.h +++ b/aegisub/src/auto4_base.h @@ -50,6 +50,8 @@ #include #endif +#include + #include "ass_export_filter.h" #include "subtitle_format.h" @@ -61,6 +63,8 @@ class wxDialog; class wxStopWatch; class wxPathList; +namespace agi { struct Context; } + DECLARE_EVENT_TYPE(wxEVT_AUTOMATION_SCRIPT_COMPLETED, -1) @@ -472,6 +476,7 @@ namespace Automation4 { void Add(Script *script); // Add a script to the manager. The ScriptManager takes owvership of the script and will automatically delete it. void Remove(Script *script); // Remove a script from the manager, and delete the Script object. void RemoveAll(); // Deletes all scripts managed + virtual void Reload() = 0; const std::vector& GetScripts() const; @@ -480,7 +485,16 @@ namespace Automation4 { // They automatically register themselves in the relevant places. }; + /// Manager for scripts specified by a subtitle file + class LocalScriptManager : public ScriptManager { + std::list slots; + agi::Context *context; + void OnSubtitlesSave(); + public: + LocalScriptManager(agi::Context *context); + void Reload(); + }; /// DOCME /// @class AutoloadScriptManager diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index 01f46c630..e578d38d1 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -122,7 +122,7 @@ FrameMain::FrameMain (wxArrayString args) context->ass->AddFileOpenListener(&FrameMain::OnSubtitlesOpen, this); context->ass->AddFileSaveListener(&FrameMain::UpdateTitle, this); - context->local_scripts = new Automation4::ScriptManager(); + context->local_scripts = new Automation4::LocalScriptManager(context.get()); StartupLog("Initializing context controls"); context->audioController = new AudioController; @@ -678,7 +678,6 @@ void FrameMain::OnSubtitlesOpen() { curSubsVFR != context->videoController->GetTimecodesName() || curSubsVideo != context->videoController->videoName || curSubsKeyframes != context->videoController->GetKeyFramesName() - || !AutoScriptString.IsEmpty() || context->local_scripts->GetScripts().size() > 0 ) { if (autoLoadMode == 1) { @@ -724,38 +723,6 @@ void FrameMain::OnSubtitlesOpen() { if (curSubsAudio != context->audioController->GetAudioURL()) { context->audioController->OpenAudio(curSubsAudio); } - - // Automation scripts - context->local_scripts->RemoveAll(); - wxStringTokenizer tok(AutoScriptString, "|", wxTOKEN_STRTOK); - wxFileName assfn(context->ass->filename); - wxString autobasefn(lagi_wxString(OPT_GET("Path/Automation/Base")->GetString())); - while (tok.HasMoreTokens()) { - wxString sfnames = tok.GetNextToken().Trim(true).Trim(false); - wxString sfnamel = sfnames.Left(1); - sfnames.Remove(0, 1); - wxString basepath; - if (sfnamel == "~") { - basepath = assfn.GetPath(); - } else if (sfnamel == "$") { - basepath = autobasefn; - } else if (sfnamel == "/") { - basepath = ""; - } else { - wxLogWarning("Automation Script referenced with unknown location specifier character.\nLocation specifier found: %s\nFilename specified: %s", - sfnamel, sfnames); - continue; - } - wxFileName sfname(sfnames); - sfname.MakeAbsolute(basepath); - if (sfname.FileExists()) { - sfnames = sfname.GetFullPath(); - context->local_scripts->Add(Automation4::ScriptFactory::CreateFromFile(sfnames, true)); - } else { - wxLogWarning("Automation Script referenced could not be found.\nFilename specified: %s%s\nSearched relative to: %s\nResolved filename: %s", - sfnamel, sfnames, basepath, sfname.GetFullPath()); - } - } } // Display @@ -764,39 +731,6 @@ void FrameMain::OnSubtitlesOpen() { void FrameMain::OnSubtitlesSave() { UpdateTitle(); - - // Store Automation script data - // Algorithm: - // 1. If script filename has Automation Base Path as a prefix, the path is relative to that (ie. "$") - // 2. Otherwise try making it relative to the ass filename - // 3. If step 2 failed, or absolute path is shorter than path relative to ass, use absolute path ("/") - // 4. Otherwise, use path relative to ass ("~") - wxString scripts_string; - wxString autobasefn(lagi_wxString(OPT_GET("Path/Automation/Base")->GetString())); - - const std::vector &scripts = context->local_scripts->GetScripts(); - for (unsigned int i = 0; i < scripts.size(); i++) { - Automation4::Script *script = scripts[i]; - - if (i != 0) - scripts_string += "|"; - - wxString autobase_rel, assfile_rel; - wxString scriptfn(script->GetFilename()); - autobase_rel = MakeRelativePath(scriptfn, autobasefn); - assfile_rel = MakeRelativePath(scriptfn, context->ass->filename); - - if (autobase_rel.size() <= scriptfn.size() && autobase_rel.size() <= assfile_rel.size()) { - scriptfn = "$" + autobase_rel; - } else if (assfile_rel.size() <= scriptfn.size() && assfile_rel.size() <= autobase_rel.size()) { - scriptfn = "~" + assfile_rel; - } else { - scriptfn = "/" + wxFileName(scriptfn).GetFullPath(wxPATH_UNIX); - } - - scripts_string += scriptfn; - } - context->ass->SetScriptInfo("Automation Scripts", scripts_string); } void FrameMain::OnKeyDown(wxKeyEvent &event) {