diff --git a/aegisub/src/auto4_base.cpp b/aegisub/src/auto4_base.cpp index ecb2983d8..1f10c97aa 100644 --- a/aegisub/src/auto4_base.cpp +++ b/aegisub/src/auto4_base.cpp @@ -55,6 +55,12 @@ #include #endif +#ifdef _WIN32 +#include +#else +#include +#endif + #ifndef __WINDOWS__ #include #include FT_FREETYPE_H @@ -230,6 +236,7 @@ namespace Automation4 { // ProgressSink wxDEFINE_EVENT(EVT_SHOW_DIALOG, wxThreadEvent); + wxDEFINE_EVENT(EVT_SHOW_SCRIPT_DIALOG, wxThreadEvent); ProgressSink::ProgressSink(agi::ProgressSink *impl, BackgroundScriptRunner *bsr) : impl(impl) @@ -241,23 +248,35 @@ namespace Automation4 { void ProgressSink::ShowDialog(ScriptDialog *config_dialog) { wxSemaphore sema(0, 1); - wxThreadEvent *evt = new wxThreadEvent(EVT_SHOW_DIALOG); + wxThreadEvent *evt = new wxThreadEvent(EVT_SHOW_SCRIPT_DIALOG); evt->SetPayload(std::make_pair(config_dialog, &sema)); bsr->QueueEvent(evt); sema.Wait(); } + int ProgressSink::ShowDialog(wxDialog *dialog) + { + int ret = 0; + wxSemaphore sema(0, 1); + wxThreadEvent *evt = new wxThreadEvent(EVT_SHOW_DIALOG); + evt->SetPayload(std::tr1::make_tuple(dialog, &sema, &ret)); + bsr->QueueEvent(evt); + sema.Wait(); + return ret; + } + BackgroundScriptRunner::BackgroundScriptRunner(wxWindow *parent, wxString const& title) : impl(new DialogProgress(parent, title)) { impl->Bind(EVT_SHOW_DIALOG, &BackgroundScriptRunner::OnDialog, this); + impl->Bind(EVT_SHOW_SCRIPT_DIALOG, &BackgroundScriptRunner::OnScriptDialog, this); } BackgroundScriptRunner::~BackgroundScriptRunner() { } - void BackgroundScriptRunner::OnDialog(wxThreadEvent &evt) + void BackgroundScriptRunner::OnScriptDialog(wxThreadEvent &evt) { std::pair payload = evt.GetPayload >(); @@ -274,7 +293,16 @@ namespace Automation4 { payload.second->Post(); } - void BackgroundScriptRunner::QueueEvent(wxEvent *evt) { + void BackgroundScriptRunner::OnDialog(wxThreadEvent &evt) + { + using namespace std::tr1; + tuple payload = evt.GetPayload >(); + *get<2>(payload) = get<0>(payload)->ShowModal(); + get<1>(payload)->Post(); + } + + void BackgroundScriptRunner::QueueEvent(wxEvent *evt) + { wxQueueEvent(impl.get(), evt); } @@ -297,6 +325,11 @@ namespace Automation4 { impl->Run(bind(progress_sink_wrapper, task, std::tr1::placeholders::_1, this), prio); } + wxWindow *BackgroundScriptRunner::GetParentWindow() const + { + return impl.get(); + } + // Script Script::Script(wxString const& filename) : filename(filename) diff --git a/aegisub/src/auto4_base.h b/aegisub/src/auto4_base.h index cac2ea094..e52d88f12 100644 --- a/aegisub/src/auto4_base.h +++ b/aegisub/src/auto4_base.h @@ -131,8 +131,10 @@ namespace Automation4 { agi::scoped_ptr impl; void OnDialog(wxThreadEvent &evt); + void OnScriptDialog(wxThreadEvent &evt); public: void QueueEvent(wxEvent *evt); + wxWindow *GetParentWindow() const; void Run(std::tr1::function task); @@ -157,6 +159,8 @@ namespace Automation4 { /// Show the passed dialog on the GUI thread, blocking the calling /// thread until it closes void ShowDialog(ScriptDialog *config_dialog); + int ShowDialog(wxDialog *dialog); + wxWindow *GetParentWindow() const { return bsr->GetParentWindow(); } /// Get the current automation trace level int GetTraceLevel() const { return trace_level; } diff --git a/aegisub/src/auto4_lua.h b/aegisub/src/auto4_lua.h index 9ece935f7..6029ef2bf 100644 --- a/aegisub/src/auto4_lua.h +++ b/aegisub/src/auto4_lua.h @@ -145,6 +145,8 @@ namespace Automation4 { static int LuaGetCancelled(lua_State *L); static int LuaDebugOut(lua_State *L); static int LuaDisplayDialog(lua_State *L); + static int LuaDisplayOpenDialog(lua_State *L); + static int LuaDisplaySaveDialog(lua_State *L); public: LuaProgressSink(lua_State *L, ProgressSink *ps, bool allow_config_dialog = true); diff --git a/aegisub/src/auto4_lua_progresssink.cpp b/aegisub/src/auto4_lua_progresssink.cpp index d9b341db1..fc9d00152 100644 --- a/aegisub/src/auto4_lua_progresssink.cpp +++ b/aegisub/src/auto4_lua_progresssink.cpp @@ -60,6 +60,16 @@ namespace { lua_pushnil(L); lua_setfield(L, idx, name); } + + inline wxString get_wxstring(lua_State *L, int idx) + { + return wxString(lua_tostring(L, idx), wxConvUTF8); + } + + inline wxString check_wxstring(lua_State *L, int idx) + { + return wxString(luaL_checkstring(L, idx), wxConvUTF8); + } } namespace Automation4 { @@ -91,6 +101,8 @@ namespace Automation4 { if (allow_config_dialog) { lua_newtable(L); set_field_to_closure(L, "display", LuaDisplayDialog); + set_field_to_closure(L, "open", LuaDisplayOpenDialog); + set_field_to_closure(L, "save", LuaDisplaySaveDialog); lua_setfield(L, -2, "dialog"); } @@ -191,6 +203,68 @@ namespace Automation4 { // more magic: puts two values on stack: button pushed and table with control results return dlg.LuaReadBack(L); } + + int LuaProgressSink::LuaDisplayOpenDialog(lua_State *L) + { + ProgressSink *ps = GetObjPointer(L, lua_upvalueindex(1)); + wxString message(check_wxstring(L, 1)); + wxString dir(check_wxstring(L, 2)); + wxString file(check_wxstring(L, 3)); + wxString wildcard(check_wxstring(L, 4)); + bool multiple = !!lua_toboolean(L, 5); + bool must_exist = lua_toboolean(L, 6) || lua_isnil(L, 6); + + int flags = wxFD_OPEN; + if (multiple) + flags |= wxFD_MULTIPLE; + if (must_exist) + flags |= wxFD_FILE_MUST_EXIST; + + wxFileDialog diag(0, message, dir, file, wildcard, flags); + if (ps->ShowDialog(&diag) == wxID_CANCEL) { + lua_pushnil(L); + return 1; + } + + if (multiple) { + wxArrayString files; + diag.GetFilenames(files); + + lua_newtable(L); + for (size_t i = 0; i < files.size(); ++i) { + lua_pushstring(L, files[i].utf8_str()); + lua_rawseti(L, -2, i + 1); + } + + return 1; + } + + lua_pushstring(L, diag.GetFilename().utf8_str()); + return 1; + } + + int LuaProgressSink::LuaDisplaySaveDialog(lua_State *L) + { + ProgressSink *ps = GetObjPointer(L, lua_upvalueindex(1)); + wxString message(check_wxstring(L, 1)); + wxString dir(check_wxstring(L, 2)); + wxString file(check_wxstring(L, 3)); + wxString wildcard(check_wxstring(L, 4)); + bool prompt_overwrite = !lua_toboolean(L, 5); + + int flags = wxFD_SAVE; + if (prompt_overwrite) + flags |= wxFD_OVERWRITE_PROMPT; + + wxFileDialog diag(ps->GetParentWindow(), message, dir, file, wildcard, flags); + if (ps->ShowDialog(&diag) == wxID_CANCEL) { + lua_pushnil(L); + return 1; + } + + lua_pushstring(L, diag.GetFilename().utf8_str()); + return 1; + } } #endif