X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_ui.cc;h=5846fa577fb88073a2ba14f8861065124d9b3532;hb=4c42a77441e74356cd909d994e270d1e1314aad4;hp=d54ae5e291c8d48333616b5ac5647c07c7d1cb3f;hpb=8d5065bc32b5d54049d8458cc14732c659fdb77f;p=ardour.git diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index d54ae5e291..5846fa577f 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -35,6 +35,8 @@ #include #include +#include +#include #include #include @@ -60,26 +62,22 @@ #include "midi++/manager.h" #include "ardour/ardour.h" -#include "ardour/callback.h" +#include "ardour/audioengine.h" +#include "ardour/audiofilesource.h" +#include "ardour/automation_watch.h" +#include "ardour/diskstream.h" +#include "ardour/filename_extensions.h" +#include "ardour/port.h" +#include "ardour/process_thread.h" #include "ardour/profile.h" -#include "ardour/plugin_manager.h" +#include "ardour/recent_sessions.h" #include "ardour/session_directory.h" #include "ardour/session_route.h" #include "ardour/session_state_utils.h" #include "ardour/session_utils.h" -#include "ardour/port.h" -#include "ardour/audioengine.h" -#include "ardour/playlist.h" -#include "ardour/utils.h" -#include "ardour/audio_diskstream.h" -#include "ardour/audiofilesource.h" -#include "ardour/recent_sessions.h" -#include "ardour/port.h" -#include "ardour/audio_track.h" -#include "ardour/midi_track.h" -#include "ardour/filesystem_paths.h" -#include "ardour/filename_extensions.h" -#include "ardour/process_thread.h" +#include "ardour/slave.h" + +#include "timecode/time.h" typedef uint64_t microseconds_t; @@ -97,9 +95,11 @@ typedef uint64_t microseconds_t; #include "gui_thread.h" #include "keyboard.h" #include "location_ui.h" +#include "main_clock.h" #include "missing_file_dialog.h" #include "missing_plugin_dialog.h" #include "mixer_ui.h" +#include "mouse_cursors.h" #include "opts.h" #include "processor_box.h" #include "prompter.h" @@ -121,6 +121,7 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtkmm2ext; using namespace Gtk; +using namespace std; ARDOUR_UI *ARDOUR_UI::theArdourUI = 0; UIConfiguration *ARDOUR_UI::ui_config = 0; @@ -130,15 +131,13 @@ sigc::signal ARDOUR_UI::RapidScreenUpdate; sigc::signal ARDOUR_UI::SuperRapidScreenUpdate; sigc::signal ARDOUR_UI::Clock; -bool could_be_a_valid_path (const string& path); - -ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) +ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) : Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp) , gui_object_state (new GUIObjectState) - , primary_clock (new AudioClock (X_("primary"), false, X_("transport"), true, true, false, true)) - , secondary_clock (new AudioClock (X_("secondary"), false, X_("secondary"), true, true, false, true)) + , primary_clock (new MainClock (X_("primary"), false, X_("transport"), true, true, true, false, true)) + , secondary_clock (new MainClock (X_("secondary"), false, X_("secondary"), true, true, false, false, true)) /* big clock */ @@ -155,7 +154,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) , rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)) , auto_return_button (ArdourButton::led_default_elements) - , auto_play_button (ArdourButton::led_default_elements) + , follow_edits_button (ArdourButton::led_default_elements) , auto_input_button (ArdourButton::led_default_elements) , auditioning_alert_button (_("audition")) @@ -168,7 +167,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) , _feedback_exists (false) { - Gtkmm2ext::init(); + Gtkmm2ext::init(localedir); about = 0; splash = 0; @@ -208,9 +207,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) original_big_clock_height = -1; original_big_clock_font_size = 0; - roll_button.set_elements (ArdourButton::Element (ArdourButton::Body|ArdourButton::Text)); - play_selection_button.set_elements (ArdourButton::Element (ArdourButton::Body|ArdourButton::Text)); - roll_button.set_controllable (roll_controllable); stop_button.set_controllable (stop_controllable); goto_start_button.set_controllable (goto_start_controllable); @@ -270,16 +266,13 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) /* lets get this party started */ try { - if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) { + if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization, localedir)) { throw failed_constructor (); } setup_gtk_ardour_enums (); setup_profile (); - GainMeter::setup_slider_pix (); - RouteTimeAxisView::setup_slider_pix (); - ProcessorEntry::setup_slider_pix (); SessionEvent::create_per_thread_pool ("GUI", 512); } catch (failed_constructor& err) { @@ -333,36 +326,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) DPIReset.connect (sigc::mem_fun (*this, &ARDOUR_UI::resize_text_widgets)); } -/** @return true if a session was chosen and `apply' clicked, otherwise false if `cancel' was clicked */ -bool -ARDOUR_UI::run_startup (bool should_be_new, string load_template) -{ - delete _startup; - _startup = new ArdourStartup (); - - XMLNode* audio_setup = Config->extra_xml ("AudioSetup"); - - if (audio_setup && _startup->engine_control()) { - _startup->engine_control()->set_state (*audio_setup); - } - - _startup->set_new_only (should_be_new); - if (!load_template.empty()) { - _startup->set_load_template (load_template); - } - _startup->present (); - - main().run(); - - _startup->hide (); - - switch (_startup->response()) { - case RESPONSE_OK: - return true; - default: - return false; - } -} int ARDOUR_UI::create_engine () @@ -436,7 +399,7 @@ ARDOUR_UI::post_engine () vector::iterator n; vector::iterator k; for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) { - cerr << "Action: " << (*n) << " bound to " << (*k) << endl; + cout << "Action: " << (*n) << " bound to " << (*k) << endl; } exit (0); @@ -464,12 +427,13 @@ ARDOUR_UI::post_engine () #ifndef GTKOSX /* OS X provides a nearly-always visible wallclock, so don't be stupid */ update_wall_clock (); - Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000); + Glib::signal_timeout().connect_seconds (sigc::mem_fun(*this, &ARDOUR_UI::update_wall_clock), 1); #endif update_disk_space (); update_cpu_load (); update_sample_rate (engine->frame_rate()); + update_timecode_format (); 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)); @@ -697,8 +661,14 @@ ARDOUR_UI::check_memory_locking () struct rlimit limits; int64_t ram; long pages, page_size; - - if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) { +#ifdef __FreeBSD__ + size_t pages_len=sizeof(pages); + if ((page_size = getpagesize()) < 0 || + sysctlbyname("hw.availpages", &pages, &pages_len, NULL, 0)) +#else + if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) +#endif + { ram = 0; } else { ram = (int64_t) pages * (int64_t) page_size; @@ -718,15 +688,23 @@ ARDOUR_UI::check_memory_locking () "This might cause %1 to run out of memory before your system " "runs out of memory. \n\n" "You can view the memory limit with 'ulimit -l', " - "and it is normally controlled by /etc/security/limits.conf"), - PROGRAM_NAME).c_str()); + "and it is normally controlled by %2"), + PROGRAM_NAME).c_str(), +#ifdef __FreeBSD__ + X_("/etc/login.conf") +#else + X_(" /etc/security/limits.conf") +#endif + ); + + msg.set_default_response (RESPONSE_OK); VBox* vbox = msg.get_vbox(); HBox hbox; CheckButton cb (_("Do not show this window again")); cb.signal_toggled().connect (sigc::mem_fun (*this, &ARDOUR_UI::no_memory_warning)); - + hbox.pack_start (cb, true, false); vbox->pack_start (hbox); cb.show(); @@ -761,12 +739,6 @@ void ARDOUR_UI::finish() { if (_session) { - int tries = 0; - - if (_session->transport_rolling() && (++tries < 8)) { - _session->request_stop (false, true); - usleep (10000); - } if (_session->dirty()) { vector actions; @@ -808,6 +780,8 @@ If you still wish to quit, please use the\n\n\ */ save_ardour_state (); + loading_message (string_compose (_("Please wait while %1 cleans up..."), PROGRAM_NAME)); + if (_session) { // _session->set_deletion_in_progress (); _session->set_clean (); @@ -890,12 +864,14 @@ ARDOUR_UI::ask_about_saving_session (const vector& actions) return -1; } + gint ARDOUR_UI::every_second () { update_cpu_load (); update_buffer_load (); update_disk_space (); + update_timecode_format (); return TRUE; } @@ -1058,16 +1034,21 @@ ARDOUR_UI::update_disk_space() return; } - framecnt_t frames = _session->available_capture_duration(); + boost::optional opt_frames = _session->available_capture_duration(); char buf[64]; framecnt_t fr = _session->frame_rate(); - if (frames == max_framecnt) { + if (!opt_frames) { + /* Available space is unknown */ + snprintf (buf, sizeof (buf), "%s", _("Disk: Unknown")); + } else if (opt_frames.get_value_or (0) == max_framecnt) { snprintf (buf, sizeof (buf), "%s", _("Disk: 24hrs+")); } else { rec_enabled_streams = 0; _session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams); + framecnt_t frames = opt_frames.get_value_or (0); + if (rec_enabled_streams) { frames /= rec_enabled_streams; } @@ -1100,18 +1081,47 @@ ARDOUR_UI::update_disk_space() disk_space_label.set_markup (buf); } +void +ARDOUR_UI::update_timecode_format () +{ + char buf[64]; + + if (_session) { + bool matching; + TimecodeSlave* tcslave; + SyncSource sync_src = Config->get_sync_source(); + + if ((sync_src == LTC || sync_src == MTC) && (tcslave = dynamic_cast(_session->slave())) != 0) { + matching = (tcslave->apparent_timecode_format() == _session->config.get_timecode_format()); + } else { + matching = true; + } + + snprintf (buf, sizeof (buf), S_("Timecode|TC: %s"), + matching ? X_("green") : X_("red"), + Timecode::timecode_format_name (_session->config.get_timecode_format()).c_str()); + } else { + snprintf (buf, sizeof (buf), "TC: n/a"); + } + + timecode_format_label.set_markup (buf); +} + gint ARDOUR_UI::update_wall_clock () { time_t now; struct tm *tm_now; - char buf[16]; + static int last_min = -1; time (&now); tm_now = localtime (&now); - - sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min); - wall_clock_label.set_text (buf); + if (last_min != tm_now->tm_min) { + char buf[16]; + sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min); + wall_clock_label.set_text (buf); + last_min = tm_now->tm_min; + } return TRUE; } @@ -1119,7 +1129,7 @@ ARDOUR_UI::update_wall_clock () void ARDOUR_UI::redisplay_recent_sessions () { - std::vector session_directories; + std::vector session_directories; RecentSessionsSorter cmp; recent_session_display.set_model (Glib::RefPtr(0)); @@ -1140,10 +1150,10 @@ ARDOUR_UI::redisplay_recent_sessions () session_directories.push_back ((*i).second); } - for (vector::const_iterator i = session_directories.begin(); + for (vector::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i) { - std::vector state_file_paths; + std::vector state_file_paths; // now get available states for this session @@ -1151,7 +1161,7 @@ ARDOUR_UI::redisplay_recent_sessions () vector* states; vector item; - string fullpath = i->to_string(); + string fullpath = *i; /* remove any trailing / */ @@ -1178,6 +1188,7 @@ ARDOUR_UI::redisplay_recent_sessions () 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) { @@ -1191,11 +1202,12 @@ ARDOUR_UI::redisplay_recent_sessions () child_row[recent_session_columns.visible_name] = *i2; child_row[recent_session_columns.fullpath] = fullpath; + child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath); } } } - recent_session_display.set_tooltip_column(1); // recent_session_columns.fullpath + recent_session_display.set_tooltip_column(1); // recent_session_columns.tip recent_session_display.set_model (recent_session_model); } @@ -1369,7 +1381,8 @@ ARDOUR_UI::open_session () void -ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many, const string& name_template, PluginInfoPtr instrument) +ARDOUR_UI::session_add_mixed_track (const ChanCount& input, const ChanCount& output, RouteGroup* route_group, + uint32_t how_many, const string& name_template, PluginInfoPtr instrument) { list > tracks; @@ -1379,18 +1392,10 @@ ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t } try { - if (disk) { - - tracks = _session->new_midi_track (instrument, ARDOUR::Normal, route_group, how_many, name_template); - - if (tracks.size() != how_many) { - if (how_many == 1) { - error << _("could not create a new midi track") << endmsg; - } else { - error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg; - } - } - + tracks = _session->new_midi_track (input, output, instrument, ARDOUR::Normal, route_group, how_many, name_template); + + if (tracks.size() != how_many) { + error << string_compose(P_("could not create %1 new mixed track", "could not create %1 new mixed tracks", how_many), how_many) << endmsg; } } @@ -1403,7 +1408,18 @@ restart JACK 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) +{ + ChanCount one_midi_channel; + one_midi_channel.set (DataType::MIDI, 1); + + if (disk) { + session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, instrument); + } +} void ARDOUR_UI::session_add_audio_route ( @@ -1429,12 +1445,8 @@ ARDOUR_UI::session_add_audio_route ( tracks = _session->new_audio_track (input_channels, output_channels, mode, route_group, how_many, name_template); if (tracks.size() != how_many) { - if (how_many == 1) { - error << _("could not create a new audio track") << endmsg; - } else { - error << string_compose (_("could only create %1 of %2 new audio %3"), - tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg; - } + error << string_compose (P_("could not create %1 new audio track", "could not create %1 new audio tracks", how_many), how_many) + << endmsg; } } else { @@ -1442,11 +1454,8 @@ ARDOUR_UI::session_add_audio_route ( routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many, name_template); if (routes.size() != how_many) { - if (how_many == 1) { - error << _("could not create a new audio bus") << endmsg; - } else { - error << string_compose (_("could not create %1 new audio busses"), how_many) << endmsg; - } + error << string_compose (P_("could not create %1 new audio bus", "could not create %1 new audio busses", how_many), how_many) + << endmsg; } } } @@ -1598,7 +1607,7 @@ ARDOUR_UI::transport_roll () #if 0 if (_session->config.get_external_sync()) { - switch (_session->config.get_sync_source()) { + switch (Config->get_sync_source()) { case JACK: break; default: @@ -1622,15 +1631,18 @@ ARDOUR_UI::transport_roll () _session->request_play_range (0, true); } - if (Config->get_always_play_range()) { - _session->request_play_range (&editor->get_selection().time, true); - } - if (!rolling) { _session->request_transport_speed (1.0f); } } +bool +ARDOUR_UI::get_smart_mode() const +{ + return ( editor->get_smart_mode() ); +} + + void ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) { @@ -1645,7 +1657,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) } if (_session->config.get_external_sync()) { - switch (_session->config.get_sync_source()) { + switch (Config->get_sync_source()) { case JACK: break; default: @@ -1681,7 +1693,7 @@ 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_always_play_range() ) { _session->request_play_range (&editor->get_selection().time, true); } @@ -1727,6 +1739,15 @@ ARDOUR_UI::transport_play_selection () editor->play_selection (); } +void +ARDOUR_UI::transport_play_preroll () +{ + if (!_session) { + return; + } + editor->play_with_preroll (); +} + void ARDOUR_UI::transport_rewind (int option) { @@ -1951,10 +1972,11 @@ JACK, reconnect and save the session."), PROGRAM_NAME); MessageDialog msg (*editor, msgstr); pop_back_splash (msg); + msg.set_keep_above (true); msg.run (); - + if (free_reason) { - free ((char*) reason); + free (const_cast (reason)); } } @@ -2075,7 +2097,7 @@ ARDOUR_UI::snapshot_session (bool switch_to_it) } } - vector p; + vector p; get_state_files_in_directory (_session->session_directory().root_path(), p); vector n = get_file_names_no_extension (p); if (find (n.begin(), n.end(), snapname) != n.end()) { @@ -2395,20 +2417,6 @@ ARDOUR_UI::idle_load (const std::string& path) } } -void -ARDOUR_UI::loading_message (const std::string& msg) -{ - if (ARDOUR_COMMAND_LINE::no_splash) { - return; - } - - show_splash (); - if (splash) { - splash->message (msg); - flush_pending (); - } -} - /** @param quit_on_cancel true if exit() should be called if the user clicks `cancel' in the new session dialog */ int ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, string load_template) @@ -2419,6 +2427,19 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri int ret = -1; bool likely_new = false; + /* deal with any existing DIRTY session now, rather than later. don't + * treat a non-dirty session this way, so that it stays visible + * as we bring up the new session dialog. + */ + + if (_session && _session->dirty()) { + if (unload_session (false)) { + /* unload cancelled by user */ + return 0; + } + ARDOUR_COMMAND_LINE::session_name = ""; + } + if (!load_template.empty()) { should_be_new = true; template_name = load_template; @@ -2426,7 +2447,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri while (ret != 0) { - if (!should_be_new && !ARDOUR_COMMAND_LINE::session_name.empty()) { + if (!ARDOUR_COMMAND_LINE::session_name.empty()) { /* if they named a specific statefile, use it, otherwise they are just giving a session folder, and we want to use it as is @@ -2443,71 +2464,82 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri session_path = ARDOUR_COMMAND_LINE::session_name; session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name); } - } else { + session_path = ""; + session_name = ""; + } - bool const apply = run_startup (should_be_new, load_template); - - if (!apply) { - if (quit_on_cancel) { - exit (1); - } else { - return ret; - } - } - - /* if we run the startup dialog again, offer more than just "new session" */ - - should_be_new = false; - - session_name = _startup->session_name (likely_new); - - string::size_type suffix = session_name.find (statefile_suffix); - - if (suffix != string::npos) { - session_name = session_name.substr (0, suffix); + delete _startup; + _startup = new ArdourStartup (should_be_new, session_name, session_path, load_template); + + if (!_startup->ready_without_display()) { + _startup->present (); + main().run(); + _startup->hide (); + } + + switch (_startup->response()) { + case RESPONSE_OK: + break; + default: + if (quit_on_cancel) { + exit (1); + } else { + return ret; } + } - /* this shouldn't happen, but we catch it just in case it does */ + /* if we run the startup dialog again, offer more than just "new session" */ + + should_be_new = false; + + session_name = _startup->session_name (likely_new); + + string::size_type suffix = session_name.find (statefile_suffix); + + if (suffix != string::npos) { + session_name = session_name.substr (0, suffix); + } + + /* this shouldn't happen, but we catch it just in case it does */ + + if (session_name.empty()) { + continue; + } + + if (_startup->use_session_template()) { + template_name = _startup->session_template_name(); + _session_is_new = true; + } + + if (session_name[0] == 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)) { + + /* absolute path or cwd-relative path specified for session name: infer session folder + from what was given. + */ + + session_path = Glib::path_get_dirname (session_name); + session_name = Glib::path_get_basename (session_name); + + } else { - if (session_name.empty()) { + session_path = _startup->session_folder(); + + char illegal = Session::session_name_is_legal (session_name); + + if (illegal) { + MessageDialog msg (*_startup, + 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; } - - if (_startup->use_session_template()) { - template_name = _startup->session_template_name(); - _session_is_new = true; - } - - if (session_name[0] == 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)) { - - /* absolute path or cwd-relative path specified for session name: infer session folder - from what was given. - */ - - session_path = Glib::path_get_dirname (session_name); - session_name = Glib::path_get_basename (session_name); - - } else { - - session_path = _startup->session_folder(); - - char illegal = Session::session_name_is_legal (session_name); - - if (illegal) { - MessageDialog msg (*_startup, - 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; - } - } } - + if (create_engine ()) { break; } @@ -2813,7 +2845,7 @@ ARDOUR_UI::launch_manual () void ARDOUR_UI::launch_reference () { - PBD::open_uri("http://ardour.org/refmanual"); + PBD::open_uri ("http://ardour.org/refmanual"); } void @@ -2831,6 +2863,20 @@ ARDOUR_UI::about_signal_response (int /*response*/) hide_about(); } +void +ARDOUR_UI::loading_message (const std::string& msg) +{ + if (ARDOUR_COMMAND_LINE::no_splash) { + return; + } + + if (!splash) { + show_splash (); + } + + splash->message (msg); +} + void ARDOUR_UI::show_splash () { @@ -2842,24 +2888,18 @@ ARDOUR_UI::show_splash () } } - splash->present (); - splash->pop_front (); - splash->queue_draw (); - splash->get_window()->process_updates (true); - flush_pending (); + splash->display (); } void ARDOUR_UI::hide_splash () { - if (splash) { - splash->hide(); - } + delete splash; + splash = 0; } void -ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title, - const string& plural_msg, const string& singular_msg) +ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title, const bool msg_delete) { size_t removed; @@ -2915,7 +2955,7 @@ require some unused files to continue to exist.")); dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP); - const string dead_directory = _session->session_directory().dead_path().to_string(); + const string dead_directory = _session->session_directory().dead_path(); /* subst: %1 - number of files removed @@ -2931,20 +2971,36 @@ require some unused files to continue to exist.")); bprefix = X_(""); space_adjusted = rep.space; } else if (rep.space < 1000000) { - bprefix = X_("kilo"); + bprefix = _("kilo"); space_adjusted = truncf((float)rep.space / 1000.0); } else if (rep.space < 1000000 * 1000) { - bprefix = X_("mega"); + bprefix = _("mega"); space_adjusted = truncf((float)rep.space / (1000.0 * 1000.0)); } else { - bprefix = X_("giga"); + bprefix = _("giga"); space_adjusted = truncf((float)rep.space / (1000.0 * 1000 * 1000.0)); } - if (removed > 1) { - txt.set_text (string_compose (plural_msg, removed, dead_directory, space_adjusted, bprefix, PROGRAM_NAME)); + if (msg_delete) { + txt.set_markup (string_compose (P_("\ +The following file was deleted from %2,\n\ +releasing %3 %4bytes of disk space", "\ +The following %1 files were deleted from %2,\n\ +releasing %3 %4bytes of disk space", removed), + removed, Glib::Markup::escape_text (dead_directory), space_adjusted, bprefix, PROGRAM_NAME)); } else { - txt.set_text (string_compose (singular_msg, removed, dead_directory, space_adjusted, bprefix, PROGRAM_NAME)); + txt.set_markup (string_compose (P_("\ +The following file was not in use and \n\ +has been moved to: %2\n\n\ +After a restart of %5\n\n\ +Session -> Clean-up -> Flush Wastebasket\n\n\ +will release an additional %3 %4bytes of disk space.\n", "\ +The following %1 files were not in use and \n\ +have been moved to: %2\n\n\ +After a restart of %5\n\n\ +Session -> Clean-up -> Flush Wastebasket\n\n\ +will release an additional %3 %4bytes of disk space.\n", removed), + removed, Glib::Markup::escape_text (dead_directory), space_adjusted, bprefix, PROGRAM_NAME)); } dhbox.pack_start (*dimage, true, false, 5); @@ -3038,26 +3094,7 @@ Clean-up will move all unused files to a \"dead\" location.")); editor->finish_cleanup (); checker.hide(); - display_cleanup_results (rep, - _("Cleaned Files"), - _("\ -The following %1 files were not in use and \n\ -have been moved to:\n\n\ -%2\n\n\ -After a restart of %5,\n\n\ -Session -> Clean-up -> Flush Wastebasket\n\n\ -will release an additional\n\ -%3 %4bytes of disk space.\n"), - _("\ -The following file was not in use and \n\ -has been moved to:\n \ -%2\n\n\ -After a restart of %5,\n\n\ -Session -> Clean-up -> Flush Wastebasket\n\n\ -will release an additional\n\ -%3 %4bytes of disk space.\n" - )); - + display_cleanup_results (rep, _("Cleaned Files"), false); } void @@ -3074,14 +3111,7 @@ ARDOUR_UI::flush_trash () return; } - display_cleanup_results (rep, - _("deleted file"), - _("The following %1 files were deleted from\n\ -%2,\n\ -releasing %3 %4bytes of disk space"), - _("The following file was deleted from\n\ -%2,\n\ -releasing %3 %4bytes of disk space")); + display_cleanup_results (rep, _("deleted file"), true); } void @@ -3122,6 +3152,12 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) return; } + PBD::ScopedConnection idle_connection; + + if (count > 8) { + ARDOUR::GUIIdle.connect (idle_connection, MISSING_INVALIDATOR, boost::bind (&Gtkmm2ext::UI::flush_pending, this), gui_context()); + } + string template_path = add_route_dialog->track_template(); if (!template_path.empty()) { @@ -3129,29 +3165,38 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) return; } - uint32_t input_chan = add_route_dialog->channels (); - uint32_t output_chan; + 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(); if (oac & AutoConnectMaster) { - output_chan = (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan); + output_chan.set (DataType::AUDIO, (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan.n_audio())); + output_chan.set (DataType::MIDI, 0); } else { output_chan = input_chan; } /* XXX do something with name template */ - if (add_route_dialog->midi_tracks_wanted()) { + 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); + break; + case AddRouteDialog::MidiTrack: session_add_midi_track (route_group, count, name_template, instrument); - } else if (add_route_dialog->audio_tracks_wanted()) { - session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count, name_template); - } else { - session_add_audio_bus (input_chan, output_chan, route_group, count, name_template); + break; + case AddRouteDialog::MixedTrack: + session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, instrument); + break; + case AddRouteDialog::AudioBus: + 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 */ } XMLNode* @@ -3310,8 +3355,8 @@ ARDOUR_UI::pending_state_dialog () Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG); ArdourDialog dialog (_("Crash Recovery"), true); Label message (string_compose (_("\ -This session appears to have been in\n\ -middle of recording when ardour or\n\ +This session appears to have been in the\n\ +middle of recording when %1 or\n\ the computer was shutdown.\n\ \n\ %1 can recover any captured audio for\n\ @@ -3341,7 +3386,7 @@ int ARDOUR_UI::sr_mismatch_dialog (framecnt_t desired, framecnt_t actual) { HBox* hbox = new HBox(); - Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG); + Image* image = new Image (Stock::DIALOG_WARNING, ICON_SIZE_DIALOG); ArdourDialog dialog (_("Sample Rate Mismatch"), true); Label message (string_compose (_("\ This session was created with a sample rate of %1 Hz, but\n\ @@ -3515,16 +3560,16 @@ ARDOUR_UI::TransportControllable::set_value (double val) action = X_("Stop"); break; case GotoStart: - action = X_("Goto Start"); + action = X_("GotoStart"); break; case GotoEnd: - action = X_("Goto End"); + action = X_("GotoEnd"); break; case AutoLoop: action = X_("Loop"); break; case PlaySelection: - action = X_("Play Selection"); + action = X_("PlaySelection"); break; case RecordEnable: action = X_("Record");