X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fluainstance.cc;h=f184368f1d07adf05a6d42a54e91106d0129fa90;hb=7d8b93add17620135eadee5029325a3d22512b12;hp=cfa380e700d13633682042ef0304ddc4d9dda0cd;hpb=418570b04129eed250e3047cc83bc4d70113f5ab;p=ardour.git diff --git a/gtk2_ardour/luainstance.cc b/gtk2_ardour/luainstance.cc index cfa380e700..f184368f1d 100644 --- a/gtk2_ardour/luainstance.cc +++ b/gtk2_ardour/luainstance.cc @@ -20,10 +20,14 @@ #include #include +#include "pbd/strsplit.h" + +#include "gtkmm2ext/bindings.h" #include "gtkmm2ext/gui_thread.h" #include "ardour/audioengine.h" -#include "ardour/diskstream.h" +#include "ardour/disk_reader.h" +#include "ardour/disk_writer.h" #include "ardour/plugin_manager.h" #include "ardour/route.h" #include "ardour/session.h" @@ -359,6 +363,8 @@ const char *luasignalstr[] = { }; // namespace +static std::string http_get_unlogged (const std::string& url) { return ArdourCurl::http_get (url, false); } + /** special cases for Ardour's Mixer UI */ namespace LuaMixer { @@ -368,6 +374,7 @@ namespace LuaMixer { } }; + //////////////////////////////////////////////////////////////////////////////// static PBD::ScopedConnectionList _luaexecs; @@ -425,6 +432,77 @@ lua_exec (std::string cmd) //////////////////////////////////////////////////////////////////////////////// +static int +lua_actionlist (lua_State *L) +{ + using namespace std; + + vector paths; + vector labels; + vector tooltips; + vector keys; + vector > actions; + Gtkmm2ext::ActionMap::get_all_actions (paths, labels, tooltips, keys, actions); + + vector::iterator p; + vector::iterator l; + + luabridge::LuaRef action_tbl (luabridge::newTable (L)); + + for (l = labels.begin(), p = paths.begin(); l != labels.end(); ++p, ++l) { + if (l->empty ()) { + continue; + } + + vector parts; + split (*p, parts, '/'); + + if (parts.empty()) { + continue; + } + + //kinda kludgy way to avoid displaying menu items as mappable + if (parts[1] == _("Main_menu")) + continue; + if (parts[1] == _("JACK")) + continue; + if (parts[1] == _("redirectmenu")) + continue; + if (parts[1] == _("Editor_menus")) + continue; + if (parts[1] == _("RegionList")) + continue; + if (parts[1] == _("ProcessorMenu")) + continue; + + /* strip / from the start */ + string path = (*p); + path = path.substr (strlen ("/")); + + if (!action_tbl[parts[1]].isTable()) { + action_tbl[parts[1]] = luabridge::newTable (L); + } + assert (action_tbl[parts[1]].isTable()); + luabridge::LuaRef tbl (action_tbl[parts[1]]); + assert (tbl.isTable()); + tbl[*l] = path; + } + + luabridge::push (L, action_tbl); + return 1; +} + +//////////////////////////////////////////////////////////////////////////////// + +// ARDOUR_UI and instance() are not exposed. +ARDOUR::PresentationInfo::order_t +lua_translate_order (RouteDialogs::InsertAt place) +{ + return ARDOUR_UI::instance()->translate_order (place); +} + +//////////////////////////////////////////////////////////////////////////////// + #define xstr(s) stringify(s) #define stringify(s) #s @@ -668,7 +746,7 @@ LuaInstance::register_classes (lua_State* L) luabridge::getGlobalNamespace (L) .beginNamespace ("ArdourUI") - .addFunction ("http_get", (std::string (*)(const std::string&))&ArdourCurl::http_get) + .addFunction ("http_get", &http_get_unlogged) .addFunction ("processor_selection", &LuaMixer::processor_selection) @@ -718,14 +796,14 @@ LuaInstance::register_classes (lua_State* L) .beginClass ("RegionSelection") .addFunction ("start", &RegionSelection::start) - .addFunction ("end_frame", &RegionSelection::end_frame) + .addFunction ("end_sample", &RegionSelection::end_sample) .addFunction ("n_midi_regions", &RegionSelection::n_midi_regions) .addFunction ("regionlist", &RegionSelection::regionlist) // XXX check windows binding (libardour) .endClass () .deriveClass > ("TimeSelection") .addFunction ("start", &TimeSelection::start) - .addFunction ("end_frame", &TimeSelection::end_frame) + .addFunction ("end_sample", &TimeSelection::end_sample) .addFunction ("length", &TimeSelection::length) .endClass () @@ -758,10 +836,9 @@ LuaInstance::register_classes (lua_State* L) .endClass () .beginClass ("Editor") - .addFunction ("snap_type", &PublicEditor::snap_type) + .addFunction ("grid_type", &PublicEditor::grid_type) .addFunction ("snap_mode", &PublicEditor::snap_mode) .addFunction ("set_snap_mode", &PublicEditor::set_snap_mode) - .addFunction ("set_snap_threshold", &PublicEditor::set_snap_threshold) .addFunction ("undo", &PublicEditor::undo) .addFunction ("redo", &PublicEditor::redo) @@ -790,8 +867,7 @@ LuaInstance::register_classes (lua_State* L) .addFunction ("add_location_from_playhead_cursor", &PublicEditor::add_location_from_playhead_cursor) .addFunction ("remove_location_at_playhead_cursor", &PublicEditor::remove_location_at_playhead_cursor) - .addFunction ("set_show_measures", &PublicEditor::set_show_measures) - .addFunction ("show_measures", &PublicEditor::show_measures) + .addFunction ("update_grid", &PublicEditor::update_grid) .addFunction ("remove_tracks", &PublicEditor::remove_tracks) .addFunction ("set_loop_range", &PublicEditor::set_loop_range) @@ -908,7 +984,16 @@ LuaInstance::register_classes (lua_State* L) .addFunction ("set_toggleaction", &PublicEditor::set_toggleaction) .endClass () + .addFunction ("translate_order", &lua_translate_order) + /* ArdourUI enums */ + .beginNamespace ("InsertAt") + .addConst ("BeforeSelection", RouteDialogs::InsertAt(RouteDialogs::BeforeSelection)) + .addConst ("AfterSelection", RouteDialogs::InsertAt(RouteDialogs::AfterSelection)) + .addConst ("First", RouteDialogs::InsertAt(RouteDialogs::First)) + .addConst ("Last", RouteDialogs::InsertAt(RouteDialogs::Last)) + .endNamespace () + .beginNamespace ("MarkerType") .addConst ("Mark", ArdourMarker::Type(ArdourMarker::Mark)) .addConst ("Tempo", ArdourMarker::Type(ArdourMarker::Tempo)) @@ -930,6 +1015,8 @@ LuaInstance::register_classes (lua_State* L) .addConst ("Add", Selection::Operation(Selection::Add)) .endNamespace () + .addCFunction ("actionlist", &lua_actionlist) + .endNamespace () // end ArdourUI .beginNamespace ("os") @@ -942,7 +1029,7 @@ LuaInstance::register_classes (lua_State* L) // Editing Symbols #undef ZOOMFOCUS -#undef SNAPTYPE +#undef GRIDTYPE #undef SNAPMODE #undef MOUSEMODE #undef DISPLAYCONTROL @@ -951,7 +1038,7 @@ LuaInstance::register_classes (lua_State* L) #undef IMPORTDISPOSITION #define ZOOMFOCUS(NAME) .addConst (stringify(NAME), (Editing::ZoomFocus)Editing::NAME) -#define SNAPTYPE(NAME) .addConst (stringify(NAME), (Editing::SnapType)Editing::NAME) +#define GRIDTYPE(NAME) .addConst (stringify(NAME), (Editing::GridType)Editing::NAME) #define SNAPMODE(NAME) .addConst (stringify(NAME), (Editing::SnapMode)Editing::NAME) #define MOUSEMODE(NAME) .addConst (stringify(NAME), (Editing::MouseMode)Editing::NAME) #define DISPLAYCONTROL(NAME) .addConst (stringify(NAME), (Editing::DisplayControl)Editing::NAME) @@ -974,9 +1061,7 @@ using namespace ARDOUR_UI_UTILS; using namespace PBD; using namespace std; -void -LuaInstance::_lua_print (std::string s) -{ +static void _lua_print (std::string s) { #ifndef NDEBUG std::cout << "LuaInstance: " << s << "\n"; #endif @@ -1045,7 +1130,7 @@ LuaInstance::init () " assert(type(f) == 'function', 'Factory is a not a function')" " assert(type(a) == 'table' or type(a) == 'nil', 'Given argument is invalid')" " self.scripts[i] = { ['n'] = n, ['s'] = s, ['f'] = f, ['a'] = a, ['c'] = c }" - " local env = _ENV; env.f = nil env.io = nil" + " local env = _ENV; env.f = nil" " self.instances[i] = load (string.dump(f, true), nil, nil, env)(a)" " if type(c) == 'function' then" " self.icons[i] = load (string.dump(c, true), nil, nil, env)(a)" @@ -1163,6 +1248,11 @@ LuaInstance::init () _lua_clear = new luabridge::LuaRef(lua_mgr["clear"]); } catch (luabridge::LuaException const& e) { + fatal << string_compose (_("programming error: %1"), + std::string ("Failed to setup Lua action interpreter") + e.what ()) + << endmsg; + abort(); /*NOTREACHED*/ + } catch (...) { fatal << string_compose (_("programming error: %1"), X_("Failed to setup Lua action interpreter")) << endmsg; @@ -1200,7 +1290,7 @@ LuaInstance::session_going_away () point_one_second_connection.disconnect (); (*_lua_clear)(); - for (int i = 0; i < 9; ++i) { + for (int i = 0; i < MAX_LUA_ACTION_SCRIPTS; ++i) { ActionChanged (i, ""); /* EMIT SIGNAL */ } SessionHandlePtr::session_going_away (); @@ -1231,8 +1321,8 @@ LuaInstance::set_state (const XMLNode& node) (*_lua_load)(std::string ((const char*)buf, size)); } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - } - for (int i = 0; i < 9; ++i) { + } catch (...) { } + for (int i = 0; i < MAX_LUA_ACTION_SCRIPTS; ++i) { std::string name; if (lua_action_name (i, name)) { ActionChanged (i, name); /* EMIT SIGNAL */ @@ -1251,7 +1341,7 @@ LuaInstance::set_state (const XMLNode& node) SlotChanged (p->id(), p->name(), p->signals()); /* EMIT SIGNAL */ } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - } + } catch (...) { } } } @@ -1268,7 +1358,7 @@ LuaInstance::interactive_add (LuaScriptInfo::ScriptType type, int id) switch (type) { case LuaScriptInfo::EditorAction: reg = lua_action_names (); - title = _("Add Lua Action"); + title = _("Add Shortcut or Lua Script"); break; case LuaScriptInfo::EditorHook: reg = lua_slot_names (); @@ -1301,18 +1391,27 @@ LuaInstance::interactive_add (LuaScriptInfo::ScriptType type, int id) try { script = Glib::file_get_contents (spi->path); - } catch (Glib::FileError e) { + } catch (Glib::FileError const& e) { string msg = string_compose (_("Cannot read script '%1': %2"), spi->path, e.what()); Gtk::MessageDialog am (msg); am.run (); return false; } - LuaScriptParamList lsp = LuaScriptParams::script_params (spi, param_function); + LuaState ls; + register_classes (ls.getState ()); + LuaScriptParamList lsp = LuaScriptParams::script_params (ls, spi->path, param_function); + + /* allow cancel */ + for (size_t i = 0; i < lsp.size(); ++i) { + if (lsp[i]->preseeded && lsp[i]->name == "x-script-abort") { + return false; + } + } ScriptParameterDialog spd (_("Set Script Parameters"), spi, reg, lsp); - if (!spd.need_interation ()) { + if (spd.need_interation ()) { switch (spd.run ()) { case Gtk::RESPONSE_ACCEPT: break; @@ -1321,7 +1420,7 @@ LuaInstance::interactive_add (LuaScriptInfo::ScriptType type, int id) } } - LuaScriptParamPtr lspp (new LuaScriptParam("x-script-origin", "", spi->path, false)); + LuaScriptParamPtr lspp (new LuaScriptParam("x-script-origin", "", spi->path, false, true)); lsp.push_back (lspp); switch (type) { @@ -1338,10 +1437,14 @@ LuaInstance::interactive_add (LuaScriptInfo::ScriptType type, int id) string msg = string_compose (_("Session script '%1' instantiation failed: %2"), spd.name(), e.what ()); Gtk::MessageDialog am (msg); am.run (); - } catch (SessionException e) { + } catch (SessionException const& e) { string msg = string_compose (_("Loading Session script '%1' failed: %2"), spd.name(), e.what ()); Gtk::MessageDialog am (msg); am.run (); + } catch (...) { + string msg = string_compose (_("Loading Session script '%1' failed: %2"), spd.name(), "Unknown Exception"); + Gtk::MessageDialog am (msg); + am.run (); } default: break; @@ -1388,7 +1491,7 @@ LuaInstance::call_action (const int id) lua.collect_garbage_step (); } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - } + } catch (...) { } } void @@ -1405,7 +1508,7 @@ LuaInstance::render_icon (int i, cairo_t* cr, int w, int h, uint32_t clr) (*_lua_render_icon)(i + 1, (Cairo::Context *)&ctx, w, h, clr); } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - } + } catch (...) { } } bool @@ -1431,6 +1534,8 @@ LuaInstance::set_lua_action ( } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; return false; + } catch (...) { + return false; } _session->set_dirty (); return true; @@ -1444,6 +1549,8 @@ LuaInstance::remove_lua_action (const int id) } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; return false; + } catch (...) { + return false; } ActionChanged (id, ""); /* EMIT SIGNAL */ _session->set_dirty (); @@ -1465,8 +1572,7 @@ LuaInstance::lua_action_name (const int id, std::string& rv) return true; } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - return false; - } + } catch (...) { } return false; } @@ -1474,7 +1580,7 @@ std::vector LuaInstance::lua_action_names () { std::vector rv; - for (int i = 0; i < 9; ++i) { + for (int i = 0; i < MAX_LUA_ACTION_SCRIPTS; ++i) { std::string name; if (lua_action_name (i, name)) { rv.push_back (name); @@ -1496,7 +1602,7 @@ LuaInstance::lua_action_has_icon (const int id) } } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - } + } catch (...) { } return false; } @@ -1531,8 +1637,7 @@ LuaInstance::lua_action (const int id, std::string& name, std::string& script, L return true; } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - return false; - } + } catch (...) { } return false; } @@ -1555,7 +1660,7 @@ LuaInstance::register_lua_slot (const std::string& name, const std::string& scri } } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - } + } catch (...) { } if (ah.none ()) { cerr << "Script registered no hooks." << endl; @@ -1572,7 +1677,7 @@ LuaInstance::register_lua_slot (const std::string& name, const std::string& scri return true; } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - } + } catch (...) { } _session->set_dirty (); return false; } @@ -1658,11 +1763,13 @@ LuaCallback::LuaCallback (Session *s, } try { - const std::string& bytecode = LuaScripting::get_factory_bytecode (script); - (*_lua_add)(name, script, bytecode, tbl_arg); + const std::string& bytecode = LuaScripting::get_factory_bytecode (script); + (*_lua_add)(name, script, bytecode, tbl_arg); } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; throw failed_constructor (); + } catch (...) { + throw failed_constructor (); } _id.reset (); @@ -1701,7 +1808,7 @@ LuaCallback::LuaCallback (Session *s, XMLNode & node) (*_lua_load)(std::string ((const char*)buf, size)); } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; - } + } catch (...) { } g_free (buf); set_session (s); @@ -1750,7 +1857,7 @@ LuaCallback::get_state (void) void LuaCallback::init (void) { - lua.Print.connect (&LuaInstance::_lua_print); + lua.Print.connect (&_lua_print); lua.sandbox (false); lua.do_command ( @@ -1763,7 +1870,7 @@ LuaCallback::init (void) " assert(type(f) == 'function', 'Factory is a not a function')" " assert(type(a) == 'table' or type(a) == 'nil', 'Given argument is invalid')" " self.script = { ['n'] = n, ['s'] = s, ['f'] = f, ['a'] = a }" - " local env = _ENV; env.f = nil env.io = nil" + " local env = _ENV; env.f = nil" " self.instance = load (string.dump(f, true), nil, nil, env)(a)" " end" "" @@ -1861,6 +1968,11 @@ LuaCallback::init (void) _lua_load = new luabridge::LuaRef(lua_mgr["restore"]); } catch (luabridge::LuaException const& e) { + fatal << string_compose (_("programming error: %1"), + std::string ("Failed to setup Lua callback interpreter: ") + e.what ()) + << endmsg; + abort(); /*NOTREACHED*/ + } catch (...) { fatal << string_compose (_("programming error: %1"), X_("Failed to setup Lua callback interpreter")) << endmsg; @@ -1909,7 +2021,7 @@ LuaCallback::lua_slot (std::string& name, std::string& script, ActionHook& ah, A } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; return false; - } + } catch (...) { } return false; } @@ -2013,6 +2125,14 @@ LuaCallback::connect_2 (enum LuaSignal::LuaSignal ls, T ref, PBD::Signal2 void +LuaCallback::connect_3 (enum LuaSignal::LuaSignal ls, T ref, PBD::Signal3 *signal) { + signal->connect ( + _connections, invalidator (*this), + boost::bind (&LuaCallback::proxy_3, this, ls, ref, _1, _2, _3), + gui_context()); +} + template void LuaCallback::proxy_0 (enum LuaSignal::LuaSignal ls, T ref) { bool ok = true; @@ -2055,3 +2175,17 @@ LuaCallback::proxy_2 (enum LuaSignal::LuaSignal ls, T ref, C1 a1, C2 a2) { drop_callback (); /* EMIT SIGNAL */ } } + +template void +LuaCallback::proxy_3 (enum LuaSignal::LuaSignal ls, T ref, C1 a1, C2 a2, C3 a3) { + bool ok = true; + { + const luabridge::LuaRef& rv ((*_lua_call)((int)ls, ref, a1, a2, a3)); + if (! rv.cast ()) { + ok = false; + } + } + if (!ok) { + drop_callback (); /* EMIT SIGNAL */ + } +}