X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_ui.cc;h=246d19a96918ccd559e6b5867316eb77cc0c6ee5;hb=adea8ab68fc8a29984264a4a17ad7cf74439c521;hp=865fba97dbf5a71f99485d94a58711fb8402e492;hpb=b8e4c446374bcb2c47b35f1f9e2ee5dd7cfba6c3;p=ardour.git diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 865fba97db..246d19a969 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -19,6 +19,7 @@ #ifdef WAF_BUILD #include "gtk2ardour-config.h" +#include "gtk2ardour-version.h" #endif #include @@ -50,9 +51,10 @@ #include "pbd/enumwriter.h" #include "pbd/memento_command.h" #include "pbd/openuri.h" +#include "pbd/stl_delete.h" #include "pbd/file_utils.h" #include "pbd/localtime_r.h" -#include "pbd/system_exec.h" +#include "pbd/pthread_utils.h" #include "gtkmm2ext/application.h" #include "gtkmm2ext/bindings.h" @@ -81,10 +83,14 @@ #include "ardour/session_state_utils.h" #include "ardour/session_utils.h" #include "ardour/slave.h" +#include "ardour/system_exec.h" #ifdef WINDOWS_VST_SUPPORT #include #endif +#ifdef AUDIOUNIT_SUPPORT +#include "ardour/audio_unit.h" +#endif #include "timecode/time.h" @@ -137,6 +143,7 @@ typedef uint64_t microseconds_t; #include "i18n.h" using namespace ARDOUR; +using namespace ARDOUR_UI_UTILS; using namespace PBD; using namespace Gtkmm2ext; using namespace Gtk; @@ -148,6 +155,7 @@ UIConfiguration *ARDOUR_UI::ui_config = 0; sigc::signal ARDOUR_UI::Blink; sigc::signal ARDOUR_UI::RapidScreenUpdate; sigc::signal ARDOUR_UI::SuperRapidScreenUpdate; +sigc::signal ARDOUR_UI::FPSUpdate; sigc::signal ARDOUR_UI::Clock; sigc::signal ARDOUR_UI::CloseAllDialogs; @@ -187,9 +195,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , follow_edits_button (ArdourButton::led_default_elements) , auto_input_button (ArdourButton::led_default_elements) - , auditioning_alert_button (_("audition")) - , solo_alert_button (_("solo")) - , feedback_alert_button (_("feedback")) + , auditioning_alert_button (_("Audition")) + , solo_alert_button (_("Solo")) + , feedback_alert_button (_("Feedback")) , editor_meter(0) , editor_meter_peak_display() @@ -219,6 +227,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) splash = 0; + _numpad_locate_happening = false; + if (theArdourUI == 0) { theArdourUI = this; } @@ -260,10 +270,6 @@ 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"); - goto_start_button.set_tweaks (ArdourButton::ShowClick); - goto_end_button.set_tweaks (ArdourButton::ShowClick); - midi_panic_button.set_tweaks (ArdourButton::ShowClick); - last_configure_time= 0; last_peak_grab = 0; @@ -307,9 +313,13 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) /* also plugin scan messages */ ARDOUR::PluginScanMessage.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::plugin_scan_dialog, this, _1, _2, _3), gui_context()); + ARDOUR::PluginScanTimeout.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::plugin_scan_timeout, this, _1), gui_context()); ARDOUR::GUIIdle.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::gui_idle_handler, this), gui_context()); + Config->ParameterChanged.connect ( forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::set_flat_buttons, this), gui_context() ); + set_flat_buttons(); + /* lets get this party started */ setup_gtk_ardour_enums (); @@ -476,6 +486,14 @@ ARDOUR_UI::post_engine () { /* Things to be done once (and once ONLY) after we have a backend running in the AudioEngine */ +#ifdef AUDIOUNIT_SUPPORT + std::string au_msg; + if (AUPluginInfo::au_get_crashlog(au_msg)) { + popup_error(_("Audio Unit Plugin Scan Failed. Automatic AU scanning has been disabled. Please see the log window for further details.")); + error << _("Audio Unit Plugin Scan Failed:") << endmsg; + info << au_msg << endmsg; + } +#endif ARDOUR::init_post_engine (); @@ -487,8 +505,6 @@ ARDOUR_UI::post_engine () _tooltips.enable(); - ActionManager::load_menus (); - if (setup_windows ()) { throw failed_constructor (); } @@ -549,9 +565,12 @@ ARDOUR_UI::post_engine () Glib::signal_timeout().connect_seconds (sigc::mem_fun(*this, &ARDOUR_UI::update_wall_clock), 1); #endif - Config->ParameterChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context()); - boost::function pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1)); - Config->map_parameters (pc); + { + DisplaySuspender ds; + Config->ParameterChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context()); + boost::function pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1)); + Config->map_parameters (pc); + } } ARDOUR_UI::~ARDOUR_UI () @@ -561,6 +580,16 @@ ARDOUR_UI::~ARDOUR_UI () } stop_video_server(); + + 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 gui_object_state; + FastMeter::flush_pattern_cache (); + } } void @@ -754,6 +783,7 @@ ARDOUR_UI::starting () try { audio_midi_setup.get (true); } catch (...) { + std::cerr << "audio-midi engine setup failed."<< std::endl; return -1; } @@ -840,6 +870,7 @@ ARDOUR_UI::starting () const bool new_session_required = (ARDOUR_COMMAND_LINE::new_session || brand_new_user); if (get_session_parameters (false, new_session_required, ARDOUR_COMMAND_LINE::load_template)) { + std::cerr << "Cannot get session parameters."<< std::endl; return -1; } } @@ -986,7 +1017,10 @@ If you still wish to quit, please use the\n\n\ second_connection.disconnect (); point_one_second_connection.disconnect (); +#ifndef PLATFORM_WINDOWS point_zero_something_second_connection.disconnect(); +#endif + fps_connection.disconnect(); } delete ARDOUR_UI::instance()->video_timeline; @@ -1001,8 +1035,6 @@ If you still wish to quit, please use the\n\n\ close_all_dialogs (); - loading_message (string_compose (_("Please wait while %1 cleans up..."), PROGRAM_NAME)); - if (_session) { // _session->set_deletion_in_progress (); _session->set_clean (); @@ -1129,14 +1161,55 @@ ARDOUR_UI::every_point_zero_something_seconds () float mpeak = editor_meter->update_meters(); if (mpeak > editor_meter_max_peak) { if (mpeak >= Config->get_meter_peak()) { - editor_meter_peak_display.set_name ("meterbridge peakindicator on"); - editor_meter_peak_display.set_elements((ArdourButton::Element) (ArdourButton::Edge|ArdourButton::Body)); + editor_meter_peak_display.set_active_state ( Gtkmm2ext::ExplicitActive ); } } } return TRUE; } +gint +ARDOUR_UI::every_fps () +{ + FPSUpdate(); /* EMIT_SIGNAL */ +#ifdef PLATFORM_WINDOWS + every_point_zero_something_seconds(); +#endif + return TRUE; +} + +void +ARDOUR_UI::set_fps_timeout_connection () +{ + unsigned int interval = 40; + if (!_session) return; + if (_session->timecode_frames_per_second() != 0) { + /* ideally we'll use a select() to sleep and not accumulate + * idle time to provide a regular periodic signal. + * See linux_vst_gui_support.cc 'elapsed_time_ms'. + * However, that'll require a dedicated thread and cross-thread + * signals to the GUI Thread.. + */ + interval = floor(500. /* update twice per FPS, since Glib::signal_timeout is very irregular */ + * _session->frame_rate() / _session->nominal_frame_rate() + / _session->timecode_frames_per_second() + ); +#ifdef PLATFORM_WINDOWS + // the smallest windows scheduler time-slice is ~15ms. + // periodic GUI timeouts shorter than that will cause + // WaitForSingleObject to spinlock (100% of one CPU Core) + // and gtk never enters idle mode. + // also changing timeBeginPeriod(1) does not affect that in + // any beneficial way, so we just limit the max rate for now. + interval = std::max(30u, interval); // at most ~33Hz. +#else + interval = std::max(8u, interval); // at most 120Hz. +#endif + } + fps_connection.disconnect(); + fps_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_fps), interval); +} + void ARDOUR_UI::update_sample_rate (framecnt_t) { @@ -1414,7 +1487,7 @@ ARDOUR_UI::redisplay_recent_sessions () get_state_files_in_directory (*i, state_file_paths); - vector* states; + vector states; vector item; string fullpath = *i; @@ -1431,8 +1504,9 @@ ARDOUR_UI::redisplay_recent_sessions () } /* now get available states for this session */ + states = Session::possible_states (fullpath); - if ((states = Session::possible_states (fullpath)) == 0) { + if (states.empty()) { /* no state file? */ continue; } @@ -1441,14 +1515,14 @@ ARDOUR_UI::redisplay_recent_sessions () Gtk::TreeModel::Row row = *(recent_session_model->append()); - row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath); row[recent_session_columns.fullpath] = fullpath; row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath); if (state_file_names.size() > 1) { + // multiple session files in the session directory - show the directory name. + row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath); // add the children - for (std::vector::iterator i2 = state_file_names.begin(); i2 != state_file_names.end(); ++i2) { @@ -1459,6 +1533,9 @@ ARDOUR_UI::redisplay_recent_sessions () child_row[recent_session_columns.fullpath] = fullpath; child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath); } + } else { + // only a single session file in the directory - show its actual name. + row[recent_session_columns.visible_name] = state_file_names.front (); } } @@ -1657,10 +1734,10 @@ ARDOUR_UI::session_add_mixed_track (const ChanCount& input, const ChanCount& out catch (...) { MessageDialog msg (*editor, - string_compose (_("There are insufficient JACK ports available\n\ + string_compose (_("There are insufficient ports available\n\ to create a new track or bus.\n\ You should save %1, exit and\n\ -restart JACK with more ports."), PROGRAM_NAME)); +restart with more ports."), PROGRAM_NAME)); msg.run (); } } @@ -1718,10 +1795,10 @@ ARDOUR_UI::session_add_audio_route ( catch (...) { MessageDialog msg (*editor, - string_compose (_("There are insufficient JACK ports available\n\ + string_compose (_("There are insufficient ports available\n\ to create a new track or bus.\n\ You should save %1, exit and\n\ -restart JACK with more ports."), PROGRAM_NAME)); +restart with more ports."), PROGRAM_NAME)); pop_back_splash (msg); msg.run (); } @@ -1826,10 +1903,39 @@ ARDOUR_UI::transport_stop () _session->request_stop (false, true); } +/** Check if any tracks are record enabled. If none are, record enable all of them. + * @return true if track record-enabled status was changed, false otherwise. + */ +bool +ARDOUR_UI::trx_record_enable_all_tracks () +{ + if (!_session) { + return false; + } + + boost::shared_ptr rl = _session->get_tracks (); + bool none_record_enabled = true; + + for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) { + boost::shared_ptr t = boost::dynamic_pointer_cast (*r); + assert (t); + + if (t->record_enabled()) { + none_record_enabled = false; + break; + } + } + + if (none_record_enabled) { + _session->set_record_enabled (rl, true, Session::rt_cleanup); + } + + return none_record_enabled; +} + void ARDOUR_UI::transport_record (bool roll) { - if (_session) { switch (_session->record_status()) { case Session::Disabled: @@ -1838,6 +1944,9 @@ ARDOUR_UI::transport_record (bool roll) msg.run (); return; } + if (Profile->get_trx()) { + roll = trx_record_enable_all_tracks (); + } _session->maybe_enable_record (); if (roll) { transport_roll (); @@ -1883,13 +1992,26 @@ ARDOUR_UI::transport_roll () bool rolling = _session->transport_rolling(); if (_session->get_play_loop()) { - /* XXX it is not possible to just leave seamless loop and keep - playing at present (nov 4th 2009) + + /* If loop playback is not a mode, then we should cancel + it when this action is requested. If it is a mode + we just leave it in place. */ - if (!Config->get_seamless_loop()) { - _session->request_play_loop (false, true); - } - } else if (_session->get_play_range () && !Config->get_always_play_range()) { + + if (!Config->get_loop_is_mode()) { + /* XXX it is not possible to just leave seamless loop and keep + playing at present (nov 4th 2009) + */ + if (!Config->get_seamless_loop()) { + /* stop loop playback and stop rolling */ + _session->request_play_loop (false, true); + } else if (rolling) { + /* stop loop playback but keep rolling */ + _session->request_play_loop (false, false); + } + } + + } else if (_session->get_play_range () ) { /* stop playing a range if we currently are */ _session->request_play_range (0, true); } @@ -1945,7 +2067,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) /* disk buffers are normal, so we can keep playing */ affect_transport = false; } - _session->request_play_loop (false, true); + _session->request_play_loop (false, affect_transport); } else if (_session->get_play_range ()) { affect_transport = false; _session->request_play_range (0, true); @@ -1956,10 +2078,10 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) if (rolling) { _session->request_stop (with_abort, true); } else { - if ( Config->get_always_play_range() ) { + if ( Config->get_follow_edits() && ( editor->get_selection().time.front().start == _session->transport_frame() ) ) { //if playhead is exactly at the start of a range, we can assume it was placed there by follow_edits _session->request_play_range (&editor->get_selection().time, true); + _session->set_requested_return_frame( editor->get_selection().time.front().start ); //force an auto-return here } - _session->request_transport_speed (1.0f); } } @@ -1976,16 +2098,23 @@ ARDOUR_UI::toggle_session_auto_loop () if (_session->get_play_loop()) { - if (_session->transport_rolling()) { + /* looping enabled, our job is to disable it */ - _session->request_locate (looploc->start(), true); - _session->request_play_loop (false); + _session->request_play_loop (false); + } else { + + /* looping not enabled, our job is to enable it. + + loop-is-NOT-mode: this action always starts the transport rolling. + loop-IS-mode: this action simply sets the loop play mechanism, but + does not start transport. + */ + if (Config->get_loop_is_mode()) { + _session->request_play_loop (true, false); } else { - _session->request_play_loop (false); + _session->request_play_loop (true, true); } - } else { - _session->request_play_loop (true); } //show the loop markers @@ -2113,7 +2242,11 @@ ARDOUR_UI::map_transport_state () auto_loop_button.set_active (true); play_selection_button.set_active (false); - roll_button.set_active (false); + if (Config->get_loop_is_mode()) { + roll_button.set_active (true); + } else { + roll_button.set_active (false); + } } else { @@ -2122,7 +2255,7 @@ ARDOUR_UI::map_transport_state () auto_loop_button.set_active (false); } - if (Config->get_always_play_range()) { + if (Config->get_follow_edits()) { /* light up both roll and play-selection if they are joined */ roll_button.set_active (true); play_selection_button.set_active (true); @@ -2135,7 +2268,11 @@ ARDOUR_UI::map_transport_state () stop_button.set_active (true); roll_button.set_active (false); play_selection_button.set_active (false); - auto_loop_button.set_active (false); + if (Config->get_loop_is_mode ()) { + auto_loop_button.set_active (_session->get_play_loop()); + } else { + auto_loop_button.set_active (false); + } update_disk_space (); } } @@ -2143,7 +2280,7 @@ ARDOUR_UI::map_transport_state () void ARDOUR_UI::update_clocks () { - if (!editor || !editor->dragging_playhead()) { + if (editor && !editor->dragging_playhead()) { Clock (_session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */ } } @@ -2152,7 +2289,7 @@ void ARDOUR_UI::start_clocking () { if (Config->get_super_rapid_clock_update()) { - clock_signal_connection = SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks)); + clock_signal_connection = FPSUpdate.connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks)); } else { clock_signal_connection = RapidScreenUpdate.connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks)); } @@ -2414,7 +2551,7 @@ ARDOUR_UI::transport_rec_enable_blink (bool onoff) if (onoff) { rec_button.set_active_state (Gtkmm2ext::ExplicitActive); } else { - rec_button.set_active_state (Gtkmm2ext::ImplicitActive); + rec_button.set_active_state (Gtkmm2ext::Off); } } else if (r == Session::Recording && h) { rec_button.set_active_state (Gtkmm2ext::ExplicitActive); @@ -2651,6 +2788,13 @@ 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::cleanup (); + pthread_cancel_all (); + exit (1); } else { return ret; @@ -2689,8 +2833,14 @@ 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) +#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() > 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 from what was given. @@ -2927,7 +3077,9 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, #ifdef WINDOWS_VST_SUPPORT fst_stop_threading(); #endif + flush_pending (); + #ifdef WINDOWS_VST_SUPPORT fst_start_threading(); #endif @@ -2999,6 +3151,8 @@ ARDOUR_UI::launch_chat () { #ifdef __APPLE__ open_uri("http://webchat.freenode.net/?channels=ardour-osx"); +#elif defined PLATFORM_WINDOWS + open_uri("http://webchat.freenode.net/?channels=ardour-windows"); #else open_uri("http://webchat.freenode.net/?channels=ardour"); #endif @@ -3355,9 +3509,8 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) setup_order_hint(); - PBD::ScopedConnection idle_connection; - string template_path = add_route_dialog->track_template(); + DisplaySuspender ds; if (!template_path.empty()) { if (add_route_dialog->name_template_is_default()) { @@ -3398,8 +3551,6 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template); break; } - - /* idle connection will end at scope end */ } void @@ -3473,18 +3624,18 @@ ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg) if (icsd_docroot.empty()) {icsd_docroot = X_("/");} GStatBuf sb; - if (!g_lstat (icsd_docroot.c_str(), &sb) == 0 || !S_ISDIR(sb.st_mode)) { + if (g_lstat (icsd_docroot.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode)) { warning << _("Specified docroot is not an existing directory.") << endmsg; continue; } #ifndef PLATFORM_WINDOWS - if ( (!g_lstat (icsd_exec.c_str(), &sb) == 0) + if ( (g_lstat (icsd_exec.c_str(), &sb) != 0) || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0 ) { warning << _("Given Video Server is not an executable file.") << endmsg; continue; } #else - if ( (!g_lstat (icsd_exec.c_str(), &sb) == 0) + if ( (g_lstat (icsd_exec.c_str(), &sb) != 0) || (sb.st_mode & (S_IXUSR)) == 0 ) { warning << _("Given Video Server is not an executable file.") << endmsg; continue; @@ -3518,7 +3669,7 @@ ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg) delete video_server_process; } - video_server_process = new SystemExec(icsd_exec, argp); + video_server_process = new ARDOUR::SystemExec(icsd_exec, argp); if (video_server_process->start()) { warning << _("Cannot launch the video-server") << endmsg; continue; @@ -3526,6 +3677,7 @@ ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg) int timeout = 120; // 6 sec while (!ARDOUR_UI::instance()->video_timeline->check_server()) { Glib::usleep (50000); + gui_idle_handler(); if (--timeout <= 0 || !video_server_process->is_running()) break; } if (timeout <= 0) { @@ -3791,13 +3943,39 @@ quickly enough to keep up with recording.\n"), PROGRAM_NAME)); } } + +/* TODO: this is getting elaborate enough to warrant being split into a dedicated class */ +static MessageDialog *scan_dlg = NULL; +static ProgressBar *scan_pbar = NULL; +static HBox *scan_tbox = NULL; + void ARDOUR_UI::cancel_plugin_scan () { PluginManager::instance().cancel_plugin_scan(); } -static MessageDialog *scan_dlg = NULL; +void +ARDOUR_UI::cancel_plugin_timeout () +{ + PluginManager::instance().cancel_plugin_timeout(); + scan_tbox->hide(); +} + +void +ARDOUR_UI::plugin_scan_timeout (int timeout) +{ + if (!scan_dlg || !scan_dlg->is_mapped() || !scan_pbar) { + return; + } + if (timeout > 0) { + scan_pbar->set_fraction ((float) timeout / (float) Config->get_vst_scan_timeout()); + scan_tbox->show(); + } else { + scan_tbox->hide(); + } + gui_idle_handler(); +} void ARDOUR_UI::plugin_scan_dialog (std::string type, std::string plugin, bool can_cancel) @@ -3819,8 +3997,9 @@ ARDOUR_UI::plugin_scan_dialog (std::string type, std::string plugin, bool can_ca } static Gtk::Button *cancel_button; + static Gtk::Button *timeout_button; if (!scan_dlg) { - scan_dlg = new MessageDialog("", false, MESSAGE_INFO, BUTTONS_NONE); + scan_dlg = new MessageDialog("", false, MESSAGE_INFO, BUTTONS_NONE); // TODO manage VBox* vbox = scan_dlg->get_vbox(); vbox->set_size_request(400,-1); scan_dlg->set_title (_("Scanning for plugins")); @@ -3828,15 +4007,38 @@ ARDOUR_UI::plugin_scan_dialog (std::string type, std::string plugin, bool can_ca cancel_button = manage(new Gtk::Button(_("Cancel plugin scan"))); cancel_button->set_name ("EditorGTKButton"); cancel_button->signal_clicked().connect ( mem_fun (*this, &ARDOUR_UI::cancel_plugin_scan) ); + cancel_button->show(); scan_dlg->get_vbox()->pack_start ( *cancel_button, PACK_SHRINK); + + scan_tbox = manage( new HBox() ); + + timeout_button = manage(new Gtk::Button(_("Stop Timeout"))); + timeout_button->set_name ("EditorGTKButton"); + timeout_button->signal_clicked().connect ( mem_fun (*this, &ARDOUR_UI::cancel_plugin_timeout) ); + timeout_button->show(); + + scan_pbar = manage(new ProgressBar()); + scan_pbar->set_orientation(Gtk::PROGRESS_RIGHT_TO_LEFT); + scan_pbar->set_text(_("Scan Timeout")); + scan_pbar->show(); + + scan_tbox->pack_start (*scan_pbar, PACK_EXPAND_WIDGET, 4); + scan_tbox->pack_start (*timeout_button, PACK_SHRINK, 4); + + scan_dlg->get_vbox()->pack_start (*scan_tbox, PACK_SHRINK, 4); } + assert(scan_dlg && scan_tbox && cancel_button); + if (type == X_("closeme")) { scan_dlg->hide(); } else { scan_dlg->set_message(type + ": " + Glib::path_get_basename(plugin)); - scan_dlg->show_all(); + scan_dlg->show(); + } + if (!can_cancel || !cancelled) { + scan_tbox->hide(); } cancel_button->set_sensitive(can_cancel && !cancelled); @@ -4185,10 +4387,18 @@ ARDOUR_UI::setup_profile () Profile->set_small_screen (); } - if (getenv ("ARDOUR_SAE")) { + if (g_getenv ("ARDOUR_SAE")) { Profile->set_sae (); Profile->set_single_package (); } + + if (g_getenv ("TRX")) { + Profile->set_trx (); + } + + if (g_getenv ("MIXBUS")) { + Profile->set_mixbus (); + } } int @@ -4285,8 +4495,7 @@ ARDOUR_UI::reset_peak_display () if (!_session || !_session->master_out() || !editor_meter) return; editor_meter->clear_meters(); editor_meter_max_peak = -INFINITY; - editor_meter_peak_display.set_name ("meterbridge peakindicator"); - editor_meter_peak_display.set_elements((ArdourButton::Element) (ArdourButton::Edge|ArdourButton::Body)); + editor_meter_peak_display.set_active_state ( Gtkmm2ext::Off ); } void @@ -4324,3 +4533,53 @@ ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate) } +gint +ARDOUR_UI::transport_numpad_timeout () +{ + _numpad_locate_happening = false; + if (_numpad_timeout_connection.connected() ) + _numpad_timeout_connection.disconnect(); + return 1; +} + +void +ARDOUR_UI::transport_numpad_decimal () +{ + _numpad_timeout_connection.disconnect(); + + if (_numpad_locate_happening) { + if (editor) editor->goto_nth_marker(_pending_locate_num - 1); + _numpad_locate_happening = false; + } else { + _pending_locate_num = 0; + _numpad_locate_happening = true; + _numpad_timeout_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::transport_numpad_timeout), 2*1000); + } +} + +void +ARDOUR_UI::transport_numpad_event (int num) +{ + if ( _numpad_locate_happening ) { + _pending_locate_num = _pending_locate_num*10 + num; + } else { + switch (num) { + case 0: toggle_roll(false, false); break; + case 1: transport_rewind(1); break; + case 2: transport_forward(1); break; + case 3: transport_record(true); break; + case 4: toggle_session_auto_loop(); break; + case 5: transport_record(false); toggle_session_auto_loop(); break; + case 6: toggle_punch(); break; + case 7: toggle_click(); break; + case 8: toggle_auto_return(); break; + case 9: toggle_follow_edits(); break; + } + } +} + +void +ARDOUR_UI::set_flat_buttons () +{ + CairoWidget::set_flat_buttons( config()->get_flat_buttons() ); +}