X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_ui.cc;h=eebd35aefbc041c1449979c5670b0e3f30cafe78;hb=74126c48c0726e5491a160d2b0f04e406fc80231;hp=2b981ace8e0c2314ec9a1ef4054fd06ebce20ed4;hpb=91ff55bd89d44bf6d9ec222ac531f71f5700a91b;p=ardour.git diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 2b981ace8e..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 @@ -67,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" @@ -101,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" @@ -114,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" @@ -193,6 +199,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) 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; @@ -459,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 @@ -602,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); } @@ -741,6 +831,7 @@ void ARDOUR_UI::finish() { if (_session) { + ARDOUR_UI::instance()->video_timeline->sync_session_state(); if (_session->dirty()) { vector actions; @@ -776,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. @@ -874,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; } @@ -2361,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; @@ -2438,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 */ @@ -2501,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) { @@ -2552,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); @@ -2845,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 @@ -3167,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; } @@ -3205,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 { @@ -3473,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); } @@ -3727,10 +4088,17 @@ ARDOUR_UI::midi_panic () void ARDOUR_UI::session_format_mismatch (std::string xml_path, std::string backup_path) { - MessageDialog msg (string_compose (_("This is a session from an older version of Ardour.\n\n" - "Ardour has copied the old session file\n\n%1\n\nto\n\n%2\n\n" - "Use %2 with older versions of %3 from now on"), - xml_path, backup_path, PROGRAM_NAME)); + 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 (); }