[nautilus] general: add recency sort for recent files



commit 048c6ef549bb08a2f3a1af000286eae68bfff9b5
Author: Carlos Soriano <csoriano gnome org>
Date:   Thu Feb 2 20:30:05 2017 +0100

    general: add recency sort for recent files
    
    The sort order is based on atime currently, which is problematic,
    because some daemons (i.e. dropbox) randomly accesses files and
    changes atime...
    Instead we should just take into account when the user accessed.
    
    Recently glib and gvfs added a new attribute in the recent namespaces
    G_FILE_ATTRIBUTE_RECENT_MODIFIED or "recent::modified" that we can use
    to sort correctly the files in Recent.
    
    This patch adds this attribute and corresponding columns etc. to the
    file data and views and makes it the default sorting when in Recent.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777507

 src/nautilus-canvas-view.c      |    7 ++++
 src/nautilus-column-utilities.c |   12 +++++++
 src/nautilus-file-private.h     |    3 +-
 src/nautilus-file.c             |   62 +++++++++++++++++++++++++++++++++++---
 src/nautilus-file.h             |    6 ++-
 src/nautilus-vfs-file.c         |   12 +++++++
 6 files changed, 94 insertions(+), 8 deletions(-)
---
diff --git a/src/nautilus-canvas-view.c b/src/nautilus-canvas-view.c
index 8e9eeab..a1a1bc7 100644
--- a/src/nautilus-canvas-view.c
+++ b/src/nautilus-canvas-view.c
@@ -176,6 +176,13 @@ static const SortCriterion sort_criteria[] =
         "search-relevance",
         TRUE,
         nautilus_file_is_in_search
+    },
+    {
+        NAUTILUS_FILE_SORT_BY_RECENCY,
+        NULL,
+        "recency",
+        TRUE,
+        nautilus_file_is_in_recent
     }
 };
 
diff --git a/src/nautilus-column-utilities.c b/src/nautilus-column-utilities.c
index 891aa82..1a2a092 100644
--- a/src/nautilus-column-utilities.c
+++ b/src/nautilus-column-utilities.c
@@ -41,6 +41,7 @@ static const char *default_column_order[] =
     "date_modified_with_time",
     "date_modified",
     "date_accessed",
+    "recency",
     NULL
 };
 
@@ -128,6 +129,7 @@ get_builtin_columns (void)
                                            "label", _("Location"),
                                            "description", _("The location of the file."),
                                            NULL));
+
     columns = g_list_append (columns,
                              g_object_new (NAUTILUS_TYPE_COLUMN,
                                            "name", "date_modified_with_time",
@@ -137,6 +139,16 @@ get_builtin_columns (void)
                                            "xalign", 1.0,
                                            NULL));
 
+    columns = g_list_append (columns,
+                             g_object_new (NAUTILUS_TYPE_COLUMN,
+                                           "name", "recency",
+                                           "attribute", "recency",
+                                           "label", _("Recency"),
+                                           "description", _("The date the file was accessed by the user."),
+                                           "default-sort-order", GTK_SORT_DESCENDING,
+                                           "xalign", 1.0,
+                                           NULL));
+
     return columns;
 }
 
diff --git a/src/nautilus-file-private.h b/src/nautilus-file-private.h
index f0ecf72..d040a51 100644
--- a/src/nautilus-file-private.h
+++ b/src/nautilus-file-private.h
@@ -30,7 +30,7 @@
 #include <eel/eel-string.h>
 
 #define NAUTILUS_FILE_DEFAULT_ATTRIBUTES                               \
-       
"standard::*,access::*,mountable::*,time::*,unix::*,owner::*,selinux::*,thumbnail::*,id::filesystem,trash::orig-path,trash::deletion-date,metadata::*"
+       
"standard::*,access::*,mountable::*,time::*,unix::*,owner::*,selinux::*,thumbnail::*,id::filesystem,trash::orig-path,trash::deletion-date,metadata::*,recent::*"
 
 /* These are in the typical sort order. Known things come first, then
  * things where we can't know, finally things where we don't yet know.
@@ -205,6 +205,7 @@ struct NautilusFileDetails
         eel_ref_str     filesystem_type;
 
        time_t trash_time; /* 0 is unknown */
+       time_t recency; /* 0 is unknown */
 
        gdouble search_relevance;
 
diff --git a/src/nautilus-file.c b/src/nautilus-file.c
index b289487..5c100f5 100644
--- a/src/nautilus-file.c
+++ b/src/nautilus-file.c
@@ -147,6 +147,7 @@ static GQuark attribute_name_q,
               attribute_trashed_on_q,
               attribute_trashed_on_full_q,
               attribute_trash_orig_path_q,
+              attribute_recency_q,
               attribute_permissions_q,
               attribute_selinux_context_q,
               attribute_octal_permissions_q,
@@ -531,6 +532,7 @@ nautilus_file_clear_info (NautilusFile *file)
     file->details->mtime = 0;
     file->details->atime = 0;
     file->details->trash_time = 0;
+    file->details->recency = 0;
     g_free (file->details->symlink_name);
     file->details->symlink_name = NULL;
     eel_ref_str_unref (file->details->mime_type);
@@ -2634,6 +2636,7 @@ update_info_internal (NautilusFile *file,
     int sort_order;
     time_t atime, mtime;
     time_t trash_time;
+    time_t recency;
     GTimeVal g_trash_time;
     const char *time_string;
     const char *symlink_name, *mime_type, *selinux_context, *name, *thumbnail_path;
@@ -3063,6 +3066,13 @@ update_info_internal (NautilusFile *file,
         file->details->trash_time = trash_time;
     }
 
+    recency = g_file_info_get_attribute_int64 (info, G_FILE_ATTRIBUTE_RECENT_MODIFIED);
+    if (file->details->recency != recency)
+    {
+        changed = TRUE;
+        file->details->recency = recency;
+    }
+
     trash_orig_path = g_file_info_get_attribute_byte_string (info, "trash::orig-path");
     if (g_strcmp0 (file->details->trash_orig_path, trash_orig_path) != 0)
     {
@@ -3347,6 +3357,12 @@ get_time (NautilusFile     *file,
         }
         break;
 
+        case NAUTILUS_DATE_TYPE_RECENCY:
+        {
+            time = file->details->recency;
+        }
+        break;
+
         default:
         {
             g_assert_not_reached ();
@@ -3890,6 +3906,16 @@ nautilus_file_compare_for_sort (NautilusFile         *file_1,
             }
             break;
 
+            case NAUTILUS_FILE_SORT_BY_RECENCY:
+            {
+                result = compare_by_time (file_1, file_2, NAUTILUS_DATE_TYPE_RECENCY);
+                if (result == 0)
+                {
+                    result = compare_by_full_path (file_1, file_2);
+                }
+            }
+            break;
+
             default:
                 g_return_val_if_reached (0);
         }
@@ -3969,6 +3995,13 @@ nautilus_file_compare_for_sort_by_attribute_q   (NautilusFile *file_1,
                                                directories_first,
                                                reversed);
     }
+    else if (attribute == attribute_recency_q)
+    {
+        return nautilus_file_compare_for_sort (file_1, file_2,
+                                               NAUTILUS_FILE_SORT_BY_RECENCY,
+                                               directories_first,
+                                               reversed);
+    }
 
     /* it is a normal attribute, compare by strings */
 
@@ -5541,7 +5574,8 @@ nautilus_file_get_date (NautilusFile     *file,
 
     g_return_val_if_fail (date_type == NAUTILUS_DATE_TYPE_ACCESSED
                           || date_type == NAUTILUS_DATE_TYPE_MODIFIED
-                          || date_type == NAUTILUS_DATE_TYPE_TRASHED,
+                          || date_type == NAUTILUS_DATE_TYPE_TRASHED
+                          || date_type == NAUTILUS_DATE_TYPE_RECENCY,
                           FALSE);
 
     if (file == NULL)
@@ -7280,7 +7314,8 @@ nautilus_file_get_deep_directory_count_as_string (NautilusFile *file)
  * "deep_file_count", "deep_total_count", "date_modified", "date_accessed",
  * "date_modified_full", "date_accessed_full",
  * "owner", "group", "permissions", "octal_permissions", "uri", "where",
- * "link_target", "volume", "free_space", "selinux_context", "trashed_on", "trashed_on_full", 
"trashed_orig_path"
+ * "link_target", "volume", "free_space", "selinux_context", "trashed_on", "trashed_on_full", 
"trashed_orig_path",
+ * "recency"
  *
  * Returns: Newly allocated string ready to display to the user, or NULL
  * if the value is unknown or @attribute_name is not supported.
@@ -7378,6 +7413,12 @@ nautilus_file_get_string_attribute_q (NautilusFile *file,
                                                  NAUTILUS_DATE_TYPE_TRASHED,
                                                  NAUTILUS_DATE_FORMAT_FULL);
     }
+    if (attribute_q == attribute_recency_q)
+    {
+        return nautilus_file_get_date_as_string (file,
+                                                 NAUTILUS_DATE_TYPE_RECENCY,
+                                                 NAUTILUS_DATE_FORMAT_REGULAR);
+    }
     if (attribute_q == attribute_permissions_q)
     {
         return nautilus_file_get_permissions_as_string (file);
@@ -7531,6 +7572,11 @@ nautilus_file_get_string_attribute_with_default_q (NautilusFile *file,
         /* If n/a */
         return g_strdup ("");
     }
+    if (attribute_q == attribute_recency_q)
+    {
+        /* If n/a */
+        return g_strdup ("");
+    }
 
     /* Fallback, use for both unknown attributes and attributes
      * for which we have no more appropriate default.
@@ -7556,7 +7602,8 @@ nautilus_file_is_date_sort_attribute_q (GQuark attribute_q)
         attribute_q == attribute_date_accessed_q ||
         attribute_q == attribute_date_accessed_full_q ||
         attribute_q == attribute_trashed_on_q ||
-        attribute_q == attribute_trashed_on_full_q)
+        attribute_q == attribute_trashed_on_full_q ||
+        attribute_q == attribute_recency_q)
     {
         return TRUE;
     }
@@ -8961,7 +9008,7 @@ nautilus_file_get_default_sort_type (NautilusFile *file,
     {
         if (is_recent)
         {
-            retval = NAUTILUS_FILE_SORT_BY_ATIME;
+            retval = NAUTILUS_FILE_SORT_BY_RECENCY;
         }
         else if (is_download)
         {
@@ -8998,7 +9045,11 @@ nautilus_file_get_default_sort_attribute (NautilusFile *file,
 
     if (res)
     {
-        if (is_recent || is_download)
+        if (is_recent)
+        {
+            retval = g_quark_to_string (attribute_recency_q);
+        }
+        else if (is_download)
         {
             retval = g_quark_to_string (attribute_date_modified_q);
         }
@@ -9259,6 +9310,7 @@ nautilus_file_class_init (NautilusFileClass *class)
     attribute_date_modified_q = g_quark_from_static_string ("date_modified");
     attribute_date_modified_full_q = g_quark_from_static_string ("date_modified_full");
     attribute_date_modified_with_time_q = g_quark_from_static_string ("date_modified_with_time");
+    attribute_recency_q = g_quark_from_static_string ("recency");
     attribute_accessed_date_q = g_quark_from_static_string ("accessed_date");
     attribute_date_accessed_q = g_quark_from_static_string ("date_accessed");
     attribute_date_accessed_full_q = g_quark_from_static_string ("date_accessed_full");
diff --git a/src/nautilus-file.h b/src/nautilus-file.h
index f471536..e941e7a 100644
--- a/src/nautilus-file.h
+++ b/src/nautilus-file.h
@@ -58,7 +58,8 @@ typedef enum {
        NAUTILUS_FILE_SORT_BY_MTIME,
         NAUTILUS_FILE_SORT_BY_ATIME,
        NAUTILUS_FILE_SORT_BY_TRASHED_TIME,
-       NAUTILUS_FILE_SORT_BY_SEARCH_RELEVANCE
+       NAUTILUS_FILE_SORT_BY_SEARCH_RELEVANCE,
+       NAUTILUS_FILE_SORT_BY_RECENCY
 } NautilusFileSortType;        
 
 typedef enum {
@@ -527,7 +528,8 @@ struct NautilusFile {
 typedef enum {
        NAUTILUS_DATE_TYPE_MODIFIED,
        NAUTILUS_DATE_TYPE_ACCESSED,
-       NAUTILUS_DATE_TYPE_TRASHED
+       NAUTILUS_DATE_TYPE_TRASHED,
+       NAUTILUS_DATE_TYPE_RECENCY
 } NautilusDateType;
 
 gboolean                nautilus_file_get_date                          (NautilusFile                   
*file,
diff --git a/src/nautilus-vfs-file.c b/src/nautilus-vfs-file.c
index 0fff497..7b87699 100644
--- a/src/nautilus-vfs-file.c
+++ b/src/nautilus-vfs-file.c
@@ -337,6 +337,18 @@ vfs_file_get_date (NautilusFile     *file,
                 *date = file->details->trash_time;
             }
             return TRUE;
+
+        case NAUTILUS_DATE_TYPE_RECENCY:
+            /* Before we have info on a file, the date is unknown. */
+            if (file->details->recency == 0)
+            {
+                return FALSE;
+            }
+            if (date != NULL)
+            {
+                *date = file->details->recency;
+            }
+            return TRUE;
     }
     return FALSE;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]