NO-OP: mark various state property names as explicitly non-translated
[ardour.git] / gtk2_ardour / ardour_ui.cc
index 486559816c2e53579ed59a88f5799be7e18b5b8a..0e7565285607633f0f279bdea310e0545f12150a 100644 (file)
@@ -86,7 +86,8 @@
 #include "ardour/audioengine.h"
 #include "ardour/audiofilesource.h"
 #include "ardour/automation_watch.h"
-#include "ardour/diskstream.h"
+#include "ardour/disk_reader.h"
+#include "ardour/disk_writer.h"
 #include "ardour/filename_extensions.h"
 #include "ardour/filesystem_paths.h"
 #include "ardour/ltc_file_reader.h"
@@ -169,6 +170,7 @@ typedef uint64_t microseconds_t;
 #include "route_time_axis.h"
 #include "route_params_ui.h"
 #include "save_as_dialog.h"
+#include "save_template_dialog.h"
 #include "script_selector.h"
 #include "session_archive_dialog.h"
 #include "session_dialog.h"
@@ -395,8 +397,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
        rec_button.set_name ("transport recenable button");
        midi_panic_button.set_name ("transport button");
 
-       ARDOUR::Diskstream::DiskOverrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context());
-       ARDOUR::Diskstream::DiskUnderrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_underrun_handler, this), gui_context());
+       ARDOUR::DiskWriter::Overrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context());
+       ARDOUR::DiskReader::Underrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_underrun_handler, this), gui_context());
 
        ARDOUR::Session::VersionMismatch.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_format_mismatch, this, _1, _2), gui_context());
 
@@ -2016,16 +2018,6 @@ ARDOUR_UI::open_session ()
        }
 }
 
-void
-ARDOUR_UI::session_add_vca (const string& name_template, uint32_t n)
-{
-       if (!_session) {
-               return;
-       }
-
-       _session->vca_manager().create_vca (n, name_template);
-}
-
 void
 ARDOUR_UI::session_add_mixed_track (
                const ChanCount& input,
@@ -2038,10 +2030,7 @@ ARDOUR_UI::session_add_mixed_track (
                Plugin::PresetRecord* pset,
                ARDOUR::PresentationInfo::order_t order)
 {
-       if (_session == 0) {
-               warning << _("You cannot add a track without a session already loaded.") << endmsg;
-               return;
-       }
+       assert (_session);
 
        if (Profile->get_mixbus ()) {
                strict_io = true;
@@ -2131,10 +2120,7 @@ ARDOUR_UI::session_add_audio_route (
        list<boost::shared_ptr<AudioTrack> > tracks;
        RouteList routes;
 
-       if (_session == 0) {
-               warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
-               return;
-       }
+       assert (_session);
 
        try {
                if (track) {
@@ -3174,60 +3160,43 @@ ARDOUR_UI::transport_rec_enable_blink (bool onoff)
        }
 }
 
-bool
-ARDOUR_UI::process_save_template_prompter (Prompter& prompter)
+void
+ARDOUR_UI::save_template_dialog_response (int response, SaveTemplateDialog* d)
 {
-       string name;
+       if (response == RESPONSE_ACCEPT) {
+               const string name = d->get_template_name ();
+               const string desc = d->get_description ();
 
-       prompter.get_result (name);
-
-       if (name.length()) {
-               int failed = _session->save_template (name);
+               int failed = _session->save_template (name, desc);
 
                if (failed == -2) { /* file already exists. */
-                       bool overwrite = overwrite_file_dialog (prompter,
+                       bool overwrite = overwrite_file_dialog (*d,
                                                                _("Confirm Template Overwrite"),
                                                                _("A template already exists with that name. Do you want to overwrite it?"));
 
                        if (overwrite) {
-                               _session->save_template (name, true);
+                               _session->save_template (name, desc, true);
                        }
                        else {
-                               return false;
+                               d->show ();
+                               return;
                        }
                }
        }
-
-       return true;
+       delete d;
 }
 
 void
 ARDOUR_UI::save_template ()
 {
-       Prompter prompter (true);
-
        if (!check_audioengine (_main_window)) {
                return;
        }
 
-       prompter.set_name (X_("Prompter"));
-       prompter.set_title (_("Save Template"));
-       prompter.set_prompt (_("Name for template:"));
-       prompter.set_initial_text(_session->name() + _("-template"));
-       prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
-
-       bool finished = false;
-       while (!finished) {
-               switch (prompter.run()) {
-               case RESPONSE_ACCEPT:
-                       finished = process_save_template_prompter (prompter);
-                       break;
-
-               default:
-                       finished = true;
-                       break;
-               }
-       }
+       const std::string desc = SessionMetadata::Metadata()->description ();
+       SaveTemplateDialog* d = new SaveTemplateDialog (_session->name (), desc);
+       d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::save_template_dialog_response), d));
+       d->show ();
 }
 
 void ARDOUR_UI::manage_templates ()
@@ -3285,44 +3254,14 @@ ARDOUR_UI::build_session_from_dialog (SessionDialog& sd, const std::string& sess
        BusProfile bus_profile;
 
        if (nsm) {
-
                bus_profile.master_out_channels = 2;
-               bus_profile.input_ac = AutoConnectPhysical;
-               bus_profile.output_ac = AutoConnectMaster;
-               bus_profile.requested_physical_in = 0; // use all available
-               bus_profile.requested_physical_out = 0; // use all available
-
        } else {
-
                /* get settings from advanced section of NSD */
-
-               if (sd.create_master_bus()) {
-                       bus_profile.master_out_channels = (uint32_t) sd.master_channel_count();
-               } else {
-                       bus_profile.master_out_channels = 0;
-               }
-
-               if (sd.connect_inputs()) {
-                       bus_profile.input_ac = AutoConnectPhysical;
-               } else {
-                       bus_profile.input_ac = AutoConnectOption (0);
-               }
-
-               bus_profile.output_ac = AutoConnectOption (0);
-
-               if (sd.connect_outputs ()) {
-                       if (sd.connect_outs_to_master()) {
-                               bus_profile.output_ac = AutoConnectMaster;
-                       } else if (sd.connect_outs_to_physical()) {
-                               bus_profile.output_ac = AutoConnectPhysical;
-                       }
-               }
-
-               bus_profile.requested_physical_in = (uint32_t) sd.input_limit_count();
-               bus_profile.requested_physical_out = (uint32_t) sd.output_limit_count();
+               bus_profile.master_out_channels = (uint32_t) sd.master_channel_count();
        }
 
-       if (build_session (session_path, session_name, bus_profile)) {
+       // NULL profile: no master, no monitor
+       if (build_session (session_path, session_name, bus_profile.master_out_channels > 0 ? &bus_profile : NULL)) {
                return -1;
        }
 
@@ -3479,15 +3418,11 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
                                break;
                        default:
                                if (quit_on_cancel) {
-                                       // JE - Currently (July 2014) this section can only get reached if the
-                                       // user quits from the main 'Session Setup' dialog (i.e. reaching this
-                                       // point does NOT indicate an abnormal termination). Therefore, let's
-                                       // behave gracefully (i.e. let's do some cleanup) before we call exit()
-                                       assert (!_session);
+                                       ARDOUR_UI::finish ();
+                                       Gtkmm2ext::Application::instance()->cleanup();
                                        ARDOUR::cleanup ();
                                        pthread_cancel_all ();
-
-                                       exit (1);
+                                       return -1; // caller is responsible to call exit()
                                } else {
                                        return ret;
                                }
@@ -3736,7 +3671,7 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name,
        }
        catch (SessionException e) {
                MessageDialog msg (string_compose(
-                                          _("Session \"%1 (snapshot %2)\" did not load successfully: %3"),
+                                          _("Session \"%1 (snapshot %2)\" did not load successfully:\n%3"),
                                           path, snap_name, e.what()),
                                   true,
                                   Gtk::MESSAGE_INFO,
@@ -3757,7 +3692,7 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name,
        catch (...) {
 
                MessageDialog msg (string_compose(
-                                          _("Session \"%1 (snapshot %2)\" did not load successfully"),
+                                          _("Session \"%1 (snapshot %2)\" did not load successfully."),
                                           path, snap_name),
                                   true,
                                   Gtk::MESSAGE_INFO,
@@ -3850,7 +3785,7 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name,
 }
 
 int
-ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, BusProfile& bus_profile)
+ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, BusProfile* bus_profile)
 {
        Session *new_session;
        int x;
@@ -3867,7 +3802,7 @@ ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name,
        _session_is_new = true;
 
        try {
-               new_session = new Session (*AudioEngine::instance(), path, snap_name, &bus_profile);
+               new_session = new Session (*AudioEngine::instance(), path, snap_name, bus_profile);
        }
 
        catch (SessionException e) {
@@ -3927,6 +3862,109 @@ ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name,
        return 0;
 }
 
+
+static void _lua_print (std::string s) {
+#ifndef NDEBUG
+       std::cout << "LuaInstance: " << s << "\n";
+#endif
+       PBD::info << "LuaInstance: " << s << endmsg;
+}
+
+std::map<std::string, std::string>
+ARDOUR_UI::route_setup_info (const std::string& script_path)
+{
+       std::map<std::string, std::string> rv;
+
+       if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
+               return rv;
+       }
+
+       LuaState lua;
+       lua.Print.connect (&_lua_print);
+       lua.sandbox (true);
+
+       lua_State* L = lua.getState();
+       LuaInstance::register_classes (L);
+       LuaBindings::set_session (L, _session);
+       luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
+       lua_setglobal (L, "Editor");
+
+       lua.do_command ("function ardour () end");
+       lua.do_file (script_path);
+
+       try {
+               luabridge::LuaRef fn = luabridge::getGlobal (L, "route_setup");
+               if (!fn.isFunction ()) {
+                       return rv;
+               }
+               luabridge::LuaRef rs = fn ();
+               if (!rs.isTable ()) {
+                       return rv;
+               }
+               for (luabridge::Iterator i(rs); !i.isNil (); ++i) {
+                       if (!i.key().isString()) {
+                               continue;
+                       }
+                       std::string key = i.key().tostring();
+                       if (i.value().isString() || i.value().isNumber() || i.value().isBoolean()) {
+                               rv[key] = i.value().tostring();
+                       }
+               }
+       } catch (luabridge::LuaException const& e) {
+               cerr << "LuaException:" << e.what () << endl;
+       } catch (...) { }
+       return rv;
+}
+
+void
+ARDOUR_UI::meta_route_setup (const std::string& script_path)
+{
+       if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
+               return;
+       }
+       assert (add_route_dialog);
+
+       int count;
+       if ((count = add_route_dialog->count()) <= 0) {
+               return;
+       }
+
+       LuaState lua;
+       lua.Print.connect (&_lua_print);
+       lua.sandbox (true);
+
+       lua_State* L = lua.getState();
+       LuaInstance::register_classes (L);
+       LuaBindings::set_session (L, _session);
+       luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
+       lua_setglobal (L, "Editor");
+
+       lua.do_command ("function ardour () end");
+       lua.do_file (script_path);
+
+       luabridge::LuaRef args (luabridge::newTable (L));
+
+       args["name"]       = add_route_dialog->name_template ();
+       args["insert_at"]  = translate_order (add_route_dialog->insert_at());
+       args["group"]      = add_route_dialog->route_group ();
+       args["strict_io"]  = add_route_dialog->use_strict_io ();
+       args["instrument"] = add_route_dialog->requested_instrument ();
+       args["track_mode"] = add_route_dialog->mode ();
+       args["channels"]   = add_route_dialog->channel_count ();
+       args["how_many"]   = count;
+
+       try {
+               luabridge::LuaRef fn = luabridge::getGlobal (L, "factory");
+               if (fn.isFunction()) {
+                       fn (args)();
+               }
+       } catch (luabridge::LuaException const& e) {
+               cerr << "LuaException:" << e.what () << endl;
+       } catch (...) {
+               display_insufficient_ports_message ();
+       }
+}
+
 void
 ARDOUR_UI::meta_session_setup (const std::string& script_path)
 {
@@ -3935,6 +3973,7 @@ ARDOUR_UI::meta_session_setup (const std::string& script_path)
        }
 
        LuaState lua;
+       lua.Print.connect (&_lua_print);
        lua.sandbox (true);
 
        lua_State* L = lua.getState();
@@ -3947,11 +3986,15 @@ ARDOUR_UI::meta_session_setup (const std::string& script_path)
        lua.do_file (script_path);
 
        try {
-               luabridge::LuaRef fn = luabridge::getGlobal (L, "session_setup");
+               luabridge::LuaRef fn = luabridge::getGlobal (L, "factory");
                if (fn.isFunction()) {
-                       fn ();
+                       fn ()();
                }
-       } catch (luabridge::LuaException const& e) { }
+       } catch (luabridge::LuaException const& e) {
+               cerr << "LuaException:" << e.what () << endl;
+       } catch (...) {
+               display_insufficient_ports_message ();
+       }
 }
 
 void
@@ -4398,10 +4441,16 @@ ARDOUR_UI::add_route ()
 void
 ARDOUR_UI::add_route_dialog_response (int r)
 {
+       if (!_session) {
+               warning << _("You cannot add tracks or busses without a session already loaded.") << endmsg;
+               return;
+       }
+
        int count;
 
        switch (r) {
        case AddRouteDialog::Add:
+               add_route_dialog->reset_name_edited ();
                break;
        case AddRouteDialog::AddAndClose:
                add_route_dialog->ArdourDialog::on_response (r);
@@ -4411,26 +4460,31 @@ ARDOUR_UI::add_route_dialog_response (int r)
                return;
        }
 
+       std::string template_path = add_route_dialog->get_template_path();
+       if (!template_path.empty() && template_path.substr (0, 11) == "urn:ardour:") {
+               meta_route_setup (template_path.substr (11));
+               return;
+       }
+
        if ((count = add_route_dialog->count()) <= 0) {
                return;
        }
 
        PresentationInfo::order_t order = translate_order (add_route_dialog->insert_at());
-       string template_path = add_route_dialog->track_template();
+       const string name_template = add_route_dialog->name_template ();
        DisplaySuspender ds;
 
-       if (!template_path.empty()) {
-               if (add_route_dialog->name_template_is_default())  {
-                       _session->new_route_from_template (count, order, template_path, string());
+       if (!template_path.empty ()) {
+               if (add_route_dialog->name_template_is_default ()) {
+                       _session->new_route_from_template (count, order, template_path, string ());
                } else {
-                       _session->new_route_from_template (count, order, template_path, add_route_dialog->name_template());
+                       _session->new_route_from_template (count, order, template_path, name_template);
                }
                return;
        }
 
        ChanCount input_chan= add_route_dialog->channels ();
        ChanCount output_chan;
-       string name_template = add_route_dialog->name_template ();
        PluginInfoPtr instrument = add_route_dialog->requested_instrument ();
        RouteGroup* route_group = add_route_dialog->route_group ();
        AutoConnectOption oac = Config->get_output_auto_connect();
@@ -4449,22 +4503,22 @@ ARDOUR_UI::add_route_dialog_response (int r)
 
        switch (add_route_dialog->type_wanted()) {
        case AddRouteDialog::AudioTrack:
-               session_add_audio_track (input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template, strict_io, order);
+               session_add_audio_route (true, input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template, strict_io, order);
                break;
        case AddRouteDialog::MidiTrack:
-               session_add_midi_track (route_group, count, name_template, strict_io, instrument, 0, order);
+               session_add_midi_route (true, route_group, count, name_template, strict_io, instrument, 0, order);
                break;
        case AddRouteDialog::MixedTrack:
                session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, strict_io, instrument, 0, order);
                break;
        case AddRouteDialog::AudioBus:
-               session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template, strict_io, order);
+               session_add_audio_route (false, input_chan.n_audio(), output_chan.n_audio(), ARDOUR::Normal, route_group, count, name_template, strict_io, order);
                break;
        case AddRouteDialog::MidiBus:
                session_add_midi_bus (route_group, count, name_template, strict_io, instrument, 0, order);
                break;
        case AddRouteDialog::VCAMaster:
-               session_add_vca (name_template, count);
+               _session->vca_manager().create_vca (count, name_template);
                break;
        }
 }