test workaround for OSX IK-Multimedia Plugin GUIs.
[ardour.git] / gtk2_ardour / ardour_ui.cc
index 9e48335ff7959b86191bbc69140da3b572104ec3..e1bcd06b7c48817e8916f6c297fc49dcfdc2d988 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
 #include "ardour/audio_unit.h"
 #endif
 
+// fix for OSX (nsm.h has a check function, AU/Apple defines check)
+#ifdef check
+#undef check
+#endif
+
 #include "timecode/time.h"
 
 typedef uint64_t microseconds_t;
@@ -124,6 +131,8 @@ typedef uint64_t microseconds_t;
 #include "keyboard.h"
 #include "keyeditor.h"
 #include "location_ui.h"
+#include "lua_script_manager.h"
+#include "luawindow.h"
 #include "main_clock.h"
 #include "missing_file_dialog.h"
 #include "missing_plugin_dialog.h"
@@ -140,6 +149,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"
@@ -263,6 +273,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"))
@@ -271,6 +282,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        , route_params (X_("inspector"), _("Tracks and Busses"))
        , audio_midi_setup (X_("audio-midi-setup"), _("Audio/MIDI Setup"))
        , export_video_dialog (X_("video-export"), _("Video Export Dialog"))
+       , lua_script_window (X_("script-manager"), _("Script Manager"))
        , session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this))
        , add_video_dialog (X_("add-video"), _("Add Video"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this))
        , bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this))
@@ -422,6 +434,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
                audio_port_matrix.set_state (*ui_xml, 0);
                midi_port_matrix.set_state (*ui_xml, 0);
                export_video_dialog.set_state (*ui_xml, 0);
+               lua_script_window.set_state (*ui_xml, 0);
        }
 
        /* Separate windows */
@@ -435,6 +448,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        WM::Manager::instance().register_window (&route_params);
        WM::Manager::instance().register_window (&audio_midi_setup);
        WM::Manager::instance().register_window (&export_video_dialog);
+       WM::Manager::instance().register_window (&lua_script_window);
        WM::Manager::instance().register_window (&bundle_manager);
        WM::Manager::instance().register_window (&location_ui);
        WM::Manager::instance().register_window (&big_clock_window);
@@ -649,15 +663,16 @@ ARDOUR_UI::~ARDOUR_UI ()
 
        if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
                // don't bother at 'real' exit. the OS cleans up for us.
-               delete big_clock;
-               delete primary_clock;
-               delete secondary_clock;
-               delete _process_thread;
-               delete meterbridge;
-               delete editor;
-               delete mixer;
-               delete nsm;
-               delete gui_object_state;
+               delete big_clock; big_clock = 0;
+               delete primary_clock; primary_clock = 0;
+               delete secondary_clock; secondary_clock = 0;
+               delete _process_thread; _process_thread = 0;
+               delete meterbridge; meterbridge = 0;
+               delete luawindow; luawindow = 0;
+               delete editor; editor = 0;
+               delete mixer; mixer = 0;
+               delete nsm; nsm = 0;
+               delete gui_object_state; gui_object_state = 0;
                FastMeter::flush_pattern_cache ();
                PixFader::flush_pattern_cache ();
        }
@@ -1791,6 +1806,31 @@ restart with more ports."), PROGRAM_NAME));
        }
 }
 
+void
+ARDOUR_UI::session_add_midi_bus (RouteGroup* route_group, uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
+{
+
+       if (_session == 0) {
+               warning << _("You cannot add a track without a session already loaded.") << endmsg;
+               return;
+       }
+
+       try {
+               RouteList routes = _session->new_midi_route (route_group, how_many, name_template, instrument);
+               if (routes.size() != how_many) {
+                       error << string_compose(P_("could not create %1 new Midi Bus", "could not create %1 new Midi Busses", how_many), how_many) << endmsg;
+               }
+
+       }
+       catch (...) {
+               MessageDialog msg (_main_window,
+                                  string_compose (_("There are insufficient ports available\n\
+to create a new track or bus.\n\
+You should save %1, exit and\n\
+restart with more ports."), PROGRAM_NAME));
+               msg.run ();
+       }
+}
 
 void
 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
@@ -1800,6 +1840,8 @@ ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t
 
        if (disk) {
                session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, instrument);
+       } else {
+               session_add_midi_bus (route_group, how_many, name_template, instrument);
        }
 }
 
@@ -3924,6 +3966,91 @@ ARDOUR_UI::add_route (Gtk::Window* /* ignored */)
        case AddRouteDialog::AudioBus:
                session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template);
                break;
+       case AddRouteDialog::MidiBus:
+               session_add_midi_bus (route_group, count, name_template, instrument);
+               break;
+       }
+}
+
+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 ();
        }
 }
 
@@ -5186,6 +5313,21 @@ ARDOUR_UI::key_event_handler (GdkEventKey* ev, Gtk::Window* event_window)
        return key_press_focus_accelerator_handler (*window, ev, bindings);
 }
 
+static Gtkmm2ext::Bindings*
+get_bindings_from_widget_heirarchy (GtkWidget* w)
+{
+       void* p;
+
+       while (w) {
+               if ((p = g_object_get_data (G_OBJECT(w), "ardour-bindings")) != 0) {
+                       break;
+               }
+               w = gtk_widget_get_parent (w);
+       }
+
+       return reinterpret_cast<Gtkmm2ext::Bindings*> (p);
+}
+
 bool
 ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev, Gtkmm2ext::Bindings* bindings)
 {
@@ -5206,6 +5348,14 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
                         */
 
                        special_handling_of_unmodified_accelerators = true;
+
+               } else {
+
+                       Gtkmm2ext::Bindings* focus_bindings = get_bindings_from_widget_heirarchy (focus);
+                       if (focus_bindings) {
+                               bindings = focus_bindings;
+                               DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Switch bindings based on focus widget, now using %1\n", bindings->name()));
+                       }
                }
        }
 
@@ -5264,7 +5414,7 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
 
                if (bindings) {
 
-                       DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tusing Ardour bindings %1 for this event\n", bindings));
+                       DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tusing Ardour bindings %1 @ %2 for this event\n", bindings->name(), bindings));
 
                        if (bindings->activate (k, Bindings::Press)) {
                                DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
@@ -5327,7 +5477,7 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey
 void
 ARDOUR_UI::load_bindings ()
 {
-       if ((global_bindings = Bindings::get_bindings ("global", global_actions)) == 0) {
+       if ((global_bindings = Bindings::get_bindings (X_("Global"), global_actions)) == 0) {
                error << _("Global keybindings are missing") << endmsg;
        }
 }