fix d6029f9 (recent sort-order)
[ardour.git] / gtk2_ardour / session_dialog.cc
index 72dd0c8fae8f404c98d9c37196e5ce4c8a64f300..e47f390eb694825f6633ae96f1cf2f6dc9997e83 100644 (file)
@@ -24,6 +24,9 @@
 #include <fstream>
 #include <algorithm>
 
+#include <glib.h>
+#include <glib/gstdio.h>
+
 #include <gtkmm/filechooser.h>
 
 #include "pbd/failed_constructor.h"
@@ -57,13 +60,6 @@ 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, bool cancel_not_quit)
        : ArdourDialog (_("Session Setup"), true, true)
        , new_only (require_new)
@@ -76,9 +72,6 @@ SessionDialog::SessionDialog (bool require_new, const std::string& session_name,
        , _master_bus_channel_count_adj (2, 0, 100, 1, 10, 0)
        , _existing_session_chooser_used (false)
 {
-#ifndef PLATFORM_WINDOWS
-       set_keep_above (true);
-#endif
        set_position (WIN_POS_CENTER);
        get_vbox()->set_spacing (6);
 
@@ -255,7 +248,7 @@ SessionDialog::session_folder ()
                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_current_folder(), legal_session_folder_name);
+               return Glib::build_filename (new_folder_chooser.get_filename (), legal_session_folder_name);
        }
 }
 
@@ -328,12 +321,15 @@ SessionDialog::setup_initial_choice_box ()
        recent_label.set_markup (string_compose ("<span weight=\"bold\" size=\"large\">%1</span>", _("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 (_("Recent Sessions"), recent_session_columns.visible_name);
+       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 (_("Disk Format"), recent_session_columns.disk_format);
-       recent_session_display.set_headers_visible (false);
+       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));
@@ -355,7 +351,7 @@ SessionDialog::setup_initial_choice_box ()
        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);
@@ -487,8 +483,6 @@ SessionDialog::setup_new_session_page ()
        } 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());
 
@@ -599,6 +593,7 @@ SessionDialog::redisplay_recent_sessions ()
        recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
        recent_session_model->clear ();
 
+       // code below is a near from ARDOUR_UI::redisplay_recent_sessions()
        ARDOUR::RecentSessions rs;
        ARDOUR::read_recent_sessions (rs);
 
@@ -606,7 +601,7 @@ SessionDialog::redisplay_recent_sessions ()
                recent_session_display.set_model (recent_session_model);
                return 0;
        }
-       //
+
        // sort them alphabetically
        sort (rs.begin(), rs.end(), cmp);
 
@@ -663,8 +658,12 @@ SessionDialog::redisplay_recent_sessions ()
 
                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] = dirname; /* just the dir, but this works too */
                row[recent_session_columns.tip] = Glib::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);
@@ -692,15 +691,26 @@ SessionDialog::redisplay_recent_sessions ()
                        // 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.fullpath] = s;
                                child_row[recent_session_columns.tip] = Glib::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);
@@ -719,21 +729,57 @@ SessionDialog::redisplay_recent_sessions ()
                                        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_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 = ARDOUR_UI::config()->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 != ARDOUR_UI::config()->get_recent_session_sort()) {
+                       ARDOUR_UI::config()->set_recent_session_sort(sort);
+               }
+       }
+}
+
 void
 SessionDialog::recent_session_row_selected ()
 {