thunar-usagebars/plugins/thunar-apr/thunar-apr-image-page.c
4aiman df58603323 thunar 4.20.7 upstream
Tree of tag thunar-4.20.7 (commit df0e054) from https://gitlab.xfce.org/xfce/thunar.
Upstream history is not included here to keep the repository small.
2026-11-04 01:40:30 +03:00

319 lines
11 KiB
C

/* vi:set et ai sw=2 sts=2 ts=2: */
/*-
* Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <exo/exo.h>
#include <thunar-apr/thunar-apr-image-page.h>
#ifdef HAVE_EXIF
#include <libexif/exif-data.h>
#endif
static void
thunar_apr_image_page_file_changed (ThunarAprAbstractPage *abstract_page,
ThunarxFileInfo *file);
#ifdef HAVE_EXIF
static const struct
{
const gchar *name;
ExifTag tag;
}
/* clang-format off */
TAIP_EXIF[] =
{
{ N_ ("Date Taken:"), EXIF_TAG_DATE_TIME_ORIGINAL, },
{ N_ ("Camera Brand:"), EXIF_TAG_MAKE, },
{ N_ ("Camera Model:"), EXIF_TAG_MODEL, },
{ N_ ("Exposure Time:"), EXIF_TAG_EXPOSURE_TIME, },
{ N_ ("Exposure Program:"), EXIF_TAG_EXPOSURE_PROGRAM, },
{ N_ ("Aperture Value:"), EXIF_TAG_APERTURE_VALUE, },
{ N_ ("Metering Mode:"), EXIF_TAG_METERING_MODE, },
{ N_ ("Flash Fired:"), EXIF_TAG_FLASH, },
{ N_ ("Focal Length:"), EXIF_TAG_FOCAL_LENGTH, },
{ N_ ("Shutter Speed:"), EXIF_TAG_SHUTTER_SPEED_VALUE, },
{ N_ ("ISO Speed Ratings:"), EXIF_TAG_ISO_SPEED_RATINGS, },
{ N_ ("Software:"), EXIF_TAG_SOFTWARE, },
{ N_ ("Description:"), EXIF_TAG_IMAGE_DESCRIPTION, },
{ N_ ("Comment:"), EXIF_TAG_USER_COMMENT, },
};
/* clang-format on */
#endif
struct _ThunarAprImagePageClass
{
ThunarAprAbstractPageClass __parent__;
};
struct _ThunarAprImagePage
{
ThunarAprAbstractPage __parent__;
GtkWidget *type_label;
GtkWidget *dimensions_label;
#ifdef HAVE_EXIF
GtkWidget *exif_labels[G_N_ELEMENTS (TAIP_EXIF)];
#endif
};
THUNARX_DEFINE_TYPE (ThunarAprImagePage,
thunar_apr_image_page,
THUNAR_APR_TYPE_ABSTRACT_PAGE);
static void
thunar_apr_image_page_class_init (ThunarAprImagePageClass *klass)
{
ThunarAprAbstractPageClass *thunarapr_abstract_page_class;
thunarapr_abstract_page_class = THUNAR_APR_ABSTRACT_PAGE_CLASS (klass);
thunarapr_abstract_page_class->file_changed = thunar_apr_image_page_file_changed;
}
static void
thunar_apr_image_page_init (ThunarAprImagePage *image_page)
{
AtkRelationSet *relations;
PangoAttribute *attribute;
PangoAttrList *attr_list;
AtkRelation *relation;
AtkObject *object;
GtkWidget *label;
GtkWidget *grid;
#ifdef HAVE_EXIF
GtkWidget *spacer;
guint n;
#endif
gtk_container_set_border_width (GTK_CONTAINER (image_page), 12);
thunarx_property_page_set_label (THUNARX_PROPERTY_PAGE (image_page), _("Image"));
/* allocate shared bold Pango attributes */
attr_list = pango_attr_list_new ();
attribute = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
attribute->start_index = 0;
attribute->end_index = -1;
pango_attr_list_insert (attr_list, attribute);
grid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_container_add (GTK_CONTAINER (image_page), grid);
gtk_widget_show (grid);
label = gtk_label_new (_("Image Type:"));
gtk_label_set_xalign (GTK_LABEL (label), 1.0f);
gtk_label_set_attributes (GTK_LABEL (label), attr_list);
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
gtk_widget_show (label);
image_page->type_label = gtk_label_new ("");
gtk_label_set_selectable (GTK_LABEL (image_page->type_label), TRUE);
gtk_label_set_xalign (GTK_LABEL (image_page->type_label), 0.0f);
gtk_label_set_ellipsize (GTK_LABEL (image_page->type_label), PANGO_ELLIPSIZE_END);
gtk_widget_set_hexpand (image_page->type_label, TRUE);
gtk_grid_attach (GTK_GRID (grid), image_page->type_label, 1, 0, 1, 1);
gtk_widget_show (image_page->type_label);
/* set Atk label relation for the label */
object = gtk_widget_get_accessible (image_page->type_label);
relations = atk_object_ref_relation_set (gtk_widget_get_accessible (label));
relation = atk_relation_new (&object, 1, ATK_RELATION_LABEL_FOR);
atk_relation_set_add (relations, relation);
g_object_unref (G_OBJECT (relation));
g_object_unref (relations);
label = gtk_label_new (_("Image Size:"));
gtk_label_set_xalign (GTK_LABEL (label), 1.0f);
gtk_label_set_attributes (GTK_LABEL (label), attr_list);
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
gtk_widget_show (label);
image_page->dimensions_label = gtk_label_new ("");
gtk_label_set_selectable (GTK_LABEL (image_page->dimensions_label), TRUE);
gtk_label_set_xalign (GTK_LABEL (image_page->dimensions_label), 0.0f);
gtk_label_set_ellipsize (GTK_LABEL (image_page->dimensions_label), PANGO_ELLIPSIZE_END);
gtk_widget_set_hexpand (image_page->dimensions_label, TRUE);
gtk_grid_attach (GTK_GRID (grid), image_page->dimensions_label, 1, 1, 1, 1);
gtk_widget_show (image_page->dimensions_label);
/* set Atk label relation for the label */
object = gtk_widget_get_accessible (image_page->dimensions_label);
relations = atk_object_ref_relation_set (gtk_widget_get_accessible (label));
relation = atk_relation_new (&object, 1, ATK_RELATION_LABEL_FOR);
atk_relation_set_add (relations, relation);
g_object_unref (G_OBJECT (relation));
g_object_unref (relations);
#ifdef HAVE_EXIF
/* some spacing between the General info and the Exif info */
spacer = g_object_new (GTK_TYPE_BOX, "orientation", GTK_ORIENTATION_VERTICAL, "height-request", 6, NULL);
gtk_grid_attach (GTK_GRID (grid), spacer, 0, 2, 2, 1);
gtk_widget_show (spacer);
/* add labels for the Exif info */
for (n = 0; n < G_N_ELEMENTS (TAIP_EXIF); ++n)
{
label = gtk_label_new (_(TAIP_EXIF[n].name));
gtk_label_set_xalign (GTK_LABEL (label), 1.0f);
gtk_label_set_attributes (GTK_LABEL (label), attr_list);
gtk_grid_attach (GTK_GRID (grid), label, 0, n + 3, 1, 1);
gtk_widget_show (label);
image_page->exif_labels[n] = gtk_label_new ("");
gtk_label_set_selectable (GTK_LABEL (image_page->exif_labels[n]), TRUE);
gtk_label_set_xalign (GTK_LABEL (image_page->exif_labels[n]), 0.0f);
gtk_label_set_ellipsize (GTK_LABEL (image_page->exif_labels[n]), PANGO_ELLIPSIZE_END);
gtk_widget_set_hexpand (image_page->exif_labels[n], TRUE);
gtk_grid_attach (GTK_GRID (grid), image_page->exif_labels[n], 1, n + 3, 1, 1);
gtk_widget_show (image_page->exif_labels[n]);
g_object_bind_property (G_OBJECT (image_page->exif_labels[n]), "visible", G_OBJECT (label), "visible", G_BINDING_SYNC_CREATE);
/* set Atk label relation for the label */
object = gtk_widget_get_accessible (image_page->exif_labels[n]);
relations = atk_object_ref_relation_set (gtk_widget_get_accessible (label));
relation = atk_relation_new (&object, 1, ATK_RELATION_LABEL_FOR);
atk_relation_set_add (relations, relation);
g_object_unref (G_OBJECT (relation));
g_object_unref (relations);
}
#endif
/* release shared bold Pango attributes */
pango_attr_list_unref (attr_list);
}
static void
thunar_apr_image_page_file_changed (ThunarAprAbstractPage *abstract_page,
ThunarxFileInfo *file)
{
ThunarAprImagePage *image_page = THUNAR_APR_IMAGE_PAGE (abstract_page);
GdkPixbufFormat *format;
gchar *filename;
gchar *text;
gchar *uri;
gint height;
gint width;
#ifdef HAVE_EXIF
ExifEntry *exif_entry;
ExifData *exif_data;
gchar exif_buffer[1024];
guint n;
#endif
/* determine the URI for the file */
uri = thunarx_file_info_get_uri (file);
if (G_UNLIKELY (uri == NULL))
return;
/* determine the local path of the file */
filename = g_filename_from_uri (uri, NULL, NULL);
if (G_LIKELY (filename != NULL))
{
/* determine the pixbuf format */
format = gdk_pixbuf_get_file_info (filename, &width, &height);
if (G_LIKELY (format != NULL))
{
/* update the "Image Type" label */
gchar *name = gdk_pixbuf_format_get_name (format);
gchar *desc = gdk_pixbuf_format_get_description (format);
text = g_strdup_printf ("%s (%s)", name, desc);
gtk_label_set_text (GTK_LABEL (image_page->type_label), text);
g_free (name);
g_free (desc);
g_free (text);
/* update the "Image Size" label */
text = g_strdup_printf (ngettext ("%dx%d pixel", "%dx%d pixels", width + height), width, height);
gtk_label_set_text (GTK_LABEL (image_page->dimensions_label), text);
g_free (text);
#ifdef HAVE_EXIF
/* hide all Exif labels (will be shown again if data is available) */
for (n = 0; n < G_N_ELEMENTS (TAIP_EXIF); ++n)
gtk_widget_hide (image_page->exif_labels[n]);
/* try to load the Exif data for the file */
exif_data = exif_data_new_from_file (filename);
if (G_LIKELY (exif_data != NULL))
{
/* update all Exif labels */
for (n = 0; n < G_N_ELEMENTS (TAIP_EXIF); ++n)
{
/* lookup the entry for the tag */
exif_entry = exif_data_get_entry (exif_data, TAIP_EXIF[n].tag);
if (G_LIKELY (exif_entry != NULL))
{
/* determine the value */
if (exif_entry_get_value (exif_entry, exif_buffer, sizeof (exif_buffer)) != NULL)
{
/* setup the label text */
text = (g_utf8_validate (exif_buffer, -1, NULL)) ? g_strdup (exif_buffer) : g_filename_display_name (exif_buffer);
gtk_label_set_text (GTK_LABEL (image_page->exif_labels[n]), text);
g_free (text);
/* show the label */
gtk_widget_show (image_page->exif_labels[n]);
}
}
}
/* cleanup */
exif_data_free (exif_data);
}
#endif
}
else
{
/* tell the user that we're unable to determine the file info */
gtk_label_set_text (GTK_LABEL (image_page->type_label), _("Unknown"));
gtk_label_set_text (GTK_LABEL (image_page->dimensions_label), _("Unknown"));
#ifdef HAVE_EXIF
/* hide all Exif labels */
for (n = 0; n < G_N_ELEMENTS (TAIP_EXIF); ++n)
gtk_widget_hide (image_page->exif_labels[n]);
#endif
}
}
/* cleanup */
g_free (filename);
g_free (uri);
}