Implement the Automation menu

Originally committed to SVN as r5648.
This commit is contained in:
Thomas Goyne 2011-09-28 19:49:56 +00:00
parent 5bb5f146a7
commit d419c7a447
4 changed files with 100 additions and 25 deletions

View file

@ -325,6 +325,8 @@ namespace Automation4 {
{
if (find(scripts.begin(), scripts.end(), script) == scripts.end())
scripts.push_back(script);
ScriptsChanged();
}
void ScriptManager::Remove(Script *script)
@ -334,11 +336,14 @@ namespace Automation4 {
delete *i;
scripts.erase(i);
}
ScriptsChanged();
}
void ScriptManager::RemoveAll()
{
delete_clear(scripts);
ScriptsChanged();
}
const std::vector<cmd::Command*>& ScriptManager::GetMacros()
@ -361,7 +366,7 @@ namespace Automation4 {
void AutoloadScriptManager::Reload()
{
RemoveAll();
delete_clear(scripts);
int error_count = 0;
@ -386,7 +391,7 @@ namespace Automation4 {
wxString fullpath = script_path.GetFullPath();
if (ScriptFactory::CanHandleScriptFormat(fullpath)) {
Script *s = ScriptFactory::CreateFromFile(fullpath, true);
Add(s);
scripts.push_back(s);
if (!s->GetLoadedState()) error_count++;
}
more = dir.GetNext(&fn);
@ -395,6 +400,8 @@ namespace Automation4 {
if (error_count > 0) {
wxLogWarning("One or more scripts placed in the Automation autoload directory failed to load\nPlease review the errors above, correct them and use the Reload Autoload dir button in Automation Manager to attempt loading the scripts again.");
}
ScriptsChanged();
}
LocalScriptManager::LocalScriptManager(agi::Context *c)
@ -406,7 +413,7 @@ namespace Automation4 {
void LocalScriptManager::Reload()
{
RemoveAll();
delete_clear(scripts);
wxString local_scripts = context->ass->GetScriptInfo("Automation Scripts");
if (local_scripts.empty()) return;
@ -434,12 +441,15 @@ namespace Automation4 {
wxFileName sfname(trimmed);
sfname.MakeAbsolute(basepath);
if (sfname.FileExists()) {
Add(Automation4::ScriptFactory::CreateFromFile(sfname.GetFullPath(), true));
} else {
scripts.push_back(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());
}
}
ScriptsChanged();
}
void LocalScriptManager::OnSubtitlesSave()

View file

@ -206,9 +206,12 @@ namespace Automation4 {
/// A manager of loaded automation scripts
class ScriptManager {
protected:
std::vector<Script*> scripts;
std::vector<cmd::Command*> macros;
agi::signal::Signal<> ScriptsChanged;
public:
/// Deletes all scripts managed
virtual ~ScriptManager();
@ -227,6 +230,8 @@ namespace Automation4 {
const std::vector<cmd::Command*>& GetMacros();
// No need to have getters for the other kinds of features, I think.
// They automatically register themselves in the relevant places.
DEFINE_SIGNAL_ADDERS(ScriptsChanged, AddScriptChangeListener)
};
/// Manager for scripts specified by a subtitle file

View file

@ -26,15 +26,15 @@
{ "command" : "edit/line/delete" }
],
"main" : [
{ "submenu" : "main/file", "text" : "&File" },
{ "submenu" : "main/edit", "text" : "&Edit" },
{ "submenu" : "main/subtitle", "text" : "&Subtitle" },
{ "submenu" : "main/timing", "text" : "&Timing" },
{ "submenu" : "main/video", "text" : "&Video" },
{ "submenu" : "main/audio", "text" : "&Audio" },
{ "submenu" : "main/automation", "text" : "A&utomation" },
{ "submenu" : "main/view", "text" : "&View" },
{ "submenu" : "main/help", "text" : "&Help", "special" : "help" }
{ "submenu" : "main/file", "text" : "&File" },
{ "submenu" : "main/edit", "text" : "&Edit" },
{ "submenu" : "main/subtitle", "text" : "&Subtitle" },
{ "submenu" : "main/timing", "text" : "&Timing" },
{ "submenu" : "main/video", "text" : "&Video" },
{ "submenu" : "main/audio", "text" : "&Audio" },
{ "special" : "automation", "text" : "A&utomation" },
{ "submenu" : "main/view", "text" : "&View" },
{ "submenu" : "main/help", "text" : "&Help", "special" : "help" }
],
"main/file" : [
{ "command" : "subtitle/new" },
@ -168,10 +168,6 @@
{ "command" : "audio/open/blank" },
{ "command" : "audio/open/noise" }
],
"main/automation" : [
{ "command" : "am/manager" },
{}
],
"main/view" : [
{ "command" : "app/language" },
{ "command" : "app/options", "special" : "options" },

View file

@ -22,8 +22,10 @@
#include "include/aegisub/menu.h"
#include "include/aegisub/context.h"
#include "include/aegisub/hotkey.h"
#include "auto4_base.h"
#include "command/command.h"
#include "compat.h"
#include "libresrc/libresrc.h"
@ -113,6 +115,14 @@ public:
}
};
struct menu_item_cmp {
wxMenuItem *item;
menu_item_cmp(wxMenuItem *item) : item(item) { }
bool operator()(std::pair<cmd::Command*, wxMenuItem*> o) const {
return o.second == item;
}
};
/// @class CommandManager
/// @brief Event dispatcher to update menus on open and handle click events
///
@ -171,6 +181,14 @@ public:
return item->GetId();
}
/// Unregister a dynamic menu item
void Remove(wxMenuItem *item) {
std::deque<std::pair<cmd::Command*, wxMenuItem*> >::iterator it =
find_if(dynamic_items.begin(), dynamic_items.end(), menu_item_cmp(item));
if (it != dynamic_items.end())
dynamic_items.erase(it);
}
/// Create a MRU menu and register the needed handlers
/// @param name MRU type
/// @param parent Menu to append the new MRU menu to
@ -280,12 +298,6 @@ void process_menu_item(wxMenu *parent, agi::Context *c, json::Object const& ele,
return;
}
if (special == "automation") {
/// @todo Actually implement this
parent->Append(-1, _("No Automation macros loaded"))->Enable(false);
return;
}
if (!read_entry(ele, "command", &command))
return;
@ -325,6 +337,51 @@ wxMenu *build_menu(std::string const& name, agi::Context *c, CommandManager *cm,
return menu;
}
struct comp_str_menu {
agi::Context *c;
comp_str_menu(agi::Context *c) : c(c) { }
bool operator()(const cmd::Command *lft, const cmd::Command *rgt) const {
return lft->StrMenu(c) < rgt->StrMenu(c);
}
};
class AutomationMenu : public wxMenu {
agi::Context *c;
CommandManager *cm;
agi::signal::Connection global_slot;
agi::signal::Connection local_slot;
void Regenerate() {
wxMenuItemList &items = GetMenuItems();
for (size_t i = items.size() - 1; i >= 2; --i) {
cm->Remove(items[i]);
Delete(items[i]);
}
std::vector<cmd::Command*> macros = wxGetApp().global_scripts->GetMacros();
std::vector<cmd::Command*> local_macros = c->local_scripts->GetMacros();
copy(local_macros.begin(), local_macros.end(), back_inserter(macros));
sort(macros.begin(), macros.end(), comp_str_menu(c));
if (macros.empty())
Append(-1, _("No Automation macros loaded"))->Enable(false);
else {
for (size_t i = 0; i < macros.size(); ++i)
cm->AddCommand(macros[i], this, "");
}
}
public:
AutomationMenu(agi::Context *c, CommandManager *cm)
: c(c)
, cm(cm)
, global_slot(wxGetApp().global_scripts->AddScriptChangeListener(&AutomationMenu::Regenerate, this))
, local_slot(c->local_scripts->AddScriptChangeListener(&AutomationMenu::Regenerate, this))
{
cm->AddCommand(cmd::get("am/manager"), this, "");
AppendSeparator();
Regenerate();
}
};
}
namespace menu {
@ -336,7 +393,14 @@ namespace menu {
std::string submenu, disp;
read_entry(*it, "submenu", &submenu);
read_entry(*it, "text", &disp);
menu->Append(build_menu(submenu, c, &menu->cm), lagi_wxString(disp));
if (!submenu.empty()) {
menu->Append(build_menu(submenu, c, &menu->cm), lagi_wxString(disp));
}
else {
read_entry(*it, "special", &submenu);
if (submenu == "automation")
menu->Append(new AutomationMenu(c, &menu->cm), lagi_wxString(disp));
}
}
window->SetMenuBar(menu);