add code to display announcements, and parameterize several URL's used in the program
[ardour.git] / gtk2_ardour / startup.cc
index c1f5d3b6bb721a541978f9e27835ffdd972ae986..208364447cb56826cba83b3e1e48ea588b0770d1 100644 (file)
 
 #include "pbd/failed_constructor.h"
 #include "pbd/file_utils.h"
-#include "pbd/filesystem.h"
 #include "pbd/replace_all.h"
 #include "pbd/whitespace.h"
+#include "pbd/stacktrace.h"
+#include "pbd/openuri.h"
 
 #include "ardour/filesystem_paths.h"
 #include "ardour/recent_sessions.h"
 #include "ardour/session.h"
 #include "ardour/session_state_utils.h"
 #include "ardour/template_utils.h"
+#include "ardour/filename_extensions.h"
 
+#include "ardour_ui.h"
 #include "startup.h"
 #include "opts.h"
 #include "engine_dialog.h"
@@ -61,107 +64,115 @@ static string poor_mans_glob (string path)
        return copy;
 }
 
-
-ArdourStartup::ArdourStartup ()
+ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
        : _response (RESPONSE_OK)
+       , config_modified (false)
+       , new_only (require_new)
+       , default_dir_chooser (0)
        , ic_new_session_button (_("Create a new session"))
        , ic_existing_session_button (_("Open an existing session"))
-       , monitor_via_hardware_button (_("Use an external mixer or the hardware mixer of your audio interface.\n\
-Ardour will play NO role in monitoring"))
+       , monitor_via_hardware_button (string_compose (_("Use an external mixer or the hardware mixer of your audio interface.\n"
+                                                        "%1 will play NO role in monitoring"), PROGRAM_NAME))
        , monitor_via_ardour_button (string_compose (_("Ask %1 to play back material as it is being recorded"), PROGRAM_NAME))
+       , engine_dialog (0)
        , new_folder_chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
        , more_new_session_options_button (_("I'd like more options for this session"))
        , _output_limit_count_adj (1, 0, 100, 1, 10, 0)
        , _input_limit_count_adj (1, 0, 100, 1, 10, 0)
        , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
+       , audio_page_index (-1)
+       , new_user_page_index (-1)
+       , default_folder_page_index (-1)
+       , monitoring_page_index (-1)
+       , session_page_index (-1)
+       , initial_choice_index (-1)
+       , final_page_index (-1)
+       , session_options_page_index (-1)
        , _existing_session_chooser_used (false)
 {
-       audio_page_index = -1;
-       initial_choice_index = -1;
-       new_user_page_index = -1;
-       default_folder_page_index = -1;
-       monitoring_page_index = -1;
-       session_page_index = -1;
-       final_page_index = -1;
-       session_options_page_index = -1;
-       new_only = false;
-
-       engine_dialog = 0;
-       config_modified = false;
-       default_dir_chooser = 0;
-
-       use_template_button.set_group (session_template_group);
-       use_session_as_template_button.set_group (session_template_group);
-
-       set_keep_above (true);
-       set_resizable (false);
-       set_position (WIN_POS_CENTER);
-       set_border_width (12);
-
-       if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
-               throw failed_constructor();
-       }
-
-       list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
-       Glib::RefPtr<Gdk::Pixbuf> icon;
-
-       if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
-               window_icons.push_back (icon);
-       }
-       if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
-               window_icons.push_back (icon);
-       }
-       if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
-               window_icons.push_back (icon);
-       }
-       if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
-               window_icons.push_back (icon);
-       }
-       if (!window_icons.empty ()) {
-               set_default_icon_list (window_icons);
-       }
-
-       new_user = !exists (been_here_before_path ());
-
-       bool need_audio_setup = !EngineControl::engine_running();
-
-        setup_prerelease_page ();
+       new_user = !Glib::file_test (been_here_before_path(), Glib::FILE_TEST_EXISTS);
+       need_audio_setup = EngineControl::need_setup ();
+       need_session_info = (session_name.empty() || require_new);
 
-       if (new_user) {
+       _provided_session_name = session_name;
+       _provided_session_path = session_path;
+       
+       if (need_audio_setup || need_session_info || new_user) {
 
-               /* Create the config directory so that we have somewhere to put the
-                  been_here_before file.
-               */
-               try {
-                       sys::create_directories (user_config_directory ());
-               }
-               catch (const sys::filesystem_error& ex) {
-                       error << "Could not create user configuration directory" << endmsg;
+               use_template_button.set_group (session_template_group);
+               use_session_as_template_button.set_group (session_template_group);
+               
+               set_keep_above (true);
+               set_position (WIN_POS_CENTER);
+               set_border_width (12);
+               
+               if ((icon_pixbuf = ::get_icon ("ardour_icon_48px")) == 0) {
+                       throw failed_constructor();
                }
                
-               setup_new_user_page ();
-               setup_first_time_config_page ();
-               setup_monitoring_choice_page ();
-               setup_monitor_section_choice_page ();
-
-               if (need_audio_setup) {
-                       setup_audio_page ();
+               list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
+               Glib::RefPtr<Gdk::Pixbuf> icon;
+               
+               if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
+                       window_icons.push_back (icon);
+               }
+               if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
+                       window_icons.push_back (icon);
+               }
+               if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
+                       window_icons.push_back (icon);
+               }
+               if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
+                       window_icons.push_back (icon);
+               }
+               if (!window_icons.empty ()) {
+                       set_default_icon_list (window_icons);
                }
 
-       } else {
-
-               if (need_audio_setup) {
-                       setup_audio_page ();
+               set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
+               
+#ifdef __APPLE__
+               setup_prerelease_page ();
+#endif
+               if (new_user) {
+                       
+                       setup_new_user_page ();
+                       setup_first_time_config_page ();
+                       setup_monitoring_choice_page ();
+                       setup_monitor_section_choice_page ();
+                       
+                       if (need_audio_setup) {
+                               setup_audio_page ();
+                       }
+                       
+                       ic_new_session_button.set_active (true); // always create new session on first run
+                       
+               } else {
+                       
+                       if (need_audio_setup) {
+                               setup_audio_page ();
+                       }
+                       
+                       setup_initial_choice_page ();
                }
 
-               setup_initial_choice_page ();
-       }
+               setup_session_page ();
+               setup_more_options_page ();
+               
+               if (new_user) {
+                       setup_final_page ();
+               }
 
-       setup_session_page ();
-       setup_more_options_page ();
+               if (new_only) {
+                       ic_vbox.hide ();
+               } else {
+                       ic_vbox.show ();
+               }
 
-       if (new_user) {
-               setup_final_page ();
+               if (!template_name.empty()) {
+                       use_template_button.set_active (false);
+                       load_template_override = template_name;
+               }
        }
 
        the_startup = this;
@@ -171,19 +182,23 @@ ArdourStartup::~ArdourStartup ()
 {
 }
 
+bool
+ArdourStartup::ready_without_display () const
+{
+       return !new_user && !need_audio_setup && !need_session_info;
+}
+
 void
 ArdourStartup::setup_prerelease_page ()
 {
         VBox* vbox = manage (new VBox);
         Label* label = manage (new Label);
         label->set_markup (_("<b>Welcome to this BETA release of Ardour 3.0</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\
+Ardour 3.0 has been released for Linux but because of the lack of testers,\n\
+it is still at the beta stage on OS X. So, a few guidelines:\n\
 \n\
 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
    though it may be so, depending on your workflow.\n\
-2) Please see http://ardour.org/a3_features for a guide to 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 3.0-beta.\n\
@@ -206,25 +221,6 @@ Full information on all the above can be found on the support page at\n\
        set_page_complete (*vbox, true);
 }
 
-void
-ArdourStartup::set_new_only (bool yn)
-{
-       new_only = yn;
-
-       if (new_only) {
-               ic_vbox.hide ();
-       } else {
-               ic_vbox.show ();
-       }
-}
-
-void
-ArdourStartup::set_load_template (string load_template)
-{
-       use_template_button.set_active (false);
-       load_template_override = load_template;
-}
-
 bool
 ArdourStartup::use_session_template ()
 {
@@ -243,8 +239,8 @@ std::string
 ArdourStartup::session_template_name ()
 {
        if (!load_template_override.empty()) {
-               string the_path = (ARDOUR::user_template_directory()/ (load_template_override + ".template")).to_string();
-               return the_path;
+               string the_path (ARDOUR::user_template_directory());
+               return Glib::build_filename (the_path, load_template_override + ARDOUR::template_suffix);
        }
 
        if (ic_existing_session_button.get_active()) {
@@ -265,6 +261,10 @@ ArdourStartup::session_template_name ()
 std::string
 ArdourStartup::session_name (bool& should_be_new)
 {
+       if (ready_without_display()) {
+               return _provided_session_name;
+       }
+
        if (ic_new_session_button.get_active()) {
                should_be_new = true;
                string val = new_name_entry.get_text ();
@@ -291,6 +291,10 @@ ArdourStartup::session_name (bool& should_be_new)
 std::string
 ArdourStartup::session_folder ()
 {
+       if (ready_without_display()) {
+               return _provided_session_path;
+       }
+
        if (ic_new_session_button.get_active()) {
                std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
                return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
@@ -334,7 +338,7 @@ ArdourStartup::setup_new_user_page ()
        foomatic->set_markup (string_compose (_("\
 <span size=\"larger\">%1 is a digital audio workstation. You can use it to \
 record, edit and mix multi-track audio. You can produce your \
-own CDs, mix video soundtracks, or just experiment with new \
+own CDs, mix video soundtracks, or experiment with new \
 ideas about music and sound. \
 \n\n\
 There are a few things that need to be configured before you start \
@@ -366,6 +370,8 @@ void
 ArdourStartup::default_dir_changed ()
 {
        Config->set_default_session_parent_dir (default_dir_chooser->get_filename());
+       // make new session folder chooser point to the new default
+       new_folder_chooser.set_current_folder (Config->get_default_session_parent_dir());       
        config_changed ();
 }
 
@@ -399,6 +405,8 @@ Where would you like new %1 sessions to be stored by default?\n\n\
        vbox->pack_start (*txt, false, false);
        vbox->pack_start (*hbox, false, true);
 
+       cerr << "Setting defaultDIR session dir to [" << Config->get_default_session_parent_dir() << "]\n";
+
        default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
        default_dir_chooser->signal_current_folder_changed().connect (sigc::mem_fun (*this, &ArdourStartup::default_dir_changed));
        default_dir_chooser->show ();
@@ -423,8 +431,9 @@ ArdourStartup::setup_monitoring_choice_page ()
 
        HBox* hbox = manage (new HBox);
        VBox* vbox = manage (new VBox);
-       RadioButton::Group g (monitor_via_hardware_button.get_group());
-       monitor_via_ardour_button.set_group (g);
+       /* first button will be on by default */
+       RadioButton::Group g (monitor_via_ardour_button.get_group());
+       monitor_via_hardware_button.set_group (g);
 
        monitor_label.set_markup(_("\
 While recording instruments or vocals, you probably want to listen to the\n\
@@ -432,7 +441,8 @@ signal as well as record it. This is called \"monitoring\". There are\n\
 different ways to do this depending on the equipment you have and the\n\
 configuration of that equipment. The two most common are presented here.\n\
 Please choose whichever one is right for your setup.\n\n\
-<i>(You can change this preference at any time, via the Preferences dialog)</i>"));
+<i>(You can change this preference at any time, via the Preferences dialog)</i>\n\n\
+<i>If you do not understand what this is about, just accept the default.</i>"));
        monitor_label.set_alignment (0.0, 0.0);
 
        vbox->set_spacing (6);
@@ -471,8 +481,7 @@ ArdourStartup::setup_monitor_section_choice_page ()
 
        no_monitor_section_button.set_label (_("Use a Master bus directly"));
        l->set_alignment (0.0, 1.0);
-       l->set_markup(_("Connect the Master bus directly to your hardware outputs.\n\
-<i>Preferable for simple use</i>."));
+       l->set_markup(_("Connect the Master bus directly to your hardware outputs. This is preferable for simple usage."));
 
        vbox = manage (new VBox);
        vbox->set_spacing (6);
@@ -506,7 +515,8 @@ greater control in monitoring without affecting the mix."));
        use_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
        no_monitor_section_button.signal_toggled().connect (sigc::mem_fun (*this, &ArdourStartup::config_changed));
 
-       monitor_section_label.set_markup(_("<i><small>(You can change this preference at any time, via the Preferences dialog)</small></i>"));
+       monitor_section_label.set_markup(_("<i>You can change this preference at any time via the Preferences dialog.\nYou can also add or remove the monitor section to/from any session.</i>\n\n\
+<i>If you do not understand what this is about, just accept the default.</i>"));
        monitor_section_label.set_alignment (0.0, 0.0);
 
        hbox->pack_start (*main_vbox, true, true, 8);
@@ -542,11 +552,38 @@ ArdourStartup::setup_initial_choice_page ()
 
        centering_vbox->pack_start (ic_new_session_button, false, true);
        centering_vbox->pack_start (ic_existing_session_button, false, true);
+       
+       if (ARDOUR_UI::instance()->announce_string() != "" ) {
+
+               Gtk::Frame *info_frame = manage(new Gtk::Frame);
+               info_frame->set_shadow_type(SHADOW_ETCHED_OUT);
+               centering_vbox->pack_start (*info_frame, false, false, 20);
+
+               Box *info_box = manage (new VBox);
+               info_box->set_border_width (12);
+               info_box->set_spacing (6);
+               info_box->set_name("mixbus_info_box");
+
+               info_box->pack_start (info_scroller_label, false, false);
+
+               info_frame->add (*info_box);
+               info_frame->show_all();
+
+               info_scroller_count = 0;
+               info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &ArdourStartup::info_scroller_update), 50);
 
-       ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
+               Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
+
+               updates_button->signal_clicked().connect (mem_fun(*this, &ArdourStartup::updates_button_clicked) );
+               ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
+
+               info_box->pack_start (*updates_button, false, false);
+       }
+       
+       ic_new_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
        ic_new_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
 
-       ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_press), false);
+       ic_existing_session_button.signal_button_press_event().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_clicked), false);
        ic_existing_session_button.signal_activate().connect(sigc::mem_fun(*this, &ArdourStartup::initial_button_activated), false);
 
        centering_hbox->pack_start (*centering_vbox, true, true);
@@ -567,20 +604,21 @@ ArdourStartup::setup_initial_choice_page ()
 }
 
 bool
-ArdourStartup::initial_button_press (GdkEventButton *event)
+ArdourStartup::initial_button_clicked (GdkEventButton* ev)
 {
-       if (event && event->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
+       if (ev->type == GDK_2BUTTON_PRESS && session_page_index != -1) {
                set_current_page(session_page_index);
-               return true;
-       } else {
-               return false;
        }
+
+       return false;
 }
 
 void
 ArdourStartup::initial_button_activated ()
 {
-       set_current_page(session_page_index);
+       if (session_page_index != -1) {
+               set_current_page(session_page_index);
+       }
 }
 
 void
@@ -626,7 +664,10 @@ void
 ArdourStartup::on_apply ()
 {
        if (engine_dialog) {
-               engine_dialog->setup_engine ();
+               if (engine_dialog->setup_engine ()) {
+                        set_current_page (audio_page_index);
+                        return;
+                }
        }
 
        if (config_modified) {
@@ -644,7 +685,7 @@ ArdourStartup::on_apply ()
                Config->set_use_monitor_bus (use_monitor_section_button.get_active());
 
                /* "touch" the been-here-before path now that we're about to save Config */
-               ofstream fout (been_here_before_path().to_string().c_str());
+               ofstream fout (been_here_before_path().c_str());
                
                Config->save_state ();
        }
@@ -707,13 +748,6 @@ ArdourStartup::populate_session_templates ()
        }
 }
 
-static bool
-lost_name_entry_focus (GdkEventFocus*)
-{
-       cerr << "lost focus\n";
-       return false;
-}
-
 void
 ArdourStartup::setup_new_session_page ()
 {
@@ -761,17 +795,25 @@ ArdourStartup::setup_new_session_page ()
 
                if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
                        new_folder_chooser.set_current_folder (poor_mans_glob (Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name)));
+               } else if (ARDOUR_UI::instance()->session_loaded) {
+                       // point the new session file chooser at the parent directory of the current session
+                       string session_parent_dir = Glib::path_get_dirname(ARDOUR_UI::instance()->the_session()->path());
+                       string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
+                       session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
+                       new_folder_chooser.set_current_folder (session_parent_dir);
+                       new_folder_chooser.add_shortcut_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
                } else {
                        new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
                }
+               new_folder_chooser.show ();
                new_folder_chooser.set_title (_("Select folder for session"));
 
-#ifdef GTKOSX
+#ifdef __APPLE__
                new_folder_chooser.add_shortcut_folder ("/Volumes");
 #endif
 
                vbox1->pack_start (*hbox2, false, false);
-
+               
                session_new_vbox.pack_start (*vbox1, false, false);
 
                /* --- */
@@ -871,16 +913,6 @@ ArdourStartup::setup_new_session_page ()
        if (more_new_session_options_button.get_active()) {
                set_page_type (session_vbox, ASSISTANT_PAGE_CONTENT);
        }
-
-       new_name_entry.signal_map().connect (sigc::mem_fun (*this, &ArdourStartup::new_name_mapped));
-       new_name_entry.signal_focus_out_event().connect (sigc::ptr_fun (lost_name_entry_focus));
-}
-
-void
-ArdourStartup::new_name_mapped ()
-{
-       cerr << "Grab new name focus\n";
-       new_name_entry.grab_focus ();
 }
 
 void
@@ -896,7 +928,7 @@ ArdourStartup::new_name_changed ()
 int
 ArdourStartup::redisplay_recent_sessions ()
 {
-       std::vector<sys::path> session_directories;
+       std::vector<std::string> session_directories;
        RecentSessionsSorter cmp;
 
        recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
@@ -916,10 +948,12 @@ ArdourStartup::redisplay_recent_sessions ()
        for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
                session_directories.push_back ((*i).second);
        }
+       
+       int session_snapshot_count = 0;
 
-       for (vector<sys::path>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
+       for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
        {
-               std::vector<sys::path> state_file_paths;
+               std::vector<std::string> state_file_paths;
 
                // now get available states for this session
 
@@ -927,7 +961,7 @@ ArdourStartup::redisplay_recent_sessions ()
 
                vector<string*>* states;
                vector<const gchar*> item;
-               string fullpath = (*i).to_string();
+               string fullpath = *i;
 
                /* remove any trailing / */
 
@@ -954,25 +988,31 @@ ArdourStartup::redisplay_recent_sessions ()
 
                row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
                row[recent_session_columns.fullpath] = fullpath;
+               row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
+               
+               ++session_snapshot_count;
 
                if (state_file_names.size() > 1) {
 
                        // add the children
 
                        for (std::vector<std::string>::iterator i2 = state_file_names.begin();
-                                       i2 != state_file_names.end(); ++i2)
-                       {
+                                       i2 != state_file_names.end(); ++i2) {
 
                                Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
 
                                child_row[recent_session_columns.visible_name] = *i2;
                                child_row[recent_session_columns.fullpath] = fullpath;
+                               child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
+                               ++session_snapshot_count;
                        }
                }
        }
 
+       recent_session_display.set_tooltip_column(1); // recent_session_columns.tip 
        recent_session_display.set_model (recent_session_model);
-       return rs.size();
+       return session_snapshot_count;
+       // return rs.size();
 }
 
 void
@@ -1023,7 +1063,14 @@ ArdourStartup::setup_existing_session_page ()
 
                existing_session_chooser.set_title (_("Select session file"));
                existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &ArdourStartup::existing_session_selected));
+               existing_session_chooser.set_current_folder(poor_mans_glob (Config->get_default_session_parent_dir()));
 
+               FileFilter session_filter;
+               session_filter.add_pattern ("*.ardour");
+               session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
+               existing_session_chooser.add_filter (session_filter);
+               existing_session_chooser.set_filter (session_filter);
+               
 #ifdef GTKOSX
                existing_session_chooser.add_shortcut_folder ("/Volumes");
 #endif
@@ -1101,7 +1148,7 @@ ArdourStartup::setup_more_options_page ()
        advanced_table.set_row_spacings(0);
        advanced_table.set_col_spacings(0);
 
-       _connect_inputs.set_label (_("Automatically connect to physical_inputs"));
+       _connect_inputs.set_label (_("Automatically connect to physical inputs"));
        _connect_inputs.set_flags(Gtk::CAN_FOCUS);
        _connect_inputs.set_relief(Gtk::RELIEF_NORMAL);
        _connect_inputs.set_mode(true);
@@ -1236,10 +1283,11 @@ ArdourStartup::setup_more_options_page ()
        _limit_output_ports.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::limit_outputs_clicked));
        _create_master_bus.signal_clicked().connect (sigc::mem_fun (*this, &ArdourStartup::master_bus_button_clicked));
 
-       /* note that more_options_vbox is NOT visible by
-        * default. this is entirely by design - this page
-        * should be skipped unless explicitly requested.
+       /* note that more_options_vbox is "visible" by default even
+        * though it may not be displayed to the user, this is so the dialog
+        * doesn't resize.
         */
+       more_options_vbox.show_all ();
 
        session_options_page_index = append_page (more_options_vbox);
        set_page_title (more_options_vbox, _("Advanced Session Options"));
@@ -1321,9 +1369,12 @@ ArdourStartup::connect_inputs_clicked ()
 void
 ArdourStartup::connect_outputs_clicked ()
 {
-       _limit_output_ports.set_sensitive(_connect_outputs.get_active());
+       bool const co = _connect_outputs.get_active ();
+       _limit_output_ports.set_sensitive(co);
+       _connect_outputs_to_master.set_sensitive(co);
+       _connect_outputs_to_physical.set_sensitive(co);
 
-       if (_connect_outputs.get_active() && _limit_output_ports.get_active()) {
+       if (co && _limit_output_ports.get_active()) {
                _output_limit_count.set_sensitive(true);
        } else {
                _output_limit_count.set_sensitive(false);
@@ -1345,9 +1396,10 @@ ArdourStartup::limit_outputs_clicked ()
 void
 ArdourStartup::master_bus_button_clicked ()
 {
-       bool yn = _create_master_bus.get_active();
+       bool const yn = _create_master_bus.get_active();
 
        _master_bus_channel_count.set_sensitive(yn);
+       _connect_outputs_to_master.set_sensitive(yn);
 }
 
 void
@@ -1380,11 +1432,34 @@ ArdourStartup::existing_session_selected ()
        move_along_now ();
 }
 
-sys::path
+std::string
 ArdourStartup::been_here_before_path () const
 {
-       sys::path b = user_config_directory();
-       b /= ".a3"; // XXXX use more specific version so we can catch upgrades
-       return b;
+       // XXXX use more specific version so we can catch upgrades
+       return Glib::build_filename (user_config_directory (), ".a3");
 }
 
+void
+ArdourStartup::updates_button_clicked ()
+{
+       //now open a browser window so user can see more
+       PBD::open_uri (Config->get_updates_url());
+}
+
+bool
+ArdourStartup::info_scroller_update()
+{
+       info_scroller_count++;
+
+       char buf[512];
+       snprintf (buf, std::min(info_scroller_count,sizeof(buf)-1), "%s", ARDOUR_UI::instance()->announce_string().c_str() );
+       buf[info_scroller_count] = NULL;
+       info_scroller_label.set_text (buf);
+       info_scroller_label.show();
+
+       if (info_scroller_count > ARDOUR_UI::instance()->announce_string().length()) {
+               info_scroller_connection.disconnect();
+       }
+
+       return true;
+}