Add lua bindings for open and save standard dialogs

Originally committed to SVN as r6499.
This commit is contained in:
Thomas Goyne 2012-02-22 04:17:16 +00:00
parent 048fc44cfa
commit b59b3c56fc
4 changed files with 116 additions and 3 deletions

View file

@ -55,6 +55,12 @@
#include <wx/tokenzr.h>
#endif
#ifdef _WIN32
#include <tuple>
#else
#include <tr1/tuple>
#endif
#ifndef __WINDOWS__
#include <ft2build.h>
#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<ScriptDialog*, wxSemaphore*> payload = evt.GetPayload<std::pair<ScriptDialog*, wxSemaphore*> >();
@ -274,7 +293,16 @@ namespace Automation4 {
payload.second->Post();
}
void BackgroundScriptRunner::QueueEvent(wxEvent *evt) {
void BackgroundScriptRunner::OnDialog(wxThreadEvent &evt)
{
using namespace std::tr1;
tuple<wxDialog*, wxSemaphore*, int*> payload = evt.GetPayload<tuple<wxDialog*, wxSemaphore*, int*> >();
*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)

View file

@ -131,8 +131,10 @@ namespace Automation4 {
agi::scoped_ptr<DialogProgress> impl;
void OnDialog(wxThreadEvent &evt);
void OnScriptDialog(wxThreadEvent &evt);
public:
void QueueEvent(wxEvent *evt);
wxWindow *GetParentWindow() const;
void Run(std::tr1::function<void(ProgressSink*)> 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; }

View file

@ -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);

View file

@ -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