#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
+#include <time.h>
#include <cerrno>
#include <fstream>
#include <pbd/error.h>
#include <pbd/basename.h>
#include <pbd/compose.h>
-#include <pbd/misc.h>
#include <pbd/pathscanner.h>
#include <pbd/failed_constructor.h>
#include <pbd/enumwriter.h>
#include <ardour/port.h>
#include <ardour/audio_track.h>
+typedef uint64_t microseconds_t;
+
#include "actions.h"
#include "ardour_ui.h"
#include "public_editor.h"
#include "add_route_dialog.h"
#include "new_session_dialog.h"
#include "about.h"
+#include "splash.h"
#include "utils.h"
#include "gui_thread.h"
#include "theme_manager.h"
#include "engine_dialog.h"
+#include "gain_meter.h"
+#include "route_time_axis.h"
#include "i18n.h"
preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
- /* adjuster table */
-
- adjuster_table (3, 3),
-
/* preroll stuff */
preroll_button (_("pre\nroll")),
_auto_display_errors = false;
#endif
- if (getenv ("ARDOUR_DEBUG_UPDATES")) {
- gdk_window_set_debug_updates (true);
- }
-
about = 0;
+ splash = 0;
+
+ if (ARDOUR_COMMAND_LINE::session_name.length()) {
+ /* only show this if we're not going to post the new session dialog */
+ show_splash ();
+ }
if (theArdourUI == 0) {
theArdourUI = this;
have_disk_speed_dialog_displayed = false;
_will_create_new_session_automatically = false;
session_loaded = false;
- loading_dialog = 0;
last_speed_displayed = -1.0f;
+ ignore_dual_punch = false;
- keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
- /* all changes go to the user directory */
- user_keybindings_path = get_user_ardour_path ();
- user_keybindings_path += '/';
- user_keybindings_path += "ardour.bindings";
-
- can_save_keybindings = false;
-
- last_configure_time.tv_sec = 0;
- last_configure_time.tv_usec = 0;
+ last_configure_time= 0;
shuttle_grabbed = false;
shuttle_fract = 0.0;
shuttle_style_menu = 0;
shuttle_unit_menu = 0;
- gettimeofday (&last_peak_grab, 0);
- gettimeofday (&last_shuttle_request, 0);
+ // We do not have jack linked in yet so;
+
+ last_shuttle_request = last_peak_grab = 0; // get_microseconds();
ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
+ /* handle dialog requests */
+
+ ARDOUR::Session::Dialog.connect (mem_fun(*this, &ARDOUR_UI::session_dialog));
+
/* handle pending state with a dialog */
ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
+ /* handle sr mismatch with a dialog */
+
+ ARDOUR::Session::AskAboutSampleRateMismatch.connect (mem_fun(*this, &ARDOUR_UI::sr_mismatch_dialog));
+
/* lets get this party started */
try {
- ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization);
+ if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) {
+ throw failed_constructor ();
+ }
+
setup_gtk_ardour_enums ();
Config->set_current_owner (ConfigVariableBase::Interface);
setup_profile ();
+ GainMeter::setup_slider_pix ();
+ RouteTimeAxisView::setup_slider_pix ();
+
} catch (failed_constructor& err) {
error << _("could not initialize Ardour.") << endmsg;
// pass it on up
- throw err;
+ throw;
}
/* we like keyboards */
keyboard = new Keyboard;
+ reset_dpi();
+
starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
platform_setup ();
-
}
int
return 0;
}
+ loading_message (_("Starting audio engine"));
+
try {
engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
/* set default clock modes */
- primary_clock.set_mode (AudioClock::SMPTE);
+ if (Profile->get_sae()) {
+ primary_clock.set_mode (AudioClock::MinSec);
+ } else {
+ primary_clock.set_mode (AudioClock::SMPTE);
+ }
secondary_clock.set_mode (AudioClock::BBT);
/* start the time-of-day-clock */
}
}
+void
+ARDOUR_UI::pop_back_splash ()
+{
+ if (Splash::instance()) {
+ // Splash::instance()->pop_back();
+ Splash::instance()->hide ();
+ }
+}
+
gint
ARDOUR_UI::configure_timeout ()
{
- struct timeval now;
- struct timeval diff;
-
- if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
+ if (last_configure_time == 0) {
/* no configure events yet */
return TRUE;
}
- gettimeofday (&now, 0);
- timersub (&now, &last_configure_time, &diff);
-
/* force a gap of 0.5 seconds since the last configure event
*/
- if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
+ if (get_microseconds() - last_configure_time < 500000) {
return TRUE;
} else {
have_configure_timeout = false;
ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
{
if (have_configure_timeout) {
- gettimeofday (&last_configure_time, 0);
+ last_configure_time = get_microseconds();
} else {
Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
have_configure_timeout = true;
Config->add_instant_xml (mnode, get_user_ardour_path());
}
- save_keybindings ();
+ Keyboard::save_keybindings ();
}
gint
ARDOUR_UI::autosave_session ()
{
+ if (g_main_depth() > 1) {
+ /* inside a recursive main loop,
+ give up because we may not be able to
+ take a lock.
+ */
+ return 1;
+ }
+
if (!Config->get_periodic_safety_backups())
return 1;
win.show_all ();
win.set_position (Gtk::WIN_POS_CENTER);
-
- if (!ARDOUR_COMMAND_LINE::no_splash) {
- hide_splash ();
- }
+ pop_back_splash ();
/* we just don't care about the result, but we want to block */
ARDOUR_UI::startup ()
{
string name, path;
- bool isnew;
new_session_dialog = new NewSessionDialog();
-
- /* If no session name is given: we're not loading a session yet, nor creating a new one */
-
- if (ARDOUR_COMMAND_LINE::session_name.length()) {
-
- /* Load session or start the new session dialog */
-
- if (Session::find_session (ARDOUR_COMMAND_LINE::session_name, path, name, isnew)) {
-
- MessageDialog msg (string_compose(_("Could not find command line session \"%1\""),
- ARDOUR_COMMAND_LINE::session_name),
- true,
- Gtk::MESSAGE_ERROR,
- Gtk::BUTTONS_OK);
-
- msg.set_position (Gtk::WIN_POS_MOUSE);
- msg.present ();
- msg.run ();
-
- exit (1);
- }
-
- if (!ARDOUR_COMMAND_LINE::new_session) {
-
- /* Supposed to be loading an existing session, but the session doesn't exist */
-
- if (isnew) {
- MessageDialog msg (string_compose (_("\n\nNo session named \"%1\" exists.\n"
- "To create it from the command line, start ardour as:\n ardour --new %1"), path),
- true,
- Gtk::MESSAGE_ERROR,
- Gtk::BUTTONS_OK);
-
- msg.set_position (Gtk::WIN_POS_MOUSE);
- msg.present ();
- msg.run ();
- exit (1);
- }
- }
- }
-
- hide_splash ();
-
- bool have_backend = EngineControl::engine_running();
+ bool backend_audio_is_running = EngineControl::engine_running();
XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
if (audio_setup) {
new_session_dialog->engine_control.set_state (*audio_setup);
}
- if (!get_session_parameters (ARDOUR_COMMAND_LINE::session_name, have_backend, ARDOUR_COMMAND_LINE::new_session)) {
+ if (!get_session_parameters (backend_audio_is_running, ARDOUR_COMMAND_LINE::new_session)) {
return;
}
+ BootMessage (_("Ardour is ready for use"));
show ();
}
hbox.pack_start (cb, true, false);
vbox->pack_start (hbox);
hbox.show_all ();
+
+ pop_back_splash ();
msg.run ();
}
Ardour was unable to save your session.\n\n\
If you still wish to quit, please use the\n\n\
\"Just quit\" option."));
+ pop_back_splash();
msg.run ();
return;
}
window.set_resizable (false);
window.show_all ();
- save_the_session = 0;
-
window.set_keep_above (true);
window.present ();
fullpath = fullpath.substr (0, fullpath.length()-1);
}
+ /* check whether session still exists */
+ if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
+ /* session doesn't exist */
+ cerr << "skipping non-existent session " << fullpath << endl;
+ continue;
+ }
+
/* now get available states for this session */
if ((states = Session::possible_states (fullpath)) == 0) {
}
}
-bool
-ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
-{
- struct stat statbuf;
-
- if (stat (info.filename.c_str(), &statbuf) != 0) {
- return false;
- }
-
- if (!S_ISDIR(statbuf.st_mode)) {
- return false;
- }
-
- // XXX Portability
-
- string session_file = info.filename;
- session_file += '/';
- session_file += Glib::path_get_basename (info.filename);
- session_file += ".ardour";
-
- if (stat (session_file.c_str(), &statbuf) != 0) {
- return false;
- }
-
- return S_ISREG (statbuf.st_mode);
-}
-
bool
ARDOUR_UI::check_audioengine ()
{
if (!engine->connected()) {
MessageDialog msg (_("Ardour is not connected to JACK\n"
"You cannot open or close sessions in this condition"));
+ pop_back_splash ();
msg.run ();
return false;
}
}
catch (...) {
- cerr << "About to complain about JACK\n";
MessageDialog msg (*editor,
_("There are insufficient JACK ports available\n\
to create a new track or bus.\n\
You should save Ardour, exit and\n\
restart JACK with more ports."));
+ pop_back_splash ();
msg.run ();
}
}
}
void
-ARDOUR_UI::transport_goto_start ()
+ARDOUR_UI::transport_goto_start ()
{
if (session) {
session->goto_start();
}
}
+void
+ARDOUR_UI::transport_goto_wallclock ()
+{
+ if (session && editor) {
+
+ time_t now;
+ struct tm tmnow;
+ nframes64_t frames;
+
+ time (&now);
+ localtime_r (&now, &tmnow);
+
+ frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
+ frames += tmnow.tm_min * (60 * session->frame_rate());
+ frames += tmnow.tm_sec * session->frame_rate();
+
+ session->request_locate (frames);
+
+ /* force displayed area in editor to start no matter
+ what "follow playhead" setting is.
+ */
+
+ if (editor) {
+ editor->reset_x_origin (frames - (editor->current_page_frames()/2));
+ }
+ }
+}
+
void
ARDOUR_UI::transport_goto_end ()
{
void
ARDOUR_UI::transport_record (bool roll)
{
+
if (session) {
switch (session->record_status()) {
case Session::Disabled:
session->disable_record (false, true);
}
}
+ //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
}
void
rolling = session->transport_rolling ();
+ //cerr << "ARDOUR_UI::transport_roll () called session->record_status() = " << session->record_status() << endl;
+
if (session->get_play_loop()) {
session->request_play_loop (false);
auto_loop_button.set_visual_state (1);
ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
Glib::RefPtr<Action> action;
- char* action_name = 0;
+ const char* action_name = 0;
switch (engine->frames_per_cycle()) {
case 32:
disconnected Ardour because Ardour\n\
was not fast enough. You can save the\n\
session and/or try to reconnect to JACK ."));
+ pop_back_splash ();
msg.run ();
}
return 0;
}
-void
-ARDOUR_UI::restore_state (string name)
-{
- if (session) {
- if (name.length() == 0) {
- name = session->name();
- }
- session->restore_state (name);
- }
-}
-
void
ARDOUR_UI::primary_clock_value_changed ()
{
}
}
-void
-ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
-{
- if (session && dstream && dstream->record_enabled()) {
-
- Session::RecordState rs;
-
- rs = session->record_status ();
-
- switch (rs) {
- case Session::Disabled:
- case Session::Enabled:
- if (w->get_state() != STATE_SELECTED) {
- w->set_state (STATE_SELECTED);
- }
- break;
-
- case Session::Recording:
- if (w->get_state() != STATE_ACTIVE) {
- w->set_state (STATE_ACTIVE);
- }
- break;
- }
-
- } else {
- if (w->get_state() != STATE_NORMAL) {
- w->set_state (STATE_NORMAL);
- }
- }
-}
-
void
ARDOUR_UI::transport_rec_enable_blink (bool onoff)
{
true,
Gtk::MESSAGE_INFO,
Gtk::BUTTONS_OK);
+ pop_back_splash ();
msg.show_all ();
msg.present ();
msg.run ();
#endif
}
-bool
-ARDOUR_UI::get_session_parameters (Glib::ustring predetermined_path, bool have_engine, bool should_be_new)
+void
+ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
{
- bool existing_session = false;
- Glib::ustring session_name;
- Glib::ustring session_path;
- Glib::ustring template_name;
+ existing_session = false;
- if (!loading_dialog) {
- loading_dialog = new MessageDialog (*new_session_dialog,
- "",
- false,
- Gtk::MESSAGE_INFO,
- Gtk::BUTTONS_NONE);
+ if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
+ session_path = cmdline_path;
+ existing_session = true;
+ } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
+ session_path = Glib::path_get_dirname (string (cmdline_path));
+ existing_session = true;
+ } else {
+ /* it doesn't exist, assume the best */
+ session_path = Glib::path_get_dirname (string (cmdline_path));
}
+
+ session_name = basename_nosuffix (string (cmdline_path));
+}
+
+int
+ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
+{
+ /* when this is called, the backend audio system must be running */
+ /* the main idea here is to deal with the fact that a cmdline argument for the session
+ can be interpreted in different ways - it could be a directory or a file, and before
+ we load, we need to know both the session directory and the snapshot (statefile) within it
+ that we are supposed to use.
+ */
- int response = Gtk::RESPONSE_NONE;
+ if (session_name.length() == 0 || session_path.length() == 0) {
+ return false;
+ }
+
+ if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
- if (predetermined_path.length()) {
+ Glib::ustring predicted_session_file;
- /* before we start, lets see if the given path looks like
- an existing ardour session. if it does, skip the
- tabs that we don't need
- */
-
- if (Glib::file_test (predetermined_path, Glib::FILE_TEST_IS_DIR)) {
- session_path = predetermined_path;
+ predicted_session_file = session_path;
+ predicted_session_file += '/';
+ predicted_session_file += session_name;
+ predicted_session_file += Session::statefile_suffix();
+
+ if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
existing_session = true;
- } else if (Glib::file_test (predetermined_path, Glib::FILE_TEST_IS_REGULAR)) {
- session_path = Glib::path_get_dirname (string (predetermined_path));
+ }
+
+ } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
+
+ if (session_path.find (Session::statefile_suffix()) == session_path.length() - 7) {
+ /* existing .ardour file */
existing_session = true;
+ }
+
+ } else {
+ existing_session = false;
+ }
+
+ /* lets just try to load it */
+
+ if (create_engine ()) {
+ backend_audio_error (false, new_session_dialog);
+ return -1;
+ }
+
+ return load_session (session_path, session_name);
+}
+
+bool
+ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
+{
+ Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
+
+ MessageDialog msg (str,
+ false,
+ Gtk::MESSAGE_WARNING,
+ Gtk::BUTTONS_YES_NO,
+ true);
+
+
+ msg.set_name (X_("CleanupDialog"));
+ msg.set_wmclass (X_("existing_session"), "Ardour");
+ msg.set_position (Gtk::WIN_POS_MOUSE);
+ pop_back_splash ();
+
+ switch (msg.run()) {
+ case RESPONSE_YES:
+ return true;
+ break;
+ }
+ return false;
+}
+
+int
+ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
+{
+
+ uint32_t cchns;
+ uint32_t mchns;
+ AutoConnectOption iconnect;
+ AutoConnectOption oconnect;
+ uint32_t nphysin;
+ uint32_t nphysout;
+
+ if (Profile->get_sae()) {
+
+ cchns = 0;
+ mchns = 2;
+ iconnect = AutoConnectPhysical;
+ oconnect = AutoConnectMaster;
+ nphysin = 0; // use all available
+ nphysout = 0; // use all available
+
+ } else {
+
+ /* get settings from advanced section of NSD */
+
+ if (new_session_dialog->create_control_bus()) {
+ cchns = (uint32_t) new_session_dialog->control_channel_count();
+ } else {
+ cchns = 0;
+ }
+
+ if (new_session_dialog->create_master_bus()) {
+ mchns = (uint32_t) new_session_dialog->master_channel_count();
+ } else {
+ mchns = 0;
+ }
+
+ if (new_session_dialog->connect_inputs()) {
+ iconnect = AutoConnectPhysical;
} else {
- /* it doesn't exist, assume the best */
- session_path = Glib::path_get_dirname (string (predetermined_path));
+ iconnect = AutoConnectOption (0);
}
-
- session_name = basename_nosuffix (string (predetermined_path));
+
+ /// @todo some minor tweaks.
+
+ if (new_session_dialog->connect_outs_to_master()) {
+ oconnect = AutoConnectMaster;
+ } else if (new_session_dialog->connect_outs_to_physical()) {
+ oconnect = AutoConnectPhysical;
+ } else {
+ oconnect = AutoConnectOption (0);
+ }
+
+ nphysin = (uint32_t) new_session_dialog->input_limit_count();
+ nphysout = (uint32_t) new_session_dialog->output_limit_count();
+ }
+
+ if (build_session (session_path,
+ session_name,
+ cchns,
+ mchns,
+ iconnect,
+ oconnect,
+ nphysin,
+ nphysout,
+ engine->frame_rate() * 60 * 5)) {
+
+ return -1;
+ }
- new_session_dialog->set_session_name (session_name);
- cerr << "set sF to " << session_path << endl;
- new_session_dialog->set_session_folder (session_path);
- new_session_dialog->set_modal (true);
+ return 0;
+}
- if (existing_session) {
+void
+ARDOUR_UI::end_loading_messages ()
+{
+ // hide_splash ();
+}
- if (session_name.length() == 0 || session_path.length() == 0) {
- error << string_compose (_("Ardour cannot understand \"%1\" as a session name"), predetermined_path) << endmsg;
- return false;
- }
-
- if (Glib::file_test (predetermined_path, Glib::FILE_TEST_IS_DIR)) {
- Glib::ustring predicted_session_file;
-
- predicted_session_file = predetermined_path;
- predicted_session_file += '/';
- predicted_session_file += session_name;
- predicted_session_file += Session::statefile_suffix();
-
- if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
- existing_session = true;
- }
-
- } else if (Glib::file_test (predetermined_path, Glib::FILE_TEST_EXISTS)) {
-
- if (predetermined_path.find (Session::statefile_suffix()) == predetermined_path.length() - 7) {
- /* existing .ardour file */
- existing_session = true;
- }
- } else {
- existing_session = false;
- }
-
- if (existing_session && have_engine) {
- /* lets just try to load it */
-
- loading_dialog->set_message (_("Starting audio engine"));
- loading_dialog->show_all ();
- flush_pending ();
-
- if (create_engine ()) {
- backend_audio_error (!have_engine, new_session_dialog);
- loading_dialog->hide ();
- return false;
- }
-
- if (load_session (session_path, session_name) == 0) {
- goto done;
- }
+void
+ARDOUR_UI::loading_message (const std::string& msg)
+{
+ show_splash ();
+ splash->message (msg);
+ flush_pending ();
+}
+
+void
+ARDOUR_UI::idle_load (const Glib::ustring& path)
+{
+ if (session) {
+ if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
+ /* /path/to/foo => /path/to/foo, foo */
+ load_session (path, basename_nosuffix (path));
+ } else {
+ /* /path/to/foo/foo.ardour => /path/to/foo, foo */
+ load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
+ }
+ } else {
+ ARDOUR_COMMAND_LINE::session_name = path;
+ if (new_session_dialog) {
+ /* make it break out of Dialog::run() and
+ start again.
+ */
+ new_session_dialog->response (1);
+ }
+ }
+}
+
+bool
+ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be_new)
+{
+ bool existing_session = false;
+ Glib::ustring session_name;
+ Glib::ustring session_path;
+ Glib::ustring template_name;
+ int response;
+
+ begin:
+ response = Gtk::RESPONSE_NONE;
+
+ if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
+
+ parse_cmdline_path (ARDOUR_COMMAND_LINE::session_name, session_name, session_path, existing_session);
+
+ /* don't ever reuse this */
+
+ ARDOUR_COMMAND_LINE::session_name = string();
+
+ if (existing_session && backend_audio_is_running) {
+
+ /* just load the thing already */
+
+ if (load_cmdline_session (session_name, session_path, existing_session) == 0) {
+ return true;
}
}
+
+ /* make the NSD use whatever information we have */
+
+ new_session_dialog->set_session_name (session_name);
+ new_session_dialog->set_session_folder (session_path);
}
/* loading failed, or we need the NSD for something */
+ new_session_dialog->set_modal (false);
new_session_dialog->set_position (WIN_POS_CENTER);
new_session_dialog->set_current_page (0);
new_session_dialog->set_existing_session (existing_session);
new_session_dialog->reset_recent();
do {
- new_session_dialog->set_have_engine (have_engine);
+ new_session_dialog->set_have_engine (backend_audio_is_running);
new_session_dialog->present ();
response = new_session_dialog->run ();
- loading_dialog->hide ();
_session_is_new = false;
/* handle possible negative responses */
- if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
-
+ switch (response) {
+ case 1:
+ /* sent by idle_load, meaning restart the whole process again */
+ new_session_dialog->hide();
+ new_session_dialog->reset();
+ goto begin;
+ break;
+
+ case Gtk::RESPONSE_CANCEL:
+ case Gtk::RESPONSE_DELETE_EVENT:
if (!session) {
quit();
}
new_session_dialog->hide ();
return false;
- } else if (response == Gtk::RESPONSE_NONE) {
+ case Gtk::RESPONSE_NONE:
/* "Clear" was pressed */
-
goto try_again;
}
fontconfig_dialog();
- /* if we're here to help set up audio parameters this is where want to do that.
- */
-
- if (!have_engine) {
- if (new_session_dialog->engine_control.setup_engine ()) {
- new_session_dialog->hide ();
+ if (!backend_audio_is_running) {
+ int ret = new_session_dialog->engine_control.setup_engine ();
+ if (ret < 0) {
return false;
- }
-
- loading_dialog->set_message (_("Starting audio engine"));
- loading_dialog->show_all ();
- flush_pending ();
+ } else if (ret > 0) {
+ response = Gtk::RESPONSE_REJECT;
+ goto try_again;
+ }
}
-
+
if (create_engine ()) {
- backend_audio_error (!have_engine, new_session_dialog);
- loading_dialog->hide ();
+
+ backend_audio_error (!backend_audio_is_running, new_session_dialog);
flush_pending ();
- /* audio setup page */
+
new_session_dialog->set_existing_session (false);
new_session_dialog->set_current_page (2);
+
response = Gtk::RESPONSE_NONE;
goto try_again;
}
- loading_dialog->hide ();
- have_engine = true;
+ backend_audio_is_running = true;
- /* now handle possible affirmative responses */
-
- if (response == Gtk::RESPONSE_YES) {
+ if (response == Gtk::RESPONSE_OK) {
- /* YES == OPEN from the session selector */
+ session_name = new_session_dialog->session_name();
- session_name = new_session_dialog->session_name();
-
if (session_name.empty()) {
response = Gtk::RESPONSE_NONE;
goto try_again;
}
+ /* if the user mistakenly typed path information into the session filename entry,
+ convert what they typed into a path & a name
+ */
+
if (session_name[0] == '/' ||
(session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
(session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
- if (load_session (Glib::path_get_dirname (session_name), session_name)) {
- response = Gtk::RESPONSE_NONE;
- goto try_again;
- }
+
+ session_path = Glib::path_get_dirname (session_name);
+ session_name = Glib::path_get_basename (session_name);
+
} else {
+
session_path = new_session_dialog->session_folder();
- if (load_session (session_path, session_name)) {
- response = Gtk::RESPONSE_NONE;
- goto try_again;
- }
}
-
- } else if (response == Gtk::RESPONSE_OK) {
-
- /* OK == OPEN button */
-
- session_name = new_session_dialog->session_name();
-
- if (session_name.empty()) {
- response = Gtk::RESPONSE_NONE;
- goto try_again;
- }
+ template_name = Glib::ustring();
switch (new_session_dialog->which_page()) {
+
case NewSessionDialog::OpenPage:
case NewSessionDialog::EnginePage:
-
- if (session_name[0] == '/' ||
- (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
- (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
- if (load_session (Glib::path_get_dirname (session_name), session_name)) {
- response = Gtk::RESPONSE_NONE;
- goto try_again;
- }
-
- } else {
- session_path = new_session_dialog->session_folder();
- if (load_session (session_path, session_name)) {
- response = Gtk::RESPONSE_NONE;
- goto try_again;
- }
- }
+ goto loadit;
break;
case NewSessionDialog::NewPage: /* nominally the "new" session creator, but could be in use for an old session */
-
- cerr << "on page zero\n";
-
- if (new_session_dialog->get_current_page() == 0 && ARDOUR_COMMAND_LINE::session_name.empty()) {
- should_be_new = true;
- }
-
- /* handle what appear to be paths rather than just a name */
-
- if (session_name[0] == '/' ||
- (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
- (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
-
- session_path = Glib::path_get_dirname (session_name);
- session_name = Glib::path_get_basename (session_name);
-
- } else {
-
- session_path = new_session_dialog->session_folder();
-
- }
-
+
+ should_be_new = true;
+
//XXX This is needed because session constructor wants a
//non-existant path. hopefully this will be fixed at some point.
session_path = Glib::build_filename (session_path, session_name);
- if (!should_be_new) {
-
- if (load_session (session_path, session_name)) {
- response = Gtk::RESPONSE_NONE;
- goto try_again;
- }
+ if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
- continue; /* leaves while() loop because response != NONE */
-
- } else if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
-
- Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
-
- MessageDialog msg (str,
- false,
- Gtk::MESSAGE_WARNING,
- Gtk::BUTTONS_YES_NO,
- true);
-
-
- msg.set_name (X_("CleanupDialog"));
- msg.set_wmclass (X_("existing_session"), "Ardour");
- msg.set_position (Gtk::WIN_POS_MOUSE);
-
- switch (msg.run()) {
- case RESPONSE_YES:
- new_session_dialog->hide ();
- goto_editor_window ();
- flush_pending ();
- if (load_session (session_path, session_name)) {
- response = Gtk::RESPONSE_NONE;
- goto try_again;
- }
- goto done;
- break;
- default:
+ if (ask_about_loading_existing_session (session_path)) {
+ goto loadit;
+ } else {
response = RESPONSE_NONE;
- new_session_dialog->reset ();
- new_session_dialog->set_existing_session (false);
- loading_dialog->hide ();
- continue;
- }
- }
+ goto try_again;
+ }
+ }
_session_is_new = true;
if (new_session_dialog->use_session_template()) {
template_name = new_session_dialog->session_template_name();
-
- new_session_dialog->hide ();
- goto_editor_window ();
- flush_pending ();
-
- if (load_session (session_path, session_name, template_name)) {
- response = Gtk::RESPONSE_NONE;
- goto try_again;
- }
-
+ goto loadit;
} else {
-
- uint32_t cchns;
- uint32_t mchns;
- AutoConnectOption iconnect;
- AutoConnectOption oconnect;
- uint32_t nphysin;
- uint32_t nphysout;
-
- if (Profile->get_sae()) {
-
- cchns = 0;
- mchns = 2;
- iconnect = AutoConnectPhysical;
- oconnect = AutoConnectMaster;
- nphysin = 0; // use all available
- nphysout = 0; // use all available
-
- } else {
-
- /* get settings from advanced section of NSD */
-
- if (new_session_dialog->create_control_bus()) {
- cchns = (uint32_t) new_session_dialog->control_channel_count();
- } else {
- cchns = 0;
- }
-
- if (new_session_dialog->create_master_bus()) {
- mchns = (uint32_t) new_session_dialog->master_channel_count();
- } else {
- mchns = 0;
- }
-
- if (new_session_dialog->connect_inputs()) {
- iconnect = AutoConnectPhysical;
- } else {
- iconnect = AutoConnectOption (0);
- }
-
- /// @todo some minor tweaks.
-
- if (new_session_dialog->connect_outs_to_master()) {
- oconnect = AutoConnectMaster;
- } else if (new_session_dialog->connect_outs_to_physical()) {
- oconnect = AutoConnectPhysical;
- } else {
- oconnect = AutoConnectOption (0);
- }
-
- nphysin = (uint32_t) new_session_dialog->input_limit_count();
- nphysout = (uint32_t) new_session_dialog->output_limit_count();
- }
-
- if (build_session (session_path,
- session_name,
- cchns,
- mchns,
- iconnect,
- oconnect,
- nphysin,
- nphysout,
- engine->frame_rate() * 60 * 5)) {
-
- response = Gtk::RESPONSE_NONE;
+ if (build_session_from_nsd (session_path, session_name)) {
+ response = RESPONSE_NONE;
goto try_again;
}
-
- new_session_dialog->hide ();
- goto_editor_window ();
- flush_pending ();
+ goto done;
}
break;
-
+
default:
break;
}
- }
+
+ loadit:
+ new_session_dialog->hide ();
+
+ if (load_session (session_path, session_name, template_name)) {
+ /* force a retry */
+ response = Gtk::RESPONSE_NONE;
+ }
- try_again:
- if (response == Gtk::RESPONSE_NONE) {
- loading_dialog->hide ();
- new_session_dialog->set_existing_session (false);
- new_session_dialog->reset ();
+ try_again:
+ if (response == Gtk::RESPONSE_NONE) {
+ new_session_dialog->set_existing_session (false);
+ new_session_dialog->reset ();
+ }
}
-
- } while (response == Gtk::RESPONSE_NONE);
+
+ } while (response == Gtk::RESPONSE_NONE || response == Gtk::RESPONSE_REJECT);
done:
show();
- loading_dialog->hide ();
new_session_dialog->hide();
+ new_session_dialog->reset();
+ goto_editor_window ();
return true;
-}
+}
void
ARDOUR_UI::close_session ()
unload_session (true);
- get_session_parameters ("", true, false);
+ get_session_parameters (true, false);
}
int
if (Glib::file_test (path.c_str(), Glib::FILE_TEST_EXISTS) && ::access (path.c_str(), W_OK)) {
MessageDialog msg (*editor, _("You do not have write access to this session.\n"
"This prevents the session from being loaded."));
+ pop_back_splash ();
msg.run ();
goto out;
}
- if (loading_dialog) {
- loading_dialog->set_markup (_("Please wait while Ardour loads your session"));
- flush_pending ();
- }
-
- disable_screen_updates ();
+ loading_message (_("Please wait while Ardour loads your session"));
try {
new_session = new Session (*engine, path, snap_name, mix_template);
msg.set_title (_("Loading Error"));
msg.set_secondary_text (_("Click the OK button to try again."));
msg.set_position (Gtk::WIN_POS_CENTER);
+ pop_back_splash ();
msg.present ();
int response = msg.run ();
msg.set_title (_("Loading Error"));
msg.set_secondary_text (_("Click the OK button to try again."));
msg.set_position (Gtk::WIN_POS_CENTER);
+ pop_back_splash ();
msg.present ();
int response = msg.run ();
session->set_clean ();
}
- enable_screen_updates ();
flush_pending ();
retval = 0;
catch (...) {
MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
+ pop_back_splash ();
msg.run ();
return -1;
}
}
void
-ARDOUR_UI::show_splash ()
+ARDOUR_UI::show_about ()
{
if (about == 0) {
- about = new About();
+ about = new About;
about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
}
- about->present();
- flush_pending ();
+
+ about->show_all ();
+}
+
+void
+ARDOUR_UI::hide_about ()
+{
+ if (about) {
+ about->get_window()->set_cursor ();
+ about->hide ();
+ }
}
void
ARDOUR_UI::about_signal_response(int response)
{
- hide_splash();
+ hide_about();
+}
+
+void
+ARDOUR_UI::show_splash ()
+{
+ if (splash == 0) {
+ try {
+ splash = new Splash;
+ } catch (...) {
+ return;
+ }
+ }
+
+ splash->show ();
+ splash->present ();
+ splash->queue_draw ();
+ splash->get_window()->process_updates (true);
+ flush_pending ();
}
void
ARDOUR_UI::hide_splash ()
{
- if (about) {
- about->get_window()->set_cursor ();
- about->hide();
+ if (splash) {
+ splash->hide();
}
}
}
if (session->cleanup_sources (rep)) {
+ editor->finish_cleanup ();
return;
}
+
+ editor->finish_cleanup ();
checker.hide();
display_cleanup_results (rep,
%4 %5bytes of disk space.\n"
));
-
-
}
void
/* XXX do something with name template */
+ cerr << "Adding with " << input_chan << " in and " << output_chan << "out\n";
+
if (track) {
session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
} else {
}
void
-ARDOUR_UI::halt_on_xrun_message ()
+ARDOUR_UI::create_xrun_marker(nframes_t where)
{
- ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
+ editor->mouse_add_new_marker (where, false, true);
+}
+void
+ARDOUR_UI::halt_on_xrun_message ()
+{
MessageDialog msg (*editor,
_("Recording was stopped because your system could not keep up."));
msg.run ();
}
+void
+ARDOUR_UI::xrun_handler(nframes_t where)
+{
+ ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
+
+ if (Config->get_create_xrun_marker() && session->actively_recording()) {
+ create_xrun_marker(where);
+ }
+
+ if (Config->get_stop_recording_on_xrun() && session->actively_recording()) {
+ halt_on_xrun_message ();
+ }
+}
+
void
ARDOUR_UI::disk_overrun_handler ()
{
delete msg;
}
+void
+ARDOUR_UI::session_dialog (std::string msg)
+{
+ ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::session_dialog), msg));
+
+ MessageDialog* d;
+
+ if (editor) {
+ d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
+ } else {
+ d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
+ }
+
+ d->show_all ();
+ d->run ();
+ delete d;
+}
+
int
ARDOUR_UI::pending_state_dialog ()
{
return 0;
}
}
+
+int
+ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
+{
+ HBox* hbox = new HBox();
+ Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
+ ArdourDialog dialog (_("Sample Rate Mismatch"), true);
+ Label message (string_compose (_("\
+This session was created with a sample rate of %1 Hz\n\
+\n\
+The audioengine is currently running at %2 Hz\n"), desired, actual));
+
+ image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
+ hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
+ hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
+ dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
+ dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
+ dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
+ dialog.set_default_response (RESPONSE_ACCEPT);
+ dialog.set_position (WIN_POS_CENTER);
+ message.show();
+ image->show();
+ hbox->show();
+
+ switch (dialog.run ()) {
+ case RESPONSE_ACCEPT:
+ return 0;
+ default:
+ return 1;
+ }
+}
+
void
ARDOUR_UI::disconnect_from_jack ()
}
}
-int
-ARDOUR_UI::cmdline_new_session (string path)
-{
- if (path[0] != '/') {
- char buf[PATH_MAX+1];
- string str;
-
- getcwd (buf, sizeof (buf));
- str = buf;
- str += '/';
- str += path;
- path = str;
- }
-
- get_session_parameters (path, false, true);
-
- _will_create_new_session_automatically = false; /* done it */
- return FALSE; /* don't call it again */
-}
-
void
ARDOUR_UI::use_config ()
{
}
}
-void
-ARDOUR_UI::set_keybindings_path (string path)
-{
- keybindings_path = path;
-}
-
-void
-ARDOUR_UI::save_keybindings ()
-{
- if (can_save_keybindings) {
- AccelMap::save (user_keybindings_path);
- }
-}
-
bool
ARDOUR_UI::first_idle ()
{
if (session) {
session->allow_auto_play (true);
}
- can_save_keybindings = true;
+
+ if (editor) {
+ editor->first_idle();
+ }
+
+ Keyboard::set_can_save_keybindings (true);
return false;
}
return;
}
- char *action = 0;
+ const char *action = 0;
switch (type) {
case Roll: