X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_ui.cc;h=fadbc0a7bbf3e9d4c4bd3233726cb272cd595ebe;hb=b98969be947e09e95028bbae32563604e19b81d7;hp=b0feef368619f5cd29952beac917b400f04aa88e;hpb=182cb897332d88e79b574136561c57bf6e7c85e9;p=ardour.git diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index b0feef3686..fadbc0a7bb 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -47,9 +47,10 @@ #include #include "pbd/gstdio_compat.h" -#include #include +#include #include +#include #include "pbd/error.h" #include "pbd/basename.h" @@ -61,21 +62,24 @@ #include "pbd/memento_command.h" #include "pbd/openuri.h" #include "pbd/stl_delete.h" +#include "pbd/types_convert.h" +#include "pbd/unwind.h" #include "pbd/file_utils.h" #include "pbd/localtime_r.h" #include "pbd/pthread_utils.h" #include "pbd/replace_all.h" +#include "pbd/scoped_file_descriptor.h" #include "pbd/xml++.h" #include "gtkmm2ext/application.h" #include "gtkmm2ext/bindings.h" #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/utils.h" -#include "gtkmm2ext/click_box.h" -#include "gtkmm2ext/fastmeter.h" -#include "gtkmm2ext/popup.h" #include "gtkmm2ext/window_title.h" +#include "widgets/fastmeter.h" +#include "widgets/prompter.h" + #include "ardour/ardour.h" #include "ardour/audio_backend.h" #include "ardour/audio_track.h" @@ -93,6 +97,7 @@ #include "ardour/profile.h" #include "ardour/recent_sessions.h" #include "ardour/record_enable_control.h" +#include "ardour/revision.h" #include "ardour/session_directory.h" #include "ardour/session_route.h" #include "ardour/session_state_utils.h" @@ -124,6 +129,7 @@ typedef uint64_t microseconds_t; #include "about.h" #include "editing.h" +#include "enums_convert.h" #include "actions.h" #include "add_route_dialog.h" #include "ambiguous_file_dialog.h" @@ -141,6 +147,7 @@ typedef uint64_t microseconds_t; #include "global_port_matrix.h" #include "gui_object.h" #include "gui_thread.h" +#include "idleometer.h" #include "keyboard.h" #include "keyeditor.h" #include "location_ui.h" @@ -151,12 +158,12 @@ typedef uint64_t microseconds_t; #include "missing_plugin_dialog.h" #include "mixer_ui.h" #include "meterbridge.h" +#include "meter_patterns.h" #include "mouse_cursors.h" #include "nsm.h" #include "opts.h" #include "pingback.h" #include "processor_box.h" -#include "prompter.h" #include "public_editor.h" #include "rc_option_editor.h" #include "route_time_axis.h" @@ -170,6 +177,7 @@ typedef uint64_t microseconds_t; #include "speaker_dialog.h" #include "splash.h" #include "startup.h" +#include "template_dialog.h" #include "time_axis_view_item.h" #include "time_info_box.h" #include "timers.h" @@ -185,6 +193,7 @@ using namespace ARDOUR; using namespace ARDOUR_UI_UTILS; using namespace PBD; using namespace Gtkmm2ext; +using namespace ArdourWidgets; using namespace Gtk; using namespace std; using namespace Editing; @@ -192,7 +201,7 @@ using namespace Editing; ARDOUR_UI *ARDOUR_UI::theArdourUI = 0; sigc::signal ARDOUR_UI::Clock; -sigc::signal ARDOUR_UI::CloseAllDialogs; +sigc::signal ARDOUR_UI::CloseAllDialogs; static bool ask_about_configuration_copy (string const & old_dir, string const & new_dir, int version) @@ -205,7 +214,7 @@ ask_about_configuration_copy (string const & old_dir, string const & new_dir, in Gtk::MESSAGE_INFO, Gtk::BUTTONS_YES_NO, true /* modal, though it hardly matters since it is the only window */ - ); + ); msg.set_default_response (Gtk::RESPONSE_YES); msg.show_all (); @@ -215,8 +224,8 @@ ask_about_configuration_copy (string const & old_dir, string const & new_dir, in static void libxml_generic_error_func (void* /* parsing_context*/, - const char* msg, - ...) + const char* msg, + ...) { va_list ap; char buf[2048]; @@ -257,6 +266,7 @@ libxml_structured_error_func (void* /* parsing_context*/, ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) : Gtkmm2ext::UI (PROGRAM_NAME, X_("gui"), argcp, argvp) , session_loaded (false) + , session_load_in_progress (false) , gui_object_state (new GUIObjectState) , primary_clock (new MainClock (X_("primary"), X_("transport"), true )) , secondary_clock (new MainClock (X_("secondary"), X_("secondary"), false)) @@ -273,6 +283,13 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , _initial_verbose_plugin_scan (false) , first_time_engine_run (true) , secondary_clock_spacer (0) + , roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)) + , stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)) + , goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)) + , goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)) + , auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)) + , play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)) + , rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)) , auto_input_button (ArdourButton::led_default_elements) , time_info_box (0) , auto_return_button (ArdourButton::led_default_elements) @@ -281,8 +298,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , solo_alert_button (_("Solo")) , feedback_alert_button (_("Feedback")) , error_alert_button ( ArdourButton::just_led_default_elements ) - , editor_meter(0) , editor_meter_peak_display() + , editor_meter(0) + , _suspend_editor_meter_callbacks (false) , _numpad_locate_happening (false) , _session_is_new (false) , last_key_press_time (0) @@ -298,6 +316,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , 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")) + , idleometer (X_("idle-o-meter"), _("Idle'o'Meter")) , 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)) @@ -324,6 +343,10 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) UIConfiguration::instance().post_gui_init (); if (ARDOUR::handle_old_configuration_files (boost::bind (ask_about_configuration_copy, _1, _2, _3))) { + { + /* "touch" the been-here-before path now that config has been migrated */ + PBD::ScopedFileDescriptor fout (g_open (been_here_before_path ().c_str(), O_CREAT|O_TRUNC|O_RDWR, 0666)); + } MessageDialog msg (string_compose (_("Your configuration files were copied. You can now restart %1."), PROGRAM_NAME), true); msg.run (); /* configuration was modified, exit immediately */ @@ -355,22 +378,13 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) boost::function pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1)); UIConfiguration::instance().map_parameters (pc); - Glib::RefPtr act; - - act = ActionManager::get_action ("Transport/Roll"); - roll_button.set_related_action (act); - act = ActionManager::get_action ("Transport/Stop"); - stop_button.set_related_action (act); - act = ActionManager::get_action ("Transport/GotoStart"); - goto_start_button.set_related_action (act); - act = ActionManager::get_action ("Transport/GotoEnd"); - goto_end_button.set_related_action (act); - act = ActionManager::get_action ("Transport/Loop"); - auto_loop_button.set_related_action (act); - act = ActionManager::get_action ("Transport/PlaySelection"); - play_selection_button.set_related_action (act); - act = ActionManager::get_action ("Transport/Record"); - rec_button.set_related_action (act); + roll_button.set_controllable (roll_controllable); + stop_button.set_controllable (stop_controllable); + goto_start_button.set_controllable (goto_start_controllable); + goto_end_button.set_controllable (goto_end_controllable); + auto_loop_button.set_controllable (auto_loop_controllable); + play_selection_button.set_controllable (play_selection_controllable); + rec_button.set_controllable (rec_controllable); roll_button.set_name ("transport button"); stop_button.set_name ("transport button"); @@ -451,7 +465,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) TimeAxisViewItem::set_constant_heights (); - /* Set this up so that our window proxies can register actions */ + /* Set this up so that our window proxies can register actions */ ActionManager::init (); @@ -474,6 +488,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) midi_port_matrix.set_state (*ui_xml, 0); export_video_dialog.set_state (*ui_xml, 0); lua_script_window.set_state (*ui_xml, 0); + idleometer.set_state (*ui_xml, 0); } /* Separate windows */ @@ -493,6 +508,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) WM::Manager::instance().register_window (&big_clock_window); WM::Manager::instance().register_window (&audio_port_matrix); WM::Manager::instance().register_window (&midi_port_matrix); + WM::Manager::instance().register_window (&idleometer); /* do not retain position for add route dialog */ add_route_dialog.set_state_mask (WindowProxy::Size); @@ -515,8 +531,8 @@ ARDOUR_UI::pre_release_dialog () ArdourDialog d (_("Pre-Release Warning"), true, false); d.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); - Label* label = manage (new Label); - label->set_markup (string_compose (_("Welcome to this pre-release build of %1 %2\n\n\ + Label* label = manage (new Label); + label->set_markup (string_compose (_("Welcome to this pre-release build of %1 %2\n\n\ There are still several issues and bugs to be worked on,\n\ as well as general workflow improvements, before this can be considered\n\ release software. So, a few guidelines:\n\ @@ -536,11 +552,11 @@ Full information on all the above can be found on the support page at\n\ http://ardour.org/support\n\ "), PROGRAM_NAME, VERSIONSTRING)); - d.get_vbox()->set_border_width (12); - d.get_vbox()->pack_start (*label, false, false, 12); - d.get_vbox()->show_all (); + d.get_vbox()->set_border_width (12); + d.get_vbox()->pack_start (*label, false, false, 12); + d.get_vbox()->show_all (); - d.run (); + d.run (); } GlobalPortMatrixWindow* @@ -676,6 +692,55 @@ ARDOUR_UI::post_engine () */ if (ARDOUR_COMMAND_LINE::show_key_actions) { + stringstream sstr; + Bindings::save_all_bindings_as_html (sstr); + + if (sstr.str().empty()) { + return; + } + gchar* file_name; + GError *err = NULL; + gint fd; + + if ((fd = g_file_open_tmp ("akprintXXXXXX.html", &file_name, &err)) < 0) { + if (err) { + error << string_compose (_("Could not open temporary file to print bindings (%1)"), err->message) << endmsg; + g_error_free (err); + } + return; + } + +#ifdef PLATFORM_WINDOWS + ::close (fd); +#endif + + err = NULL; + + if (!g_file_set_contents (file_name, sstr.str().c_str(), sstr.str().size(), &err)) { +#ifndef PLATFORM_WINDOWS + ::close (fd); +#endif + g_unlink (file_name); + if (err) { + error << string_compose (_("Could not save bindings to file (%1)"), err->message) << endmsg; + g_error_free (err); + } + return; + } + +#ifndef PLATFORM_WINDOWS + ::close (fd); +#endif + + PBD::open_uri (string_compose ("file:///%1", file_name)); + + halt_connection.disconnect (); + AudioEngine::instance()->stop (); + exit (0); + + } + + if (ARDOUR_COMMAND_LINE::show_actions) { vector paths; @@ -683,21 +748,70 @@ ARDOUR_UI::post_engine () vector tooltips; vector keys; vector > actions; + string ver_in = revision; + string ver = ver_in.substr(0, ver_in.find("-")); + + stringstream output; + output << "\n

Menu actions

" << endl; + output << "

\n Every single menu item in " << PROGRAM_NAME << "'s GUI is accessible by control" << endl; + output << " surfaces or scripts.\n

\n" << endl; + output << "

\n The list below shows all available values of action-name as of" << endl; + output << " " << PROGRAM_NAME << " " << ver << ". You can get the current list at any" << endl; + output << " time by running " << PROGRAM_NAME << " with the -A flag.\n

\n" << endl; + output << "\n " << endl; + output << " " << endl; + output << " \n " << endl; Gtkmm2ext::ActionMap::get_all_actions (paths, labels, tooltips, keys, actions); - vector::iterator k; vector::iterator p; + vector::iterator l; - for (p = paths.begin(), k = keys.begin(); p != paths.end(); ++k, ++p) { + for (p = paths.begin(), l = labels.begin(); p != paths.end(); ++p, ++l) { + output << " " << endl; + } + output << " \n
Action NameMenu Name
" << (*p).substr (9, string::npos); + output << "" << *l << "
" << endl; + + // output this mess to a browser for easiest X-platform use + // it is not pretty HTML, but it works and it's main purpose + // is to create raw html to fit in Ardour's manual with no editing + gchar* file_name; + GError *err = NULL; + gint fd; + + if ((fd = g_file_open_tmp ("akprintXXXXXX.html", &file_name, &err)) < 0) { + if (err) { + error << string_compose (_("Could not open temporary file to print bindings (%1)"), err->message) << endmsg; + g_error_free (err); + } + return; + } - if ((*k).empty()) { - cout << *p << endl; - } else { - cout << *p << " => " << *k << endl; +#ifdef PLATFORM_WINDOWS + ::close (fd); +#endif + + err = NULL; + + if (!g_file_set_contents (file_name, output.str().c_str(), output.str().size(), &err)) { +#ifndef PLATFORM_WINDOWS + ::close (fd); +#endif + g_unlink (file_name); + if (err) { + error << string_compose (_("Could not save bindings to file (%1)"), err->message) << endmsg; + g_error_free (err); } + return; } +#ifndef PLATFORM_WINDOWS + ::close (fd); +#endif + + PBD::open_uri (string_compose ("file:///%1", file_name)); + halt_connection.disconnect (); AudioEngine::instance()->stop (); exit (0); @@ -753,7 +867,7 @@ ARDOUR_UI::~ARDOUR_UI () delete gui_object_state; gui_object_state = 0; delete main_window_visibility; FastMeter::flush_pattern_cache (); - PixFader::flush_pattern_cache (); + ArdourFader::flush_pattern_cache (); } #ifndef NDEBUG @@ -807,6 +921,54 @@ ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/) return FALSE; } +void +ARDOUR_UI::set_transport_controllable_state (const XMLNode& node) +{ + std::string str; + + if (node.get_property ("roll", str)){ + roll_controllable->set_id (str); + } + if (node.get_property ("stop", str)) { + stop_controllable->set_id (str); + } + if (node.get_property ("goto-start", str)) { + goto_start_controllable->set_id (str); + } + if (node.get_property ("goto-end", str)) { + goto_end_controllable->set_id (str); + } + if (node.get_property ("auto-loop", str)) { + auto_loop_controllable->set_id (str); + } + if (node.get_property ("play-selection", str)) { + play_selection_controllable->set_id (str); + } + if (node.get_property ("rec", str)) { + rec_controllable->set_id (str); + } + if (node.get_property ("shuttle", str)) { + shuttle_box.controllable()->set_id (str); + } +} + +XMLNode& +ARDOUR_UI::get_transport_controllable_state () +{ + XMLNode* node = new XMLNode(X_("TransportControllables")); + + node->set_property (X_("roll"), roll_controllable->id()); + node->set_property (X_("stop"), stop_controllable->id()); + node->set_property (X_("goto-start"), goto_start_controllable->id()); + node->set_property (X_("goto-end"), goto_end_controllable->id()); + node->set_property (X_("auto-loop"), auto_loop_controllable->id()); + node->set_property (X_("play-selection"), play_selection_controllable->id()); + node->set_property (X_("rec"), rec_controllable->id()); + node->set_property (X_("shuttle"), shuttle_box.controllable()->id()); + + return *node; +} + void ARDOUR_UI::save_session_at_its_request (std::string snapshot_name) { @@ -1124,11 +1286,6 @@ ARDOUR_UI::starting () BootMessage (string_compose (_("%1 is ready for use"), PROGRAM_NAME)); - if (splash && splash->is_visible()) { - // in 1 second, hide the splash screen - Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000); - } - /* all other dialogs are created conditionally */ return 0; @@ -1769,10 +1926,6 @@ ARDOUR_UI::open_recent_session () can_return = false; } - if (splash && splash->is_visible()) { - // in 1 second, hide the splash screen - Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000); - } } bool @@ -1780,9 +1933,9 @@ ARDOUR_UI::check_audioengine (Gtk::Window& parent) { if (!AudioEngine::instance()->connected()) { MessageDialog msg (parent, string_compose ( - _("%1 is not connected to any audio backend.\n" - "You cannot open or close sessions in this condition"), - PROGRAM_NAME)); + _("%1 is not connected to any audio backend.\n" + "You cannot open or close sessions in this condition"), + PROGRAM_NAME)); pop_back_splash (msg); msg.run (); return false; @@ -2397,6 +2550,15 @@ ARDOUR_UI::transport_rec_preroll () editor->rec_with_preroll (); } +void +ARDOUR_UI::transport_rec_count_in () +{ + if (!_session) { + return; + } + editor->rec_with_count_in (); +} + void ARDOUR_UI::transport_rewind (int option) { @@ -2541,11 +2703,15 @@ void ARDOUR_UI::blink_handler (bool blink_on) { transport_rec_enable_blink (blink_on); - solo_blink (blink_on); sync_blink (blink_on); + + if (!UIConfiguration::instance().get_blink_alert_indicators()) { + blink_on = true; + } + error_blink (blink_on); + solo_blink (blink_on); audition_blink (blink_on); feedback_blink (blink_on); - error_blink (blink_on); } void @@ -2600,6 +2766,33 @@ ARDOUR_UI::save_session_as () return; } + if (_session->dirty()) { + vector actions; + actions.push_back (_("Abort save-as")); + actions.push_back (_("Don't save now, just save-as")); + actions.push_back (_("Save it first")); + switch (ask_about_saving_session(actions)) { + case -1: + return; + break; + case 1: + if (save_state_canfail ("")) { + MessageDialog msg (_main_window, + string_compose (_("\ +%1 was unable to save your session.\n\n\ +If you still wish to proceeed, please use the\n\n\ +\"Don't save now\" option."), PROGRAM_NAME)); + pop_back_splash(msg); + msg.run (); + return; + } + // no break + case 0: + _session->remove_pending_capture_state (); + break; + } + } + if (!save_as_dialog) { save_as_dialog = new SaveAsDialog; } @@ -2634,16 +2827,17 @@ ARDOUR_UI::save_session_as () */ ArdourDialog progress_dialog (_("Save As"), true); + ScopedConnection c; if (sa.include_media && sa.copy_media) { - Gtk::Label label; - Gtk::ProgressBar progress_bar; + Gtk::Label* label = manage (new Gtk::Label()); + Gtk::ProgressBar* progress_bar = manage (new Gtk::ProgressBar ()); - progress_dialog.get_vbox()->pack_start (label); - progress_dialog.get_vbox()->pack_start (progress_bar); - label.show (); - progress_bar.show (); + progress_dialog.get_vbox()->pack_start (*label); + progress_dialog.get_vbox()->pack_start (*progress_bar); + label->show (); + progress_bar->show (); /* this signal will be emitted from within this, the calling thread, * after every file is copied. It provides information on percentage @@ -2651,9 +2845,7 @@ ARDOUR_UI::save_session_as () * copied so far, and the total number to copy. */ - ScopedConnection c; - - sa.Progress.connect_same_thread (c, boost::bind (&ARDOUR_UI::save_as_progress_update, this, _1, _2, _3, &label, &progress_bar)); + sa.Progress.connect_same_thread (c, boost::bind (&ARDOUR_UI::save_as_progress_update, this, _1, _2, _3, label, progress_bar)); progress_dialog.show_all (); progress_dialog.present (); @@ -2676,7 +2868,6 @@ ARDOUR_UI::save_session_as () if (!sa.include_media && sa.switch_to) { unload_session (false); load_session (sa.final_session_folder_name, sa.new_name); - hide_splash (); } } @@ -2716,13 +2907,16 @@ ARDOUR_UI::quick_snapshot_session (bool switch_to_it) time (&n); localtime_r (&n, &local_time); strftime (timebuf, sizeof(timebuf), "%FT%H.%M.%S", &local_time); + if (switch_to_it && _session->dirty ()) { + save_state_canfail (""); + } save_state (timebuf, switch_to_it); } bool -ARDOUR_UI::process_snapshot_session_prompter (ArdourPrompter& prompter, bool switch_to_it) +ARDOUR_UI::process_snapshot_session_prompter (Prompter& prompter, bool switch_to_it) { string snapname; @@ -2734,7 +2928,7 @@ ARDOUR_UI::process_snapshot_session_prompter (ArdourPrompter& prompter, bool swi char illegal = Session::session_name_is_legal(snapname); if (illegal) { MessageDialog msg (string_compose (_("To ensure compatibility with various systems\n" - "snapshot names may not contain a '%1' character"), illegal)); + "snapshot names may not contain a '%1' character"), illegal)); msg.run (); return false; } @@ -2768,8 +2962,34 @@ ARDOUR_UI::process_snapshot_session_prompter (ArdourPrompter& prompter, bool swi void ARDOUR_UI::snapshot_session (bool switch_to_it) { - ArdourPrompter prompter (true); + if (switch_to_it && _session->dirty()) { + vector actions; + actions.push_back (_("Abort saving snapshot")); + actions.push_back (_("Don't save now, just snapshot")); + actions.push_back (_("Save it first")); + switch (ask_about_saving_session(actions)) { + case -1: + return; + break; + case 1: + if (save_state_canfail ("")) { + MessageDialog msg (_main_window, + string_compose (_("\ +%1 was unable to save your session.\n\n\ +If you still wish to proceeed, please use the\n\n\ +\"Don't save now\" option."), PROGRAM_NAME)); + pop_back_splash(msg); + msg.run (); + return; + } + // no break + case 0: + _session->remove_pending_capture_state (); + break; + } + } + Prompter prompter (true); prompter.set_name ("Prompter"); prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); if (switch_to_it) { @@ -2813,7 +3033,7 @@ ARDOUR_UI::rename_session () return; } - ArdourPrompter prompter (true); + Prompter prompter (true); string name; prompter.set_name ("Prompter"); @@ -2834,7 +3054,7 @@ ARDOUR_UI::rename_session () if (illegal) { MessageDialog msg (string_compose (_("To ensure compatibility with various systems\n" - "session names may not contain a '%1' character"), illegal)); + "session names may not contain a '%1' character"), illegal)); msg.run (); goto again; } @@ -2955,7 +3175,7 @@ ARDOUR_UI::transport_rec_enable_blink (bool onoff) } bool -ARDOUR_UI::process_save_template_prompter (ArdourPrompter& prompter) +ARDOUR_UI::process_save_template_prompter (Prompter& prompter) { string name; @@ -2984,7 +3204,7 @@ ARDOUR_UI::process_save_template_prompter (ArdourPrompter& prompter) void ARDOUR_UI::save_template () { - ArdourPrompter prompter (true); + Prompter prompter (true); if (!check_audioengine (_main_window)) { return; @@ -3010,6 +3230,12 @@ ARDOUR_UI::save_template () } } +void ARDOUR_UI::manage_templates () +{ + TemplateDialog td; + td.run(); +} + void ARDOUR_UI::edit_metadata () { @@ -3184,7 +3410,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri /* if there is already a session, relabel the button on the SessionDialog so that we don't Quit directly */ - cancel_not_quit = (_session != 0); + cancel_not_quit = (_session != 0) && !quit_on_cancel; if (_session && _session->dirty()) { if (unload_session (false)) { @@ -3253,14 +3479,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() + 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; } @@ -3277,7 +3500,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri session_path = session_dialog.session_folder (); if (nsm) { - likely_new = true; + likely_new = true; } if (!likely_new) { @@ -3314,12 +3537,12 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri if (session_name[0] == G_DIR_SEPARATOR || #ifdef PLATFORM_WINDOWS - (session_name.length() > 3 && session_name[1] == ':' && session_name[2] == G_DIR_SEPARATOR) + (session_name.length() > 3 && session_name[1] == ':' && session_name[2] == G_DIR_SEPARATOR) #else - (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == G_DIR_SEPARATOR) || - (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == G_DIR_SEPARATOR) + (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == G_DIR_SEPARATOR) || + (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == G_DIR_SEPARATOR) #endif - ) + ) { /* absolute path or cwd-relative path specified for session name: infer session folder @@ -3337,9 +3560,9 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri if (illegal) { MessageDialog msg (session_dialog, - string_compose (_("To ensure compatibility with various systems\n" - "session names may not contain a '%1' character"), - illegal)); + string_compose (_("To ensure compatibility with various systems\n" + "session names may not contain a '%1' character"), + illegal)); msg.run (); ARDOUR_COMMAND_LINE::session_name = ""; // cancel that continue; @@ -3376,7 +3599,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri if (illegal) { pop_back_splash (session_dialog); MessageDialog msg (session_dialog, string_compose(_("To ensure compatibility with various systems\n" - "session names may not contain a '%1' character"), illegal)); + "session names may not contain a '%1' character"), illegal)); msg.run (); ARDOUR_COMMAND_LINE::session_name = ""; // cancel that continue; @@ -3385,7 +3608,12 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri _session_is_new = true; } - if (likely_new && template_name.empty()) { + if (!template_name.empty() && template_name.substr (0, 11) == "urn:ardour:") { + + ret = build_session_from_dialog (session_dialog, session_path, session_name); + meta_session_setup (template_name.substr (11)); + + } else if (likely_new && template_name.empty()) { ret = build_session_from_dialog (session_dialog, session_path, session_name); @@ -3432,10 +3660,6 @@ ARDOUR_UI::close_session() if (get_session_parameters (true, false)) { exit (1); } - if (splash && splash->is_visible()) { - // in 1 second, hide the splash screen - Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000); - } } /** @param snap_name Snapshot name (without .ardour suffix). @@ -3444,6 +3668,18 @@ ARDOUR_UI::close_session() int ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, std::string mix_template) { + /* load_session calls flush_pending() which allows + * GUI interaction and potentially loading another session + * (that was easy via snapshot sidebar). + * Recursing into load_session() from load_session() and recusive + * event loops causes all kind of crashes. + */ + assert (!session_load_in_progress); + if (session_load_in_progress) { + return -1; + } + PBD::Unwinder lsu (session_load_in_progress, true); + Session *new_session; int unload_status; int retval = -1; @@ -3517,8 +3753,8 @@ 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"), - path, snap_name), + _("Session \"%1 (snapshot %2)\" did not load successfully"), + path, snap_name), true, Gtk::MESSAGE_INFO, BUTTONS_OK); @@ -3558,6 +3794,16 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, msg.hide (); } + + /* Now the session been created, add the transport controls */ + new_session->add_controllable(roll_controllable); + new_session->add_controllable(stop_controllable); + new_session->add_controllable(goto_start_controllable); + new_session->add_controllable(goto_end_controllable); + new_session->add_controllable(auto_loop_controllable); + new_session->add_controllable(play_selection_controllable); + new_session->add_controllable(rec_controllable); + set_session (new_session); session_loaded = true; @@ -3580,7 +3826,22 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, #endif retval = 0; + if (!mix_template.empty ()) { + /* if mix_template is given, assume this is a new session */ + string metascript = Glib::build_filename (mix_template, "template.lua"); + meta_session_setup (metascript); + } + + out: + /* For successful session load the splash is hidden by ARDOUR_UI::first_idle, + * which is queued by set_session(). + * If session-loading fails we hide it explicitly. + * This covers both cases in a central place. + */ + if (retval) { + hide_splash (); + } return retval; } @@ -3649,8 +3910,8 @@ ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, /* Put the playhead at 0 and scroll fully left */ n = new_session->instant_xml (X_("Editor")); if (n) { - n->add_property (X_("playhead"), X_("0")); - n->add_property (X_("left-frame"), X_("0")); + n->set_property (X_("playhead"), X_("0")); + n->set_property (X_("left-frame"), X_("0")); } set_session (new_session); @@ -3662,6 +3923,33 @@ ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, return 0; } +void +ARDOUR_UI::meta_session_setup (const std::string& script_path) +{ + if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) { + return; + } + + LuaState lua; + lua.sandbox (true); + + lua_State* L = lua.getState(); + LuaInstance::register_classes (L); + LuaBindings::set_session (L, _session); + luabridge::push (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, "session_setup"); + if (fn.isFunction()) { + fn (); + } + } catch (luabridge::LuaException const& e) { } +} + void ARDOUR_UI::launch_chat () { @@ -3774,8 +4062,8 @@ ARDOUR_UI::show_splash () void ARDOUR_UI::hide_splash () { - delete splash; - splash = 0; + delete splash; + splash = 0; } void @@ -3787,12 +4075,12 @@ ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* lis if (removed == 0) { MessageDialog msgd (_main_window, - _("No files were ready for clean-up"), - true, - Gtk::MESSAGE_INFO, - Gtk::BUTTONS_OK); + _("No files were ready for clean-up"), + true, + Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK); msgd.set_title (_("Clean-up")); - msgd.set_secondary_text (_("If this seems suprising, \n\ + msgd.set_secondary_text (_("If this seems surprising, \n\ check for any existing snapshots.\n\ These may still include regions that\n\ require some unused files to continue to exist.")); @@ -3804,12 +4092,12 @@ require some unused files to continue to exist.")); ArdourDialog results (_("Clean-up"), true, false); struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord { - CleanupResultsModelColumns() { - add (visible_name); - add (fullpath); - } - Gtk::TreeModelColumn visible_name; - Gtk::TreeModelColumn fullpath; + CleanupResultsModelColumns() { + add (visible_name); + add (fullpath); + } + Gtk::TreeModelColumn visible_name; + Gtk::TreeModelColumn fullpath; }; @@ -4039,7 +4327,7 @@ PresentationInfo::order_t ARDOUR_UI::translate_order (RouteDialogs::InsertAt place) { if (editor->get_selection().tracks.empty()) { - return PresentationInfo::max_order; + return place == RouteDialogs::First ? 0 : PresentationInfo::max_order; } PresentationInfo::order_t order_hint = PresentationInfo::max_order; @@ -4087,7 +4375,7 @@ void ARDOUR_UI::add_route () { if (!add_route_dialog.get (false)) { - add_route_dialog->signal_response().connect (sigc::mem_fun (*this, &ARDOUR_UI::add_route_dialog_finished)); + add_route_dialog->signal_response().connect (sigc::mem_fun (*this, &ARDOUR_UI::add_route_dialog_response)); } if (!_session) { @@ -4104,18 +4392,19 @@ ARDOUR_UI::add_route () } void -ARDOUR_UI::add_route_dialog_finished (int r) +ARDOUR_UI::add_route_dialog_response (int r) { int count; - add_route_dialog->hide(); - switch (r) { - case RESPONSE_ACCEPT: - break; - default: - return; - break; + case AddRouteDialog::Add: + break; + case AddRouteDialog::AddAndClose: + add_route_dialog->ArdourDialog::on_response (r); + break; + default: + add_route_dialog->ArdourDialog::on_response (r); + return; } if ((count = add_route_dialog->count()) <= 0) { @@ -4176,89 +4465,6 @@ ARDOUR_UI::add_route_dialog_finished (int r) } } -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; - } - ss.hide(); - - 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 = LuaScriptParams::script_params (spi, "sess_params"); - std::vector 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 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) { @@ -4378,9 +4584,8 @@ ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg) if (icsd_docroot == X_("/") || icsd_docroot == X_("C:\\")) { Config->set_video_advanced_setup(false); } else { - std::ostringstream osstream; - osstream << "http://127.0.0.1:" << video_server_dialog->get_listenport() << "/"; - Config->set_video_server_url(osstream.str()); + std::string url_str = "http://127.0.0.1:" + to_string(video_server_dialog->get_listenport()) + "/"; + Config->set_video_server_url(url_str); Config->set_video_server_docroot(icsd_docroot); Config->set_video_advanced_setup(true); } @@ -4512,11 +4717,11 @@ ARDOUR_UI::add_video (Gtk::Window* float_window) if (video_timeline->video_file_info(path, local_file)) { XMLNode* node = new XMLNode(X_("Videotimeline")); - node->add_property (X_("Filename"), path); - node->add_property (X_("AutoFPS"), auto_set_session_fps?X_("1"):X_("0")); - node->add_property (X_("LocalFile"), local_file?X_("1"):X_("0")); + node->set_property (X_("Filename"), path); + node->set_property (X_("AutoFPS"), auto_set_session_fps); + node->set_property (X_("LocalFile"), local_file); if (orig_local_file) { - node->add_property (X_("OriginalVideoFile"), orig_path); + node->set_property (X_("OriginalVideoFile"), orig_path); } else { node->remove_property (X_("OriginalVideoFile")); } @@ -4736,8 +4941,8 @@ ARDOUR_UI::create_xrun_marker (framepos_t where) void ARDOUR_UI::halt_on_xrun_message () { - cerr << "HALT on xrun\n"; - MessageDialog msg (_main_window, _("Recording was stopped because your system could not keep up.")); + cerr << "HALT on xrun\n"; + MessageDialog msg (_main_window, _("Recording was stopped because your system could not keep up.")); msg.run (); } @@ -4992,10 +5197,10 @@ audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual case RESPONSE_ACCEPT: return 0; default: - break; + break; } - return 1; + return 1; } void @@ -5016,6 +5221,10 @@ Menu > Window > Audio/Midi Setup"), void ARDOUR_UI::use_config () { + XMLNode* node = Config->extra_xml (X_("TransportControllables")); + if (node) { + set_transport_controllable_state (*node); + } } void @@ -5087,6 +5296,15 @@ ARDOUR_UI::first_idle () editor->first_idle(); } + /* in 1 second, hide the splash screen + * + * Consider hiding it *now*. If a user opens opens a dialog + * during that one second while the splash is still visible, + * the dialog will push-back the splash. + * Closing the dialog later will pop it back. + */ + Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000); + Keyboard::set_can_save_keybindings (true); return false; } @@ -5099,9 +5317,9 @@ ARDOUR_UI::store_clock_modes () for (vector::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) { XMLNode* child = new XMLNode (X_("Clock")); - child->add_property (X_("name"), (*x)->name()); - child->add_property (X_("mode"), enum_2_string ((*x)->mode())); - child->add_property (X_("on"), ((*x)->off() ? X_("no") : X_("yes"))); + child->set_property (X_("name"), (*x)->name()); + child->set_property (X_("mode"), (*x)->mode()); + child->set_property (X_("on"), (*x)->on()); node->add_child_nocopy (*child); } @@ -5110,6 +5328,86 @@ ARDOUR_UI::store_clock_modes () _session->set_dirty (); } +ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp) + : Controllable (name), ui (u), type(tp) +{ + +} + +void +ARDOUR_UI::TransportControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /*group_override*/) +{ + if (val < 0.5) { + /* do nothing: these are radio-style actions */ + return; + } + + const char *action = 0; + + switch (type) { + case Roll: + action = X_("Roll"); + break; + case Stop: + action = X_("Stop"); + break; + case GotoStart: + action = X_("GotoStart"); + break; + case GotoEnd: + action = X_("GotoEnd"); + break; + case AutoLoop: + action = X_("Loop"); + break; + case PlaySelection: + action = X_("PlaySelection"); + break; + case RecordEnable: + action = X_("Record"); + break; + default: + break; + } + + if (action == 0) { + return; + } + + Glib::RefPtr act = ActionManager::get_action ("Transport", action); + + if (act) { + act->activate (); + } +} + +double +ARDOUR_UI::TransportControllable::get_value (void) const +{ + float val = 0.0; + + switch (type) { + case Roll: + break; + case Stop: + break; + case GotoStart: + break; + case GotoEnd: + break; + case AutoLoop: + break; + case PlaySelection: + break; + case RecordEnable: + break; + default: + break; + } + + return val; +} + void ARDOUR_UI::setup_profile () { @@ -5205,15 +5503,61 @@ ARDOUR_UI::session_format_mismatch (std::string xml_path, std::string backup_pat const char* end_mono = ""; MessageDialog msg (string_compose (_("%4This is a session from an older version of %3%5\n\n" - "%3 has copied the old session file\n\n%6%1%7\n\nto\n\n%6%2%7\n\n" - "From now on, use the backup copy with older versions of %3"), - xml_path, backup_path, PROGRAM_NAME, - start_big, end_big, - start_mono, end_mono), true); + "%3 has copied the old session file\n\n%6%1%7\n\nto\n\n%6%2%7\n\n" + "From now on, use the backup copy with older versions of %3"), + xml_path, backup_path, PROGRAM_NAME, + start_big, end_big, + start_mono, end_mono), true); msg.run (); } +void +ARDOUR_UI::add_editor_meter_type_item (Menu_Helpers::MenuList& items, RadioMenuItem::Group& group, string const & name, MeterType type) +{ + using namespace Menu_Helpers; + + items.push_back (RadioMenuElem (group, name, sigc::bind (sigc::mem_fun (editor_meter, &LevelMeterHBox::set_meter_type), type))); + RadioMenuItem* i = dynamic_cast (&items.back ()); + i->set_active (editor_meter->meter_type () == type); +} + +void +ARDOUR_UI::popup_editor_meter_menu (GdkEventButton* ev) +{ + using namespace Gtk::Menu_Helpers; + + Gtk::Menu* m = manage (new Menu); + MenuList& items = m->items (); + + RadioMenuItem::Group group; + + _suspend_editor_meter_callbacks = true; + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterPeak), MeterPeak); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterPeak0dB), MeterPeak0dB); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterKrms), MeterKrms); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterIEC1DIN), MeterIEC1DIN); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterIEC1NOR), MeterIEC1NOR); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterIEC2BBC), MeterIEC2BBC); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterIEC2EBU), MeterIEC2EBU); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterK20), MeterK20); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterK14), MeterK14); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterK12), MeterK12); + add_editor_meter_type_item (items, group, ArdourMeter::meter_type_string(MeterVU), MeterVU); + + m->popup (ev->button, ev->time); + _suspend_editor_meter_callbacks = false; +} + +bool +ARDOUR_UI::editor_meter_button_press (GdkEventButton* ev) +{ + if (ev->button == 3 && editor_meter) { + popup_editor_meter_menu (ev); + return true; + } + return false; +} void ARDOUR_UI::reset_peak_display () @@ -5248,19 +5592,27 @@ ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate) audio_midi_setup->set_desired_sample_rate (desired_sample_rate); audio_midi_setup->set_position (WIN_POS_CENTER); - if (Config->get_try_autostart_engine () || getenv ("TRY_AUTOSTART_ENGINE")) { - audio_midi_setup->try_autostart (); - if (ARDOUR::AudioEngine::instance()->running()) { - return 0; + if (desired_sample_rate != 0) { + if (Config->get_try_autostart_engine () || getenv ("TRY_AUTOSTART_ENGINE")) { + audio_midi_setup->try_autostart (); + if (ARDOUR::AudioEngine::instance()->running()) { + return 0; + } } } while (true) { int response = audio_midi_setup->run(); - printf("RESPONSE %d\n", response); switch (response) { case Gtk::RESPONSE_DELETE_EVENT: - return -1; + // after latency callibration engine may run, + // Running() signal was emitted, but dialog will not + // have emitted a response. The user needs to close + // the dialog -> Gtk::RESPONSE_DELETE_EVENT + if (!AudioEngine::instance()->running()) { + return -1; + } + // fall through default: if (!AudioEngine::instance()->running()) { continue; @@ -5383,7 +5735,7 @@ ARDOUR_UI::audioengine_became_silent () void ARDOUR_UI::hide_application () { - Application::instance ()-> hide (); + Application::instance ()-> hide (); } void @@ -5509,7 +5861,7 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey bool special_handling_of_unmodified_accelerators = false; const guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK)); - if (focus) { + if (focus) { /* some widget has keyboard focus */ @@ -5532,13 +5884,13 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey } } - DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 [title = %9] 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, - Gtkmm2ext::show_gdk_event_state (ev->state), + DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 [title = %9] 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, + Gtkmm2ext::show_gdk_event_state (ev->state), special_handling_of_unmodified_accelerators, Keyboard::some_magic_widget_has_focus(), - focus, + focus, (focus ? gtk_widget_get_name (focus) : "no focus widget"), ((ev->state & mask) ? "yes" : "no"), window.get_title())); @@ -5579,7 +5931,7 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey /* no special handling or there are modifiers in effect: accelerate first */ - DEBUG_TRACE (DEBUG::Accelerators, "\tactivate, then propagate\n"); + DEBUG_TRACE (DEBUG::Accelerators, "\tactivate, then propagate\n"); DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tevent send-event:%1 time:%2 length:%3 name %7 string:%4 hardware_keycode:%5 group:%6\n", ev->send_event, ev->time, ev->length, ev->string, ev->hardware_keycode, ev->group, gdk_keyval_name (ev->keyval))); @@ -5614,12 +5966,12 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey return true; } - DEBUG_TRACE (DEBUG::Accelerators, "\tnot accelerated, now propagate\n"); + DEBUG_TRACE (DEBUG::Accelerators, "\tnot accelerated, now propagate\n"); - if (gtk_window_propagate_key_event (win, ev)) { - DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate handled\n"); - return true; - } + if (gtk_window_propagate_key_event (win, ev)) { + DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate handled\n"); + return true; + } } else {