Move the local script logic from FrameMain to a new LocalScriptManager

Originally committed to SVN as r5623.
This commit is contained in:
Thomas Goyne 2011-09-28 19:45:55 +00:00
parent 3029436a2d
commit 7680d6c246
3 changed files with 94 additions and 67 deletions

View File

@ -62,9 +62,11 @@
#include "ass_style.h" #include "ass_style.h"
#include "auto4_base.h" #include "auto4_base.h"
#include "compat.h" #include "compat.h"
#include "include/aegisub/context.h"
#include "main.h" #include "main.h"
#include "standard_paths.h" #include "standard_paths.h"
#include "string_codec.h" #include "string_codec.h"
#include "utils.h"
/// DOCME /// DOCME
namespace Automation4 { 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 // ScriptFactory

View File

@ -50,6 +50,8 @@
#include <wx/timer.h> #include <wx/timer.h>
#endif #endif
#include <libaegisub/signal.h>
#include "ass_export_filter.h" #include "ass_export_filter.h"
#include "subtitle_format.h" #include "subtitle_format.h"
@ -61,6 +63,8 @@ class wxDialog;
class wxStopWatch; class wxStopWatch;
class wxPathList; class wxPathList;
namespace agi { struct Context; }
DECLARE_EVENT_TYPE(wxEVT_AUTOMATION_SCRIPT_COMPLETED, -1) 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 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 Remove(Script *script); // Remove a script from the manager, and delete the Script object.
void RemoveAll(); // Deletes all scripts managed void RemoveAll(); // Deletes all scripts managed
virtual void Reload() = 0;
const std::vector<Script*>& GetScripts() const; const std::vector<Script*>& GetScripts() const;
@ -480,7 +485,16 @@ namespace Automation4 {
// They automatically register themselves in the relevant places. // They automatically register themselves in the relevant places.
}; };
/// Manager for scripts specified by a subtitle file
class LocalScriptManager : public ScriptManager {
std::list<agi::signal::Connection> slots;
agi::Context *context;
void OnSubtitlesSave();
public:
LocalScriptManager(agi::Context *context);
void Reload();
};
/// DOCME /// DOCME
/// @class AutoloadScriptManager /// @class AutoloadScriptManager

View File

@ -122,7 +122,7 @@ FrameMain::FrameMain (wxArrayString args)
context->ass->AddFileOpenListener(&FrameMain::OnSubtitlesOpen, this); context->ass->AddFileOpenListener(&FrameMain::OnSubtitlesOpen, this);
context->ass->AddFileSaveListener(&FrameMain::UpdateTitle, 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"); StartupLog("Initializing context controls");
context->audioController = new AudioController; context->audioController = new AudioController;
@ -678,7 +678,6 @@ void FrameMain::OnSubtitlesOpen() {
curSubsVFR != context->videoController->GetTimecodesName() || curSubsVFR != context->videoController->GetTimecodesName() ||
curSubsVideo != context->videoController->videoName || curSubsVideo != context->videoController->videoName ||
curSubsKeyframes != context->videoController->GetKeyFramesName() curSubsKeyframes != context->videoController->GetKeyFramesName()
|| !AutoScriptString.IsEmpty() || context->local_scripts->GetScripts().size() > 0
) )
{ {
if (autoLoadMode == 1) { if (autoLoadMode == 1) {
@ -724,38 +723,6 @@ void FrameMain::OnSubtitlesOpen() {
if (curSubsAudio != context->audioController->GetAudioURL()) { if (curSubsAudio != context->audioController->GetAudioURL()) {
context->audioController->OpenAudio(curSubsAudio); 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 // Display
@ -764,39 +731,6 @@ void FrameMain::OnSubtitlesOpen() {
void FrameMain::OnSubtitlesSave() { void FrameMain::OnSubtitlesSave() {
UpdateTitle(); 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<Automation4::Script*> &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) { void FrameMain::OnKeyDown(wxKeyEvent &event) {