X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_ui.cc;h=eebd35aefbc041c1449979c5670b0e3f30cafe78;hb=74126c48c0726e5491a160d2b0f04e406fc80231;hp=831e95c997a851c9a12c02fa90051b835439a66d;hpb=341cbfbd19dd9e885020c6fe1120fbcc497d621e;p=ardour.git diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 831e95c997..eebd35aefb 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 1999-2007 Paul Davis + Copyright (C) 1999-2013 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,6 +35,8 @@ #include #include +#include +#include #include #include @@ -65,6 +67,7 @@ #include "ardour/automation_watch.h" #include "ardour/diskstream.h" #include "ardour/filename_extensions.h" +#include "ardour/filesystem_paths.h" #include "ardour/port.h" #include "ardour/process_thread.h" #include "ardour/profile.h" @@ -99,6 +102,7 @@ typedef uint64_t microseconds_t; #include "mixer_ui.h" #include "mouse_cursors.h" #include "opts.h" +#include "pingback.h" #include "processor_box.h" #include "prompter.h" #include "public_editor.h" @@ -112,6 +116,10 @@ typedef uint64_t microseconds_t; #include "time_axis_view_item.h" #include "utils.h" #include "window_proxy.h" +#include "video_server_dialog.h" +#include "add_video_dialog.h" +#include "transcode_video_dialog.h" +#include "system_exec.h" #include "i18n.h" @@ -129,7 +137,7 @@ sigc::signal ARDOUR_UI::RapidScreenUpdate; sigc::signal ARDOUR_UI::SuperRapidScreenUpdate; sigc::signal ARDOUR_UI::Clock; -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) @@ -165,7 +173,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) , _feedback_exists (false) { - Gtkmm2ext::init(); + Gtkmm2ext::init(localedir); about = 0; splash = 0; @@ -191,6 +199,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) session_selector_window = 0; last_key_press_time = 0; add_route_dialog = 0; + add_video_dialog = 0; + video_server_process = 0; route_params = 0; bundle_manager = 0; rc_option_editor = 0; @@ -232,6 +242,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) ARDOUR::Diskstream::DiskOverrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context()); ARDOUR::Diskstream::DiskUnderrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_underrun_handler, this), gui_context()); + ARDOUR::Session::VersionMismatch.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_format_mismatch, this, _1, _2), gui_context()); + /* handle dialog requests */ ARDOUR::Session::Dialog.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dialog, this, _1), gui_context()); @@ -264,16 +276,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) { @@ -428,7 +437,7 @@ 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 (); @@ -458,6 +467,10 @@ ARDOUR_UI::~ARDOUR_UI () delete editor; delete mixer; delete add_route_dialog; + if (add_video_dialog) { + delete add_video_dialog; + } + stop_video_server(); } void @@ -601,21 +614,99 @@ ARDOUR_UI::update_autosave () } } +void +ARDOUR_UI::check_announcements () +{ +#ifdef PHONE_HOME + string _annc_filename; + +#ifdef __APPLE__ + _annc_filename = PROGRAM_NAME "_announcements_osx_"; +#else + _annc_filename = PROGRAM_NAME "_announcements_linux_"; +#endif + _annc_filename.append (VERSIONSTRING); + + std::string path = Glib::build_filename (user_config_directory(), _annc_filename); + std::ifstream announce_file (path.c_str()); + if ( announce_file.fail() ) + _announce_string = ""; + else { + std::stringstream oss; + oss << announce_file.rdbuf(); + _announce_string = oss.str(); + } + + pingback (VERSIONSTRING, path); +#endif +} + void ARDOUR_UI::startup () { Application* app = Application::instance (); - + char *nsm_url; app->ShouldQuit.connect (sigc::mem_fun (*this, &ARDOUR_UI::queue_finish)); app->ShouldLoad.connect (sigc::mem_fun (*this, &ARDOUR_UI::idle_load)); -#ifdef PHONE_HOME - call_the_mothership (VERSIONSTRING); -#endif + if (ARDOUR_COMMAND_LINE::check_announcements) { + check_announcements (); + } app->ready (); - if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session, ARDOUR_COMMAND_LINE::load_template)) { + nsm_url = getenv ("NSM_URL"); + nsm = 0; + + if (nsm_url) { + nsm = new NSM_Client; + if (!nsm->init (nsm_url)) { + nsm->announce (PROGRAM_NAME, ":dirty:", "ardour3"); + + unsigned int i = 0; + // wait for announce reply from nsm server + for ( i = 0; i < 5000; ++i) { + nsm->check (); + usleep (i); + if (nsm->is_active()) + break; + } + // wait for open command from nsm server + for ( i = 0; i < 5000; ++i) { + nsm->check (); + usleep (1000); + if (nsm->client_id ()) + break; + } + + if (_session && nsm) { + _session->set_nsm_state( nsm->is_active() ); + } + + // nsm requires these actions disabled + vector action_names; + action_names.push_back("SaveAs"); + action_names.push_back("Rename"); + action_names.push_back("New"); + action_names.push_back("Open"); + action_names.push_back("Recent"); + action_names.push_back("Close"); + + for (vector::const_iterator n = action_names.begin(); n != action_names.end(); ++n) { + Glib::RefPtr act = ActionManager::get_action (X_("Main"), (*n).c_str()); + if (act) { + act->set_sensitive (false); + } + } + + } + else { + delete nsm; + nsm = 0; + } + } + + else if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session, ARDOUR_COMMAND_LINE::load_template)) { exit (1); } @@ -662,8 +753,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; @@ -683,15 +780,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(); @@ -726,6 +831,7 @@ void ARDOUR_UI::finish() { if (_session) { + ARDOUR_UI::instance()->video_timeline->sync_session_state(); if (_session->dirty()) { vector actions; @@ -761,6 +867,9 @@ If you still wish to quit, please use the\n\n\ point_zero_one_second_connection.disconnect(); } + delete ARDOUR_UI::instance()->video_timeline; + stop_video_server(); + /* Save state before deleting the session, as that causes some windows to be destroyed before their visible state can be saved. @@ -859,6 +968,19 @@ ARDOUR_UI::every_second () update_buffer_load (); update_disk_space (); update_timecode_format (); + + if (nsm && nsm->is_active ()) { + nsm->check (); + + if (!_was_dirty && _session->dirty ()) { + nsm->is_dirty (); + _was_dirty = true; + } + else if (_was_dirty && !_session->dirty ()){ + nsm->is_clean (); + _was_dirty = false; + } + } return TRUE; } @@ -1099,13 +1221,16 @@ 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; } @@ -1172,6 +1297,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) { @@ -1185,11 +1311,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); } @@ -1377,11 +1504,7 @@ ARDOUR_UI::session_add_mixed_track (const ChanCount& input, const ChanCount& out tracks = _session->new_midi_track (input, output, instrument, ARDOUR::Normal, route_group, how_many, name_template); if (tracks.size() != how_many) { - if (how_many == 1) { - error << _("could not create a new mixed track") << endmsg; - } else { - error << string_compose (_("could not create %1 new mixed tracks"), how_many) << endmsg; - } + error << string_compose(P_("could not create %1 new mixed track", "could not create %1 new mixed tracks", how_many), how_many) << endmsg; } } @@ -1431,12 +1554,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 { @@ -1444,11 +1563,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; } } } @@ -1965,8 +2081,9 @@ 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 (const_cast (reason)); } @@ -2001,7 +2118,11 @@ ARDOUR_UI::update_clocks () void ARDOUR_UI::start_clocking () { - clock_signal_connection = RapidScreenUpdate.connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks)); + if (Config->get_super_rapid_clock_update()) { + clock_signal_connection = SuperRapidScreenUpdate.connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks)); + } else { + clock_signal_connection = RapidScreenUpdate.connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks)); + } } void @@ -2347,7 +2468,7 @@ ARDOUR_UI::build_session_from_nsd (const std::string& session_path, const std::s { BusProfile bus_profile; - if (Profile->get_sae()) { + if (nsm || Profile->get_sae()) { bus_profile.master_out_channels = 2; bus_profile.input_ac = AutoConnectPhysical; @@ -2424,6 +2545,10 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri * as we bring up the new session dialog. */ + if (_session && ARDOUR_UI::instance()->video_timeline) { + ARDOUR_UI::instance()->video_timeline->sync_session_state(); + } + if (_session && _session->dirty()) { if (unload_session (false)) { /* unload cancelled by user */ @@ -2487,6 +2612,10 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri session_name = _startup->session_name (likely_new); + if (nsm) { + likely_new = true; + } + string::size_type suffix = session_name.find (statefile_suffix); if (suffix != string::npos) { @@ -2538,7 +2667,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) { - if (likely_new) { + if (likely_new && !nsm) { std::string existing = Glib::build_filename (session_path, session_name); @@ -2831,13 +2960,13 @@ ARDOUR_UI::show_about () void ARDOUR_UI::launch_manual () { - PBD::open_uri("http://ardour.org/flossmanual"); + PBD::open_uri (Config->get_tutorial_manual_url()); } void ARDOUR_UI::launch_reference () { - PBD::open_uri ("http://ardour.org/refmanual"); + PBD::open_uri (Config->get_reference_manual_url()); } void @@ -2891,8 +3020,7 @@ ARDOUR_UI::hide_splash () } 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; @@ -2961,7 +3089,7 @@ require some unused files to continue to exist.")); double space_adjusted = 0; if (rep.space < 1000) { - bprefix = _(""); + bprefix = X_(""); space_adjusted = rep.space; } else if (rep.space < 1000000) { bprefix = _("kilo"); @@ -2974,10 +3102,26 @@ require some unused files to continue to exist.")); space_adjusted = truncf((float)rep.space / (1000.0 * 1000 * 1000.0)); } - if (removed > 1) { - txt.set_markup (string_compose (plural_msg, removed, Glib::Markup::escape_text (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_markup (string_compose (singular_msg, removed, Glib::Markup::escape_text (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); @@ -3071,22 +3215,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: %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 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" - )); - + display_cleanup_results (rep, _("Cleaned Files"), false); } void @@ -3103,12 +3232,7 @@ ARDOUR_UI::flush_trash () return; } - display_cleanup_results (rep, - _("deleted file"), - _("The following %1 files were deleted from %2,\n\ -releasing %3 %4bytes of disk space"), - _("The following file was deleted from %2,\n\ -releasing %3 %4bytes of disk space")); + display_cleanup_results (rep, _("deleted file"), true); } void @@ -3158,7 +3282,11 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) string template_path = add_route_dialog->track_template(); if (!template_path.empty()) { - _session->new_route_from_template (count, template_path); + if (add_route_dialog->name_template_is_default()) { + _session->new_route_from_template (count, template_path, string()); + } else { + _session->new_route_from_template (count, template_path, add_route_dialog->name_template()); + } return; } @@ -3196,6 +3324,247 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) /* idle connection will end at scope end */ } +void +ARDOUR_UI::stop_video_server (bool ask_confirm) +{ + if (!video_server_process && ask_confirm) { + warning << _("Video-Server was not launched by Ardour. The request to stop it is ignored.") << endmsg; + } + if (video_server_process) { + if(ask_confirm) { + ArdourDialog confirm (_("Stop Video-Server"), true); + Label m (_("Do you really want to stop the Video Server?")); + confirm.get_vbox()->pack_start (m, true, true); + confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + confirm.add_button (_("Yes, Stop It"), Gtk::RESPONSE_ACCEPT); + confirm.show_all (); + if (confirm.run() == RESPONSE_CANCEL) { + return; + } + } + delete video_server_process; + video_server_process =0; + } +} + +void +ARDOUR_UI::start_video_server_menu (Gtk::Window* float_window) +{ + ARDOUR_UI::start_video_server( float_window, true); +} + +bool +ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg) +{ + if (!_session) { + return false; + } + if (popup_msg) { + if (ARDOUR_UI::instance()->video_timeline->check_server()) { + if (video_server_process) { + popup_error(_("The Video Server is already started.")); + } else { + popup_error(_("An external Video Server is configured and can be reached. Not starting a new instance.")); + } + } + } + + int firsttime = 0; + while (!ARDOUR_UI::instance()->video_timeline->check_server()) { + if (firsttime++) { + warning << _("Could not connect to the Video Server. Start it or configure its access URL in Edit -> Preferences.") << endmsg; + } + VideoServerDialog *video_server_dialog = new VideoServerDialog (_session); + if (float_window) { + video_server_dialog->set_transient_for (*float_window); + } + + if (!Config->get_show_video_server_dialog() && firsttime < 2) { + video_server_dialog->hide(); + } else { + ResponseType r = (ResponseType) video_server_dialog->run (); + video_server_dialog->hide(); + if (r != RESPONSE_ACCEPT) { return false; } + if (video_server_dialog->show_again()) { + Config->set_show_video_server_dialog(false); + } + } + + std::string icsd_exec = video_server_dialog->get_exec_path(); + std::string icsd_docroot = video_server_dialog->get_docroot(); + if (icsd_docroot.empty()) {icsd_docroot = X_("/");} + + struct stat sb; + if (!lstat (icsd_docroot.c_str(), &sb) == 0 || !S_ISDIR(sb.st_mode)) { + warning << _("Specified docroot is not an existing directory.") << endmsg; + continue; + } + if ( (!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; + } + + char **argp; + argp=(char**) calloc(9,sizeof(char*)); + argp[0] = strdup(icsd_exec.c_str()); + argp[1] = strdup("-P"); + argp[2] = (char*) calloc(16,sizeof(char)); snprintf(argp[2], 16, "%s", video_server_dialog->get_listenaddr().c_str()); + argp[3] = strdup("-p"); + argp[4] = (char*) calloc(6,sizeof(char)); snprintf(argp[4], 6, "%i", video_server_dialog->get_listenport()); + argp[5] = strdup("-C"); + argp[6] = (char*) calloc(6,sizeof(char)); snprintf(argp[6], 6, "%i", video_server_dialog->get_cachesize()); + argp[7] = strdup(icsd_docroot.c_str()); + argp[8] = 0; + stop_video_server(); + + if (icsd_docroot == X_("/")) { + Config->set_video_advanced_setup(false); + } else { + std::ostringstream osstream; + osstream << "http://localhost:" << video_server_dialog->get_listenport() << "/"; + Config->set_video_server_url(osstream.str()); + Config->set_video_server_docroot(icsd_docroot); + Config->set_video_advanced_setup(true); + } + + video_server_process = new SystemExec(icsd_exec, argp); + video_server_process->start(); + sleep(1); + } + return true; +} + +void +ARDOUR_UI::add_video (Gtk::Window* float_window) +{ + if (!_session) { + return; + } + + if (!start_video_server(float_window, false)) { + warning << _("Could not connect to the Video Server. Start it or configure its access URL in Edit -> Preferences.") << endmsg; + return; + } + + if (add_video_dialog == 0) { + add_video_dialog = new AddVideoDialog (_session); + if (float_window) { + add_video_dialog->set_transient_for (*float_window); + } + } + + if (add_video_dialog->is_visible()) { + /* we're already doing this */ + return; + } + ResponseType r = (ResponseType) add_video_dialog->run (); + add_video_dialog->hide(); + if (r != RESPONSE_ACCEPT) { return; } + + bool local_file; + std::string path = add_video_dialog->file_name(local_file); + bool auto_set_session_fps = add_video_dialog->auto_set_session_fps(); + + if (local_file && !Glib::file_test(path, Glib::FILE_TEST_EXISTS)) { + warning << string_compose(_("could not open %1"), path) << endmsg; + return; + } + if (!local_file && path.length() == 0) { + warning << _("no video-file selected") << endmsg; + return; + } + + switch (add_video_dialog->import_option()) { + case VTL_IMPORT_TRANSCODE: + { + TranscodeVideoDialog *transcode_video_dialog; + transcode_video_dialog = new TranscodeVideoDialog (_session, path); + ResponseType r = (ResponseType) transcode_video_dialog->run (); + transcode_video_dialog->hide(); + if (r != RESPONSE_ACCEPT) { + delete transcode_video_dialog; + return; + } + if (!transcode_video_dialog->get_audiofile().empty()) { + editor->embed_audio_from_video(transcode_video_dialog->get_audiofile()); + } + switch (transcode_video_dialog->import_option()) { + case VTL_IMPORT_TRANSCODED: + path = transcode_video_dialog->get_filename(); + local_file = true; + break; + case VTL_IMPORT_REFERENCE: + break; + default: + delete transcode_video_dialog; + return; + } + delete transcode_video_dialog; + } + break; + default: + case VTL_IMPORT_NONE: + break; + } + + /* strip _session->session_directory().video_path() from video file if possible */ + if (local_file && !path.compare(0, _session->session_directory().video_path().size(), _session->session_directory().video_path())) { + path=path.substr(_session->session_directory().video_path().size()); + if (path.at(0) == G_DIR_SEPARATOR) { + path=path.substr(1); + } + } + + video_timeline->set_update_session_fps(auto_set_session_fps); + 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")); + _session->add_extra_xml (*node); + _session->set_dirty (); + + _session->maybe_update_session_range( + std::max(video_timeline->get_offset(), (ARDOUR::frameoffset_t) 0), + std::max(video_timeline->get_offset() + video_timeline->get_duration(), (ARDOUR::frameoffset_t) 0)); + + + if (add_video_dialog->launch_xjadeo() && local_file) { + editor->set_xjadeo_sensitive(true); + editor->toggle_xjadeo_proc(1); + } else { + editor->toggle_xjadeo_proc(0); + } + editor->toggle_ruler_video(true); + } +} + +void +ARDOUR_UI::remove_video () +{ + video_timeline->close_session(); + editor->toggle_ruler_video(false); + + /* delete session state */ + XMLNode* node = new XMLNode(X_("Videotimeline")); + _session->add_extra_xml(*node); + node = new XMLNode(X_("Videomonitor")); + _session->add_extra_xml(*node); + stop_video_server(); +} + +void +ARDOUR_UI::flush_videotimeline_cache (bool localcacheonly) +{ + if (localcacheonly) { + video_timeline->vmon_update(); + } else { + video_timeline->flush_cache(); + } + editor->queue_visual_videotimeline_update(); +} + XMLNode* ARDOUR_UI::mixer_settings () const { @@ -3352,8 +3721,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\ @@ -3383,7 +3752,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\ @@ -3464,6 +3833,7 @@ ARDOUR_UI::update_transport_clocks (framepos_t pos) if (big_clock_window->get()) { big_clock->set (pos); } + ARDOUR_UI::instance()->video_timeline->manual_seek_video_monitor(pos); } @@ -3626,43 +3996,6 @@ ARDOUR_UI::setup_profile () } } -void -ARDOUR_UI::toggle_translations () -{ - using namespace Glib; - - RefPtr act = ActionManager::get_action (X_("Main"), X_("EnableTranslation")); - if (act) { - RefPtr ract = RefPtr::cast_dynamic (act); - if (ract) { - - string i18n_killer = ARDOUR::translation_kill_path(); - - bool already_enabled = !ARDOUR::translations_are_disabled (); - - if (ract->get_active ()) { - /* we don't care about errors */ - int fd = ::open (i18n_killer.c_str(), O_RDONLY|O_CREAT, 0644); - close (fd); - } else { - /* we don't care about errors */ - unlink (i18n_killer.c_str()); - } - - if (already_enabled != ract->get_active()) { - MessageDialog win (already_enabled ? _("Translations disabled") : _("Translations enabled"), - false, - Gtk::MESSAGE_WARNING, - Gtk::BUTTONS_OK); - win.set_secondary_text (string_compose (_("You must restart %1 for this to take effect."), PROGRAM_NAME)); - win.set_position (Gtk::WIN_POS_CENTER); - win.present (); - win.run (); - } - } - } -} - /** Add a window proxy to our list, so that its state will be saved. * This call also causes the window to be created and opened if its * state was saved as `visible'. @@ -3751,3 +4084,21 @@ ARDOUR_UI::midi_panic () _session->midi_panic(); } } + +void +ARDOUR_UI::session_format_mismatch (std::string xml_path, std::string backup_path) +{ + const char* start_big = ""; + const char* end_big = ""; + const char* start_mono = ""; + 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 -2000 version with older versions of %3"), + xml_path, backup_path, PROGRAM_NAME, + start_big, end_big, + start_mono, end_mono), true); + + msg.run (); +}