file-info: Add a set of attributes for large thumbnails

Some applications (eg., gnome-photos) really want a large thumbnail,
if one can be created. Simply falling back to a smaller one (probably
created by an old nautilus), without giving the application a chance
to create a bigger thumbnail, is undesirable because they will appear
fuzzy.

Therefore, at separate attribute sets for all the thumbnail sizes
that are supported in the spec: normal/large/x-large/xx-large.

The old attribute will now return by default the biggest available, as
it used to be, but also including the x-large and xx-large cases.

Co-Authored-by: Marco Trevisan <mail@3v1n0.net>

Fixes: #621
This commit is contained in:
Matthias Clasen
2022-09-22 16:29:41 -04:00
committed by Marco Trevisan (Treviño)
parent 4b6cc2d87b
commit f0606d5421
6 changed files with 547 additions and 17 deletions

View File

@@ -29,6 +29,18 @@
G_FILE_ATTRIBUTE_THUMBNAIL_PATH "," \
G_FILE_ATTRIBUTE_THUMBNAILING_FAILED "," \
G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID "," \
G_FILE_ATTRIBUTE_THUMBNAIL_PATH_NORMAL "," \
G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_NORMAL "," \
G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_NORMAL "," \
G_FILE_ATTRIBUTE_THUMBNAIL_PATH_LARGE "," \
G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_LARGE "," \
G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_LARGE "," \
G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XLARGE "," \
G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XLARGE "," \
G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XLARGE "," \
G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XXLARGE "," \
G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XXLARGE "," \
G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XXLARGE "," \
)
/* Must be kept in order, for priority */
@@ -202,6 +214,48 @@ create_thumbnail_from_test_file (const gchar *source_name,
return thumbnail;
}
static gboolean
get_size_attributes (const char *size,
const gchar **path,
const gchar **is_valid,
const gchar **failed)
{
if (g_str_equal (size, "normal"))
{
*path = G_FILE_ATTRIBUTE_THUMBNAIL_PATH_NORMAL;
*is_valid = G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_NORMAL;
*failed = G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_NORMAL;
return TRUE;
}
else if (g_str_equal (size, "large"))
{
*path = G_FILE_ATTRIBUTE_THUMBNAIL_PATH_LARGE;
*is_valid = G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_LARGE;
*failed = G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_LARGE;
return TRUE;
}
else if (g_str_equal (size, "x-large"))
{
*path = G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XLARGE;
*is_valid = G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XLARGE;
*failed = G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XLARGE;
return TRUE;
}
else if (g_str_equal (size, "xx-large"))
{
*path = G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XXLARGE;
*is_valid = G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XXLARGE;
*failed = G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XXLARGE;
return TRUE;
}
*path = NULL;
*is_valid = NULL;
*failed = NULL;
return FALSE;
}
static void
test_valid_thumbnail_size (gconstpointer data)
{
@@ -211,6 +265,7 @@ test_valid_thumbnail_size (gconstpointer data)
GError *error = NULL;
GFileInfo *info;
const gchar *size = data;
const gchar *path_attr, *failed_attr, *is_valid_attr;
thumbnail = create_thumbnail_from_test_file ("valid.png", size, &source);
info = g_file_query_info (source, THUMBNAILS_ATTRIBS, G_FILE_QUERY_INFO_NONE,
@@ -227,12 +282,31 @@ test_valid_thumbnail_size (gconstpointer data)
==,
g_file_peek_path (thumbnail)
);
g_clear_object (&f);
/* TODO: We can't really test this without having a proper thumbnail created
g_assert_true (
g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
*/
g_assert_true (get_size_attributes (size, &path_attr, &is_valid_attr, &failed_attr));
g_assert_true (g_file_info_has_attribute (info, path_attr));
g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
g_assert_false (g_file_info_has_attribute (info, failed_attr));
f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, path_attr));
g_assert_cmpstr (
g_file_info_get_attribute_byte_string (info, path_attr),
==,
g_file_peek_path (thumbnail)
);
g_clear_object (&f);
/* TODO: We can't really test this without having a proper thumbnail created
g_assert_true (g_file_info_get_attribute_boolean (info, is_valid_attr));
*/
g_clear_object (&source);
g_clear_object (&thumbnail);
g_clear_error (&error);
@@ -258,6 +332,22 @@ test_unknown_thumbnail_size (gconstpointer data)
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH_NORMAL));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_NORMAL));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_NORMAL));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH_LARGE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_LARGE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_LARGE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XLARGE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XLARGE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XLARGE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XXLARGE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XXLARGE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XXLARGE));
g_clear_object (&source);
g_clear_object (&thumbnail);
g_clear_error (&error);
@@ -309,6 +399,7 @@ test_thumbnails_size_priority (void)
for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
{
GFile *thumbnail = create_thumbnail (source, SIZES_NAMES[i]);
const gchar *path_attr, *failed_attr, *is_valid_attr;
GFile *f;
g_ptr_array_add (sized_thumbnails, thumbnail);
@@ -327,6 +418,21 @@ test_thumbnails_size_priority (void)
==,
g_file_peek_path (thumbnail)
);
g_clear_object (&f);
g_assert_true (get_size_attributes (SIZES_NAMES[i],
&path_attr, &is_valid_attr, &failed_attr));
g_assert_true (g_file_info_has_attribute (info, path_attr));
g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
g_assert_false (g_file_info_has_attribute (info, failed_attr));
f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, path_attr));
g_assert_cmpstr (
g_file_peek_path (f),
==,
g_file_peek_path (thumbnail)
);
g_clear_object (&info);
g_clear_object (&f);
@@ -334,11 +440,41 @@ test_thumbnails_size_priority (void)
g_assert_cmpuint (sized_thumbnails->len, ==, G_N_ELEMENTS (SIZES_NAMES));
/* Ensuring we can access to all the thumbnails by explicit size request */
for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
{
GFile *thumbnail = g_ptr_array_index (sized_thumbnails, i);
const gchar *path_attr, *failed_attr, *is_valid_attr;
GFile *f;
info = g_file_query_info (source, THUMBNAILS_ATTRIBS,
G_FILE_QUERY_INFO_NONE, NULL, &error);
g_assert_no_error (error);
g_assert_true (get_size_attributes (SIZES_NAMES[i],
&path_attr, &is_valid_attr, &failed_attr));
g_assert_true (g_file_info_has_attribute (info, path_attr));
g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
g_assert_false (g_file_info_has_attribute (info, failed_attr));
f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, path_attr));
g_assert_cmpstr (
g_file_peek_path (f),
==,
g_file_peek_path (thumbnail)
);
g_clear_object (&f);
g_clear_object (&info);
}
/* Now removing them in the inverse order, to check this again */
for (i = G_N_ELEMENTS (SIZES_NAMES); i > 1; i--)
{
GFile *thumbnail = g_ptr_array_index (sized_thumbnails, i - 1);
GFile *less_priority_thumbnail = g_ptr_array_index (sized_thumbnails, i - 2);
const gchar *path_attr, *failed_attr, *is_valid_attr;
GFile *f;
g_file_delete (thumbnail, NULL, &error);
@@ -358,6 +494,21 @@ test_thumbnails_size_priority (void)
==,
g_file_peek_path (less_priority_thumbnail)
);
g_clear_object (&f);
g_assert_true (get_size_attributes (SIZES_NAMES[i-2],
&path_attr, &is_valid_attr, &failed_attr));
g_assert_true (g_file_info_has_attribute (info, path_attr));
g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
g_assert_false (g_file_info_has_attribute (info, failed_attr));
f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, path_attr));
g_assert_cmpstr (
g_file_peek_path (f),
==,
g_file_peek_path (less_priority_thumbnail)
);
g_clear_object (&info);
g_clear_object (&f);
@@ -382,6 +533,28 @@ test_thumbnails_size_priority (void)
g_clear_object (&info);
/* And check if we get the failed state for all explicit requests */
for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
{
const gchar *path_attr, *failed_attr, *is_valid_attr;
info = g_file_query_info (source, THUMBNAILS_ATTRIBS,
G_FILE_QUERY_INFO_NONE, NULL, &error);
g_assert_no_error (error);
g_assert_true (get_size_attributes (SIZES_NAMES[i],
&path_attr, &is_valid_attr, &failed_attr));
g_assert_false (g_file_info_has_attribute (info, path_attr));
g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
g_assert_true (g_file_info_has_attribute (info, failed_attr));
g_assert_false (g_file_info_get_attribute_boolean (info, is_valid_attr));
g_assert_true (g_file_info_get_attribute_boolean (info, failed_attr));
g_clear_object (&info);
}
/* Removing the failed thumbnail too, so no thumbnail should be available */
g_file_delete (failed_thumbnail, NULL, &error);
g_assert_no_error (error);
@@ -394,6 +567,26 @@ test_thumbnails_size_priority (void)
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
g_clear_object (&info);
for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
{
const gchar *path_attr, *failed_attr, *is_valid_attr;
info = g_file_query_info (source, THUMBNAILS_ATTRIBS,
G_FILE_QUERY_INFO_NONE, NULL, &error);
g_assert_no_error (error);
g_assert_true (get_size_attributes (SIZES_NAMES[i],
&path_attr, &is_valid_attr, &failed_attr));
g_assert_false (g_file_info_has_attribute (info, path_attr));
g_assert_false (g_file_info_has_attribute (info, is_valid_attr));
g_assert_false (g_file_info_has_attribute (info, failed_attr));
g_clear_object (&info);
}
g_clear_object (&source);
g_clear_pointer (&sized_thumbnails, g_ptr_array_unref);
g_clear_object (&failed_thumbnail);