summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/eom-exif-util.c91
-rw-r--r--src/eom-exif-util.h17
-rw-r--r--src/eom-metadata-sidebar.c634
-rw-r--r--src/eom-metadata-sidebar.h61
-rw-r--r--src/eom-properties-dialog.c118
-rw-r--r--src/eom-window.c47
-rw-r--r--src/eom-window.h2
8 files changed, 851 insertions, 121 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8b3539c..d9ef069 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,6 +23,7 @@ NOINST_H_FILES = \
eom-config-keys.h \
eom-image-jpeg.h \
eom-image-private.h \
+ eom-metadata-sidebar.h \
eom-uri-converter.h \
eom-metadata-reader.h \
eom-metadata-reader-jpg.h \
@@ -80,6 +81,7 @@ libeom_c_files = \
eom-scroll-view.c \
eom-thumb-view.c \
eom-list-store.c \
+ eom-metadata-sidebar.c \
eom-thumbnail.c \
eom-job-queue.c \
eom-jobs.c \
diff --git a/src/eom-exif-util.c b/src/eom-exif-util.c
index 8ff9636..8bc4afd 100644
--- a/src/eom-exif-util.c
+++ b/src/eom-exif-util.c
@@ -35,6 +35,7 @@
#include <time.h>
#include "eom-exif-util.h"
+#include "eom-util.h"
#include <string.h>
#include <glib/gi18n.h>
@@ -192,6 +193,96 @@ eom_exif_util_format_date (const gchar *date)
return new_date;
}
+void
+eom_exif_util_set_label_text (GtkLabel *label,
+ EomExifData *exif_data,
+ gint tag_id)
+{
+ gchar exif_buffer[512];
+ const gchar *buf_ptr;
+ gchar *label_text = NULL;
+
+ g_return_if_fail (GTK_IS_LABEL (label));
+
+ if (exif_data) {
+ buf_ptr = eom_exif_data_get_value (exif_data, tag_id,
+ exif_buffer, 512);
+
+ if (tag_id == EXIF_TAG_DATE_TIME_ORIGINAL && buf_ptr)
+ label_text = eom_exif_util_format_date (buf_ptr);
+ else
+ label_text = eom_util_make_valid_utf8 (buf_ptr);
+ }
+
+ gtk_label_set_text (label, label_text);
+ g_free (label_text);
+}
+
+void
+eom_exif_util_set_focal_length_label_text (GtkLabel *label,
+ EomExifData *exif_data)
+{
+ ExifEntry *entry = NULL, *entry35mm = NULL;
+ ExifByteOrder byte_order;
+ gfloat f_val = 0.0;
+ gchar *fl_text = NULL,*fl35_text = NULL;
+
+ /* If no ExifData is supplied the label will be
+ * cleared later as fl35_text is NULL. */
+ if (exif_data != NULL) {
+ entry = exif_data_get_entry (exif_data, EXIF_TAG_FOCAL_LENGTH);
+ entry35mm = exif_data_get_entry (exif_data,
+ EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM);
+ byte_order = exif_data_get_byte_order (exif_data);
+ }
+
+ if (entry && G_LIKELY (entry->format == EXIF_FORMAT_RATIONAL)) {
+ ExifRational value;
+
+ /* Decode value by hand as libexif is not necessarily returning
+ * it in the format we want it to be.
+ */
+ value = exif_get_rational (entry->data, byte_order);
+ /* Guard against div by zero */
+ if (G_LIKELY(value.denominator != 0))
+ f_val = (gfloat)value.numerator/
+ (gfloat)value.denominator;
+
+ /* TRANSLATORS: This is the actual focal length used when
+ the image was taken.*/
+ fl_text = g_strdup_printf (_("%.1f (lens)"), f_val);
+
+ }
+ if (entry35mm && G_LIKELY (entry35mm->format == EXIF_FORMAT_SHORT)) {
+ ExifShort s_val;
+
+ s_val = exif_get_short (entry35mm->data, byte_order);
+
+ /* Print as float to get a similar look as above. */
+ /* TRANSLATORS: This is the equivalent focal length assuming
+ a 35mm film camera. */
+ fl35_text = g_strdup_printf(_("%.1f (35mm film)"),(float)s_val);
+ }
+
+ if (fl_text) {
+ if (fl35_text) {
+ gchar *merged_txt;
+
+ merged_txt = g_strconcat (fl35_text,", ", fl_text, NULL);
+ gtk_label_set_text (label, merged_txt);
+ g_free (merged_txt);
+ } else {
+ gtk_label_set_text (label, fl_text);
+ }
+ } else {
+ /* This will also clear the label if no ExifData was supplied */
+ gtk_label_set_text (label, fl35_text);
+ }
+
+ g_free (fl35_text);
+ g_free (fl_text);
+}
+
/**
* eom_exif_data_get_value:
* @exif_data: pointer to an <structname>ExifData</structname> struct
diff --git a/src/eom-exif-util.h b/src/eom-exif-util.h
index f1bbf62..ebc7122 100644
--- a/src/eom-exif-util.h
+++ b/src/eom-exif-util.h
@@ -29,20 +29,29 @@
#include <glib.h>
#include <glib-object.h>
+#include <gtk/gtk.h>
#include <libexif/exif-data.h>
G_BEGIN_DECLS
#define EOM_TYPE_EXIF_DATA eom_exif_data_get_type()
-gchar* eom_exif_util_format_date (const gchar *date);
+gchar *eom_exif_util_format_date (const gchar *date);
+void eom_exif_util_set_label_text (GtkLabel *label,
+ ExifData *exif_data,
+ gint tag_id);
-const gchar *eom_exif_data_get_value (ExifData *exif_data, gint tag_id, gchar *buffer, guint buf_size);
+void eom_exif_util_set_focal_length_label_text (GtkLabel *label,
+ ExifData *exif_data);
+
+const gchar *eom_exif_data_get_value (ExifData *exif_data,
+ gint tag_id, gchar *buffer,
+ guint buf_size);
GType eom_exif_data_get_type (void) G_GNUC_CONST;
-ExifData * eom_exif_data_copy (ExifData *data);
-void eom_exif_data_free (ExifData *data);
+ExifData *eom_exif_data_copy (ExifData *data);
+void eom_exif_data_free (ExifData *data);
G_END_DECLS
diff --git a/src/eom-metadata-sidebar.c b/src/eom-metadata-sidebar.c
new file mode 100644
index 0000000..1f8da5a
--- /dev/null
+++ b/src/eom-metadata-sidebar.c
@@ -0,0 +1,634 @@
+/*
+ * eom-metadata-sidebar.c
+ * This file is part of eom
+ *
+ * Author: Felix Riemann <[email protected]>
+ *
+ * Portions based on code by: Lucas Rocha <[email protected]>
+ * Hubert Figuiere <[email protected]> (XMP support)
+ *
+ * Copyright (C) 2011 GNOME Foundation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "eom-dialog.h"
+#include "eom-image.h"
+#include "eom-metadata-sidebar.h"
+#include "eom-properties-dialog.h"
+#include "eom-scroll-view.h"
+#include "eom-util.h"
+#include "eom-window.h"
+
+#if HAVE_EXEMPI
+#include <exempi/xmp.h>
+#include <exempi/xmpconsts.h>
+#endif
+
+enum {
+ PROP_0,
+ PROP_IMAGE,
+ PROP_PARENT_WINDOW
+};
+
+struct _EomMetadataSidebarPrivate {
+ EomWindow *parent_window;
+ EomImage *image;
+
+ gulong image_changed_id;
+ gulong thumb_changed_id;
+
+ GtkWidget *grid;
+
+ GtkWidget *name_label;
+ GtkWidget *height_label;
+ GtkWidget *width_label;
+ GtkWidget *type_label;
+ GtkWidget *size_label;
+ GtkWidget *folder_button;
+
+ GtkWidget *aperture_label;
+ GtkWidget *exposure_label;
+ GtkWidget *focallen_label;
+ GtkWidget *flash_label;
+ GtkWidget *iso_label;
+ GtkWidget *metering_label;
+ GtkWidget *model_label;
+ GtkWidget *date_label;
+
+ GtkWidget *location_label;
+ GtkWidget *desc_label;
+ GtkWidget *keyword_label;
+ GtkWidget *creator_label;
+ GtkWidget *rights_label;
+
+ GtkWidget *details_button;
+};
+
+#define EOM_METADATA_SIDEBAR_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EOM_TYPE_METADATA_SIDEBAR, EomMetadataSidebarPrivate))
+
+G_DEFINE_TYPE(EomMetadataSidebar, eom_metadata_sidebar, GTK_TYPE_SCROLLED_WINDOW)
+
+static GtkWidget*
+_gtk_grid_append_title_line (GtkGrid *grid, GtkWidget *sibling,
+ const gchar *text)
+{
+ GtkWidget *label;
+ gchar *markup;
+
+ label = gtk_label_new (NULL);
+
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ gtk_label_set_markup (GTK_LABEL (label), markup);
+
+ gtk_grid_attach_next_to (grid, label, sibling, GTK_POS_BOTTOM, 2, 1);
+ return label;
+}
+
+static GtkWidget*
+_gtk_grid_append_prop_line (GtkGrid *grid, GtkWidget *sibling,
+ GtkWidget **data_label, const gchar *text)
+{
+ GtkWidget *label;
+
+ label = gtk_label_new (text);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_grid_attach_next_to (grid, label, sibling, GTK_POS_BOTTOM, 1, 1);
+
+ if (G_LIKELY (data_label != NULL)) {
+ *data_label = gtk_label_new (NULL);
+ gtk_label_set_ellipsize (GTK_LABEL (*data_label), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment (GTK_MISC (*data_label), 0.0, 0.5);
+ gtk_grid_attach_next_to (grid, *data_label, label,
+ GTK_POS_RIGHT, 1, 1);
+ }
+
+ return label;
+}
+
+#if HAVE_EXEMPI
+static void
+eom_xmp_set_label (XmpPtr xmp,
+ const char *ns,
+ const char *propname,
+ GtkWidget *w)
+{
+ uint32_t options;
+
+ XmpStringPtr value = xmp_string_new ();
+
+ if (xmp && xmp_get_property (xmp, ns, propname, value, &options)) {
+ if (XMP_IS_PROP_SIMPLE (options)) {
+ gtk_label_set_text (GTK_LABEL (w), xmp_string_cstr (value));
+ } else if (XMP_IS_PROP_ARRAY (options)) {
+ XmpIteratorPtr iter = xmp_iterator_new (xmp,
+ ns,
+ propname,
+ XMP_ITER_JUSTLEAFNODES);
+
+ GString *string = g_string_new ("");
+
+ if (iter) {
+ gboolean first = TRUE;
+
+ while (xmp_iterator_next (iter, NULL, NULL, value, &options)
+ && !XMP_IS_PROP_QUALIFIER (options)) {
+
+ if (!first) {
+ g_string_append_printf(string, ", ");
+ } else {
+ first = FALSE;
+ }
+
+ g_string_append_printf (string,
+ "%s",
+ xmp_string_cstr (value));
+ }
+
+ xmp_iterator_free (iter);
+ }
+
+ gtk_label_set_text (GTK_LABEL (w), string->str);
+ g_string_free (string, TRUE);
+ }
+ } else {
+ /* Property was not found */
+ /* Clear label so it won't show bogus data */
+ gtk_label_set_text (GTK_LABEL (w), NULL);
+ }
+
+ xmp_string_free (value);
+}
+#endif
+
+static void
+eom_metadata_sidebar_update_general_section (EomMetadataSidebar *sidebar)
+{
+ EomMetadataSidebarPrivate *priv = sidebar->priv;
+ EomImage *img = priv->image;
+ GFile *file, *parent_file;
+ GFileInfo *file_info;
+ gchar *str;
+ goffset bytes;
+ gint width, height;
+
+ if (G_UNLIKELY (img == NULL)) {
+ gtk_label_set_text (GTK_LABEL (priv->name_label), NULL);
+ gtk_label_set_text (GTK_LABEL (priv->height_label), NULL);
+ gtk_label_set_text (GTK_LABEL (priv->width_label), NULL);
+ gtk_label_set_text (GTK_LABEL (priv->type_label), NULL);
+ gtk_label_set_text (GTK_LABEL (priv->size_label), NULL);
+ return;
+ }
+
+ gtk_label_set_text (GTK_LABEL (priv->name_label),
+ eom_image_get_caption (img));
+ eom_image_get_size (img, &width, &height);
+ str = g_strdup_printf ("%d %s", height,
+ ngettext ("pixel", "pixels", height));
+ gtk_label_set_text (GTK_LABEL (priv->height_label), str);
+ g_free (str);
+ str = g_strdup_printf ("%d %s", width,
+ ngettext ("pixel", "pixels", width));
+ gtk_label_set_text (GTK_LABEL (priv->width_label), str);
+ g_free (str);
+
+ file = eom_image_get_file (img);
+ file_info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ 0, NULL, NULL);
+ if (file_info == NULL) {
+ str = g_strdup (_("Unknown"));
+ } else {
+ const gchar *mime_str;
+
+ mime_str = g_file_info_get_content_type (file_info);
+ str = g_content_type_get_description (mime_str);
+ g_object_unref (file_info);
+ }
+ gtk_label_set_text (GTK_LABEL (priv->type_label), str);
+ g_free (str);
+
+ bytes = eom_image_get_bytes (img);
+ str = g_format_size (bytes);
+ gtk_label_set_text (GTK_LABEL (priv->size_label), str);
+ g_free (str);
+
+ parent_file = g_file_get_parent (file);
+ if (parent_file == NULL) {
+ /* file is root directory itself */
+ parent_file = g_object_ref (file);
+ }
+ str = g_file_get_basename (parent_file);
+ gtk_button_set_label (GTK_BUTTON (priv->folder_button), str);
+ g_free (str);
+ g_object_unref (parent_file);
+}
+
+static void
+eom_metadata_sidebar_update_metadata_section (EomMetadataSidebar *sidebar)
+{
+ EomMetadataSidebarPrivate *priv = sidebar->priv;
+ EomImage *img = priv->image;
+ ExifData *exif_data = NULL;
+ XmpPtr xmp_data = NULL;
+
+
+ if (img) {
+ exif_data = eom_image_get_exif_info (img);
+ xmp_data = eom_image_get_xmp_info (img);
+ }
+
+
+ eom_exif_util_set_label_text (GTK_LABEL (priv->aperture_label),
+ exif_data, EXIF_TAG_FNUMBER);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->exposure_label),
+ exif_data,
+ EXIF_TAG_EXPOSURE_TIME);
+ eom_exif_util_set_focal_length_label_text (
+ GTK_LABEL (priv->focallen_label),
+ exif_data);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->flash_label),
+ exif_data, EXIF_TAG_FLASH);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->iso_label),
+ exif_data,
+ EXIF_TAG_ISO_SPEED_RATINGS);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->metering_label),
+ exif_data,
+ EXIF_TAG_METERING_MODE);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->model_label),
+ exif_data, EXIF_TAG_MODEL);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->date_label),
+ exif_data,
+ EXIF_TAG_DATE_TIME_ORIGINAL);
+
+ /* exif_data_unref can handle NULL-values */
+ exif_data_unref(exif_data);
+
+#if HAVE_EXEMPI
+ eom_xmp_set_label (xmp_data,
+ NS_IPTC4XMP,
+ "Location",
+ priv->location_label);
+
+ eom_xmp_set_label (xmp_data,
+ NS_DC,
+ "description",
+ priv->desc_label);
+
+ eom_xmp_set_label (xmp_data,
+ NS_DC,
+ "subject",
+ priv->keyword_label);
+
+ eom_xmp_set_label (xmp_data,
+ NS_DC,
+ "creator",
+ priv->creator_label);
+
+ eom_xmp_set_label (xmp_data,
+ NS_DC,
+ "rights",
+ priv->rights_label);
+
+
+ if (xmp_data != NULL)
+ xmp_free (xmp_data);
+#endif
+
+}
+
+static void
+eom_metadata_sidebar_update (EomMetadataSidebar *sidebar)
+{
+ g_return_if_fail (EOM_IS_METADATA_SIDEBAR (sidebar));
+
+ eom_metadata_sidebar_update_general_section (sidebar);
+ eom_metadata_sidebar_update_metadata_section (sidebar);
+}
+
+static void
+_thumbnail_changed_cb (EomImage *image, gpointer user_data)
+{
+ eom_metadata_sidebar_update (EOM_METADATA_SIDEBAR (user_data));
+}
+
+static void
+eom_metadata_sidebar_set_image (EomMetadataSidebar *sidebar, EomImage *image)
+{
+ EomMetadataSidebarPrivate *priv = sidebar->priv;
+
+ if (image == priv->image)
+ return;
+
+
+ if (priv->thumb_changed_id != 0) {
+ g_signal_handler_disconnect (priv->image,
+ priv->thumb_changed_id);
+ priv->thumb_changed_id = 0;
+ }
+
+ if (priv->image)
+ g_object_unref (priv->image);
+
+ priv->image = image;
+
+ if (priv->image) {
+ g_object_ref (priv->image);
+ priv->thumb_changed_id =
+ g_signal_connect (priv->image, "thumbnail-changed",
+ G_CALLBACK (_thumbnail_changed_cb),
+ sidebar);
+ eom_metadata_sidebar_update (sidebar);
+ }
+
+ g_object_notify (G_OBJECT (sidebar), "image");
+}
+
+static void
+_notify_image_cb (GObject *gobject, GParamSpec *pspec, gpointer user_data)
+{
+ EomImage *image;
+
+ g_return_if_fail (EOM_IS_METADATA_SIDEBAR (user_data));
+ g_return_if_fail (EOM_IS_SCROLL_VIEW (gobject));
+
+ image = eom_scroll_view_get_image (EOM_SCROLL_VIEW (gobject));
+
+ eom_metadata_sidebar_set_image (EOM_METADATA_SIDEBAR (user_data),
+ image);
+
+ if (image)
+ g_object_unref (image);
+}
+
+static void
+_folder_button_clicked_cb (GtkButton *button, gpointer user_data)
+{
+ EomMetadataSidebarPrivate *priv = EOM_METADATA_SIDEBAR(user_data)->priv;
+ EomImage *img;
+ GdkScreen *screen;
+ GFile *file;
+
+ g_return_if_fail (priv->parent_window != NULL);
+
+ img = eom_window_get_image (priv->parent_window);
+ screen = gtk_widget_get_screen (GTK_WIDGET (priv->parent_window));
+ file = eom_image_get_file (img);
+
+ eom_util_show_file_in_filemanager (file, screen);
+
+ g_object_unref (file);
+}
+
+static void
+_details_button_clicked_cb (GtkButton *button, gpointer user_data)
+{
+ EomMetadataSidebarPrivate *priv = EOM_METADATA_SIDEBAR(user_data)->priv;
+ EomDialog *dlg;
+
+ g_return_if_fail (priv->parent_window != NULL);
+
+ dlg = eom_window_get_properties_dialog (
+ EOM_WINDOW (priv->parent_window));
+ g_return_if_fail (dlg != NULL);
+ eom_properties_dialog_set_page (EOM_PROPERTIES_DIALOG (dlg),
+ EOM_PROPERTIES_DIALOG_PAGE_DETAILS);
+ eom_dialog_show (dlg);
+}
+
+
+static void
+eom_metadata_sidebar_set_parent_window (EomMetadataSidebar *sidebar,
+ EomWindow *window)
+{
+ EomMetadataSidebarPrivate *priv;
+ GtkWidget *view;
+
+ g_return_if_fail (EOM_IS_METADATA_SIDEBAR (sidebar));
+ priv = sidebar->priv;
+ g_return_if_fail (priv->parent_window == NULL);
+
+ priv->parent_window = g_object_ref (window);
+ eom_metadata_sidebar_update (sidebar);
+ view = eom_window_get_view (window);
+ priv->image_changed_id = g_signal_connect (view, "notify::image",
+ G_CALLBACK (_notify_image_cb),
+ sidebar);
+
+ g_object_notify (G_OBJECT (sidebar), "parent-window");
+
+}
+
+static void
+eom_metadata_sidebar_init (EomMetadataSidebar *sidebar)
+{
+ EomMetadataSidebarPrivate *priv;
+ GtkWidget *label;
+
+ priv = sidebar->priv = EOM_METADATA_SIDEBAR_GET_PRIVATE (sidebar);
+ priv->grid = gtk_grid_new ();
+ g_object_set (G_OBJECT (priv->grid),
+ "row-spacing", 6,
+ "column-spacing", 6,
+ NULL);
+
+ label = _gtk_grid_append_title_line (GTK_GRID (priv->grid),
+ NULL, _("General"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->name_label, _("Name:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->width_label, _("Width:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->height_label, _("Height:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->type_label, _("Type:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->size_label, _("File size:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ NULL, _("Folder:"));
+
+ priv->folder_button = gtk_button_new_with_label ("");
+ g_signal_connect (priv->folder_button, "clicked",
+ G_CALLBACK (_folder_button_clicked_cb), sidebar);
+ gtk_grid_attach_next_to (GTK_GRID (priv->grid), priv->folder_button,
+ label, GTK_POS_RIGHT, 1, 1);
+
+ label = _gtk_grid_append_title_line (GTK_GRID (priv->grid),
+ label, _("Metadata"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->aperture_label,
+ _("Aperture Value:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->exposure_label,
+ _("Exposure Time:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->focallen_label,
+ _("Focal Length:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->flash_label, _("Flash:"));
+ gtk_label_set_line_wrap (GTK_LABEL (priv->flash_label), TRUE);
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->iso_label,
+ _("ISO Speed Rating:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->metering_label,
+ _("Metering Mode:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->model_label,
+ _("Camera Model:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->date_label, _("Date/Time:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->desc_label,
+ _("Description:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->location_label,
+ _("Location:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->keyword_label,
+ _("Keywords:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->creator_label, _("Author:"));
+ label = _gtk_grid_append_prop_line (GTK_GRID (priv->grid), label,
+ &priv->rights_label,
+ _("Copyright:"));
+
+ priv->details_button = gtk_button_new_with_label (_("Details"));
+ g_signal_connect (priv->details_button, "clicked",
+ G_CALLBACK (_details_button_clicked_cb), sidebar);
+ gtk_grid_attach_next_to (GTK_GRID (priv->grid), priv->details_button,
+ label, GTK_POS_BOTTOM, 1, 1);
+
+
+ gtk_widget_show_all (priv->grid);
+}
+
+static void
+eom_metadata_sidebar_constructed (GObject *object)
+{
+ EomMetadataSidebarPrivate *priv;
+
+ priv = EOM_METADATA_SIDEBAR (object)->priv;
+
+ /* This can only happen after all construct properties for
+ * GtkScrolledWindow are set/handled. */
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (object),
+ priv->grid);
+ gtk_widget_show (GTK_WIDGET (object));
+
+ G_OBJECT_CLASS (eom_metadata_sidebar_parent_class)->constructed (object);
+}
+
+static void
+eom_metadata_sidebar_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ EomMetadataSidebar *sidebar;
+
+ g_return_if_fail (EOM_IS_METADATA_SIDEBAR (object));
+
+ sidebar = EOM_METADATA_SIDEBAR (object);
+
+ switch (property_id) {
+ case PROP_IMAGE:
+ {
+ g_value_set_object (value, sidebar->priv->image);
+ break;
+ }
+ case PROP_PARENT_WINDOW:
+ g_value_set_object (value, sidebar->priv->parent_window);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+eom_metadata_sidebar_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ EomMetadataSidebar *sidebar;
+
+ g_return_if_fail (EOM_IS_METADATA_SIDEBAR (object));
+
+ sidebar = EOM_METADATA_SIDEBAR (object);
+
+ switch (property_id) {
+ case PROP_IMAGE:
+ {
+ break;
+ }
+ case PROP_PARENT_WINDOW:
+ {
+ EomWindow *window;
+
+ window = g_value_get_object (value);
+ eom_metadata_sidebar_set_parent_window (sidebar, window);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+
+}
+static void
+eom_metadata_sidebar_class_init (EomMetadataSidebarClass *klass)
+{
+ GObjectClass *g_obj_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof(EomMetadataSidebarPrivate));
+
+ g_obj_class->constructed = eom_metadata_sidebar_constructed;
+ g_obj_class->get_property = eom_metadata_sidebar_get_property;
+ g_obj_class->set_property = eom_metadata_sidebar_set_property;
+/* g_obj_class->dispose = eom_metadata_sidebar_dispose;*/
+
+ g_object_class_install_property (
+ g_obj_class, PROP_PARENT_WINDOW,
+ g_param_spec_object ("parent-window", NULL, NULL,
+ EOM_TYPE_WINDOW, G_PARAM_READWRITE
+ | G_PARAM_CONSTRUCT_ONLY
+ | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (
+ g_obj_class, PROP_IMAGE,
+ g_param_spec_object ("image", NULL, NULL, EOM_TYPE_IMAGE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
+ );
+}
+
+
+GtkWidget*
+eom_metadata_sidebar_new (EomWindow *window)
+{
+ return gtk_widget_new (EOM_TYPE_METADATA_SIDEBAR,
+ "hadjustment", NULL,
+ "vadjustment", NULL,
+ "hscrollbar-policy", GTK_POLICY_NEVER,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "border-width", 6,
+ "parent-window", window,
+ NULL);
+}
diff --git a/src/eom-metadata-sidebar.h b/src/eom-metadata-sidebar.h
new file mode 100644
index 0000000..1b3cd96
--- /dev/null
+++ b/src/eom-metadata-sidebar.h
@@ -0,0 +1,61 @@
+/*
+ * eom-metadata-sidebar.h
+ * This file is part of eom
+ *
+ * Author: Felix Riemann <[email protected]>
+ *
+ * Copyright (C) 2011 GNOME Foundation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __EOM_METADATA_SIDEBAR_H__
+#define __EOM_METADATA_SIDEBAR_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "eom-window.h"
+
+G_BEGIN_DECLS
+
+#define EOM_TYPE_METADATA_SIDEBAR (eom_metadata_sidebar_get_type ())
+#define EOM_METADATA_SIDEBAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EOM_TYPE_METADATA_SIDEBAR, EomMetadataSidebar))
+#define EOM_METADATA_SIDEBAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EOM_TYPE_METADATA_SIDEBAR, EomMetadataSidebarClass))
+#define EOM_IS_METADATA_SIDEBAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EOM_TYPE_METADATA_SIDEBAR))
+#define EOM_IS_METADATA_SIDEBAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EOM_TYPE_METADATA_SIDEBAR))
+#define EOM_METADATA_SIDEBAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EOM_TYPE_METADATA_SIDEBAR, EomMetadataSidebarClass))
+
+typedef struct _EomMetadataSidebar EomMetadataSidebar;
+typedef struct _EomMetadataSidebarClass EomMetadataSidebarClass;
+typedef struct _EomMetadataSidebarPrivate EomMetadataSidebarPrivate;
+
+struct _EomMetadataSidebar {
+ GtkScrolledWindow parent;
+
+ EomMetadataSidebarPrivate *priv;
+};
+
+struct _EomMetadataSidebarClass {
+ GtkScrolledWindowClass parent_klass;
+};
+
+GType eom_metadata_sidebar_get_type (void) G_GNUC_CONST;
+
+GtkWidget* eom_metadata_sidebar_new (EomWindow *window);
+
+G_END_DECLS
+
+#endif /* __EOM_METADATA_SIDEBAR_H__ */
diff --git a/src/eom-properties-dialog.c b/src/eom-properties-dialog.c
index 6ef84f9..00bada5 100644
--- a/src/eom-properties-dialog.c
+++ b/src/eom-properties-dialog.c
@@ -176,94 +176,6 @@ pd_update_general_tab (EomPropertiesDialog *prop_dlg,
g_free (uri_str);
}
-#if HAVE_EXIF
-static void
-eom_exif_set_label (GtkWidget *w, ExifData *exif_data, gint tag_id)
-{
- gchar exif_buffer[512];
- const gchar *buf_ptr;
- gchar *label_text = NULL;
-
- if (exif_data) {
- buf_ptr = eom_exif_data_get_value (exif_data, tag_id,
- exif_buffer, 512);
-
- if (tag_id == EXIF_TAG_DATE_TIME_ORIGINAL && buf_ptr)
- label_text = eom_exif_util_format_date (buf_ptr);
- else
- label_text = eom_util_make_valid_utf8 (buf_ptr);
- }
-
- gtk_label_set_text (GTK_LABEL (w), label_text);
- g_free (label_text);
-}
-
-static void
-eom_exif_set_focal_length_label (GtkWidget *w, ExifData *exif_data)
-{
- ExifEntry *entry = NULL, *entry35mm = NULL;
- ExifByteOrder byte_order;
- gfloat f_val = 0.0;
- gchar *fl_text = NULL,*fl35_text = NULL;
-
- /* If no ExifData is supplied the label will be
- * cleared later as fl35_text is NULL. */
- if (exif_data != NULL) {
- entry = exif_data_get_entry (exif_data, EXIF_TAG_FOCAL_LENGTH);
- entry35mm = exif_data_get_entry (exif_data,
- EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM);
- byte_order = exif_data_get_byte_order (exif_data);
- }
-
- if (entry && G_LIKELY (entry->format == EXIF_FORMAT_RATIONAL)) {
- ExifRational value;
-
- /* Decode value by hand as libexif is not necessarily returning
- * it in the format we want it to be.
- */
- value = exif_get_rational (entry->data, byte_order);
- /* Guard against div by zero */
- if (G_LIKELY(value.denominator != 0))
- f_val = (gfloat)value.numerator/
- (gfloat)value.denominator;
-
- /* TRANSLATORS: This is the actual focal length used when
- the image was taken.*/
- fl_text = g_strdup_printf (_("%.1f (lens)"), f_val);
-
- }
- if (entry35mm && G_LIKELY (entry35mm->format == EXIF_FORMAT_SHORT)) {
- ExifShort s_val;
-
- s_val = exif_get_short (entry35mm->data, byte_order);
-
- /* Print as float to get a similar look as above. */
- /* TRANSLATORS: This is the equivalent focal length assuming
- a 35mm film camera. */
- fl35_text = g_strdup_printf(_("%.1f (35mm film)"),(float)s_val);
- }
-
- if (fl_text) {
- if (fl35_text) {
- gchar *merged_txt;
-
- merged_txt = g_strconcat (fl35_text,", ", fl_text, NULL);
- gtk_label_set_text (GTK_LABEL (w), merged_txt);
- g_free (merged_txt);
- } else {
- gtk_label_set_text (GTK_LABEL (w), fl_text);
- }
- } else {
- /* This will also clear the label if no ExifData was supplied */
- gtk_label_set_text (GTK_LABEL (w), fl35_text);
- }
-
- g_free (fl35_text);
- g_free (fl_text);
-
-}
-#endif
-
#if HAVE_EXEMPI
static void
eom_xmp_set_label (XmpPtr xmp,
@@ -374,29 +286,29 @@ pd_update_metadata_tab (EomPropertiesDialog *prop_dlg,
#if HAVE_EXIF
exif_data = (ExifData *) eom_image_get_exif_info (image);
- eom_exif_set_label (priv->exif_aperture_label,
- exif_data, EXIF_TAG_FNUMBER);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->exif_aperture_label),
+ exif_data, EXIF_TAG_FNUMBER);
- eom_exif_set_label (priv->exif_exposure_label,
- exif_data, EXIF_TAG_EXPOSURE_TIME);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->exif_exposure_label),
+ exif_data, EXIF_TAG_EXPOSURE_TIME);
- eom_exif_set_focal_length_label (priv->exif_focal_label, exif_data);
+ eom_exif_util_set_focal_length_label_text (GTK_LABEL (priv->exif_focal_label), exif_data);
- eom_exif_set_label (priv->exif_flash_label,
- exif_data, EXIF_TAG_FLASH);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->exif_flash_label),
+ exif_data, EXIF_TAG_FLASH);
- eom_exif_set_label (priv->exif_iso_label,
- exif_data, EXIF_TAG_ISO_SPEED_RATINGS);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->exif_iso_label),
+ exif_data, EXIF_TAG_ISO_SPEED_RATINGS);
- eom_exif_set_label (priv->exif_metering_label,
- exif_data, EXIF_TAG_METERING_MODE);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->exif_metering_label),
+ exif_data, EXIF_TAG_METERING_MODE);
- eom_exif_set_label (priv->exif_model_label,
- exif_data, EXIF_TAG_MODEL);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->exif_model_label),
+ exif_data, EXIF_TAG_MODEL);
- eom_exif_set_label (priv->exif_date_label,
- exif_data, EXIF_TAG_DATE_TIME_ORIGINAL);
+ eom_exif_util_set_label_text (GTK_LABEL (priv->exif_date_label),
+ exif_data, EXIF_TAG_DATE_TIME_ORIGINAL);
eom_exif_details_update (EOM_EXIF_DETAILS (priv->exif_details),
exif_data);
diff --git a/src/eom-window.c b/src/eom-window.c
index a7c3575..a56dfbf 100644
--- a/src/eom-window.c
+++ b/src/eom-window.c
@@ -52,6 +52,7 @@
#include "eom-save-as-dialog-helper.h"
#include "eom-close-confirmation-dialog.h"
#include "eom-clipboard-handler.h"
+#include "eom-metadata-sidebar.h"
#include "eom-enum-types.h"
@@ -3010,26 +3011,26 @@ eom_window_cmd_print (GtkAction *action, gpointer user_data)
eom_window_print (window);
}
-static void
-eom_window_cmd_properties (GtkAction *action, gpointer user_data)
+EomDialog*
+eom_window_get_properties_dialog (EomWindow *window)
{
- EomWindow *window = EOM_WINDOW (user_data);
EomWindowPrivate *priv;
- GtkAction *next_image_action, *previous_image_action;
- priv = window->priv;
+ g_return_val_if_fail (EOM_IS_WINDOW (window), NULL);
- next_image_action =
- gtk_action_group_get_action (priv->actions_collection,
- "GoNext");
+ priv = window->priv;
- previous_image_action =
- gtk_action_group_get_action (priv->actions_collection,
- "GoPrevious");
+ if (priv->properties_dlg == NULL) {
+ GtkAction *next_image_action, *previous_image_action;
- if (window->priv->properties_dlg == NULL) {
+ next_image_action =
+ gtk_action_group_get_action (priv->actions_collection,
+ "GoNext");
- window->priv->properties_dlg =
+ previous_image_action =
+ gtk_action_group_get_action (priv->actions_collection,
+ "GoPrevious");
+ priv->properties_dlg =
eom_properties_dialog_new (GTK_WINDOW (window),
EOM_THUMB_VIEW (priv->thumbview),
next_image_action,
@@ -3043,7 +3044,20 @@ eom_window_cmd_properties (GtkAction *action, gpointer user_data)
G_SETTINGS_BIND_GET);
}
- eom_dialog_show (EOM_DIALOG (window->priv->properties_dlg));
+ return EOM_DIALOG (priv->properties_dlg);
+}
+
+static void
+eom_window_cmd_properties (GtkAction *action, gpointer user_data)
+{
+ EomWindow *window = EOM_WINDOW (user_data);
+ EomWindowPrivate *priv;
+ EomDialog *dialog;
+
+ priv = window->priv;
+
+ dialog = eom_window_get_properties_dialog (window);
+ eom_dialog_show (dialog);
}
static void
@@ -4459,6 +4473,11 @@ eom_window_construct_ui (EomWindow *window)
window);
priv->view = eom_scroll_view_new ();
+
+ eom_sidebar_add_page (EOM_SIDEBAR (priv->sidebar),
+ _("Image Properties"),
+ GTK_WIDGET (eom_metadata_sidebar_new (window)));
+
gtk_widget_set_size_request (GTK_WIDGET (priv->view), 100, 100);
g_signal_connect (G_OBJECT (priv->view),
"zoom_changed",
diff --git a/src/eom-window.h b/src/eom-window.h
index 8be1e67..630645e 100644
--- a/src/eom-window.h
+++ b/src/eom-window.h
@@ -30,6 +30,7 @@
#include "eom-list-store.h"
#include "eom-image.h"
+#include "eom-dialog.h"
#include <glib.h>
#include <glib-object.h>
@@ -124,6 +125,7 @@ void eom_window_open_file_list (EomWindow *window,
gboolean eom_window_is_empty (EomWindow *window);
void eom_window_reload_image (EomWindow *window);
+EomDialog *eom_window_get_properties_dialog (EomWindow *window);
G_END_DECLS
#endif