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
parent cc6c855c
......@@ -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
}
};
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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");
......
......@@ -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,
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment