Consolidate two more engine-checks
[ardour.git] / gtk2_ardour / lua_script_manager.cc
index c33dea3e5554f67f40fd88aac382a699ddecbcf3..caf2ad7065e1f9af454aa7e9f506f3bacffb105d 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
+#include <gtkmm/box.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/messagedialog.h>
+
+#include "gtkmm2ext/gui_thread.h"
 #include "gtkmm2ext/utils.h"
 
+#include "ardour/session.h"
+
+#include "LuaBridge/LuaBridge.h"
+
+#include "ardour_ui.h"
 #include "lua_script_manager.h"
+#include "luawindow.h"
 #include "script_selector.h"
 #include "pbd/i18n.h"
 
@@ -34,6 +45,8 @@ LuaScriptManager::LuaScriptManager ()
        , _a_call_button (_("Call"))
        , _c_add_button (_("New Hook"))
        , _c_del_button (_("Remove"))
+       , _s_add_button (_("Load"))
+       , _s_del_button (_("Remove"))
 {
        /* action script page */
        _a_store = ListStore::create (_a_model);
@@ -45,6 +58,9 @@ LuaScriptManager::LuaScriptManager ()
        _a_view.get_column(1)->set_resizable (true);
        _a_view.get_column(1)->set_expand (true);
 
+       Frame* f;
+       Gtk::Label* doc;
+
        Gtk::HBox* edit_box = manage (new Gtk::HBox);
        edit_box->set_spacing(3);
 
@@ -62,9 +78,18 @@ LuaScriptManager::LuaScriptManager ()
        LuaInstance::instance()->ActionChanged.connect (sigc::mem_fun (*this, &LuaScriptManager::set_action_script_name));
        LuaInstance::instance()->SlotChanged.connect (sigc::mem_fun (*this, &LuaScriptManager::set_callback_script_name));
 
+       f = manage (new Frame (_("Description")));
+       doc = manage (new Label (
+                               _("Action Scripts are user initiated actions (menu, shortcuts, toolbar-button) for batch processing or customized tasks.")
+                               ));
+       doc->set_padding (5, 5);
+       doc->set_line_wrap();
+       f->add (*doc);
+
        Gtk::VBox *vbox = manage (new VBox());
        vbox->pack_start (_a_view, false, false);
        vbox->pack_end (*edit_box, false, false);
+       vbox->pack_end (*f, false, false);
        vbox->show_all ();
 
        pages.pages ().push_back (Notebook_Helpers::TabElem (*vbox, "Action Scripts"));
@@ -91,28 +116,87 @@ LuaScriptManager::LuaScriptManager ()
        _c_del_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::del_callback_btn_clicked));
        _c_view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &LuaScriptManager::callback_selection_changed));
 
+       f = manage (new Frame (_("Description")));
+       doc = manage (new Label (
+                               _("Lua action hooks are event-triggered callbacks for the Editor/Mixer GUI. Once a script is registered it is automatically triggered by events to perform some task.")
+                               ));
+       doc->set_padding (5, 5);
+       doc->set_line_wrap();
+       f->add (*doc);
+
        vbox = manage (new VBox());
        vbox->pack_start (_c_view, false, false);
        vbox->pack_end (*edit_box, false, false);
+       vbox->pack_end (*f, false, false);
        vbox->show_all ();
 
        pages.pages ().push_back (Notebook_Helpers::TabElem (*vbox, "Action Hooks"));
 
+       /* session script page */
+
+       _s_store = ListStore::create (_s_model);
+       _s_view.set_model (_s_store);
+       _s_view.append_column (_("Name"), _s_model.name);
+       _s_view.get_column(0)->set_resizable (true);
+       _s_view.get_column(0)->set_expand (true);
+
+       edit_box = manage (new Gtk::HBox);
+       edit_box->set_spacing(3);
+       edit_box->pack_start (_s_add_button, true, true);
+       edit_box->pack_start (_s_del_button, true, true);
+
+       _s_add_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::add_sess_btn_clicked));
+       _s_del_button.signal_clicked().connect (sigc::mem_fun(*this, &LuaScriptManager::del_sess_btn_clicked));
+       _s_view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &LuaScriptManager::session_script_selection_changed));
+
+       f = manage (new Frame (_("Description")));
+       doc = manage (new Label (
+                               _("Lua session scripts are loaded into processing engine and run in realtime. They are called periodically at the start of every audio cycle in the realtime process context before any processing takes place.")
+                               ));
+       doc->set_padding (5, 5);
+       doc->set_line_wrap();
+       f->add (*doc);
+
+       vbox = manage (new VBox());
+       vbox->pack_start (_s_view, false, false);
+       vbox->pack_end (*edit_box, false, false);
+       vbox->pack_end (*f, false, false);
+       vbox->show_all ();
+
+       pages.pages ().push_back (Notebook_Helpers::TabElem (*vbox, "Session Scripts"));
+
+       /* global layout */
 
        add (pages);
        pages.show();
 
        setup_actions ();
        setup_callbacks ();
+       setup_session_scripts ();
 
        action_selection_changed ();
        callback_selection_changed ();
+       session_script_selection_changed ();
+}
+
+void
+LuaScriptManager::set_session (ARDOUR::Session *s)
+{
+       ArdourWindow::set_session (s);
+       setup_session_scripts ();
+       if (!_session) {
+               return;
+       }
+
+       _session->LuaScriptsChanged.connect (_session_script_connection,  invalidator (*this), boost::bind (&LuaScriptManager::setup_session_scripts, this), gui_context());
+       setup_session_scripts ();
 }
 
 void
 LuaScriptManager::session_going_away ()
 {
        ArdourWindow::session_going_away ();
+       _session_script_connection.disconnect ();
        hide_all();
 }
 
@@ -120,7 +204,7 @@ void
 LuaScriptManager::setup_actions ()
 {
        LuaInstance *li = LuaInstance::instance();
-       for (int i = 0; i < 9; ++i) {
+       for (int i = 0; i < MAX_LUA_ACTION_SCRIPTS; ++i) {
                std::string name;
                TreeModel::Row r = *_a_store->append ();
                r[_a_model.id] = i;
@@ -148,7 +232,7 @@ LuaScriptManager::action_selection_changed ()
 
        if (row && row[_a_model.enabled]) {
                _a_del_button.set_sensitive (true);
-               _a_edit_button.set_sensitive (false); // TODO
+               _a_edit_button.set_sensitive (true);
                _a_call_button.set_sensitive (true);
        } else {
                _a_del_button.set_sensitive (false);
@@ -198,20 +282,7 @@ LuaScriptManager::edit_action_btn_clicked ()
        if (!li->lua_action (id, name, script, args)) {
                return;
        }
-
-       // TODO text-editor window, update script directly
-
-       if (!LuaScripting::try_compile (script, args)) {
-               // compilation failed, keep editing
-               return;
-       }
-
-       if (li->set_lua_action (id, name, script, args)) {
-               // OK
-       } else {
-               // load failed,  keep editing..
-       }
-       action_selection_changed ();
+       LuaWindow::instance()->edit_script (name, script);
 }
 
 void
@@ -310,3 +381,61 @@ LuaScriptManager::set_callback_script_name (PBD::ID id, const std::string& name,
        }
        callback_selection_changed ();
 }
+
+
+void
+LuaScriptManager::setup_session_scripts ()
+{
+       _s_store->clear ();
+       if (!_session) {
+               return;
+       }
+       std::vector<std::string> reg = _session->registered_lua_functions ();
+       for (std::vector<string>::const_iterator i = reg.begin(); i != reg.end(); ++i) {
+               TreeModel::Row r = *_s_store->append ();
+               r[_s_model.name] = *i;
+       }
+       session_script_selection_changed ();
+}
+
+void
+LuaScriptManager::session_script_selection_changed ()
+{
+       if (!_session) {
+               _s_del_button.set_sensitive (false);
+               _s_add_button.set_sensitive (false);
+               return;
+       }
+       TreeModel::Row row = *(_s_view.get_selection()->get_selected());
+       if (row) {
+               _s_del_button.set_sensitive (true);
+       } else {
+               _s_del_button.set_sensitive (false);
+       }
+       _s_add_button.set_sensitive (true);
+}
+
+void
+LuaScriptManager::add_sess_btn_clicked ()
+{
+       if (!_session) {
+               return;
+       }
+       LuaInstance *li = LuaInstance::instance();
+       li->interactive_add (LuaScriptInfo::Session, -1);
+}
+
+void
+LuaScriptManager::del_sess_btn_clicked ()
+{
+       assert (_session);
+       TreeModel::Row row = *(_s_view.get_selection()->get_selected());
+       const std::string& name = row[_s_model.name];
+       try {
+               _session->unregister_lua_function (name);
+       } catch (luabridge::LuaException const& e) {
+               string msg = string_compose (_("Session script '%1' removal failed: %2"), name, e.what ());
+               MessageDialog am (msg);
+               am.run ();
+       }
+}