fixes for destructive track offsets of various kinds; move from jack_nframes_t -...
[ardour.git] / gtk2_ardour / ardour_ui.cc
index a802aaebba99a5543700e4d198c3b2ca4359b4eb..a6cd045fb245f9fae9166b8326a727b5cdaa29eb 100644 (file)
 #include <midi++/mmc.h>
 
 #include <ardour/ardour.h>
+#include <ardour/session_route.h>
 #include <ardour/port.h>
 #include <ardour/audioengine.h>
 #include <ardour/playlist.h>
 #include <ardour/utils.h>
-#include <ardour/diskstream.h>
-#include <ardour/filesource.h>
+#include <ardour/audio_diskstream.h>
+#include <ardour/audiofilesource.h>
 #include <ardour/recent_sessions.h>
-#include <ardour/session_diskstream.h>
 #include <ardour/port.h>
 #include <ardour/audio_track.h>
 
@@ -76,6 +76,7 @@
 #include "i18n.h"
 
 using namespace ARDOUR;
+using namespace PBD;
 using namespace Gtkmm2ext;
 using namespace Gtk;
 using namespace sigc;
@@ -85,7 +86,7 @@ ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
 sigc::signal<void,bool> ARDOUR_UI::Blink;
 sigc::signal<void>      ARDOUR_UI::RapidScreenUpdate;
 sigc::signal<void>      ARDOUR_UI::SuperRapidScreenUpdate;
-sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
+sigc::signal<void,nframes_t> ARDOUR_UI::Clock;
 
 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
 
@@ -115,16 +116,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
 
          shuttle_units_button (_("% ")),
 
-         punch_in_button (_("punch\nin")),
-         punch_out_button (_("punch\nout")),
-         auto_return_button (_("auto\nreturn")),
-         auto_play_button (_("auto\nplay")),
-         auto_input_button (_("auto\ninput")),
-         click_button (_("click")),
-         auditioning_alert_button (_("AUDITIONING")),
+         punch_in_button (_("Punch In")),
+         punch_out_button (_("Punch Out")),
+         auto_return_button (_("Auto Return")),
+         auto_play_button (_("Autuo Play")),
+         auto_input_button (_("Auto Input")),
+         click_button (_("Click")),
+         auditioning_alert_button (_("AUDITION")),
          solo_alert_button (_("SOLO")),
          shown_flag (false)
-
 {
        using namespace Gtk::Menu_Helpers;
 
@@ -136,8 +136,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
                theArdourUI = this;
        }
 
-       ActionManager::init ();
-
        /* load colors */
 
        color_manager = new ColorManager();
@@ -146,7 +144,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        
        color_manager->load (color_file);
 
-       m_new_session_dialog = new NewSessionDialog();
        editor = 0;
        mixer = 0;
        session = 0;
@@ -175,18 +172,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        shuttle_fract = 0.0;
        shuttle_max_speed = 8.0f;
 
-       set_shuttle_units (Percentage);
-       set_shuttle_behaviour (Sprung);
-
        shuttle_style_menu = 0;
        shuttle_unit_menu = 0;
 
        gettimeofday (&last_peak_grab, 0);
        gettimeofday (&last_shuttle_request, 0);
 
-       ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
-       ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
-       ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
+       ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
+       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 pending state with a dialog */
 
@@ -205,26 +199,13 @@ ARDOUR_UI::set_engine (AudioEngine& e)
        engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
        engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
 
+               ActionManager::init ();
+       new_session_dialog = new NewSessionDialog();
+
        _tooltips.enable();
 
        keyboard = new Keyboard;
 
-       string meter_path;
-
-       meter_path = ARDOUR::find_data_file("v_meter_strip.xpm", "pixmaps");
-       if (meter_path.empty()) {
-               error << _("no vertical meter strip image found") << endmsg;
-               exit (1);
-       }
-       FastMeter::set_vertical_xpm (meter_path);
-
-       meter_path = ARDOUR::find_data_file("h_meter_strip.xpm", "pixmaps");
-       if (meter_path.empty()) {
-               error << _("no horizontal meter strip image found") << endmsg;
-               exit (1);
-       }
-       FastMeter::set_horizontal_xpm (meter_path);
-
        if (setup_windows ()) {
                throw failed_constructor ();
        }
@@ -257,10 +238,10 @@ ARDOUR_UI::set_engine (AudioEngine& e)
 
        /* this being a GUI and all, we want peakfiles */
 
-       FileSource::set_build_peakfiles (true);
-       FileSource::set_build_missing_peakfiles (true);
+       AudioFileSource::set_build_peakfiles (true);
+       AudioFileSource::set_build_missing_peakfiles (true);
 
-       if (Source::start_peak_thread ()) {
+       if (AudioSource::start_peak_thread ()) {
                throw failed_constructor();
        }
 
@@ -297,7 +278,7 @@ ARDOUR_UI::~ARDOUR_UI ()
                delete add_route_dialog;
        }
 
-       Source::stop_peak_thread ();
+       AudioSource::stop_peak_thread ();
 }
 
 gint
@@ -354,15 +335,15 @@ ARDOUR_UI::save_ardour_state ()
        Config->add_extra_xml (*node);
        Config->save_state();
 
-       XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
-       XMLNode& mnode (mixer->get_state());
+       XMLNode enode(static_cast<Stateful*>(editor)->get_state());
+       XMLNode mnode(mixer->get_state());
 
        if (session) {
-               session->add_instant_xml(enode, session->path());
-               session->add_instant_xml(mnode, session->path());
+               session->add_instant_xml (enode, session->path());
+               session->add_instant_xml (mnode, session->path());
        } else {
-               Config->add_instant_xml(enode, get_user_ardour_path());
-               Config->add_instant_xml(mnode, get_user_ardour_path());
+               Config->add_instant_xml (enode, get_user_ardour_path());
+               Config->add_instant_xml (mnode, get_user_ardour_path());
        }
 
        /* keybindings */
@@ -507,7 +488,7 @@ ARDOUR_UI::every_point_zero_one_seconds ()
 }
 
 void
-ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
+ARDOUR_UI::update_sample_rate (nframes_t ignored)
 {
        char buf[32];
 
@@ -519,14 +500,14 @@ ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
 
        } else {
 
-               jack_nframes_t rate = engine->frame_rate();
+               nframes_t rate = engine->frame_rate();
                
                if (fmod (rate, 1000.0) != 0.0) {
-                       snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"), 
+                       snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"), 
                                  (float) rate/1000.0f,
                                  (engine->frames_per_cycle() / (float) rate) * 1000.0f);
                } else {
-                       snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"), 
+                       snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"), 
                                  rate/1000,
                                  (engine->frames_per_cycle() / (float) rate) * 1000.0f);
                }
@@ -539,7 +520,7 @@ void
 ARDOUR_UI::update_cpu_load ()
 {
        char buf[32];
-       snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
+       snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
        cpu_load_label.set_text (buf);
 }
 
@@ -558,9 +539,10 @@ ARDOUR_UI::update_buffer_load ()
 }
 
 void
-ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
+ARDOUR_UI::count_recenabled_diskstreams (Route& route)
 {
-       if (ds.record_enabled()) {
+       Track* track = dynamic_cast<Track*>(&route);
+       if (track && track->diskstream()->record_enabled()) {
                rec_enabled_diskstreams++;
        }
 }
@@ -572,21 +554,21 @@ ARDOUR_UI::update_disk_space()
                return;
        }
 
-       jack_nframes_t frames = session->available_capture_duration();
+       nframes_t frames = session->available_capture_duration();
        char buf[64];
 
        if (frames == max_frames) {
-               strcpy (buf, _("space: 24hrs+"));
+               strcpy (buf, _("Disk: 24hrs+"));
        } else {
                int hrs;
                int mins;
                int secs;
-               jack_nframes_t fr = session->frame_rate();
+               nframes_t fr = session->frame_rate();
                
                if (session->actively_recording()){
                        
                        rec_enabled_diskstreams = 0;
-                       session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
+                       session->foreach_route (this, &ARDOUR_UI::count_recenabled_diskstreams);
                        
                        if (rec_enabled_diskstreams) {
                                frames /= rec_enabled_diskstreams;
@@ -606,7 +588,7 @@ ARDOUR_UI::update_disk_space()
                frames -= mins * fr * 60;
                secs = frames / fr;
                
-               snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
+               snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
        }
 
        disk_space_label.set_text (buf);
@@ -889,23 +871,38 @@ ARDOUR_UI::session_add_midi_track ()
 }
 
 void
-ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode)
+ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
 {
-       Route* route;
+       list<boost::shared_ptr<AudioTrack> > tracks;
+       Session::RouteList routes;
 
        if (session == 0) {
-               warning << _("You cannot add a track without a session already loaded.") << endmsg;
+               warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
                return;
        }
 
        try { 
-               if (disk) {
-                       if ((route = session->new_audio_track (input_channels, output_channels, mode)) == 0) {
-                               error << _("could not create new audio track") << endmsg;
+               if (track) {
+                       tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
+
+                       if (tracks.size() != how_many) {
+                               if (how_many == 1) {
+                                       error << _("could not create a new audio track") << endmsg;
+                               } else {
+                                       error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
+                               }
                        }
+
                } else {
-                       if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
-                               error << _("could not create new audio bus") << endmsg;
+
+                       routes = session->new_audio_route (input_channels, output_channels, how_many);
+
+                       if (routes.size() != how_many) {
+                               if (how_many == 1) {
+                                       error << _("could not create a new audio track") << endmsg;
+                               } else {
+                                       error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
+                               }
                        }
                }
                
@@ -933,17 +930,13 @@ restart JACK with more ports."));
 }
 
 void
-ARDOUR_UI::diskstream_added (DiskStream* ds)
-{
-}
-
-void
-ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
+ARDOUR_UI::do_transport_locate (nframes_t new_position)
 {
-       jack_nframes_t _preroll;
+       nframes_t _preroll = 0;
 
        if (session) {
-               _preroll = session->convert_to_frames_at (new_position, session->preroll);
+               // XXX CONFIG_CHANGE FIX - requires AnyTime handling
+               // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
 
                if (new_position > _preroll) {
                        new_position -= _preroll;
@@ -993,7 +986,7 @@ void
 ARDOUR_UI::transport_goto_end ()
 {
        if (session) {
-               jack_nframes_t frame = session->current_end_frame();
+               nframes_t frame = session->current_end_frame();
                session->request_locate (frame);
 
                /* force displayed area in editor to start no matter
@@ -1018,8 +1011,8 @@ ARDOUR_UI::transport_stop ()
                return;
        }
        
-       if (session->get_auto_loop()) {
-               session->request_auto_loop (false);
+       if (Config->get_auto_loop()) {
+               session->request_play_loop (false);
        }
        
        session->request_stop ();
@@ -1073,8 +1066,8 @@ ARDOUR_UI::transport_roll ()
 
        rolling = session->transport_rolling ();
 
-       if (session->get_auto_loop()) {
-               session->request_auto_loop (false);
+       if (Config->get_auto_loop()) {
+               session->request_play_loop (false);
                auto_loop_button.set_active (false);
                roll_button.set_active (true);
        } else if (session->get_play_range ()) {
@@ -1091,7 +1084,7 @@ void
 ARDOUR_UI::transport_loop()
 {
        if (session) {
-               if (session->get_auto_loop()) {
+               if (Config->get_auto_loop()) {
                        if (session->transport_rolling()) {
                                Location * looploc = session->locations()->auto_loop_location();
                                if (looploc) {
@@ -1100,7 +1093,7 @@ ARDOUR_UI::transport_loop()
                        }
                }
                else {
-                       session->request_auto_loop (true);
+                       session->request_play_loop (true);
                }
        }
 }
@@ -1174,32 +1167,25 @@ ARDOUR_UI::transport_forward (int option)
 }
 
 void
-ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
+ARDOUR_UI::toggle_record_enable (uint32_t dstream)
 {
        if (session == 0) {
                return;
        }
 
-       DiskStream *ds;
+       boost::shared_ptr<Route> r;
+       
+       if ((r = session->route_by_remote_id (dstream)) != 0) {
 
-       if ((ds = session->diskstream_by_id (dstream)) != 0) {
-               Port *port = ds->io()->input (0);
-               port->request_monitor_input (!port->monitoring_input());
-       }
-}
+               Track* t;
 
-void
-ARDOUR_UI::toggle_record_enable (guint32 dstream)
-{
+               if ((t = dynamic_cast<Track*>(r.get())) != 0) {
+                       t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
+               }
+       }
        if (session == 0) {
                return;
        }
-
-       DiskStream *ds;
-
-       if ((ds = session->diskstream_by_id (dstream)) != 0) {
-               ds->set_record_enabled (!ds->record_enabled(), this);
-       }
 }
 
 void
@@ -1387,7 +1373,7 @@ ARDOUR_UI::start_blinking ()
 
        if (blink_timeout_tag < 0) {
                blink_on = false;       
-               blink_timeout_tag = gtk_timeout_add (240, _blink, this);
+               blink_timeout_tag = g_timeout_add (240, _blink, this);
        }
 }
 
@@ -1395,68 +1381,11 @@ void
 ARDOUR_UI::stop_blinking ()
 {
        if (blink_timeout_tag >= 0) {
-               gtk_timeout_remove (blink_timeout_tag);
+               g_source_remove (blink_timeout_tag);
                blink_timeout_tag = -1;
        }
 }
 
-
-void
-ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
-{
-       using namespace Gtk;
-       using namespace Menu_Helpers;
-
-       if (dstream.hidden()) {
-               return;
-       }
-
-       MenuList& items = diskstream_menu->items();
-       items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
-}
-       
-void
-ARDOUR_UI::diskstream_selected (gint32 id)
-{
-       selected_dstream = id;
-       Main::quit ();
-}
-
-gint32
-ARDOUR_UI::select_diskstream (GdkEventButton *ev)
-{
-       using namespace Gtk;
-       using namespace Menu_Helpers;
-
-       if (session == 0) {
-               return -1;
-       }
-
-       diskstream_menu = new Menu();
-       diskstream_menu->set_name ("ArdourContextMenu");
-       using namespace Gtk;
-       using namespace Menu_Helpers;
-
-       MenuList& items = diskstream_menu->items();
-       items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
-
-       session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
-
-       if (ev) {
-               diskstream_menu->popup (ev->button, ev->time);
-       } else {
-               diskstream_menu->popup (0, 0);
-       }
-
-       selected_dstream = -1;
-
-       Main::run ();
-
-       delete diskstream_menu;
-
-       return selected_dstream;
-}
-
 void
 ARDOUR_UI::name_io_setup (AudioEngine& engine, 
                          string& buf,
@@ -1585,7 +1514,7 @@ ARDOUR_UI::secondary_clock_value_changed ()
 }
 
 void
-ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
+ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
 {
        if (session && dstream && dstream->record_enabled()) {
 
@@ -1685,123 +1614,174 @@ ARDOUR_UI::save_template ()
 void
 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
 {
-       m_new_session_dialog->show();
-       m_new_session_dialog->set_modal(true);
-       m_new_session_dialog->set_name(predetermined_path);
-       m_new_session_dialog->reset_recent();
+       string session_name;
+       string session_path;
+
+       int response = Gtk::RESPONSE_NONE;
 
-       int response = Gtk::RESPONSE_CANCEL;
+       new_session_dialog->set_modal(true);
+       new_session_dialog->set_name(predetermined_path);
+       new_session_dialog->reset_recent();
+       new_session_dialog->show();
+
+       //Glib::RefPtr<Gdk::Window> nsd_window = new_session_dialog->get_window();
 
        do {
-               response = m_new_session_dialog->run ();
+               response = new_session_dialog->run ();
+               //nsd_window ->set_cursor(Gdk::Cursor(Gdk::WATCH));
                if(response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
-                 quit();
-                 return;
+                       quit();
+                       return;
 
                } else if (response == Gtk::RESPONSE_NONE) {
-                 /* Clear was pressed */
-                 m_new_session_dialog->reset();
+                       /* Clear was pressed */
+                       new_session_dialog->reset();
 
                } else if (response == Gtk::RESPONSE_YES) {
-                 /* YES  == OPEN, but there's no enum for that */
-                 std::string session_name = m_new_session_dialog->session_name();
-                 std::string session_path = m_new_session_dialog->session_folder();
-                 load_session (session_path, session_name);
 
+                       /* YES  == OPEN, but there's no enum for that */
 
-               } else if (response == Gtk::RESPONSE_OK) {
-                 if (m_new_session_dialog->get_current_page() == 1) {
-
-                   /* XXX this is a bit of a hack.. 
-                      i really want the new sesion dialog to return RESPONSE_YES
-                      if we're on page 1 (the load page)
-                      Unfortunately i can't see how atm.. 
-                   */
-                       std::string session_name = m_new_session_dialog->session_name();
-                       std::string session_path = m_new_session_dialog->session_folder();
-                       load_session (session_path, session_name);
-
-                 } else {
-
-                       _session_is_new = true;
+                       session_name = new_session_dialog->session_name();
                        
-                       std::string session_name = m_new_session_dialog->session_name();
-                       std::string session_path = m_new_session_dialog->session_folder();
+                       if (session_name.empty()) {
+                               response = Gtk::RESPONSE_NONE;
+                               cerr << "session name is empty\n";
+                               continue;
+                       } 
+
+                       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] == '/')) {
+                               load_session (Glib::path_get_dirname (session_name), session_name);
+                       } else {
+                               session_path = new_session_dialog->session_folder();
+                               load_session (session_path, session_name);
+                       }
                        
+               } else if (response == Gtk::RESPONSE_OK) {
 
-                         //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);
-                       
-                       std::string template_name = m_new_session_dialog->session_template_name();
-                       
-                       if (m_new_session_dialog->use_session_template()) {
-                               
-                               load_session (session_path, session_name, &template_name);
+                       if (new_session_dialog->get_current_page() == 1) {
+                 
+                               /* XXX this is a bit of a hack.. 
+                                  i really want the new sesion dialog to return RESPONSE_YES
+                                  if we're on page 1 (the load page)
+                                  Unfortunately i can't see how atm.. 
+                               */
                                
-                       } else {
-                               
-                               uint32_t cchns;
-                               uint32_t mchns;
-                               Session::AutoConnectOption iconnect;
-                               Session::AutoConnectOption oconnect;
+                               if (session_name.empty()) {
+                                       response = Gtk::RESPONSE_NONE;
+                                       cerr << "session name is empty 2\n";
+                                       continue;
+                               } 
                                
-                               if (m_new_session_dialog->create_control_bus()) {
-                                       cchns = (uint32_t) m_new_session_dialog->control_channel_count();
+                               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] == '/')) {
+                                       load_session (Glib::path_get_dirname (session_name), session_name);
                                } else {
-                                       cchns = 0;
+                                       session_path = new_session_dialog->session_folder();
+                                       load_session (session_path, session_name);
                                }
-                               
-                               if (m_new_session_dialog->create_master_bus()) {
-                                       mchns = (uint32_t) m_new_session_dialog->master_channel_count();
+                       
+                       } else {
+
+                               _session_is_new = true;
+                             
+                               session_name = new_session_dialog->session_name();
+                       
+                               if (session_name.empty()) {
+                                       response = Gtk::RESPONSE_NONE;
+                                       cerr << "session name is empty 3\n";
+                                       continue;
+                               } 
+
+                               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 {
-                                       mchns = 0;
+
+                                       std::string session_path = new_session_dialog->session_folder();
+                                       
                                }
+                       
+                               //XXX This is needed because session constructor wants a 
+                               //non-existant path. hopefully this will be fixed at some point.
                                
-                               if (m_new_session_dialog->connect_inputs()) {
-                                       iconnect = Session::AutoConnectPhysical;
+                               session_path = Glib::build_filename (session_path, session_name);
+                                               
+                               std::string template_name = new_session_dialog->session_template_name();
+                                               
+                               if (new_session_dialog->use_session_template()) {
+                                                       
+                                       load_session (session_path, session_name, &template_name);
+                         
                                } else {
-                                       iconnect = Session::AutoConnectOption (0);
+                                                       
+                                       uint32_t cchns;
+                                       uint32_t mchns;
+                                       AutoConnectOption iconnect;
+                                       AutoConnectOption oconnect;
+                                                       
+                                       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);
+                                       } 
+                                                       
+                                       uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
+                                       uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
+                                                       
+                                       build_session (session_path,
+                                                      session_name,
+                                                      cchns,
+                                                      mchns,
+                                                      iconnect,
+                                                      oconnect,
+                                                      nphysin,
+                                                      nphysout, 
+                                                      engine->frame_rate() * 60 * 5);
                                }
-                               
-                               /// @todo some minor tweaks.
-
-                               if (m_new_session_dialog->connect_outs_to_master()) {
-                                       oconnect = Session::AutoConnectMaster;
-                               } else if (m_new_session_dialog->connect_outs_to_physical()) {
-                                       oconnect = Session::AutoConnectPhysical;
-                               } else {
-                                       oconnect = Session::AutoConnectOption (0);
-                               } 
-                               
-                               uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
-                               uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
-                               
-                               build_session (session_path,
-                                              session_name,
-                                              cchns,
-                                              mchns,
-                                              iconnect,
-                                              oconnect,
-                                              nphysin,
-                                              nphysout, 
-                                              engine->frame_rate() * 60 * 5);
                        }
-                 }     
                }
                
        } while (response == Gtk::RESPONSE_NONE);
-       m_new_session_dialog->hide();
-       show();
 
+       show();
+       new_session_dialog->get_window()->set_cursor();
+       new_session_dialog->hide();
 }
 
 void
 ARDOUR_UI::close_session()
 {
-  unload_session();
-  new_session ();
+       unload_session();
+       new_session ();
 }
 
 int
@@ -1840,9 +1820,8 @@ This prevents the session from being loaded."));
 
        connect_to_session (new_session);
 
-       //if (engine->running()) {
-       //mixer->show_window();
-       //}
+       Config->set_current_owner (ConfigVariableBase::Interface);
+
        session_loaded = true;
        return 0;
 }
@@ -1863,11 +1842,11 @@ int
 ARDOUR_UI::build_session (const string & path, const string & snap_name, 
                          uint32_t control_channels,
                          uint32_t master_channels, 
-                         Session::AutoConnectOption input_connect,
-                         Session::AutoConnectOption output_connect,
+                         AutoConnectOption input_connect,
+                         AutoConnectOption output_connect,
                          uint32_t nphysin,
                          uint32_t nphysout,
-                         jack_nframes_t initial_length)
+                         nframes_t initial_length)
 {
        Session *new_session;
        int x;
@@ -1895,9 +1874,6 @@ ARDOUR_UI::build_session (const string & path, const string & snap_name,
 
        connect_to_session (new_session);
 
-       //if (engine->running()) {
-       //mixer->show_window();
-       //}
        session_loaded = true;
        return 0;
 }
@@ -1907,11 +1883,12 @@ ARDOUR_UI::show ()
 {
        if (editor) {
                editor->show_window ();
-               shown_flag = true;
-       }
+               
+               if (!shown_flag) {
+                       editor->present ();
+               }
 
-       if (session && mixer) {
-               // mixer->show_window ();
+               shown_flag = true;
        }
        
        if (about) {
@@ -1932,7 +1909,8 @@ void
 ARDOUR_UI::hide_splash ()
 {
        if (about) {
-               // about->hide();
+               about->get_window()->set_cursor ();
+               about->hide();
        }
 }
 
@@ -2149,9 +2127,9 @@ ARDOUR_UI::add_route ()
        string name_template = add_route_dialog->name_template ();
        bool track = add_route_dialog->track ();
 
-       Session::AutoConnectOption oac = session->get_output_auto_connect();
+       AutoConnectOption oac = Config->get_output_auto_connect();
 
-       if (oac & Session::AutoConnectMaster) {
+       if (oac & AutoConnectMaster) {
                output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
        } else {
                output_chan = input_chan;
@@ -2159,17 +2137,10 @@ ARDOUR_UI::add_route ()
 
        /* XXX do something with name template */
 
-       while (count) {
-               if (track) {
-                       session_add_audio_track (input_chan, output_chan, add_route_dialog->mode());
-               } else {
-                       session_add_audio_bus (input_chan, output_chan);
-               }
-               --count;
-               
-               while (Main::events_pending()) {
-                       Main::iteration ();
-               }
+       if (track) {
+               session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
+       } else {
+               session_add_audio_bus (input_chan, output_chan, count);
        }
 }
 
@@ -2232,12 +2203,12 @@ ARDOUR_UI::halt_on_xrun_message ()
 }
 
 void 
-ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
+ARDOUR_UI::delete_sources_in_the_right_thread (list<boost::shared_ptr<ARDOUR::Source> >* deletion_list)
 {
        ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
 
-       for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
-               delete *i;
+       for (list<boost::shared_ptr<Source> >::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
+               (*i)->drop_references ();
        }
 
        delete deletion_list;
@@ -2346,7 +2317,7 @@ ARDOUR_UI::reconnect_to_jack ()
 }
 
 void
-ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
+ARDOUR_UI::set_jack_buffer_size (nframes_t nframes)
 {
        engine->request_buffer_size (nframes);
        update_sample_rate (0);
@@ -2393,6 +2364,12 @@ ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
        case RF64:
                act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
                break;
+       case CAF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
+               break;
+       case AIFF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
+               break;
        }
 
        if (act) {
@@ -2467,6 +2444,12 @@ ARDOUR_UI::use_config ()
        case RF64:
                act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
                break;
+       case CAF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
+               break;
+       case AIFF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
+               break;
        }
 
        if (act) {