fix d6029f9 (recent sort-order)
[ardour.git] / gtk2_ardour / session_dialog.cc
index 26bb9356f0003ba9be9029afbab289dfd7e28752..e47f390eb694825f6633ae96f1cf2f6dc9997e83 100644 (file)
@@ -321,11 +321,14 @@ 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 (_("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);
        
@@ -585,7 +588,7 @@ int
 SessionDialog::redisplay_recent_sessions ()
 {
        std::vector<std::string> session_directories;
-       RecentSessionsTimeSorter cmp;
+       RecentSessionsSorter cmp;
 
        recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
        recent_session_model->clear ();
@@ -599,25 +602,10 @@ SessionDialog::redisplay_recent_sessions ()
                return 0;
        }
 
-       // sort by session modificaion time.
-       // TODO it would be nicer to sort using the model (and make the TV sortable)
-       std::vector< std::pair<int64_t,std::string> > rss;
-       for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
-               std::vector<std::string> state_file_paths;
-               get_state_files_in_directory ((*i).second, state_file_paths);
-               if (state_file_paths.empty()) {
-                       continue;
-               }
-               GStatBuf gsb;
-               if (g_stat (state_file_paths.front().c_str(), &gsb)) {
-                       continue;
-               }
-               rss.push_back (std::make_pair((int64_t)gsb.st_mtime, (*i).second));
-       }
-
-       sort (rss.begin(), rss.end(), cmp);
+       // sort them alphabetically
+       sort (rs.begin(), rs.end(), cmp);
 
-       for (std::vector< std::pair<int64_t,std::string> >::iterator i = rss.begin(); i != rss.end(); ++i) {
+       for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
                session_directories.push_back ((*i).second);
        }
        
@@ -670,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);
@@ -699,6 +691,7 @@ 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) {
@@ -709,6 +702,15 @@ SessionDialog::redisplay_recent_sessions ()
                                child_row[recent_session_columns.visible_name] = *i2;
                                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);
@@ -727,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 ()
 {