Add GUI to instantiate session-scripts
[ardour.git] / gtk2_ardour / ardour_ui.cc
index 1e87d4a988c1bc311a3ac26b5b72ede6b91a3114..a40d192e72ded259631b7896a1450927909e9364 100644 (file)
@@ -91,6 +91,8 @@
 #include "ardour/slave.h"
 #include "ardour/system_exec.h"
 
+#include "LuaBridge/LuaBridge.h"
+
 #ifdef WINDOWS_VST_SUPPORT
 #include <fst.h>
 #endif
@@ -124,6 +126,7 @@ typedef uint64_t microseconds_t;
 #include "keyboard.h"
 #include "keyeditor.h"
 #include "location_ui.h"
+#include "luawindow.h"
 #include "main_clock.h"
 #include "missing_file_dialog.h"
 #include "missing_plugin_dialog.h"
@@ -140,6 +143,7 @@ typedef uint64_t microseconds_t;
 #include "route_time_axis.h"
 #include "route_params_ui.h"
 #include "save_as_dialog.h"
+#include "script_selector.h"
 #include "session_dialog.h"
 #include "session_metadata_dialog.h"
 #include "session_option_editor.h"
@@ -226,12 +230,7 @@ libxml_structured_error_func (void* /* parsing_context*/,
 
 
 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
-<<<<<<< HEAD
-
        : Gtkmm2ext::UI (PROGRAM_NAME, X_("gui"), argcp, argvp)
-=======
-       : Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp)
->>>>>>> first compilable version of tabbable design.
        , session_loaded (false)
        , gui_object_state (new GUIObjectState)
        , primary_clock   (new MainClock (X_("primary"),   X_("transport"), true ))
@@ -268,6 +267,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        , last_key_press_time (0)
        , save_as_dialog (0)
        , meterbridge (0)
+       , luawindow (0)
        , rc_option_editor (0)
        , speaker_config_window (X_("speaker-config"), _("Speaker Configuration"))
        , add_route_dialog (X_("add-routes"), _("Add Tracks/Busses"))
@@ -293,6 +293,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        , _feedback_exists (false)
        , _log_not_acknowledged (LogLevelNone)
        , duplicate_routes_dialog (0)
+       , editor_visibility_button (S_("Window|Editor"))
+       , mixer_visibility_button (S_("Window|Mixer"))
+       , prefs_visibility_button (S_("Window|Preferences"))
 {
        Gtkmm2ext::init (localedir);
 
@@ -398,9 +401,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
                keyboard->set_state (*node, Stateful::loading_state_version);
        }
 
-       /* we don't like certain modifiers */
-       Bindings::set_ignored_state (GDK_LOCK_MASK|GDK_MOD2_MASK|GDK_MOD3_MASK);
-
        UIConfiguration::instance().reset_dpi ();
 
        TimeAxisViewItem::set_constant_heights ();
@@ -630,7 +630,7 @@ ARDOUR_UI::post_engine ()
 
        /* start the time-of-day-clock */
 
-#ifndef GTKOSX
+#ifndef __APPLE__
        /* OS X provides a nearly-always visible wallclock, so don't be stupid */
        update_wall_clock ();
        Glib::signal_timeout().connect_seconds (sigc::mem_fun(*this, &ARDOUR_UI::update_wall_clock), 1);
@@ -659,6 +659,7 @@ ARDOUR_UI::~ARDOUR_UI ()
                delete secondary_clock;
                delete _process_thread;
                delete meterbridge;
+               delete luawindow;
                delete editor;
                delete mixer;
                delete nsm;
@@ -2928,8 +2929,6 @@ ARDOUR_UI::load_from_application_api (const std::string& path)
                if (get_session_parameters (true, false)) {
                        exit (1);
                }
-
-               goto_editor_window ();
        }
 }
 
@@ -3934,6 +3933,88 @@ ARDOUR_UI::add_route (Gtk::Window* /* ignored */)
        }
 }
 
+void
+ARDOUR_UI::add_lua_script ()
+{
+       if (!_session) {
+               return;
+       }
+
+       LuaScriptInfoPtr spi;
+       ScriptSelector ss ("Add Lua Session Script", LuaScriptInfo::Session);
+       switch (ss.run ()) {
+               case Gtk::RESPONSE_ACCEPT:
+                       spi = ss.script();
+                       break;
+               default:
+                       return;
+       }
+
+       std::string script = "";
+
+       try {
+               script = Glib::file_get_contents (spi->path);
+       } catch (Glib::FileError e) {
+               string msg = string_compose (_("Cannot read session script '%1': %2"), spi->path, e.what());
+               MessageDialog am (msg);
+               am.run ();
+               return;
+       }
+
+       LuaScriptParamList lsp = LuaScripting::session_script_params (spi);
+       std::vector<std::string> reg = _session->registered_lua_functions ();
+
+       ScriptParameterDialog spd (_("Set Script Parameters"), spi, reg, lsp);
+       switch (spd.run ()) {
+               case Gtk::RESPONSE_ACCEPT:
+                       break;
+               default:
+                       return;
+       }
+
+       try {
+               _session->register_lua_function (spd.name(), script, lsp);
+       } catch (luabridge::LuaException const& e) {
+               string msg = string_compose (_("Session script '%1' instantiation failed: %2"), spd.name(), e.what ());
+               MessageDialog am (msg);
+               am.run ();
+       } catch (SessionException e) {
+               string msg = string_compose (_("Loading Session script '%1' failed: %2"), spd.name(), e.what ());
+               MessageDialog am (msg);
+               am.run ();
+       }
+}
+
+void
+ARDOUR_UI::remove_lua_script ()
+{
+       if (!_session) {
+               return;
+       }
+       if (_session->registered_lua_function_count () ==  0) {
+               string msg = _("There are no active Lua session scripts present in this session.");
+               MessageDialog am (msg);
+               am.run ();
+               return;
+       }
+
+       std::vector<std::string> reg = _session->registered_lua_functions ();
+       SessionScriptManager sm ("Remove Lua Session Script", reg);
+       switch (sm.run ()) {
+               case Gtk::RESPONSE_ACCEPT:
+                       break;
+               default:
+                       return;
+       }
+       try {
+               _session->unregister_lua_function (sm.name());
+       } catch (luabridge::LuaException const& e) {
+               string msg = string_compose (_("Session script '%1' removal failed: %2"), sm.name(), e.what ());
+               MessageDialog am (msg);
+               am.run ();
+       }
+}
+
 void
 ARDOUR_UI::stop_video_server (bool ask_confirm)
 {
@@ -5199,12 +5280,8 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
        GtkWindow* win = window.gobj();
        GtkWidget* focus = gtk_window_get_focus (win);
        bool special_handling_of_unmodified_accelerators = false;
-       /* consider all relevant modifiers but not LOCK or SHIFT */
        const guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK));
 
-       GdkModifierType modifier = GdkModifierType (ev->state);
-        modifier = GdkModifierType (modifier & gtk_accelerator_get_default_mod_mask());
-
         if (focus) {
 
                /* some widget has keyboard focus */
@@ -5220,14 +5297,15 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
                }
        }
 
-        DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 focus = %7 (%8) Key event: code = %2  state = %3 special handling ? %4 magic widget focus ? %5 focus widget %6 named %7\n",
+        DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 focus = %7 (%8) Key event: code = %2  state = %3 special handling ? %4 magic widget focus ? %5 focus widget %6 named %7 mods ? %8\n",
                                                           win,
                                                           ev->keyval,
                                                          show_gdk_event_state (ev->state),
                                                           special_handling_of_unmodified_accelerators,
                                                           Keyboard::some_magic_widget_has_focus(),
                                                          focus,
-                                                          (focus ? gtk_widget_get_name (focus) : "no focus widget")));
+                                                          (focus ? gtk_widget_get_name (focus) : "no focus widget"),
+                                                          ((ev->state & mask) ? "yes" : "no")));
 
        /* This exists to allow us to override the way GTK handles
           key events. The normal sequence is: