X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_ui.cc;h=5bef863c955e964a736535c3bc62529626c88207;hb=c08b336292cd66e066eae23bc6272dce42ae28c2;hp=5846fa577fb88073a2ba14f8861065124d9b3532;hpb=2fee2bc60c4f675cd2c71f5d4d7d98dbb62afcf0;p=ardour.git diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 5846fa577f..5bef863c95 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 @@ -21,18 +21,21 @@ #include "gtk2ardour-config.h" #endif -#include - #include #include +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#include #include #include #include #include -#include -#include - -#include #include #include @@ -49,6 +52,7 @@ #include "pbd/memento_command.h" #include "pbd/openuri.h" #include "pbd/file_utils.h" +#include "pbd/localtime_r.h" #include "gtkmm2ext/application.h" #include "gtkmm2ext/bindings.h" @@ -67,6 +71,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" @@ -87,6 +92,7 @@ typedef uint64_t microseconds_t; #include "ambiguous_file_dialog.h" #include "ardour_ui.h" #include "audio_clock.h" +#include "big_clock_window.h" #include "bundle_manager.h" #include "engine_dialog.h" #include "gain_meter.h" @@ -94,6 +100,7 @@ typedef uint64_t microseconds_t; #include "gui_object.h" #include "gui_thread.h" #include "keyboard.h" +#include "keyeditor.h" #include "location_ui.h" #include "main_clock.h" #include "missing_file_dialog.h" @@ -101,11 +108,15 @@ 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" +#include "rc_option_editor.h" #include "route_time_axis.h" +#include "route_params_ui.h" #include "session_metadata_dialog.h" +#include "session_option_editor.h" #include "shuttle_control.h" #include "speaker_dialog.h" #include "splash.h" @@ -113,7 +124,10 @@ typedef uint64_t microseconds_t; #include "theme_manager.h" #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" @@ -130,18 +144,29 @@ sigc::signal ARDOUR_UI::Blink; sigc::signal ARDOUR_UI::RapidScreenUpdate; sigc::signal ARDOUR_UI::SuperRapidScreenUpdate; sigc::signal ARDOUR_UI::Clock; +sigc::signal ARDOUR_UI::CloseAllDialogs; 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 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 */ , big_clock (new AudioClock (X_("bigclock"), false, "big", true, true, false, false)) + , video_timeline(0) + + /* start of private members */ + + , _startup (0) + , engine (0) + , nsm (0) + , _was_dirty (false) + , _mixer_on_top (false) /* transport */ @@ -161,6 +186,21 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , solo_alert_button (_("solo")) , feedback_alert_button (_("feedback")) + , speaker_config_window (X_("speaker-config"), _("Speaker Configuration")) + , theme_manager (X_("theme-manager"), _("Theme Manager")) + , key_editor (X_("key-editor"), _("Key Bindings")) + , rc_option_editor (X_("rc-options-editor"), _("Preferences")) + , add_route_dialog (X_("add-routes"), _("Add Tracks/Busses")) + , about (X_("about"), _("About")) + , location_ui (X_("locations"), _("Locations")) + , route_params (X_("inspector"), _("Tracks and Busses")) + , session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this)) + , add_video_dialog (X_("add-video"), _("Add Tracks/Busses"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this)) + , bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this)) + , big_clock_window (X_("big-clock"), _("Big Clock"), boost::bind (&ARDOUR_UI::create_big_clock_window, this)) + , audio_port_matrix (X_("audio-connection-manager"), _("Audio Connections"), boost::bind (&ARDOUR_UI::create_global_port_matrix, this, ARDOUR::DataType::AUDIO)) + , midi_port_matrix (X_("midi-connection-manager"), _("MIDI Connections"), boost::bind (&ARDOUR_UI::create_global_port_matrix, this, ARDOUR::DataType::MIDI)) + , error_log_button (_("Errors")) , _status_bar_visibility (X_("status-bar")) @@ -169,43 +209,28 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) { Gtkmm2ext::init(localedir); - about = 0; splash = 0; - _startup = 0; if (theArdourUI == 0) { theArdourUI = this; } ui_config = new UIConfiguration(); - theme_manager = new ThemeManager(); - - key_editor = 0; editor = 0; mixer = 0; + meterbridge = 0; editor = 0; engine = 0; _session_is_new = false; - big_clock_window = 0; - big_clock_height = 0; - big_clock_resize_in_progress = false; session_selector_window = 0; last_key_press_time = 0; - add_route_dialog = 0; - route_params = 0; - bundle_manager = 0; - rc_option_editor = 0; - session_option_editor = 0; - location_ui = 0; + video_server_process = 0; open_session_selector = 0; have_configure_timeout = false; have_disk_speed_dialog_displayed = false; session_loaded = false; ignore_dual_punch = false; - original_big_clock_width = -1; - original_big_clock_height = -1; - original_big_clock_font_size = 0; roll_button.set_controllable (roll_controllable); stop_button.set_controllable (stop_controllable); @@ -234,6 +259,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) 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()); @@ -297,26 +324,53 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) TimeAxisViewItem::set_constant_heights (); - /* The following must happen after ARDOUR::init() so that Config is set up */ - - location_ui = new ActionWindowProxy (X_("locations"), Config->extra_xml (X_("UI")), X_("ToggleLocations")); - big_clock_window = new ActionWindowProxy (X_("bigclock"), Config->extra_xml (X_("UI")), X_("ToggleBigClock")); - speaker_config_window = new ActionWindowProxy (X_("speakerconf"), Config->extra_xml (X_("UI")), X_("toggle-speaker-config")); - - for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) { - _global_port_matrix[*i] = new ActionWindowProxy ( - string_compose ("GlobalPortMatrix-%1", (*i).to_string()), - Config->extra_xml (X_("UI")), - string_compose ("toggle-%1-connection-manager", (*i).to_string()) - ); - } + /* Set this up so that our window proxies can register actions */ - setup_clock (); + ActionManager::init (); - SpeakerDialog* s = new SpeakerDialog (); - s->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("/Common/toggle-speaker-config"))); - speaker_config_window->set (s); + /* The following must happen after ARDOUR::init() so that Config is set up */ + const XMLNode* ui_xml = Config->extra_xml (X_("UI")); + + if (ui_xml) { + theme_manager.set_state (*ui_xml); + key_editor.set_state (*ui_xml); + rc_option_editor.set_state (*ui_xml); + session_option_editor.set_state (*ui_xml); + speaker_config_window.set_state (*ui_xml); + about.set_state (*ui_xml); + add_route_dialog.set_state (*ui_xml); + add_video_dialog.set_state (*ui_xml); + route_params.set_state (*ui_xml); + bundle_manager.set_state (*ui_xml); + location_ui.set_state (*ui_xml); + big_clock_window.set_state (*ui_xml); + audio_port_matrix.set_state (*ui_xml); + midi_port_matrix.set_state (*ui_xml); + } + + WM::Manager::instance().register_window (&theme_manager); + WM::Manager::instance().register_window (&key_editor); + WM::Manager::instance().register_window (&rc_option_editor); + WM::Manager::instance().register_window (&session_option_editor); + WM::Manager::instance().register_window (&speaker_config_window); + WM::Manager::instance().register_window (&about); + WM::Manager::instance().register_window (&add_route_dialog); + WM::Manager::instance().register_window (&add_video_dialog); + WM::Manager::instance().register_window (&route_params); + WM::Manager::instance().register_window (&bundle_manager); + WM::Manager::instance().register_window (&location_ui); + WM::Manager::instance().register_window (&big_clock_window); + WM::Manager::instance().register_window (&audio_port_matrix); + WM::Manager::instance().register_window (&midi_port_matrix); + + /* We need to instantiate the theme manager because it loads our + theme files. This should really change so that its window + and its functionality are separate + */ + + (void) theme_manager.get (true); + starting.connect (sigc::mem_fun(*this, &ARDOUR_UI::startup)); stopping.connect (sigc::mem_fun(*this, &ARDOUR_UI::shutdown)); @@ -326,6 +380,14 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) DPIReset.connect (sigc::mem_fun (*this, &ARDOUR_UI::resize_text_widgets)); } +GlobalPortMatrixWindow* +ARDOUR_UI::create_global_port_matrix (ARDOUR::DataType type) +{ + if (!_session) { + return 0; + } + return new GlobalPortMatrixWindow (_session, type); +} int ARDOUR_UI::create_engine () @@ -367,12 +429,10 @@ ARDOUR_UI::post_engine () ARDOUR::init_post_engine (); - /* load up the UI manager */ - - ActionManager::init (); - _tooltips.enable(); + ActionManager::load_menus (); + if (setup_windows ()) { throw failed_constructor (); } @@ -456,7 +516,9 @@ ARDOUR_UI::~ARDOUR_UI () delete keyboard; delete editor; delete mixer; - delete add_route_dialog; + delete meterbridge; + + stop_video_server(); } void @@ -600,21 +662,98 @@ 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"); + + 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); } @@ -622,14 +761,7 @@ ARDOUR_UI::startup () goto_editor_window (); - /* Add the window proxies here; their addition may cause windows to be opened, and we want them - to be opened on top of the editor window that goto_editor_window() just opened. - */ - add_window_proxy (location_ui); - add_window_proxy (big_clock_window); - for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) { - add_window_proxy (_global_port_matrix[*i]); - } + WM::Manager::instance().show_visible (); /* We have to do this here since goto_editor_window() ends up calling show_all() on the * editor window, and we may want stuff to be hidden. @@ -649,7 +781,7 @@ ARDOUR_UI::no_memory_warning () void ARDOUR_UI::check_memory_locking () { -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(WIN32) /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */ return; #else // !__APPLE__ @@ -689,13 +821,13 @@ ARDOUR_UI::check_memory_locking () "runs out of memory. \n\n" "You can view the memory limit with 'ulimit -l', " "and it is normally controlled by %2"), - PROGRAM_NAME).c_str(), + PROGRAM_NAME, #ifdef __FreeBSD__ - X_("/etc/login.conf") + X_("/etc/login.conf") #else - X_(" /etc/security/limits.conf") + X_(" /etc/security/limits.conf") #endif - ); + ).c_str()); msg.set_default_response (RESPONSE_OK); @@ -739,6 +871,7 @@ void ARDOUR_UI::finish() { if (_session) { + ARDOUR_UI::instance()->video_timeline->sync_session_state(); if (_session->dirty()) { vector actions; @@ -774,12 +907,18 @@ If you still wish to quit, please use the\n\n\ point_zero_one_second_connection.disconnect(); } + delete ARDOUR_UI::instance()->video_timeline; + ARDOUR_UI::instance()->video_timeline = NULL; + stop_video_server(); + /* Save state before deleting the session, as that causes some windows to be destroyed before their visible state can be saved. */ save_ardour_state (); + close_all_dialogs (); + loading_message (string_compose (_("Please wait while %1 cleans up..."), PROGRAM_NAME)); if (_session) { @@ -790,7 +929,6 @@ If you still wish to quit, please use the\n\n\ _session = 0; } - ArdourDialog::close_all_dialogs (); engine->stop (true); quit (); } @@ -837,7 +975,6 @@ ARDOUR_UI::ask_about_saving_session (const vector& actions) window.get_vbox()->pack_start (dhbox); window.set_name (_("Prompter")); - window.set_position (Gtk::WIN_POS_MOUSE); window.set_modal (true); window.set_resizable (false); @@ -872,6 +1009,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; } @@ -1258,8 +1408,6 @@ ARDOUR_UI::open_recent_session () while (true) { - session_selector_window->set_position (WIN_POS_MOUSE); - ResponseType r = (ResponseType) session_selector_window->run (); switch (r) { @@ -2009,7 +2157,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 @@ -2193,11 +2345,7 @@ ARDOUR_UI::save_state (const string & name, bool switch_to_it) { XMLNode* node = new XMLNode (X_("UI")); - for (list::iterator i = _window_proxies.begin(); i != _window_proxies.end(); ++i) { - if (!(*i)->rc_configured()) { - node->add_child_nocopy (*((*i)->get_state ())); - } - } + WM::Manager::instance().add_state (*node); node->add_child_nocopy (gui_object_state->get_state()); @@ -2355,7 +2503,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; @@ -2432,6 +2580,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 */ @@ -2495,6 +2647,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) { @@ -2546,7 +2702,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); @@ -2824,43 +2980,16 @@ ARDOUR_UI::launch_chat () #endif } -void -ARDOUR_UI::show_about () -{ - if (about == 0) { - about = new About; - about->signal_response().connect (sigc::mem_fun (*this, &ARDOUR_UI::about_signal_response)); - } - - about->set_transient_for(*editor); - about->show_all (); -} - 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"); -} - -void -ARDOUR_UI::hide_about () -{ - if (about) { - about->get_window()->set_cursor (); - about->hide (); - } -} - -void -ARDOUR_UI::about_signal_response (int /*response*/) -{ - hide_about(); + PBD::open_uri (Config->get_reference_manual_url()); } void @@ -3123,19 +3252,15 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) return; } - if (add_route_dialog == 0) { - add_route_dialog = new AddRouteDialog (_session); - add_route_dialog->set_position (WIN_POS_MOUSE); - if (float_window) { - add_route_dialog->set_transient_for (*float_window); - } - } - if (add_route_dialog->is_visible()) { /* we're already doing this */ return; } + if (float_window) { + add_route_dialog->set_transient_for (*float_window); + } + ResponseType r = (ResponseType) add_route_dialog->run (); add_route_dialog->hide(); @@ -3161,7 +3286,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; } @@ -3199,6 +3328,273 @@ 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); + } + + if (video_server_process) { + delete video_server_process; + } + + video_server_process = new SystemExec(icsd_exec, argp); + if (video_server_process->start()) { + warning << _("Cannot launch the video-server") << endmsg; + continue; + } + int timeout = 120; // 6 sec + while (!ARDOUR_UI::instance()->video_timeline->check_server()) { + usleep (50000); + if (--timeout <= 0 || !video_server_process->is_running()) break; + } + if (timeout <= 0) { + warning << _("Video-server was started but does not respond to requests...") << endmsg; + } else { + if (!ARDOUR_UI::instance()->video_timeline->check_server_docroot()) { + delete video_server_process; + video_server_process = 0; + } + } + } + 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 (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, orig_local_file; + std::string path = add_video_dialog->file_name(local_file); + + std::string orig_path = path; + orig_local_file = 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")); + if (orig_local_file) { + node->add_property (X_("OriginalVideoFile"), orig_path); + } else { + node->remove_property (X_("OriginalVideoFile")); + } + _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 { @@ -3405,12 +3801,14 @@ audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual image->show(); hbox->show(); - switch (dialog.run ()) { + switch (dialog.run()) { case RESPONSE_ACCEPT: return 0; default: - return 1; + break; } + + return 1; } @@ -3464,12 +3862,12 @@ ARDOUR_UI::update_transport_clocks (framepos_t pos) secondary_clock->set (pos); } - if (big_clock_window->get()) { + if (big_clock_window) { big_clock->set (pos); } + ARDOUR_UI::instance()->video_timeline->manual_seek_video_monitor(pos); } - void ARDOUR_UI::step_edit_status_change (bool yn) { @@ -3490,7 +3888,7 @@ ARDOUR_UI::record_state_changed () { ENSURE_GUI_THREAD (*this, &ARDOUR_UI::record_state_changed); - if (!_session || !big_clock_window->get()) { + if (!_session || !big_clock_window) { /* why bother - the clock isn't visible */ return; } @@ -3629,63 +4027,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'. - */ -void -ARDOUR_UI::add_window_proxy (WindowProxyBase* p) -{ - _window_proxies.push_back (p); - p->maybe_show (); -} - -/** Remove a window proxy from our list. Must be called if a WindowProxy - * is deleted, to prevent hanging pointers. - */ -void -ARDOUR_UI::remove_window_proxy (WindowProxyBase* p) -{ - _window_proxies.remove (p); -} - int ARDOUR_UI::missing_file (Session*s, std::string str, DataType type) { @@ -3754,3 +4095,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 (); +}