#include "gtk2ardour-config.h"
#endif
-#include <fstream>
#include <algorithm>
+#include <glib.h>
+#include "pbd/gstdio_compat.h"
+
+#include <glibmm.h>
+#include <glibmm/datetime.h>
+
#include <gtkmm/filechooser.h>
+#include "pbd/basename.h"
#include "pbd/failed_constructor.h"
#include "pbd/file_utils.h"
#include "pbd/replace_all.h"
#include "pbd/whitespace.h"
#include "pbd/stacktrace.h"
+#include "pbd/stl_delete.h"
#include "pbd/openuri.h"
+#include "gtkmm2ext/utils.h"
+
#include "ardour/audioengine.h"
#include "ardour/filesystem_paths.h"
#include "ardour/recent_sessions.h"
#include "session_dialog.h"
#include "opts.h"
#include "engine_dialog.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
+#include "tooltips.h"
+#include "ui_config.h"
#include "utils.h"
using namespace std;
using namespace Glib;
using namespace PBD;
using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
-static string poor_mans_glob (string path)
-{
- string copy = path;
- replace_all (copy, "~", Glib::get_home_dir());
- return copy;
-}
-
-SessionDialog::SessionDialog (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
- : ArdourDialog (_("Session Setup"))
+SessionDialog::SessionDialog (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name, bool cancel_not_quit)
+ : ArdourDialog (_("Session Setup"), true, true)
, new_only (require_new)
, _provided_session_name (session_name)
, _provided_session_path (session_path)
, _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
, _existing_session_chooser_used (false)
{
- if (!session_name.empty() && !require_new) {
- response (RESPONSE_OK);
- return;
- }
-
- set_keep_above (true);
set_position (WIN_POS_CENTER);
get_vbox()->set_spacing (6);
- string image_path;
+ cancel_button = add_button ((cancel_not_quit ? Stock::CANCEL : Stock::QUIT), RESPONSE_CANCEL);
+ back_button = add_button (Stock::GO_BACK, RESPONSE_NO);
+ open_button = add_button (Stock::OPEN, RESPONSE_ACCEPT);
+
+ back_button->signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::back_button_pressed), false);
+
+ open_button->set_sensitive (false);
+ back_button->set_sensitive (false);
- if (find_file_in_search_path (ardour_data_search_path(), "small-splash.png", image_path)) {
- Gtk::Image* image;
- if ((image = manage (new Gtk::Image (image_path))) != 0) {
- get_vbox()->pack_start (*image, false, false);
- }
- }
-
/* this is where announcements will be displayed, but it may be empty
* and invisible most of the time.
*/
get_vbox()->pack_start (info_frame, false, false);
setup_new_session_page ();
-
+
if (!new_only) {
setup_initial_choice_box ();
get_vbox()->pack_start (ic_vbox, true, true);
} else {
get_vbox()->pack_start (session_new_vbox, true, true);
}
-
+
if (!template_name.empty()) {
use_template_button.set_active (false);
load_template_override = template_name;
}
-
- get_vbox()->show_all ();
- cancel_button = add_button (Stock::QUIT, RESPONSE_CANCEL);
- back_button = add_button (Stock::GO_BACK, RESPONSE_NO);
- open_button = add_button (Stock::OPEN, RESPONSE_ACCEPT);
-
- back_button->signal_button_press_event().connect (sigc::mem_fun (*this, &SessionDialog::back_button_pressed), false);
-
- open_button->set_sensitive (false);
- back_button->set_sensitive (false);
+ get_vbox()->show_all ();
- /* fill data models and how/hide accordingly */
+ /* fill data models and show/hide accordingly */
populate_session_templates ();
if (cnt > 0) {
recent_scroller.show();
recent_label.show ();
-
+
if (cnt > 4) {
recent_scroller.set_size_request (-1, 300);
+ } else {
+ recent_scroller.set_size_request (-1, 80);
}
} else {
recent_scroller.hide();
recent_label.hide ();
}
}
+
+ /* possibly get out of here immediately if everything is ready to go.
+ We still need to set up the whole dialog because of the way
+ ARDOUR_UI::get_session_parameters() might skip it on a first
+ pass then require it for a second pass (e.g. when there
+ is an error with session loading and we have to ask the user
+ what to do next).
+ */
+
+ if (!session_name.empty() && !require_new) {
+ response (RESPONSE_OK);
+ return;
+ }
+}
+
+SessionDialog::SessionDialog ()
+ : ArdourDialog (_("Recent Sessions"), true, true)
+ , new_only (false)
+ , _provided_session_name ("")
+ , _provided_session_path ("")
+ // the following are unused , but have no default ctor
+ , _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)
+ , _existing_session_chooser_used (false) // caller must check should_be_new
+{
+ get_vbox()->set_spacing (6);
+
+ cancel_button = add_button (Stock::CANCEL, RESPONSE_CANCEL);
+ open_button = add_button (Stock::OPEN, RESPONSE_ACCEPT);
+ open_button->set_sensitive (false);
+
+ setup_recent_sessions ();
+
+ get_vbox()->pack_start (recent_scroller, true, true);
+ get_vbox()->show_all ();
+
+ recent_scroller.show();
+
+ int cnt = redisplay_recent_sessions ();
+ if (cnt > 4) {
+ recent_scroller.set_size_request (-1, 300);
+ } else {
+ recent_scroller.set_size_request (-1, 80);
+ }
+
}
+
+
SessionDialog::~SessionDialog()
{
}
+void
+SessionDialog::clear_given ()
+{
+ _provided_session_path = "";
+ _provided_session_name = "";
+}
+
bool
SessionDialog::use_session_template ()
{
TreeModel::Row row = (*iter);
string s = row[session_template_columns.path];
return s;
- }
+ }
return string();
}
SessionDialog::session_name (bool& should_be_new)
{
if (!_provided_session_name.empty() && !new_only) {
+ should_be_new = false;
return _provided_session_name;
}
/* Try recent session selection */
TreeIter iter = recent_session_display.get_selection()->get_selected();
-
+
if (iter) {
should_be_new = false;
+ string s = (*iter)[recent_session_columns.fullpath];
+ if (Glib::file_test (s, Glib::FILE_TEST_IS_REGULAR)) {
+ return PBD::basename_nosuffix (s);
+ }
return (*iter)[recent_session_columns.visible_name];
}
}
/* Try recent session selection */
-
+
TreeIter iter = recent_session_display.get_selection()->get_selected();
-
+
if (iter) {
- return (*iter)[recent_session_columns.fullpath];
+ string s = (*iter)[recent_session_columns.fullpath];
+ if (Glib::file_test (s, Glib::FILE_TEST_IS_REGULAR)) {
+ return Glib::path_get_dirname (s);
+ }
+ return s;
}
if (_existing_session_chooser_used) {
/* existing session chosen from file chooser */
- return existing_session_chooser.get_current_folder ();
+ return Glib::path_get_dirname (existing_session_chooser.get_current_folder ());
} else {
- 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);
+ std::string val = new_name_entry.get_text();
+ strip_whitespace_edges (val);
+ std::string legal_session_folder_name = legalize_for_path (val);
+ return Glib::build_filename (new_folder_chooser.get_filename (), legal_session_folder_name);
}
}
+void
+SessionDialog::setup_recent_sessions ()
+{
+ recent_session_model = TreeStore::create (recent_session_columns);
+ recent_session_model->signal_sort_column_changed().connect (sigc::mem_fun (*this, &SessionDialog::recent_session_sort_changed));
+
+ recent_session_display.set_model (recent_session_model);
+ recent_session_display.append_column (_("Session Name"), recent_session_columns.visible_name);
+ recent_session_display.append_column (_("Sample Rate"), recent_session_columns.sample_rate);
+ recent_session_display.append_column (_("File Resolution"), recent_session_columns.disk_format);
+ recent_session_display.append_column (_("Last Modified"), recent_session_columns.time_formatted);
+ recent_session_display.set_headers_visible (true);
+ recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
+
+ recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &SessionDialog::recent_session_row_selected));
+
+ recent_scroller.add (recent_session_display);
+ recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
+
+ recent_session_display.show();
+ recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &SessionDialog::recent_row_activated));
+}
+
void
SessionDialog::setup_initial_choice_box ()
{
centering_vbox->set_spacing (6);
Label* new_label = manage (new Label);
- new_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Create a new session")));
+ new_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("New Session")));
+ new_label->set_justify (JUSTIFY_CENTER);
ic_new_session_button.add (*new_label);
ic_new_session_button.signal_clicked().connect (sigc::mem_fun (*this, &SessionDialog::new_session_button_clicked));
- centering_vbox->pack_start (ic_new_session_button, false, false);
+ Gtk::HBox* hbox = manage (new HBox);
+ Gtk::VBox* vbox = manage (new VBox);
+ hbox->set_spacing (12);
+ vbox->set_spacing (12);
+
+ string image_path;
+
+ Searchpath rc (ARDOUR::ardour_data_search_path());
+ rc.add_subdirectory_to_paths ("resources");
+
+ if (find_file (rc, PROGRAM_NAME "-small-splash.png", image_path)) {
+ Gtk::Image* image;
+ if ((image = manage (new Gtk::Image (image_path))) != 0) {
+ hbox->pack_start (*image, false, false);
+ }
+ }
+
+ vbox->pack_start (ic_new_session_button, true, true, 20);
+ hbox->pack_start (*vbox, true, true, 20);
+
+ centering_vbox->pack_start (*hbox, false, false);
/* Possible update message */
info_box->pack_start (info_scroller_label, false, false);
- cerr << "Frame should be visible\n";
-
info_scroller_count = 0;
info_scroller_connection = Glib::signal_timeout().connect (mem_fun(*this, &SessionDialog::info_scroller_update), 50);
Gtk::Button *updates_button = manage (new Gtk::Button (_("Check the website for more...")));
updates_button->signal_clicked().connect (mem_fun(*this, &SessionDialog::updates_button_clicked) );
- ARDOUR_UI::instance()->tooltips().set_tip (*updates_button, _("Click to open the program website in your web browser"));
+ set_tooltip (*updates_button, _("Click to open the program website in your web browser"));
info_box->pack_start (*updates_button, false, false);
}
/* recent session scroller */
+ setup_recent_sessions ();
recent_label.set_no_show_all (true);
recent_scroller.set_no_show_all (true);
-
- recent_label.set_markup (string_compose ("<span style=\"italic\" size=\"large\">%1</span>", _("... or load a recent session")));
- recent_label.set_alignment (0, 0.5);
-
- recent_session_model = TreeStore::create (recent_session_columns);
-
- recent_session_display.set_model (recent_session_model);
- recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
- recent_session_display.append_column (_("Sample Rate"), recent_session_columns.sample_rate);
- recent_session_display.append_column (_("Disk Format"), recent_session_columns.disk_format);
- recent_session_display.set_headers_visible (false);
- recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
-
- recent_session_display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &SessionDialog::recent_session_row_selected));
-
- recent_scroller.add (recent_session_display);
- recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
- recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
-
- recent_session_display.show();
- recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &SessionDialog::recent_row_activated));
-
+
+ recent_label.set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Recent Sessions")));
+
centering_vbox->pack_start (recent_label, false, false, 12);
- centering_vbox->pack_start (recent_scroller, false, true);
+ centering_vbox->pack_start (recent_scroller, true, true);
/* Browse button */
-
+
existing_session_chooser.set_title (_("Select session file"));
existing_session_chooser.signal_file_set().connect (sigc::mem_fun (*this, &SessionDialog::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.add_pattern (string_compose(X_("*%1"), ARDOUR::statefile_suffix));
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
-
+
+ Gtkmm2ext::add_volume_shortcuts (existing_session_chooser);
+
Label* browse_label = manage (new Label);
- browse_label->set_markup (string_compose ("<span style=\"italic\" size=\"large\">%1</span>", _("... or browse for existing sessions")));
- browse_label->set_alignment (0, 0.5);
-
+ browse_label->set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("Other Sessions")));
+
centering_vbox->pack_start (*browse_label, false, false, 12);
centering_vbox->pack_start (existing_session_chooser, false, false);
+ /* --disable plugins UI */
+
+ _disable_plugins.set_label (_("Safe Mode: Disable all Plugins"));
+ _disable_plugins.set_flags (Gtk::CAN_FOCUS);
+ _disable_plugins.set_relief (Gtk::RELIEF_NORMAL);
+ _disable_plugins.set_mode (true);
+ _disable_plugins.set_active (ARDOUR::Session::get_disable_all_loaded_plugins());
+ _disable_plugins.set_border_width(0);
+ _disable_plugins.signal_clicked().connect (sigc::mem_fun (*this, &SessionDialog::disable_plugins_clicked));
+ centering_vbox->pack_start (_disable_plugins, false, false);
+
/* pack it all up */
centering_hbox->pack_start (*centering_vbox, true, true);
} 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);
string default_session_folder = poor_mans_glob (Config->get_default_session_parent_dir());
new_folder_chooser.show ();
new_folder_chooser.set_title (_("Select folder for session"));
-#ifdef __APPLE__
- new_folder_chooser.add_shortcut_folder ("/Volumes");
-#endif
+ Gtkmm2ext::add_volume_shortcuts (new_folder_chooser);
vbox1->pack_start (*hbox2, false, false);
-
+
session_new_vbox.pack_start (*vbox1, false, false);
/* --- */
HBox* hbox4a = manage (new HBox);
use_template_button.set_label (_("Use this template"));
-
+
TreeModel::Row row = *template_model->prepend ();
row[session_template_columns.name] = (_("no template"));
row[session_template_columns.path] = string();
-
+
hbox4a->set_spacing (6);
hbox4a->pack_start (use_template_button, false, false);
hbox4a->pack_start (template_chooser, true, true);
-
+
template_chooser.set_model (template_model);
-
+
Gtk::CellRendererText* text_renderer = Gtk::manage (new Gtk::CellRendererText);
text_renderer->property_editable() = false;
-
+
template_chooser.pack_start (*text_renderer);
template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
template_chooser.set_active (0);
vbox3->pack_start (*hbox4a, false, false);
/* --- */
-
+
HBox* hbox5 = manage (new HBox);
-
+
hbox5->set_spacing (6);
hbox5->pack_start (more_new_session_options_button, false, false);
-
+
setup_more_options_box ();
more_new_session_options_button.add (more_options_vbox);
-
+
vbox3->pack_start (*hbox5, false, false);
hbox3->pack_start (*vbox3, true, true, 8);
vbox2->pack_start (*hbox3, false, false);
-
+
/* --- */
-
+
session_new_vbox.pack_start (*vbox2, false, false);
session_new_vbox.show_all ();
}
recent_session_display.set_model (recent_session_model);
return 0;
}
- //
+
// sort them alphabetically
sort (rs.begin(), rs.end(), cmp);
for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
session_directories.push_back ((*i).second);
}
-
+
int session_snapshot_count = 0;
for (vector<std::string>::const_iterator i = session_directories.begin(); i != session_directories.end(); ++i)
get_state_files_in_directory (*i, state_file_paths);
- vector<string*>* states;
+ vector<string> states;
vector<const gchar*> item;
string dirname = *i;
/* now get available states for this session */
- if ((states = Session::possible_states (dirname)) == 0) {
+ states = Session::possible_states (dirname);
+
+ if (states.empty()) {
/* no state file? */
continue;
}
float sr;
SampleFormat sf;
- std::string s = Glib::build_filename (dirname, state_file_names.front() + statefile_suffix);
- row[recent_session_columns.visible_name] = Glib::path_get_basename (dirname);
- row[recent_session_columns.fullpath] = dirname; /* just the dir, but this works too */
- row[recent_session_columns.tip] = Glib::Markup::escape_text (dirname);
+ std::string state_file_basename;
+
+ if (state_file_names.size() > 1) {
+ state_file_basename = Session::get_snapshot_from_instant (dirname);
+ std::string s = Glib::build_filename (dirname, state_file_basename + statefile_suffix);
+ if (!Glib::file_test (s, Glib::FILE_TEST_IS_REGULAR)) {
+ state_file_basename = "";
+ }
+ }
+
+ if (state_file_basename.empty()) {
+ state_file_basename = state_file_names.front();
+ }
+
+ std::string s = Glib::build_filename (dirname, state_file_basename + statefile_suffix);
+
+ GStatBuf gsb;
+ g_stat (s.c_str(), &gsb);
+
+ row[recent_session_columns.fullpath] = s;
+ row[recent_session_columns.tip] = Gtkmm2ext::markup_escape_text (dirname);
+ row[recent_session_columns.time_modified] = gsb.st_mtime;
if (Session::get_info_from_path (s, sr, sf) == 0) {
row[recent_session_columns.sample_rate] = rate_as_string (sr);
switch (sf) {
case FormatFloat:
- row[recent_session_columns.disk_format] = _("32 bit float");
+ row[recent_session_columns.disk_format] = _("32-bit float");
break;
case FormatInt24:
- row[recent_session_columns.disk_format] = _("24 bit");
+ row[recent_session_columns.disk_format] = _("24-bit");
break;
case FormatInt16:
- row[recent_session_columns.disk_format] = _("16 bit");
+ row[recent_session_columns.disk_format] = _("16-bit");
break;
}
} else {
++session_snapshot_count;
if (state_file_names.size() > 1) {
+ // multiple session files in the session directory - show the directory name.
+ // if there's not a session file with the same name as the session directory,
+ // opening the parent item will fail, but expanding it will show the session
+ // files that actually exist, and the right one can then be opened.
+ row[recent_session_columns.visible_name] = Glib::path_get_basename (dirname);
+ int64_t most_recent = 0;
// add the children
-
for (std::vector<std::string>::iterator i2 = state_file_names.begin(); i2 != state_file_names.end(); ++i2) {
+ s = Glib::build_filename (dirname, *i2 + statefile_suffix);
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] = Glib::build_filename (dirname, *i2 + statefile_suffix);
- child_row[recent_session_columns.tip] = Glib::Markup::escape_text (dirname);
-
+ child_row[recent_session_columns.fullpath] = s;
+ child_row[recent_session_columns.tip] = Gtkmm2ext::markup_escape_text (dirname);
+ g_stat (s.c_str(), &gsb);
+ child_row[recent_session_columns.time_modified] = gsb.st_mtime;
+
+ Glib::DateTime gdt(Glib::DateTime::create_now_local (gsb.st_mtime));
+ child_row[recent_session_columns.time_formatted] = gdt.format ("%F %H:%M");
+
+ if (gsb.st_mtime > most_recent) {
+ most_recent = gsb.st_mtime;
+ }
+
if (Session::get_info_from_path (s, sr, sf) == 0) {
child_row[recent_session_columns.sample_rate] = rate_as_string (sr);
switch (sf) {
case FormatFloat:
- child_row[recent_session_columns.disk_format] = _("32 bit float");
+ child_row[recent_session_columns.disk_format] = _("32-bit float");
break;
case FormatInt24:
- child_row[recent_session_columns.disk_format] = _("24 bit");
+ child_row[recent_session_columns.disk_format] = _("24-bit");
break;
case FormatInt16:
- child_row[recent_session_columns.disk_format] = _("16 bit");
+ child_row[recent_session_columns.disk_format] = _("16-bit");
break;
}
} else {
child_row[recent_session_columns.sample_rate] = "??";
child_row[recent_session_columns.disk_format] = "--";
}
-
++session_snapshot_count;
}
+
+ assert (most_recent >= row[recent_session_columns.time_modified]);
+ row[recent_session_columns.time_modified] = most_recent;
+
+ } else {
+ // only a single session file in the directory - show its actual name.
+ row[recent_session_columns.visible_name] = state_file_basename;
}
+
+ Glib::DateTime gdt(Glib::DateTime::create_now_local (row[recent_session_columns.time_modified]));
+ row[recent_session_columns.time_formatted] = gdt.format ("%F %H:%M");
}
- recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
+ recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
recent_session_display.set_model (recent_session_model);
+
+ // custom sort
+ Gtk::TreeView::Column* pColumn;
+ if ((pColumn = recent_session_display.get_column (0))) { // name
+ pColumn->set_sort_column (recent_session_columns.visible_name);
+ }
+ if ((pColumn = recent_session_display.get_column (3))) { // date
+ pColumn->set_sort_column (recent_session_columns.time_modified); // unixtime
+ }
+
+ int32_t sort = UIConfiguration::instance().get_recent_session_sort();
+ if (abs(sort) != 1 + recent_session_columns.visible_name.index () &&
+ abs(sort) != 1 + recent_session_columns.time_modified.index ()) {
+ sort = 1 + recent_session_columns.visible_name.index();
+ }
+ recent_session_model->set_sort_column (abs (sort) -1, sort < 0 ? Gtk::SORT_DESCENDING : Gtk::SORT_ASCENDING);
+
return session_snapshot_count;
}
+void
+SessionDialog::recent_session_sort_changed ()
+{
+ int column;
+ SortType order;
+ if (recent_session_model->get_sort_column_id (column, order)) {
+ int32_t sort = (column + 1) * (order == Gtk::SORT_DESCENDING ? -1 : 1);
+ if (sort != UIConfiguration::instance().get_recent_session_sort()) {
+ UIConfiguration::instance().set_recent_session_sort(sort);
+ }
+ }
+}
+
void
SessionDialog::recent_session_row_selected ()
{
response (RESPONSE_ACCEPT);
}
+void
+SessionDialog::disable_plugins_clicked ()
+{
+ ARDOUR::Session::set_disable_all_loaded_plugins (_disable_plugins.get_active());
+}
+
void
SessionDialog::existing_session_selected ()
{
_existing_session_chooser_used = true;
+ recent_session_display.get_selection()->unselect_all();
/* mark this sensitive in case we come back here after a failed open
* attempt and the user has hacked up the fix. sigh.
*/