#include <glib.h>
#include "pbd/gstdio_compat.h"
-#include <gtkmm/messagedialog.h>
#include <gtkmm/accelmap.h>
+#include <gtkmm/messagedialog.h>
#include <gtkmm/stock.h>
+#include <gtkmm/uimanager.h>
#include "pbd/error.h"
#include "pbd/basename.h"
#include "pbd/openuri.h"
#include "pbd/stl_delete.h"
#include "pbd/types_convert.h"
+#include "pbd/unwind.h"
#include "pbd/file_utils.h"
#include "pbd/localtime_r.h"
#include "pbd/pthread_utils.h"
#include "gtkmm2ext/bindings.h"
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/utils.h"
-#include "gtkmm2ext/click_box.h"
-#include "gtkmm2ext/fastmeter.h"
-#include "gtkmm2ext/popup.h"
#include "gtkmm2ext/window_title.h"
+#include "widgets/fastmeter.h"
+#include "widgets/prompter.h"
+
#include "ardour/ardour.h"
#include "ardour/audio_backend.h"
#include "ardour/audio_track.h"
#include "ardour/audioengine.h"
#include "ardour/audiofilesource.h"
#include "ardour/automation_watch.h"
-#include "ardour/diskstream.h"
+#include "ardour/disk_reader.h"
+#include "ardour/disk_writer.h"
#include "ardour/filename_extensions.h"
#include "ardour/filesystem_paths.h"
#include "ardour/ltc_file_reader.h"
#undef check
#endif
-#include "timecode/time.h"
+#include "temporal/time.h"
typedef uint64_t microseconds_t;
#include "audio_clock.h"
#include "audio_region_view.h"
#include "big_clock_window.h"
+#include "big_transport_window.h"
#include "bundle_manager.h"
#include "duplicate_routes_dialog.h"
#include "debug.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 "save_as_dialog.h"
+#include "save_template_dialog.h"
#include "script_selector.h"
#include "session_archive_dialog.h"
#include "session_dialog.h"
#include "speaker_dialog.h"
#include "splash.h"
#include "startup.h"
+#include "template_dialog.h"
#include "time_axis_view_item.h"
#include "time_info_box.h"
#include "timers.h"
using namespace ARDOUR_UI_UTILS;
using namespace PBD;
using namespace Gtkmm2ext;
+using namespace ArdourWidgets;
using namespace Gtk;
using namespace std;
using namespace Editing;
ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
-sigc::signal<void, framepos_t, bool, framepos_t> ARDOUR_UI::Clock;
-sigc::signal<void> ARDOUR_UI::CloseAllDialogs;
+sigc::signal<void, samplepos_t> ARDOUR_UI::Clock;
+sigc::signal<void> ARDOUR_UI::CloseAllDialogs;
static bool
ask_about_configuration_copy (string const & old_dir, string const & new_dir, int version)
Gtk::MESSAGE_INFO,
Gtk::BUTTONS_YES_NO,
true /* modal, though it hardly matters since it is the only window */
- );
+ );
msg.set_default_response (Gtk::RESPONSE_YES);
msg.show_all ();
static void
libxml_generic_error_func (void* /* parsing_context*/,
- const char* msg,
- ...)
+ const char* msg,
+ ...)
{
va_list ap;
char buf[2048];
ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
: Gtkmm2ext::UI (PROGRAM_NAME, X_("gui"), argcp, argvp)
, session_loaded (false)
+ , session_load_in_progress (false)
, gui_object_state (new GUIObjectState)
, primary_clock (new MainClock (X_("primary"), X_("transport"), true ))
, secondary_clock (new MainClock (X_("secondary"), X_("secondary"), false))
, _initial_verbose_plugin_scan (false)
, first_time_engine_run (true)
, secondary_clock_spacer (0)
- , roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll))
- , stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop))
- , goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart))
- , goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd))
- , auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop))
- , play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection))
- , rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable))
, auto_input_button (ArdourButton::led_default_elements)
, time_info_box (0)
, auto_return_button (ArdourButton::led_default_elements)
, solo_alert_button (_("Solo"))
, feedback_alert_button (_("Feedback"))
, error_alert_button ( ArdourButton::just_led_default_elements )
- , editor_meter(0)
, editor_meter_peak_display()
+ , editor_meter(0)
, _suspend_editor_meter_callbacks (false)
, _numpad_locate_happening (false)
, _session_is_new (false)
, add_video_dialog (X_("add-video"), _("Add Video"), 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))
+ , big_transport_window (X_("big-transport"), _("Transport Controls"), boost::bind (&ARDOUR_UI::create_big_transport_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))
, key_editor (X_("key-editor"), _("Keyboard Shortcuts"), boost::bind (&ARDOUR_UI::create_key_editor, this))
boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
UIConfiguration::instance().map_parameters (pc);
- roll_button.set_controllable (roll_controllable);
- stop_button.set_controllable (stop_controllable);
- goto_start_button.set_controllable (goto_start_controllable);
- goto_end_button.set_controllable (goto_end_controllable);
- auto_loop_button.set_controllable (auto_loop_controllable);
- play_selection_button.set_controllable (play_selection_controllable);
- rec_button.set_controllable (rec_controllable);
-
- roll_button.set_name ("transport button");
- stop_button.set_name ("transport button");
- goto_start_button.set_name ("transport button");
- goto_end_button.set_name ("transport button");
- auto_loop_button.set_name ("transport button");
- play_selection_button.set_name ("transport button");
- rec_button.set_name ("transport recenable button");
- midi_panic_button.set_name ("transport button");
-
- 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());
+ transport_ctrl.setup (this);
+
+ ARDOUR::DiskWriter::Overrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context());
+ ARDOUR::DiskReader::Underrun.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());
TimeAxisViewItem::set_constant_heights ();
- /* Set this up so that our window proxies can register actions */
+ /* Set this up so that our window proxies can register actions */
ActionManager::init ();
bundle_manager.set_state (*ui_xml, 0);
location_ui.set_state (*ui_xml, 0);
big_clock_window.set_state (*ui_xml, 0);
+ big_transport_window.set_state (*ui_xml, 0);
audio_port_matrix.set_state (*ui_xml, 0);
midi_port_matrix.set_state (*ui_xml, 0);
export_video_dialog.set_state (*ui_xml, 0);
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 (&big_transport_window);
WM::Manager::instance().register_window (&audio_port_matrix);
WM::Manager::instance().register_window (&midi_port_matrix);
WM::Manager::instance().register_window (&idleometer);
ArdourDialog d (_("Pre-Release Warning"), true, false);
d.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
- Label* label = manage (new Label);
- label->set_markup (string_compose (_("<b>Welcome to this pre-release build of %1 %2</b>\n\n\
+ Label* label = manage (new Label);
+ label->set_markup (string_compose (_("<b>Welcome to this pre-release build of %1 %2</b>\n\n\
There are still several issues and bugs to be worked on,\n\
as well as general workflow improvements, before this can be considered\n\
release software. So, a few guidelines:\n\
2) Please wait for a helpful writeup of new features.\n\
3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
4) Please <b>DO</b> use the bugtracker at http://tracker.ardour.org/ to report issues\n\
- making sure to note the product version number as 5.0-pre.\n\
+ making sure to note the product version number as 6.0-pre.\n\
5) Please <b>DO</b> use the ardour-users mailing list to discuss ideas and pass on comments.\n\
6) Please <b>DO</b> join us on IRC for real time discussions about %1 %2. You\n\
can get there directly from within the program via the Help->Chat menu option.\n\
http://ardour.org/support\n\
"), PROGRAM_NAME, VERSIONSTRING));
- d.get_vbox()->set_border_width (12);
- d.get_vbox()->pack_start (*label, false, false, 12);
- d.get_vbox()->show_all ();
+ d.get_vbox()->set_border_width (12);
+ d.get_vbox()->pack_start (*label, false, false, 12);
+ d.get_vbox()->show_all ();
- d.run ();
+ d.run ();
}
GlobalPortMatrixWindow*
throw failed_constructor ();
}
+ transport_ctrl.map_actions ();
+
/* Do this after setup_windows (), as that's when the _status_bar_visibility is created */
XMLNode* n = Config->extra_xml (X_("UI"));
if (n) {
vector<string>::iterator l;
for (p = paths.begin(), l = labels.begin(); p != paths.end(); ++p, ++l) {
- output << " <tr><th><kbd class=\"osc\">" << (*p).substr (9, string::npos);
+ output << " <tr><th><kbd class=\"osc\">" << (*p).substr (10, string::npos);
output << "</kbd></th><td>" << *l << "</td></tr>" << endl;
}
output << " </tbody>\n </table>" << endl;
GError *err = NULL;
gint fd;
- if ((fd = g_file_open_tmp ("akprintXXXXXX.html", &file_name, &err)) < 0) {
+ if ((fd = g_file_open_tmp ("list-of-menu-actionsXXXXXX.html", &file_name, &err)) < 0) {
if (err) {
error << string_compose (_("Could not open temporary file to print bindings (%1)"), err->message) << endmsg;
g_error_free (err);
delete gui_object_state; gui_object_state = 0;
delete main_window_visibility;
FastMeter::flush_pattern_cache ();
- PixFader::flush_pattern_cache ();
+ ArdourFader::flush_pattern_cache ();
}
#ifndef NDEBUG
* The wrapper startup script should set the environment variable 'ARDOUR_SELF'
*/
const char *process_name = g_getenv ("ARDOUR_SELF");
- nsm->announce (PROGRAM_NAME, ":dirty:", process_name ? process_name : "ardour4");
+ nsm->announce (PROGRAM_NAME, ":dirty:", process_name ? process_name : "ardour6");
unsigned int i = 0;
// wait for announce reply from nsm server
Searchpath ds (ARDOUR::ardour_data_search_path());
ds.add_subdirectory_to_paths ("sessions");
vector<string> demos;
- find_files_matching_pattern (demos, ds, "*.tar.xz");
+ find_files_matching_pattern (demos, ds, ARDOUR::session_archive_suffix);
ARDOUR::RecentSessions rs;
ARDOUR::read_recent_sessions (rs);
for (vector<string>::iterator i = demos.begin(); i != demos.end (); ++i) {
- /* "demo-session" must be inside "demo-session.tar.xz"
- * strip ".tar.xz"
- */
+ /* "demo-session" must be inside "demo-session.<session_archive_suffix>" */
std::string name = basename_nosuffix (basename_nosuffix (*i));
std::string path = Glib::build_filename (dspd, name);
/* skip if session-dir already exists */
BootMessage (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
- if (splash) {
- // in 1 second, hide the splash screen
- Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000);
- }
-
/* all other dialogs are created conditionally */
return 0;
void
ARDOUR_UI::every_point_one_seconds ()
{
- // TODO get rid of this..
- // ShuttleControl is updated directly via TransportStateChange signal
+ if (editor) editor->build_region_boundary_cache();
}
void
* signals to the GUI Thread..
*/
interval = floor(500. /* update twice per FPS, since Glib::signal_timeout is very irregular */
- * _session->frame_rate() / _session->nominal_frame_rate()
+ * _session->sample_rate() / _session->nominal_sample_rate()
/ _session->timecode_frames_per_second()
);
#ifdef PLATFORM_WINDOWS
}
void
-ARDOUR_UI::update_sample_rate (framecnt_t)
+ARDOUR_UI::update_sample_rate (samplecnt_t)
{
char buf[64];
} else {
- framecnt_t rate = AudioEngine::instance()->sample_rate();
+ samplecnt_t rate = AudioEngine::instance()->sample_rate();
if (rate == 0) {
/* no sample rate available */
if (_session) {
const unsigned int x = _session->get_xrun_count ();
+ dsp_load_indicator.set_xrun_count (x);
if (x > 9999) {
snprintf (buf, sizeof (buf), _("X: <span foreground=\"%s\">>10K</span>"), X_("red"));
} else {
}
} else {
snprintf (buf, sizeof (buf), _("X: <span foreground=\"%s\">?</span>"), X_("yellow"));
+ dsp_load_indicator.set_xrun_count (UINT_MAX);
}
xrun_label.set_markup (buf);
set_tip (xrun_label, _("Audio dropouts. Shift+click to reset"));
*/
double const c = AudioEngine::instance()->get_dsp_load ();
+ dsp_load_indicator.set_dsp_load (c);
snprintf (buf, sizeof (buf), _("DSP: <span foreground=\"%s\">%5.1f%%</span>"), c >= 90 ? X_("red") : X_("green"), c);
cpu_load_label.set_markup (buf);
}
ARDOUR_UI::update_disk_space()
{
if (_session == 0) {
+ disk_space_indicator.set_available_disk_sec (-1);
return;
}
- boost::optional<framecnt_t> opt_frames = _session->available_capture_duration();
+ boost::optional<samplecnt_t> opt_samples = _session->available_capture_duration();
char buf[64];
- framecnt_t fr = _session->frame_rate();
+ samplecnt_t fr = _session->sample_rate();
if (fr == 0) {
/* skip update - no SR available */
+ disk_space_indicator.set_available_disk_sec (-1);
return;
}
- if (!opt_frames) {
+ if (!opt_samples) {
/* Available space is unknown */
snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">Unknown</span>"));
- } else if (opt_frames.get_value_or (0) == max_framecnt) {
+ disk_space_indicator.set_available_disk_sec (-1);
+ } else if (opt_samples.get_value_or (0) == max_samplecnt) {
snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">24hrs+</span>"));
+ disk_space_indicator.set_available_disk_sec (max_samplecnt);
} else {
rec_enabled_streams = 0;
_session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams, false);
- framecnt_t frames = opt_frames.get_value_or (0);
+ samplecnt_t samples = opt_samples.get_value_or (0);
if (rec_enabled_streams) {
- frames /= rec_enabled_streams;
+ samples /= rec_enabled_streams;
}
int hrs;
int mins;
int secs;
- hrs = frames / (fr * 3600);
+ disk_space_indicator.set_available_disk_sec (samples / (float)fr);
+
+ hrs = samples / (fr * 3600);
if (hrs > 24) {
snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">>24 hrs</span>"));
} else {
- frames -= hrs * fr * 3600;
- mins = frames / (fr * 60);
- frames -= mins * fr * 60;
- secs = frames / fr;
+ samples -= hrs * fr * 3600;
+ mins = samples / (fr * 60);
+ samples -= mins * fr * 60;
+ secs = samples / fr;
bool const low = (hrs == 0 && mins <= 30);
can_return = false;
}
- if (splash) {
- // in 1 second, hide the splash screen
- Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000);
- }
}
bool
{
if (!AudioEngine::instance()->connected()) {
MessageDialog msg (parent, string_compose (
- _("%1 is not connected to any audio backend.\n"
- "You cannot open or close sessions in this condition"),
- PROGRAM_NAME));
+ _("%1 is not connected to any audio backend.\n"
+ "You cannot open or close sessions in this condition"),
+ PROGRAM_NAME));
pop_back_splash (msg);
msg.run ();
return false;
string default_session_folder = Config->get_default_session_parent_dir();
open_session_selector.add_shortcut_folder (default_session_folder);
}
- catch (Glib::Error & e) {
+ catch (Glib::Error const& e) {
std::cerr << "open_session_selector.add_shortcut_folder() threw Glib::Error " << e.what() << std::endl;
}
open_session_selector.add_filter (session_filter);
FileFilter archive_filter;
- archive_filter.add_pattern (X_("*.tar.xz"));
+ archive_filter.add_pattern (string_compose(X_("*%1"), ARDOUR::session_archive_suffix));
archive_filter.set_name (_("Session Archives"));
open_session_selector.add_filter (archive_filter);
}
}
-void
-ARDOUR_UI::session_add_vca (const string& name_template, uint32_t n)
-{
- if (!_session) {
- return;
- }
-
- _session->vca_manager().create_vca (n, name_template);
-}
-
void
ARDOUR_UI::session_add_mixed_track (
const ChanCount& input,
Plugin::PresetRecord* pset,
ARDOUR::PresentationInfo::order_t order)
{
- if (_session == 0) {
- warning << _("You cannot add a track without a session already loaded.") << endmsg;
- return;
- }
+ assert (_session);
if (Profile->get_mixbus ()) {
strict_io = true;
list<boost::shared_ptr<AudioTrack> > tracks;
RouteList routes;
- if (_session == 0) {
- warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
- return;
- }
+ assert (_session);
try {
if (track) {
*/
if (editor) {
- editor->center_screen (_session->current_start_frame ());
+ editor->center_screen (_session->current_start_sample ());
}
}
}
time_t now;
struct tm tmnow;
- framepos_t frames;
+ samplepos_t samples;
time (&now);
localtime_r (&now, &tmnow);
- framecnt_t frame_rate = _session->frame_rate();
+ samplecnt_t sample_rate = _session->sample_rate();
- if (frame_rate == 0) {
+ if (sample_rate == 0) {
/* no frame rate available */
return;
}
- frames = tmnow.tm_hour * (60 * 60 * frame_rate);
- frames += tmnow.tm_min * (60 * frame_rate);
- frames += tmnow.tm_sec * frame_rate;
+ samples = tmnow.tm_hour * (60 * 60 * sample_rate);
+ samples += tmnow.tm_min * (60 * sample_rate);
+ samples += tmnow.tm_sec * sample_rate;
- _session->request_locate (frames, _session->transport_rolling ());
+ _session->request_locate (samples, _session->transport_rolling ());
/* force displayed area in editor to start no matter
what "follow playhead" setting is.
*/
if (editor) {
- editor->center_screen (frames);
+ editor->center_screen (samples);
}
}
}
ARDOUR_UI::transport_goto_end ()
{
if (_session) {
- framepos_t const frame = _session->current_end_frame();
- _session->request_locate (frame);
+ samplepos_t const sample = _session->current_end_sample();
+ _session->request_locate (sample);
/* force displayed area in editor to start no matter
what "follow playhead" setting is.
*/
if (editor) {
- editor->center_screen (frame);
+ editor->center_screen (sample);
}
}
}
* want to do this.
*/
- if (UIConfiguration::instance().get_follow_edits() && ( editor->get_selection().time.front().start == _session->transport_frame() ) ) { //if playhead is exactly at the start of a range, we can assume it was placed there by follow_edits
+ if (UIConfiguration::instance().get_follow_edits() && ( editor->get_selection().time.front().start == _session->transport_sample() ) ) { //if playhead is exactly at the start of a range, we can assume it was placed there by follow_edits
_session->request_play_range (&editor->get_selection().time, true);
- _session->set_requested_return_frame( editor->get_selection().time.front().start ); //force an auto-return here
+ _session->set_requested_return_sample( editor->get_selection().time.front().start ); //force an auto-return here
}
_session->request_transport_speed (1.0f);
}
ARDOUR_UI::map_transport_state ()
{
if (!_session) {
- auto_loop_button.unset_active_state ();
- play_selection_button.unset_active_state ();
- roll_button.unset_active_state ();
- stop_button.set_active_state (Gtkmm2ext::ExplicitActive);
layered_button.set_sensitive (false);
return;
}
float sp = _session->transport_speed();
if (sp != 0.0f) {
-
- /* we're rolling */
-
- if (_session->get_play_range()) {
-
- play_selection_button.set_active_state (Gtkmm2ext::ExplicitActive);
- roll_button.unset_active_state ();
- auto_loop_button.unset_active_state ();
-
- } else if (_session->get_play_loop ()) {
-
- auto_loop_button.set_active (true);
- play_selection_button.set_active (false);
- if (Config->get_loop_is_mode()) {
- roll_button.set_active (true);
- } else {
- roll_button.set_active (false);
- }
-
- } else {
-
- roll_button.set_active (true);
- play_selection_button.set_active (false);
- auto_loop_button.set_active (false);
- }
-
- if (UIConfiguration::instance().get_follow_edits() && !_session->config.get_external_sync()) {
- /* light up both roll and play-selection if they are joined */
- roll_button.set_active (true);
- play_selection_button.set_active (true);
- }
layered_button.set_sensitive (!_session->actively_recording ());
-
- stop_button.set_active (false);
-
} else {
-
layered_button.set_sensitive (true);
- stop_button.set_active (true);
- roll_button.set_active (false);
- play_selection_button.set_active (false);
- if (Config->get_loop_is_mode ()) {
- auto_loop_button.set_active (_session->get_play_loop());
- } else {
- auto_loop_button.set_active (false);
- }
update_disk_space ();
}
}
void
ARDOUR_UI::blink_handler (bool blink_on)
{
- transport_rec_enable_blink (blink_on);
sync_blink (blink_on);
if (!UIConfiguration::instance().get_blink_alert_indicators()) {
solo_blink (blink_on);
audition_blink (blink_on);
feedback_blink (blink_on);
+
+ dsp_load_indicator.blink(blink_on);
+ disk_space_indicator.blink(blink_on);
}
void
if (!_session) return;
if (editor && !editor->dragging_playhead()) {
- Clock (_session->audible_frame(), false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD)); /* EMIT_SIGNAL */
+ Clock (_session->audible_sample()); /* EMIT_SIGNAL */
}
}
return;
}
+ if (_session->dirty()) {
+ vector<string> actions;
+ actions.push_back (_("Abort save-as"));
+ actions.push_back (_("Don't save now, just save-as"));
+ actions.push_back (_("Save it first"));
+ switch (ask_about_saving_session(actions)) {
+ case -1:
+ return;
+ break;
+ case 1:
+ if (save_state_canfail ("")) {
+ MessageDialog msg (_main_window,
+ string_compose (_("\
+%1 was unable to save your session.\n\n\
+If you still wish to proceeed, please use the\n\n\
+\"Don't save now\" option."), PROGRAM_NAME));
+ pop_back_splash(msg);
+ msg.run ();
+ return;
+ }
+ // no break
+ case 0:
+ _session->remove_pending_capture_state ();
+ break;
+ }
+ }
+
if (!save_as_dialog) {
save_as_dialog = new SaveAsDialog;
}
if (!sa.include_media && sa.switch_to) {
unload_session (false);
load_session (sa.final_session_folder_name, sa.new_name);
- hide_splash ();
}
}
return;
}
- if (_session->archive_session (sad.target_folder(), sad.name(), sad.encode_option (), sad.only_used_sources (), &sad)) {
+ if (_session->archive_session (sad.target_folder(), sad.name(), sad.encode_option (), sad.compression_level (), sad.only_used_sources (), &sad)) {
MessageDialog msg (_("Session Archiving failed."));
msg.run ();
}
time (&n);
localtime_r (&n, &local_time);
strftime (timebuf, sizeof(timebuf), "%FT%H.%M.%S", &local_time);
+ if (switch_to_it && _session->dirty ()) {
+ save_state_canfail ("");
+ }
save_state (timebuf, switch_to_it);
}
bool
-ARDOUR_UI::process_snapshot_session_prompter (ArdourPrompter& prompter, bool switch_to_it)
+ARDOUR_UI::process_snapshot_session_prompter (Prompter& prompter, bool switch_to_it)
{
string snapname;
char illegal = Session::session_name_is_legal(snapname);
if (illegal) {
MessageDialog msg (string_compose (_("To ensure compatibility with various systems\n"
- "snapshot names may not contain a '%1' character"), illegal));
+ "snapshot names may not contain a '%1' character"), illegal));
msg.run ();
return false;
}
void
ARDOUR_UI::snapshot_session (bool switch_to_it)
{
- ArdourPrompter prompter (true);
+ if (switch_to_it && _session->dirty()) {
+ vector<string> actions;
+ actions.push_back (_("Abort saving snapshot"));
+ actions.push_back (_("Don't save now, just snapshot"));
+ actions.push_back (_("Save it first"));
+ switch (ask_about_saving_session(actions)) {
+ case -1:
+ return;
+ break;
+ case 1:
+ if (save_state_canfail ("")) {
+ MessageDialog msg (_main_window,
+ string_compose (_("\
+%1 was unable to save your session.\n\n\
+If you still wish to proceeed, please use the\n\n\
+\"Don't save now\" option."), PROGRAM_NAME));
+ pop_back_splash(msg);
+ msg.run ();
+ return;
+ }
+ // no break
+ case 0:
+ _session->remove_pending_capture_state ();
+ break;
+ }
+ }
+ Prompter prompter (true);
prompter.set_name ("Prompter");
prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
if (switch_to_it) {
return;
}
- ArdourPrompter prompter (true);
+ Prompter prompter (true);
string name;
prompter.set_name ("Prompter");
if (illegal) {
MessageDialog msg (string_compose (_("To ensure compatibility with various systems\n"
- "session names may not contain a '%1' character"), illegal));
+ "session names may not contain a '%1' character"), illegal));
msg.run ();
goto again;
}
_session->request_locate (secondary_clock->current_time ());
}
}
-
void
-ARDOUR_UI::transport_rec_enable_blink (bool onoff)
-{
- if (_session == 0) {
- return;
- }
-
- if (_session->step_editing()) {
- return;
- }
-
- Session::RecordState const r = _session->record_status ();
- bool const h = _session->have_rec_enabled_track ();
-
- if (r == Session::Enabled || (r == Session::Recording && !h)) {
- if (onoff) {
- rec_button.set_active_state (Gtkmm2ext::ExplicitActive);
- } else {
- rec_button.set_active_state (Gtkmm2ext::Off);
- }
- } else if (r == Session::Recording && h) {
- rec_button.set_active_state (Gtkmm2ext::ExplicitActive);
- } else {
- rec_button.unset_active_state ();
- }
-}
-
-bool
-ARDOUR_UI::process_save_template_prompter (ArdourPrompter& prompter)
+ARDOUR_UI::save_template_dialog_response (int response, SaveTemplateDialog* d)
{
- string name;
-
- prompter.get_result (name);
+ if (response == RESPONSE_ACCEPT) {
+ const string name = d->get_template_name ();
+ const string desc = d->get_description ();
- if (name.length()) {
- int failed = _session->save_template (name);
+ int failed = _session->save_template (name, desc);
if (failed == -2) { /* file already exists. */
- bool overwrite = overwrite_file_dialog (prompter,
+ bool overwrite = overwrite_file_dialog (*d,
_("Confirm Template Overwrite"),
_("A template already exists with that name. Do you want to overwrite it?"));
if (overwrite) {
- _session->save_template (name, true);
+ _session->save_template (name, desc, true);
}
else {
- return false;
+ d->show ();
+ return;
}
}
}
-
- return true;
+ delete d;
}
void
ARDOUR_UI::save_template ()
{
- ArdourPrompter prompter (true);
-
if (!check_audioengine (_main_window)) {
return;
}
- prompter.set_name (X_("Prompter"));
- prompter.set_title (_("Save Template"));
- prompter.set_prompt (_("Name for template:"));
- prompter.set_initial_text(_session->name() + _("-template"));
- prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
-
- bool finished = false;
- while (!finished) {
- switch (prompter.run()) {
- case RESPONSE_ACCEPT:
- finished = process_save_template_prompter (prompter);
- break;
+ const std::string desc = SessionMetadata::Metadata()->description ();
+ SaveTemplateDialog* d = new SaveTemplateDialog (_session->name (), desc);
+ d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::save_template_dialog_response), d));
+ d->show ();
+}
- default:
- finished = true;
- break;
- }
- }
+void ARDOUR_UI::manage_templates ()
+{
+ TemplateDialog td;
+ td.run();
}
void
BusProfile bus_profile;
if (nsm) {
-
bus_profile.master_out_channels = 2;
- bus_profile.input_ac = AutoConnectPhysical;
- bus_profile.output_ac = AutoConnectMaster;
- bus_profile.requested_physical_in = 0; // use all available
- bus_profile.requested_physical_out = 0; // use all available
-
} else {
-
/* get settings from advanced section of NSD */
-
- if (sd.create_master_bus()) {
- bus_profile.master_out_channels = (uint32_t) sd.master_channel_count();
- } else {
- bus_profile.master_out_channels = 0;
- }
-
- if (sd.connect_inputs()) {
- bus_profile.input_ac = AutoConnectPhysical;
- } else {
- bus_profile.input_ac = AutoConnectOption (0);
- }
-
- bus_profile.output_ac = AutoConnectOption (0);
-
- if (sd.connect_outputs ()) {
- if (sd.connect_outs_to_master()) {
- bus_profile.output_ac = AutoConnectMaster;
- } else if (sd.connect_outs_to_physical()) {
- bus_profile.output_ac = AutoConnectPhysical;
- }
- }
-
- bus_profile.requested_physical_in = (uint32_t) sd.input_limit_count();
- bus_profile.requested_physical_out = (uint32_t) sd.output_limit_count();
+ bus_profile.master_out_channels = (uint32_t) sd.master_channel_count();
}
- if (build_session (session_path, session_name, bus_profile)) {
+ // NULL profile: no master, no monitor
+ if (build_session (session_path, session_name, bus_profile.master_out_channels > 0 ? &bus_profile : NULL)) {
return -1;
}
break;
default:
if (quit_on_cancel) {
- // JE - Currently (July 2014) this section can only get reached if the
- // user quits from the main 'Session Setup' dialog (i.e. reaching this
- // point does NOT indicate an abnormal termination). Therefore, let's
- // behave gracefully (i.e. let's do some cleanup) before we call exit()
+ ARDOUR_UI::finish ();
+ Gtkmm2ext::Application::instance()->cleanup();
ARDOUR::cleanup ();
pthread_cancel_all ();
-
- exit (1);
+ return -1; // caller is responsible to call exit()
} else {
return ret;
}
session_path = session_dialog.session_folder ();
if (nsm) {
- likely_new = true;
+ likely_new = true;
}
if (!likely_new) {
if (session_name[0] == G_DIR_SEPARATOR ||
#ifdef PLATFORM_WINDOWS
- (session_name.length() > 3 && session_name[1] == ':' && session_name[2] == G_DIR_SEPARATOR)
+ (session_name.length() > 3 && session_name[1] == ':' && session_name[2] == G_DIR_SEPARATOR)
#else
- (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == G_DIR_SEPARATOR) ||
- (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == G_DIR_SEPARATOR)
+ (session_name.length() > 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)
#endif
- )
+ )
{
/* absolute path or cwd-relative path specified for session name: infer session folder
if (illegal) {
MessageDialog msg (session_dialog,
- string_compose (_("To ensure compatibility with various systems\n"
- "session names may not contain a '%1' character"),
- illegal));
+ 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 (illegal) {
pop_back_splash (session_dialog);
MessageDialog msg (session_dialog, string_compose(_("To ensure compatibility with various systems\n"
- "session names may not contain a '%1' character"), illegal));
+ "session names may not contain a '%1' character"), illegal));
msg.run ();
ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
continue;
_session_is_new = true;
}
- if (likely_new && template_name.empty()) {
+ if (!template_name.empty() && template_name.substr (0, 11) == "urn:ardour:") {
+
+ ret = build_session_from_dialog (session_dialog, session_path, session_name);
+ meta_session_setup (template_name.substr (11));
+
+ } else if (likely_new && template_name.empty()) {
ret = build_session_from_dialog (session_dialog, session_path, session_name);
if (get_session_parameters (true, false)) {
exit (1);
}
- if (splash && splash->is_visible()) {
- // in 1 second, hide the splash screen
- Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000);
- }
}
/** @param snap_name Snapshot name (without .ardour suffix).
int
ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, std::string mix_template)
{
+ /* load_session calls flush_pending() which allows
+ * GUI interaction and potentially loading another session
+ * (that was easy via snapshot sidebar).
+ * Recursing into load_session() from load_session() and recusive
+ * event loops causes all kind of crashes.
+ */
+ assert (!session_load_in_progress);
+ if (session_load_in_progress) {
+ return -1;
+ }
+ PBD::Unwinder<bool> lsu (session_load_in_progress, true);
+
Session *new_session;
int unload_status;
int retval = -1;
/* this one is special */
- catch (AudioEngine::PortRegistrationFailure& err) {
+ catch (AudioEngine::PortRegistrationFailure const& err) {
MessageDialog msg (err.what(),
true,
}
goto out;
}
- catch (SessionException e) {
+ catch (SessionException const& e) {
MessageDialog msg (string_compose(
- _("Session \"%1 (snapshot %2)\" did not load successfully: %3"),
+ _("Session \"%1 (snapshot %2)\" did not load successfully:\n%3"),
path, snap_name, e.what()),
true,
Gtk::MESSAGE_INFO,
catch (...) {
MessageDialog msg (string_compose(
- _("Session \"%1 (snapshot %2)\" did not load successfully"),
- path, snap_name),
+ _("Session \"%1 (snapshot %2)\" did not load successfully."),
+ path, snap_name),
true,
Gtk::MESSAGE_INFO,
BUTTONS_OK);
#endif
retval = 0;
+ if (!mix_template.empty ()) {
+ /* if mix_template is given, assume this is a new session */
+ string metascript = Glib::build_filename (mix_template, "template.lua");
+ meta_session_setup (metascript);
+ }
+
+
out:
+ /* For successful session load the splash is hidden by ARDOUR_UI::first_idle,
+ * which is queued by set_session().
+ * If session-loading fails we hide it explicitly.
+ * This covers both cases in a central place.
+ */
+ if (retval) {
+ hide_splash ();
+ }
return retval;
}
int
-ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, BusProfile& bus_profile)
+ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, BusProfile* bus_profile)
{
Session *new_session;
int x;
_session_is_new = true;
try {
- new_session = new Session (*AudioEngine::instance(), path, snap_name, &bus_profile);
+ new_session = new Session (*AudioEngine::instance(), path, snap_name, bus_profile);
}
- catch (SessionException e) {
+ catch (SessionException const& e) {
cerr << "Here are the errors associated with this failed session:\n";
dump_errors (cerr);
cerr << "---------\n";
return 0;
}
+
+static void _lua_print (std::string s) {
+#ifndef NDEBUG
+ std::cout << "LuaInstance: " << s << "\n";
+#endif
+ PBD::info << "LuaInstance: " << s << endmsg;
+}
+
+std::map<std::string, std::string>
+ARDOUR_UI::route_setup_info (const std::string& script_path)
+{
+ std::map<std::string, std::string> rv;
+
+ if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
+ return rv;
+ }
+
+ LuaState lua;
+ lua.Print.connect (&_lua_print);
+ lua.sandbox (true);
+
+ lua_State* L = lua.getState();
+ LuaInstance::register_classes (L);
+ LuaBindings::set_session (L, _session);
+ luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
+ lua_setglobal (L, "Editor");
+
+ lua.do_command ("function ardour () end");
+ lua.do_file (script_path);
+
+ try {
+ luabridge::LuaRef fn = luabridge::getGlobal (L, "route_setup");
+ if (!fn.isFunction ()) {
+ return rv;
+ }
+ luabridge::LuaRef rs = fn ();
+ if (!rs.isTable ()) {
+ return rv;
+ }
+ for (luabridge::Iterator i(rs); !i.isNil (); ++i) {
+ if (!i.key().isString()) {
+ continue;
+ }
+ std::string key = i.key().tostring();
+ if (i.value().isString() || i.value().isNumber() || i.value().isBoolean()) {
+ rv[key] = i.value().tostring();
+ }
+ }
+ } catch (luabridge::LuaException const& e) {
+ cerr << "LuaException:" << e.what () << endl;
+ } catch (...) { }
+ return rv;
+}
+
+void
+ARDOUR_UI::meta_route_setup (const std::string& script_path)
+{
+ if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
+ return;
+ }
+ assert (add_route_dialog);
+
+ int count;
+ if ((count = add_route_dialog->count()) <= 0) {
+ return;
+ }
+
+ LuaState lua;
+ lua.Print.connect (&_lua_print);
+ lua.sandbox (true);
+
+ lua_State* L = lua.getState();
+ LuaInstance::register_classes (L);
+ LuaBindings::set_session (L, _session);
+ luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
+ lua_setglobal (L, "Editor");
+
+ lua.do_command ("function ardour () end");
+ lua.do_file (script_path);
+
+ luabridge::LuaRef args (luabridge::newTable (L));
+
+ args["name"] = add_route_dialog->name_template ();
+ args["insert_at"] = translate_order (add_route_dialog->insert_at());
+ args["group"] = add_route_dialog->route_group ();
+ args["strict_io"] = add_route_dialog->use_strict_io ();
+ args["instrument"] = add_route_dialog->requested_instrument ();
+ args["track_mode"] = add_route_dialog->mode ();
+ args["channels"] = add_route_dialog->channel_count ();
+ args["how_many"] = count;
+
+ try {
+ luabridge::LuaRef fn = luabridge::getGlobal (L, "factory");
+ if (fn.isFunction()) {
+ fn (args)();
+ }
+ } catch (luabridge::LuaException const& e) {
+ cerr << "LuaException:" << e.what () << endl;
+ } catch (...) {
+ display_insufficient_ports_message ();
+ }
+}
+
+void
+ARDOUR_UI::meta_session_setup (const std::string& script_path)
+{
+ if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
+ return;
+ }
+
+ LuaState lua;
+ lua.Print.connect (&_lua_print);
+ lua.sandbox (true);
+
+ lua_State* L = lua.getState();
+ LuaInstance::register_classes (L);
+ LuaBindings::set_session (L, _session);
+ luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
+ lua_setglobal (L, "Editor");
+
+ lua.do_command ("function ardour () end");
+ lua.do_file (script_path);
+
+ try {
+ luabridge::LuaRef fn = luabridge::getGlobal (L, "factory");
+ if (fn.isFunction()) {
+ fn ()();
+ }
+ } catch (luabridge::LuaException const& e) {
+ cerr << "LuaException:" << e.what () << endl;
+ } catch (...) {
+ display_insufficient_ports_message ();
+ }
+}
+
void
ARDOUR_UI::launch_chat ()
{
void
ARDOUR_UI::hide_splash ()
{
- delete splash;
- splash = 0;
+ delete splash;
+ splash = 0;
}
void
if (removed == 0) {
MessageDialog msgd (_main_window,
- _("No files were ready for clean-up"),
- true,
- Gtk::MESSAGE_INFO,
- Gtk::BUTTONS_OK);
+ _("No files were ready for clean-up"),
+ true,
+ Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_OK);
msgd.set_title (_("Clean-up"));
- msgd.set_secondary_text (_("If this seems suprising, \n\
+ msgd.set_secondary_text (_("If this seems surprising, \n\
check for any existing snapshots.\n\
These may still include regions that\n\
require some unused files to continue to exist."));
ArdourDialog results (_("Clean-up"), true, false);
struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
- CleanupResultsModelColumns() {
- add (visible_name);
- add (fullpath);
- }
- Gtk::TreeModelColumn<std::string> visible_name;
- Gtk::TreeModelColumn<std::string> fullpath;
+ CleanupResultsModelColumns() {
+ add (visible_name);
+ add (fullpath);
+ }
+ Gtk::TreeModelColumn<std::string> visible_name;
+ Gtk::TreeModelColumn<std::string> fullpath;
};
RegionSelection rs;
TrackViewList empty;
empty.clear();
- editor->get_regions_after(rs, (framepos_t) 0, empty);
+ editor->get_regions_after(rs, (samplepos_t) 0, empty);
std::list<RegionView*> views = rs.by_layer();
// remove displayed audio-region-views waveforms
ARDOUR_UI::translate_order (RouteDialogs::InsertAt place)
{
if (editor->get_selection().tracks.empty()) {
- return PresentationInfo::max_order;
+ return place == RouteDialogs::First ? 0 : PresentationInfo::max_order;
}
PresentationInfo::order_t order_hint = PresentationInfo::max_order;
void
ARDOUR_UI::add_route_dialog_response (int r)
{
+ if (!_session) {
+ warning << _("You cannot add tracks or busses without a session already loaded.") << endmsg;
+ return;
+ }
+
int count;
switch (r) {
case AddRouteDialog::Add:
+ add_route_dialog->reset_name_edited ();
break;
case AddRouteDialog::AddAndClose:
add_route_dialog->ArdourDialog::on_response (r);
return;
}
+ std::string template_path = add_route_dialog->get_template_path();
+ if (!template_path.empty() && template_path.substr (0, 11) == "urn:ardour:") {
+ meta_route_setup (template_path.substr (11));
+ return;
+ }
+
if ((count = add_route_dialog->count()) <= 0) {
return;
}
PresentationInfo::order_t order = translate_order (add_route_dialog->insert_at());
- string template_path = add_route_dialog->track_template();
+ const string name_template = add_route_dialog->name_template ();
DisplaySuspender ds;
- if (!template_path.empty()) {
- if (add_route_dialog->name_template_is_default()) {
- _session->new_route_from_template (count, order, template_path, string());
+ if (!template_path.empty ()) {
+ if (add_route_dialog->name_template_is_default ()) {
+ _session->new_route_from_template (count, order, template_path, string ());
} else {
- _session->new_route_from_template (count, order, template_path, add_route_dialog->name_template());
+ _session->new_route_from_template (count, order, template_path, name_template);
}
return;
}
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();
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, strict_io, order);
+ session_add_audio_route (true, input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template, strict_io, order);
break;
case AddRouteDialog::MidiTrack:
- session_add_midi_track (route_group, count, name_template, strict_io, instrument, 0, order);
+ session_add_midi_route (true, route_group, count, name_template, strict_io, instrument, 0, order);
break;
case AddRouteDialog::MixedTrack:
session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, strict_io, instrument, 0, order);
break;
case AddRouteDialog::AudioBus:
- session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template, strict_io, order);
+ session_add_audio_route (false, input_chan.n_audio(), output_chan.n_audio(), ARDOUR::Normal, route_group, count, name_template, strict_io, order);
break;
case AddRouteDialog::MidiBus:
session_add_midi_bus (route_group, count, name_template, strict_io, instrument, 0, order);
break;
case AddRouteDialog::VCAMaster:
- session_add_vca (name_template, count);
+ _session->vca_manager().create_vca (count, name_template);
break;
}
}
LTCFileReader ltcr (audio_from_video, video_timeline->get_video_file_fps());
/* TODO ASK user which channel: 0 .. ltcr->channels() - 1 */
- ltc_seq = ltcr.read_ltc (/*channel*/ 0, /*max LTC frames to decode*/ 15);
+ ltc_seq = ltcr.read_ltc (/*channel*/ 0, /*max LTC samples to decode*/ 15);
/* TODO seek near end of file, and read LTC until end.
- * if it fails to find any LTC frames, scan complete file
+ * if it fails to find any LTC samples, scan complete file
*
* calculate drift of LTC compared to video-duration,
* ask user for reference (timecode from start/mid/end)
} else {
/* the very first TC in the file is somteimes not aligned properly */
int i = ltc_seq.size() -1;
- ARDOUR::frameoffset_t video_start_offset =
- _session->nominal_frame_rate() * (ltc_seq[i].timecode_sec - ltc_seq[i].framepos_sec);
+ ARDOUR::sampleoffset_t video_start_offset =
+ _session->nominal_sample_rate() * (ltc_seq[i].timecode_sec - ltc_seq[i].framepos_sec);
PBD::info << string_compose (_("Align video-start to %1 [samples]"), video_start_offset) << endmsg;
video_timeline->set_offset(video_start_offset);
}
}
_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));
+ std::max(video_timeline->get_offset(), (ARDOUR::sampleoffset_t) 0),
+ std::max(video_timeline->get_offset() + video_timeline->get_duration(), (ARDOUR::sampleoffset_t) 0));
if (add_video_dialog->launch_xjadeo() && local_file) {
}
void
-ARDOUR_UI::create_xrun_marker (framepos_t where)
+ARDOUR_UI::create_xrun_marker (samplepos_t where)
{
if (_session) {
Location *location = new Location (*_session, where, where, _("xrun"), Location::IsMark, 0);
void
ARDOUR_UI::halt_on_xrun_message ()
{
- cerr << "HALT on xrun\n";
- MessageDialog msg (_main_window, _("Recording was stopped because your system could not keep up."));
+ cerr << "HALT on xrun\n";
+ MessageDialog msg (_main_window, _("Recording was stopped because your system could not keep up."));
msg.run ();
}
void
-ARDOUR_UI::xrun_handler (framepos_t where)
+ARDOUR_UI::xrun_handler (samplepos_t where)
{
if (!_session) {
return;
ENSURE_GUI_THREAD (*this, &ARDOUR_UI::xrun_handler, where)
+ if (_session && _session->actively_recording()) {
+ dsp_load_indicator.set_xrun_while_recording();
+ }
+
if (_session && Config->get_create_xrun_marker() && _session->actively_recording()) {
create_xrun_marker(where);
}
}
int
-ARDOUR_UI::sr_mismatch_dialog (framecnt_t desired, framecnt_t actual)
+ARDOUR_UI::sr_mismatch_dialog (samplecnt_t desired, samplecnt_t actual)
{
HBox* hbox = new HBox();
Image* image = new Image (Stock::DIALOG_WARNING, ICON_SIZE_DIALOG);
case RESPONSE_ACCEPT:
return 0;
default:
- break;
+ break;
}
- return 1;
+ return 1;
}
void
-ARDOUR_UI::sr_mismatch_message (framecnt_t desired, framecnt_t actual)
+ARDOUR_UI::sr_mismatch_message (samplecnt_t desired, samplecnt_t actual)
{
MessageDialog msg (string_compose (_("\
This session was created with a sample rate of %1 Hz, but\n\
}
void
-ARDOUR_UI::update_transport_clocks (framepos_t pos)
+ARDOUR_UI::update_transport_clocks (samplepos_t pos)
{
- if (UIConfiguration::instance().get_primary_clock_delta_edit_cursor()) {
- primary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD));
- } else {
- primary_clock->set (pos);
+ switch (UIConfiguration::instance().get_primary_clock_delta_mode()) {
+ case NoDelta:
+ primary_clock->set (pos);
+ break;
+ case DeltaEditPoint:
+ primary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD));
+ break;
+ case DeltaOriginMarker:
+ {
+ Location* loc = _session->locations()->clock_origin_location ();
+ primary_clock->set (pos, false, loc ? loc->start() : 0);
+ }
+ break;
}
- if (UIConfiguration::instance().get_secondary_clock_delta_edit_cursor()) {
- secondary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD));
- } else {
- secondary_clock->set (pos);
+ switch (UIConfiguration::instance().get_secondary_clock_delta_mode()) {
+ case NoDelta:
+ secondary_clock->set (pos);
+ break;
+ case DeltaEditPoint:
+ secondary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD));
+ break;
+ case DeltaOriginMarker:
+ {
+ Location* loc = _session->locations()->clock_origin_location ();
+ secondary_clock->set (pos, false, loc ? loc->start() : 0);
+ }
+ break;
}
if (big_clock_window) {
ARDOUR_UI::instance()->video_timeline->manual_seek_video_monitor(pos);
}
-void
-ARDOUR_UI::step_edit_status_change (bool yn)
-{
- // XXX should really store pre-step edit status of things
- // we make insensitive
-
- if (yn) {
- rec_button.set_active_state (Gtkmm2ext::ImplicitActive);
- rec_button.set_sensitive (false);
- } else {
- rec_button.unset_active_state ();;
- rec_button.set_sensitive (true);
- }
-}
void
ARDOUR_UI::record_state_changed ()
editor->first_idle();
}
+ /* in 1 second, hide the splash screen
+ *
+ * Consider hiding it *now*. If a user opens opens a dialog
+ * during that one second while the splash is still visible,
+ * the dialog will push-back the splash.
+ * Closing the dialog later will pop it back.
+ */
+ Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000);
+
Keyboard::set_can_save_keybindings (true);
return false;
}
_session->set_dirty ();
}
-ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
- : Controllable (name), ui (u), type(tp)
-{
-
-}
-
-void
-ARDOUR_UI::TransportControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /*group_override*/)
-{
- if (val < 0.5) {
- /* do nothing: these are radio-style actions */
- return;
- }
-
- const char *action = 0;
-
- switch (type) {
- case Roll:
- action = X_("Roll");
- break;
- case Stop:
- action = X_("Stop");
- break;
- case GotoStart:
- action = X_("GotoStart");
- break;
- case GotoEnd:
- action = X_("GotoEnd");
- break;
- case AutoLoop:
- action = X_("Loop");
- break;
- case PlaySelection:
- action = X_("PlaySelection");
- break;
- case RecordEnable:
- action = X_("Record");
- break;
- default:
- break;
- }
-
- if (action == 0) {
- return;
- }
-
- Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
-
- if (act) {
- act->activate ();
- }
-}
-
-double
-ARDOUR_UI::TransportControllable::get_value (void) const
-{
- float val = 0.0;
-
- switch (type) {
- case Roll:
- break;
- case Stop:
- break;
- case GotoStart:
- break;
- case GotoEnd:
- break;
- case AutoLoop:
- break;
- case PlaySelection:
- break;
- case RecordEnable:
- break;
- default:
- break;
- }
-
- return val;
-}
-
void
ARDOUR_UI::setup_profile ()
{
const char* end_mono = "</tt>";
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 backup copy with older versions of %3"),
- xml_path, backup_path, PROGRAM_NAME,
- start_big, end_big,
- start_mono, end_mono), true);
+ "%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 backup copy with older versions of %3"),
+ xml_path, backup_path, PROGRAM_NAME,
+ start_big, end_big,
+ start_mono, end_mono), true);
msg.run ();
}
void
ARDOUR_UI::hide_application ()
{
- Application::instance ()-> hide ();
+ Application::instance ()-> hide ();
}
void
bool special_handling_of_unmodified_accelerators = false;
const guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK));
- if (focus) {
+ if (focus) {
/* some widget has keyboard focus */
}
}
- DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 [title = %9] focus = %7 (%8) Key event: code = %2 state = %3 special handling ? %4 magic widget focus ? %5 focus widget %6 named %7 mods ? %8\n",
- win,
- ev->keyval,
- Gtkmm2ext::show_gdk_event_state (ev->state),
+ DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 [title = %9] focus = %7 (%8) Key event: code = %2 state = %3 special handling ? %4 magic widget focus ? %5 focus widget %6 named %7 mods ? %8\n",
+ win,
+ ev->keyval,
+ Gtkmm2ext::show_gdk_event_state (ev->state),
special_handling_of_unmodified_accelerators,
Keyboard::some_magic_widget_has_focus(),
- focus,
+ focus,
(focus ? gtk_widget_get_name (focus) : "no focus widget"),
((ev->state & mask) ? "yes" : "no"),
window.get_title()));
/* no special handling or there are modifiers in effect: accelerate first */
- DEBUG_TRACE (DEBUG::Accelerators, "\tactivate, then propagate\n");
+ DEBUG_TRACE (DEBUG::Accelerators, "\tactivate, then propagate\n");
DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tevent send-event:%1 time:%2 length:%3 name %7 string:%4 hardware_keycode:%5 group:%6\n",
ev->send_event, ev->time, ev->length, ev->string, ev->hardware_keycode, ev->group, gdk_keyval_name (ev->keyval)));
return true;
}
- DEBUG_TRACE (DEBUG::Accelerators, "\tnot accelerated, now propagate\n");
+ DEBUG_TRACE (DEBUG::Accelerators, "\tnot accelerated, now propagate\n");
- if (gtk_window_propagate_key_event (win, ev)) {
- DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate handled\n");
- return true;
- }
+ if (gtk_window_propagate_key_event (win, ev)) {
+ DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate handled\n");
+ return true;
+ }
} else {