diff --git a/aegisub/auto4_auto3.cpp b/aegisub/auto4_auto3.cpp index 8cd3b0ed9..c3f80e71e 100644 --- a/aegisub/auto4_auto3.cpp +++ b/aegisub/auto4_auto3.cpp @@ -298,8 +298,7 @@ namespace Automation4 { return res; } - Auto3ConfigDialog::Auto3ConfigDialog(lua_State *L, const wxString &_ident) - : ident(_ident) + Auto3ConfigDialog::Auto3ConfigDialog(lua_State *L) { present = false; if (!lua_istable(L, -1)) { @@ -523,8 +522,6 @@ continue_invalid_option: void Auto3ConfigDialog::ReadBack() { - wxString opthname = wxString::Format(_T("Automation Settings %s"), ident.c_str()); - for (std::vector::iterator ctl = controls.begin(); ctl != controls.end(); ctl++) { switch (ctl->option->kind) { case COK_TEXT: @@ -560,12 +557,9 @@ continue_invalid_option: break; } } - - // serialize the new settings and save them to the file - AssFile::top->SetScriptInfo(opthname, serialize()); } - wxString Auto3ConfigDialog::serialize() + wxString Auto3ConfigDialog::Serialise() { if (options.size() == 0) return _T(""); @@ -599,7 +593,7 @@ continue_invalid_option: return result; } - void Auto3ConfigDialog::unserialize(wxString &settings) + void Auto3ConfigDialog::Unserialise(const wxString &settings) { wxStringTokenizer toker(settings, _T("|"), wxTOKEN_STRTOK); while (toker.HasMoreTokens()) { @@ -667,11 +661,7 @@ continue_invalid_option: { // configuration (let the config object do all the loading) lua_getglobal(L, "configuration"); - config = new Auto3ConfigDialog(L, GetName()); - - wxString opthname = wxString::Format(_T("Automation Settings %s"), GetName().c_str()); - wxString serialized = AssFile::top->GetScriptInfo(opthname); - config->unserialize(serialized); + config = new Auto3ConfigDialog(L); return config; } diff --git a/aegisub/auto4_auto3.h b/aegisub/auto4_auto3.h index 93aa4809f..0b20ea118 100644 --- a/aegisub/auto4_auto3.h +++ b/aegisub/auto4_auto3.h @@ -113,20 +113,18 @@ namespace Automation4 { }; std::vector controls; - wxString ident; - protected: wxWindow* CreateWindow(wxWindow *parent); public: - Auto3ConfigDialog(lua_State *L, const wxString &_ident); + Auto3ConfigDialog(lua_State *L); virtual ~Auto3ConfigDialog(); int LuaReadBack(lua_State *L); // read back internal structure to lua structures void ReadBack(); // from auto4 base - wxString serialize(); // make a string from the option name+value pairs - void unserialize(wxString &settings); // set the option values from a serialized string + wxString Serialise(); // make a string from the option name+value pairs + void Unserialise(const wxString &settings); // set the option values from a serialized string }; diff --git a/aegisub/auto4_base.cpp b/aegisub/auto4_base.cpp index fc0039ca9..336c38b41 100644 --- a/aegisub/auto4_base.cpp +++ b/aegisub/auto4_base.cpp @@ -36,6 +36,8 @@ #include "auto4_base.h" #include "ass_style.h" #include "options.h" +#include "string_codec.h" +#include "ass_file.h" #include #include #include @@ -243,12 +245,21 @@ namespace Automation4 { Unregister(); } + wxString FeatureFilter::GetScriptSettingsIdentifier() + { + return inline_string_encode(wxString::Format(_T("Automation Settings %s"), GetName().c_str())); + } + wxWindow* FeatureFilter::GetConfigDialogWindow(wxWindow *parent) { if (config_dialog) { delete config_dialog; config_dialog = 0; } if ((config_dialog = GenerateConfigDialog(parent)) != NULL) { + wxString val = AssFile::top->GetScriptInfo(GetScriptSettingsIdentifier()); + if (!val.IsEmpty()) { + config_dialog->Unserialise(val); + } return config_dialog->GetWindow(parent); } else { return 0; @@ -258,6 +269,11 @@ namespace Automation4 { void FeatureFilter::LoadSettings(bool IsDefault) { if (config_dialog) { config_dialog->ReadBack(); + + wxString val = config_dialog->Serialise(); + if (!val.IsEmpty()) { + AssFile::top->SetScriptInfo(GetScriptSettingsIdentifier(), val); + } } } @@ -306,6 +322,11 @@ namespace Automation4 { win = 0; } + wxString ScriptConfigDialog::Serialise() + { + return _T(""); + } + // ProgressSink diff --git a/aegisub/auto4_base.h b/aegisub/auto4_base.h index 8ce3bb476..490c03a65 100644 --- a/aegisub/auto4_base.h +++ b/aegisub/auto4_base.h @@ -127,6 +127,8 @@ namespace Automation4 { virtual ScriptConfigDialog* GenerateConfigDialog(wxWindow *parent) = 0; // subclasses should implement this, producing a new ScriptConfigDialog + wxString GetScriptSettingsIdentifier(); + public: virtual ~FeatureFilter(); @@ -174,6 +176,9 @@ namespace Automation4 { wxWindow* GetWindow(wxWindow *parent); void DeleteWindow(); virtual void ReadBack() = 0; + + virtual wxString Serialise(); + virtual void Unserialise(const wxString &serialised) { } }; diff --git a/aegisub/auto4_lua.cpp b/aegisub/auto4_lua.cpp index 68c04d11a..03998cd9d 100644 --- a/aegisub/auto4_lua.cpp +++ b/aegisub/auto4_lua.cpp @@ -736,12 +736,12 @@ namespace Automation4 { ps->ShowModal(); wxThread::ExitCode code = call.Wait(); - //if (code) ThrowError(); delete ps; - // The config dialog table should now be on stack + if (!code) { + // The config dialog table should now be on stack as LuaConfigDialog constructor expects return config_dialog = new LuaConfigDialog(L, false); } else { return config_dialog = 0; diff --git a/aegisub/auto4_lua.h b/aegisub/auto4_lua.h index d0b314ed9..191d6a899 100644 --- a/aegisub/auto4_lua.h +++ b/aegisub/auto4_lua.h @@ -130,6 +130,10 @@ namespace Automation4 { virtual void ControlReadBack() = 0; virtual void LuaReadBack(lua_State *L) = 0; + virtual bool CanSerialiseValue() { return false; } + virtual wxString SerialiseValue() { return _T(""); } + virtual void UnserialiseValue(const wxString &serialised) { } + LuaConfigDialogControl(lua_State *L); virtual ~LuaConfigDialogControl() { } }; @@ -157,6 +161,9 @@ namespace Automation4 { virtual ~LuaConfigDialog(); int LuaReadBack(lua_State *L); // read back internal structure to lua structures + wxString Serialise(); + void Unserialise(const wxString &serialised); + void ReadBack(); // from auto4 base }; diff --git a/aegisub/auto4_lua_dialog.cpp b/aegisub/auto4_lua_dialog.cpp index 96ec9e07e..4762f278a 100644 --- a/aegisub/auto4_lua_dialog.cpp +++ b/aegisub/auto4_lua_dialog.cpp @@ -36,11 +36,14 @@ #include "auto4_lua.h" #include "../lua51/src/lualib.h" #include "../lua51/src/lauxlib.h" +#include "string_codec.h" +#include "utils.h" #include #include #include #include #include +#include #include namespace Automation4 { @@ -125,6 +128,8 @@ namespace Automation4 { virtual ~Label() { } + // Doesn't have a serialisable value so don't implement that sub-interface + wxControl *Create(wxWindow *parent) { return cw = new wxStaticText(parent, -1, label); @@ -159,6 +164,21 @@ namespace Automation4 { virtual ~Edit() { } + bool CanSerialiseValue() + { + return true; + } + + wxString SerialiseValue() + { + return inline_string_encode(text); + } + + void UnserialiseValue(const wxString &serialised) + { + text = inline_string_decode(serialised); + } + wxControl *Create(wxWindow *parent) { return cw = new wxTextCtrl(parent, -1, text, wxDefaultPosition, wxDefaultSize, 0); @@ -190,6 +210,8 @@ namespace Automation4 { virtual ~Textbox() { } + // Same serialisation interface as single-line edit + wxControl *Create(wxWindow *parent) { cw = new wxTextCtrl(parent, -1, text, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); @@ -238,6 +260,23 @@ nospin: virtual ~IntEdit() { } + bool CanSerialiseValue() + { + return true; + } + + wxString SerialiseValue() + { + return wxString::Format(_T("%d"), value); + } + + void UnserialiseValue(const wxString &serialised) + { + long tmp; + if (serialised.ToLong(&tmp)) + value = tmp; + } + typedef wxValidator IntTextValidator; // TODO wxControl *Create(wxWindow *parent) { @@ -288,6 +327,23 @@ nospin: virtual ~FloatEdit() { } + bool CanSerialiseValue() + { + return true; + } + + wxString SerialiseValue() + { + return PrettyFloatF(value); + } + + void UnserialiseValue(const wxString &serialised) + { + double tmp; + if (serialised.ToDouble(&tmp)) + value = (float)tmp; + } + typedef wxValidator FloatTextValidator; wxControl *Create(wxWindow *parent) { @@ -338,6 +394,21 @@ nospin: virtual ~Dropdown() { } + bool CanSerialiseValue() + { + return true; + } + + wxString SerialiseValue() + { + return inline_string_encode(value); + } + + void UnserialiseValue(const wxString &serialised) + { + value = inline_string_decode(serialised); + } + wxControl *Create(wxWindow *parent) { return cw = new wxComboBox(parent, -1, value, wxDefaultPosition, wxDefaultSize, items, wxCB_READONLY); @@ -377,6 +448,22 @@ nospin: virtual ~Checkbox() { } + bool CanSerialiseValue() + { + return true; + } + + wxString SerialiseValue() + { + return value ? _T("1") : _T("0"); + } + + void UnserialiseValue(const wxString &serialised) + { + // fixme? should this allow more different "false" values? + value = (serialised == _T("0")) ? false : true; + } + wxControl *Create(wxWindow *parent) { return cw = new wxCheckBox(parent, -1, label); @@ -576,6 +663,48 @@ badcontrol: } } + wxString LuaConfigDialog::Serialise() + { + if (controls.size() == 0) + return _T(""); + + wxString res; + + // Format into "name1:value1|name2:value2|name3:value3|" + for (size_t i = 0; i < controls.size(); ++i) { + if (controls[i]->CanSerialiseValue()) { + wxString sn = inline_string_encode(controls[i]->name); + wxString sv = controls[i]->SerialiseValue(); + res += wxString::Format(_T("%s:%s|"), sn.c_str(), sv.c_str()); + } + } + + // Remove trailing pipe + if (!res.IsEmpty()) + res.RemoveLast(); + + return res; + } + + void LuaConfigDialog::Unserialise(const wxString &serialised) + { + // Split by pipe + wxStringTokenizer tk(serialised, _T("|")); + while (tk.HasMoreTokens()) { + // Split by colon + wxString pair = tk.GetNextToken(); + wxString name = inline_string_decode(pair.BeforeFirst(_T(':'))); + wxString value = pair.AfterFirst(_T(':')); + + // Hand value to all controls matching name + for (size_t i = 0; i < controls.size(); ++i) { + if (controls[i]->name == name && controls[i]->CanSerialiseValue()) { + controls[i]->UnserialiseValue(value); + } + } + } + } + void LuaConfigDialog::ReadBack() { for (size_t i = 0; i < controls.size(); ++i) { diff --git a/aegisub/string_codec.cpp b/aegisub/string_codec.cpp index 35064f182..48323090c 100644 --- a/aegisub/string_codec.cpp +++ b/aegisub/string_codec.cpp @@ -38,7 +38,7 @@ #include "string_codec.h" -wxString inline_string_encode(wxString &input) +wxString inline_string_encode(const wxString &input) { const size_t inlen = input.length(); wxString output(_T("")); @@ -54,7 +54,7 @@ wxString inline_string_encode(wxString &input) return output; } -wxString inline_string_decode(wxString &input) +wxString inline_string_decode(const wxString &input) { const size_t inlen = input.length(); wxString output(_T("")); diff --git a/aegisub/string_codec.h b/aegisub/string_codec.h index 70a6f7623..a5b33e342 100644 --- a/aegisub/string_codec.h +++ b/aegisub/string_codec.h @@ -58,7 +58,7 @@ #include #include -wxString inline_string_encode(wxString &input); -wxString inline_string_decode(wxString &input); +wxString inline_string_encode(const wxString &input); +wxString inline_string_decode(const wxString &input); #endif