1 /* Eye Of Mate - Image Properties Dialog
2 *
3 * Copyright (C) 2006 The Free Software Foundation
4 *
5 * Author: Lucas Rocha <lucasr@gnome.org>
6 * Hubert Figuiere <hub@figuiere.net> (XMP support)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "eom-properties-dialog.h"
28 #include "eom-image.h"
29 #include "eom-util.h"
30 #include "eom-thumb-view.h"
31
32 #if HAVE_EXIF
33 #include "eom-exif-util.h"
34 #endif
35
36 #include <glib.h>
37 #include <glib/gi18n.h>
38 #include <glib-object.h>
39 #include <gio/gio.h>
40 #include <gtk/gtk.h>
41
42 #if HAVE_EXEMPI
43 #include <exempi/xmp.h>
44 #include <exempi/xmpconsts.h>
45 #endif
46 #if HAVE_EXIF || HAVE_EXEMPI
47 #define HAVE_METADATA 1
48 #endif
49
50 #if HAVE_METADATA
51 #include "eom-metadata-details.h"
52 #endif
53
54 enum {
55 PROP_0,
56 PROP_THUMBVIEW,
57 PROP_NETBOOK_MODE
58 };
59
60 struct _EomPropertiesDialogPrivate {
61 EomThumbView *thumbview;
62
63 gboolean update_page;
64 EomPropertiesDialogPage current_page;
65
66 GtkWidget *notebook;
67 GtkWidget *close_button;
68 GtkWidget *next_button;
69 GtkWidget *previous_button;
70
71 GtkWidget *general_box;
72 GtkWidget *thumbnail_image;
73 GtkWidget *name_label;
74 GtkWidget *width_label;
75 GtkWidget *height_label;
76 GtkWidget *type_label;
77 GtkWidget *bytes_label;
78 GtkWidget *folder_button;
79 gchar *folder_button_uri;
80 #ifdef HAVE_EXIF
81 GtkWidget *exif_aperture_label;
82 GtkWidget *exif_exposure_label;
83 GtkWidget *exif_focal_label;
84 GtkWidget *exif_flash_label;
85 GtkWidget *exif_iso_label;
86 GtkWidget *exif_metering_label;
87 GtkWidget *exif_model_label;
88 GtkWidget *exif_date_label;
89 #endif
90 #ifdef HAVE_EXEMPI
91 GtkWidget *xmp_location_label;
92 GtkWidget *xmp_description_label;
93 GtkWidget *xmp_keywords_label;
94 GtkWidget *xmp_creator_label;
95 GtkWidget *xmp_rights_label;
96 #else
97 GtkWidget *xmp_box;
98 GtkWidget *xmp_box_label;
99 #endif
100 #if HAVE_METADATA
101 GtkWidget *metadata_box;
102 GtkWidget *metadata_details_expander;
103 GtkWidget *metadata_details;
104 GtkWidget *metadata_details_box;
105 GtkWidget *metadata_details_sw;
106 #endif
107
108 gboolean netbook_mode;
109 };
110
111 G_DEFINE_TYPE_WITH_PRIVATE (EomPropertiesDialog, eom_properties_dialog, GTK_TYPE_DIALOG);
112
113 static void
parent_file_display_name_query_info_cb(GObject * source_object,GAsyncResult * res,gpointer user_data)114 parent_file_display_name_query_info_cb (GObject *source_object,
115 GAsyncResult *res,
116 gpointer user_data)
117 {
118 EomPropertiesDialog *prop_dlg = EOM_PROPERTIES_DIALOG (user_data);
119 GFile *parent_file = G_FILE (source_object);
120 GFileInfo *file_info;
121 gchar *display_name;
122
123
124 file_info = g_file_query_info_finish (parent_file, res, NULL);
125 if (file_info == NULL) {
126 display_name = g_file_get_basename (parent_file);
127 } else {
128 display_name = g_strdup (
129 g_file_info_get_display_name (file_info));
130 g_object_unref (file_info);
131 }
132 gtk_button_set_label (GTK_BUTTON (prop_dlg->priv->folder_button),
133 display_name);
134 gtk_widget_set_sensitive (prop_dlg->priv->folder_button, TRUE);
135
136 g_free (display_name);
137 g_object_unref (prop_dlg);
138 }
139
140 static void
pd_update_general_tab(EomPropertiesDialog * prop_dlg,EomImage * image)141 pd_update_general_tab (EomPropertiesDialog *prop_dlg,
142 EomImage *image)
143 {
144 gchar *bytes_str, *dir_str_long;
145 gchar *width_str, *height_str;
146 GFile *file, *parent_file;
147 GFileInfo *file_info;
148 const char *mime_str;
149 char *type_str;
150 gint width, height;
151 goffset bytes;
152
153 g_object_set (G_OBJECT (prop_dlg->priv->thumbnail_image),
154 "pixbuf", eom_image_get_thumbnail (image),
155 NULL);
156
157 gtk_label_set_text (GTK_LABEL (prop_dlg->priv->name_label),
158 eom_image_get_caption (image));
159
160 eom_image_get_size (image, &width, &height);
161
162 width_str = g_strdup_printf ("%d %s", width,
163 ngettext ("pixel", "pixels", width));
164 height_str = g_strdup_printf ("%d %s", height,
165 ngettext ("pixel", "pixels", height));
166
167 gtk_label_set_text (GTK_LABEL (prop_dlg->priv->width_label), width_str);
168
169 gtk_label_set_text (GTK_LABEL (prop_dlg->priv->height_label),
170 height_str);
171
172 g_free (height_str);
173 g_free (width_str);
174
175 file = eom_image_get_file (image);
176 file_info = g_file_query_info (file,
177 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
178 0, NULL, NULL);
179 if (file_info == NULL) {
180 type_str = g_strdup (_("Unknown"));
181 } else {
182 mime_str = g_file_info_get_content_type (file_info);
183 type_str = g_content_type_get_description (mime_str);
184 g_object_unref (file_info);
185 }
186
187 gtk_label_set_text (GTK_LABEL (prop_dlg->priv->type_label), type_str);
188
189 bytes = eom_image_get_bytes (image);
190 bytes_str = g_format_size (bytes);
191
192 gtk_label_set_text (GTK_LABEL (prop_dlg->priv->bytes_label), bytes_str);
193
194 parent_file = g_file_get_parent (file);
195 if (parent_file == NULL) {
196 /* file is root directory itself */
197 parent_file = g_object_ref (file);
198 }
199
200 gtk_widget_set_sensitive (prop_dlg->priv->folder_button, FALSE);
201 gtk_button_set_label (GTK_BUTTON (prop_dlg->priv->folder_button), NULL);
202
203 dir_str_long = g_file_get_path (parent_file);
204 gtk_widget_set_tooltip_text (GTK_WIDGET (prop_dlg->priv->folder_button),
205 dir_str_long);
206
207 g_free (prop_dlg->priv->folder_button_uri);
208 prop_dlg->priv->folder_button_uri = g_file_get_uri (parent_file);
209
210 g_file_query_info_async (parent_file,
211 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
212 G_FILE_QUERY_INFO_NONE,
213 G_PRIORITY_DEFAULT,
214 NULL,
215 parent_file_display_name_query_info_cb,
216 g_object_ref (prop_dlg));
217
218 g_object_unref (parent_file);
219
220 g_free (type_str);
221 g_free (bytes_str);
222 g_free (dir_str_long);
223 }
224
225 #if HAVE_EXEMPI
226 static void
eom_xmp_set_label(XmpPtr xmp,const char * ns,const char * propname,GtkWidget * w)227 eom_xmp_set_label (XmpPtr xmp,
228 const char *ns,
229 const char *propname,
230 GtkWidget *w)
231 {
232 uint32_t options;
233
234 XmpStringPtr value = xmp_string_new ();
235
236 if (xmp_get_property (xmp, ns, propname, value, &options)) {
237 if (XMP_IS_PROP_SIMPLE (options)) {
238 gtk_label_set_text (GTK_LABEL (w), xmp_string_cstr (value));
239 } else if (XMP_IS_PROP_ARRAY (options)) {
240 XmpIteratorPtr iter = xmp_iterator_new (xmp,
241 ns,
242 propname,
243 XMP_ITER_JUSTLEAFNODES);
244
245 GString *string = g_string_new ("");
246
247 if (iter) {
248 gboolean first = TRUE;
249
250 while (xmp_iterator_next (iter, NULL, NULL, value, &options)
251 && !XMP_IS_PROP_QUALIFIER (options)) {
252
253 if (!first) {
254 g_string_append_printf(string, ", ");
255 } else {
256 first = FALSE;
257 }
258
259 g_string_append_printf (string,
260 "%s",
261 xmp_string_cstr (value));
262 }
263
264 xmp_iterator_free (iter);
265 }
266
267 gtk_label_set_text (GTK_LABEL (w), string->str);
268 g_string_free (string, TRUE);
269 }
270 } else {
271 /* Property was not found */
272 /* Clear label so it won't show bogus data */
273 gtk_label_set_text (GTK_LABEL (w), NULL);
274 }
275
276 xmp_string_free (value);
277 }
278 #endif
279
280 #if HAVE_METADATA
281 static void
pd_update_metadata_tab(EomPropertiesDialog * prop_dlg,EomImage * image)282 pd_update_metadata_tab (EomPropertiesDialog *prop_dlg,
283 EomImage *image)
284 {
285 EomPropertiesDialogPrivate *priv;
286 GtkNotebook *notebook;
287 #if HAVE_EXIF
288 ExifData *exif_data;
289 #endif
290 #if HAVE_EXEMPI
291 XmpPtr xmp_data;
292 #endif
293
294 g_return_if_fail (EOM_IS_PROPERTIES_DIALOG (prop_dlg));
295
296 priv = prop_dlg->priv;
297
298 notebook = GTK_NOTEBOOK (priv->notebook);
299
300 if (TRUE
301 #if HAVE_EXIF
302 && !eom_image_has_data (image, EOM_IMAGE_DATA_EXIF)
303 #endif
304 #if HAVE_EXEMPI
305 && !eom_image_has_data (image, EOM_IMAGE_DATA_XMP)
306 #endif
307 ) {
308 if (gtk_notebook_get_current_page (notebook) == EOM_PROPERTIES_DIALOG_PAGE_EXIF) {
309 gtk_notebook_prev_page (notebook);
310 } else if (gtk_notebook_get_current_page (notebook) == EOM_PROPERTIES_DIALOG_PAGE_DETAILS) {
311 gtk_notebook_set_current_page (notebook, EOM_PROPERTIES_DIALOG_PAGE_GENERAL);
312 }
313
314 if (gtk_widget_get_visible (priv->metadata_box)) {
315 gtk_widget_hide (priv->metadata_box);
316 }
317 if (gtk_widget_get_visible (priv->metadata_details_box)) {
318 gtk_widget_hide (priv->metadata_details_box);
319 }
320
321 return;
322 } else {
323 if (!gtk_widget_get_visible (priv->metadata_box))
324 gtk_widget_show_all (priv->metadata_box);
325 if (priv->netbook_mode &&
326 !gtk_widget_get_visible (priv->metadata_details_box)) {
327 gtk_widget_show_all (priv->metadata_details_box);
328 gtk_widget_hide (priv->metadata_details_expander);
329 }
330 }
331
332 #if HAVE_EXIF
333 exif_data = (ExifData *) eom_image_get_exif_info (image);
334
335 eom_exif_util_set_label_text (GTK_LABEL (priv->exif_aperture_label),
336 exif_data, EXIF_TAG_FNUMBER);
337
338 eom_exif_util_set_label_text (GTK_LABEL (priv->exif_exposure_label),
339 exif_data, EXIF_TAG_EXPOSURE_TIME);
340
341 eom_exif_util_set_focal_length_label_text (GTK_LABEL (priv->exif_focal_label), exif_data);
342
343 eom_exif_util_set_label_text (GTK_LABEL (priv->exif_flash_label),
344 exif_data, EXIF_TAG_FLASH);
345
346 eom_exif_util_set_label_text (GTK_LABEL (priv->exif_iso_label),
347 exif_data, EXIF_TAG_ISO_SPEED_RATINGS);
348
349
350 eom_exif_util_set_label_text (GTK_LABEL (priv->exif_metering_label),
351 exif_data, EXIF_TAG_METERING_MODE);
352
353 eom_exif_util_set_label_text (GTK_LABEL (priv->exif_model_label),
354 exif_data, EXIF_TAG_MODEL);
355
356 eom_exif_util_set_label_text (GTK_LABEL (priv->exif_date_label),
357 exif_data, EXIF_TAG_DATE_TIME_ORIGINAL);
358
359 eom_metadata_details_update (EOM_METADATA_DETAILS (priv->metadata_details),
360 exif_data);
361
362 /* exif_data_unref can handle NULL-values */
363 exif_data_unref(exif_data);
364 #endif
365
366 #if HAVE_EXEMPI
367 xmp_data = (XmpPtr) eom_image_get_xmp_info (image);
368
369 if (xmp_data != NULL) {
370 eom_xmp_set_label (xmp_data,
371 NS_IPTC4XMP,
372 "Location",
373 priv->xmp_location_label);
374
375 eom_xmp_set_label (xmp_data,
376 NS_DC,
377 "description",
378 priv->xmp_description_label);
379
380 eom_xmp_set_label (xmp_data,
381 NS_DC,
382 "subject",
383 priv->xmp_keywords_label);
384
385 eom_xmp_set_label (xmp_data,
386 NS_DC,
387 "creator",
388 priv->xmp_creator_label);
389
390 eom_xmp_set_label (xmp_data,
391 NS_DC,
392 "rights",
393 priv->xmp_rights_label);
394
395 eom_metadata_details_xmp_update (EOM_METADATA_DETAILS (priv->metadata_details), xmp_data);
396
397 xmp_free (xmp_data);
398 } else {
399 /* Image has no XMP data */
400
401 /* Clear the labels so they won't display foreign data.*/
402
403 gtk_label_set_text (GTK_LABEL (priv->xmp_location_label), NULL);
404 gtk_label_set_text (GTK_LABEL (priv->xmp_description_label),
405 NULL);
406 gtk_label_set_text (GTK_LABEL (priv->xmp_keywords_label), NULL);
407 gtk_label_set_text (GTK_LABEL (priv->xmp_creator_label), NULL);
408 gtk_label_set_text (GTK_LABEL (priv->xmp_rights_label), NULL);
409 }
410 #endif
411 }
412
413 static gboolean
pd_resize_dialog(gpointer user_data)414 pd_resize_dialog (gpointer user_data)
415 {
416 gint width, height;
417
418 gtk_window_get_size (GTK_WINDOW (user_data),
419 &width,
420 &height);
421
422 gtk_window_resize (GTK_WINDOW (user_data), width, 1);
423
424 return FALSE;
425 }
426
427 static void
pd_exif_details_activated_cb(GtkExpander * expander,GParamSpec * param_spec,GtkWidget * dialog)428 pd_exif_details_activated_cb (GtkExpander *expander,
429 GParamSpec *param_spec,
430 GtkWidget *dialog)
431 {
432 gboolean expanded;
433
434 expanded = gtk_expander_get_expanded (expander);
435
436 /*FIXME: this is depending on the expander animation
437 * duration. Need to find a safer way for doing that. */
438 if (!expanded)
439 g_timeout_add (150, pd_resize_dialog, dialog);
440 }
441 #endif
442
443 static void
pd_folder_button_clicked_cb(GtkButton * button,gpointer data)444 pd_folder_button_clicked_cb (GtkButton *button, gpointer data)
445 {
446 EomPropertiesDialogPrivate *priv = EOM_PROPERTIES_DIALOG (data)->priv;
447 GtkWindow *window;
448 guint32 timestamp;
449
450 if (!priv->folder_button_uri)
451 return;
452
453 timestamp = gtk_get_current_event_time ();
454
455 window = GTK_WINDOW (data);
456 gtk_show_uri_on_window (window, priv->folder_button_uri, timestamp, NULL);
457 }
458
459 static gboolean
eom_properties_dialog_page_switch(GtkNotebook * notebook,gpointer page,guint page_index,EomPropertiesDialog * prop_dlg)460 eom_properties_dialog_page_switch (GtkNotebook *notebook,
461 gpointer page,
462 guint page_index,
463 EomPropertiesDialog *prop_dlg)
464 {
465 if (prop_dlg->priv->update_page)
466 prop_dlg->priv->current_page = page_index;
467
468 return TRUE;
469 }
470
471 void
eom_properties_dialog_set_netbook_mode(EomPropertiesDialog * dlg,gboolean enable)472 eom_properties_dialog_set_netbook_mode (EomPropertiesDialog *dlg,
473 gboolean enable)
474 {
475 EomPropertiesDialogPrivate *priv;
476
477 g_return_if_fail (EOM_IS_PROPERTIES_DIALOG (dlg));
478
479 priv = dlg->priv;
480
481 if (priv->netbook_mode == enable)
482 return;
483
484 priv->netbook_mode = enable;
485
486 #ifdef HAVE_METADATA
487 if (enable) {
488 g_object_ref (priv->metadata_details_sw);
489 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (priv->metadata_details_sw)),
490 priv->metadata_details_sw);
491 gtk_container_add (GTK_CONTAINER (priv->metadata_details_box), priv->metadata_details_sw);
492 g_object_unref (priv->metadata_details_sw);
493 // Only show details box if metadata is being displayed
494 if (gtk_widget_get_visible (priv->metadata_box))
495 gtk_widget_show_all (priv->metadata_details_box);
496
497 gtk_widget_hide (priv->metadata_details_expander);
498 } else {
499 g_object_ref (priv->metadata_details_sw);
500 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (priv->metadata_details_sw)),
501 priv->metadata_details_sw);
502 gtk_container_add (GTK_CONTAINER (priv->metadata_details_expander), priv->metadata_details_sw);
503 g_object_unref (priv->metadata_details_sw);
504 gtk_widget_show_all (priv->metadata_details_expander);
505
506 if (gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook)) == EOM_PROPERTIES_DIALOG_PAGE_DETAILS)
507 gtk_notebook_prev_page (GTK_NOTEBOOK (priv->notebook));
508 gtk_widget_hide (priv->metadata_details_box);
509 }
510 #endif
511 }
512
513 static void
eom_properties_dialog_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)514 eom_properties_dialog_set_property (GObject *object,
515 guint prop_id,
516 const GValue *value,
517 GParamSpec *pspec)
518 {
519 EomPropertiesDialog *prop_dlg = EOM_PROPERTIES_DIALOG (object);
520
521 switch (prop_id) {
522 case PROP_THUMBVIEW:
523 prop_dlg->priv->thumbview = g_value_get_object (value);
524 break;
525 case PROP_NETBOOK_MODE:
526 eom_properties_dialog_set_netbook_mode (prop_dlg,
527 g_value_get_boolean (value));
528 break;
529 default:
530 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id,
531 pspec);
532 break;
533 }
534 }
535
536 static void
eom_properties_dialog_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)537 eom_properties_dialog_get_property (GObject *object,
538 guint prop_id,
539 GValue *value,
540 GParamSpec *pspec)
541 {
542 EomPropertiesDialog *prop_dlg = EOM_PROPERTIES_DIALOG (object);
543
544 switch (prop_id) {
545 case PROP_THUMBVIEW:
546 g_value_set_object (value, prop_dlg->priv->thumbview);
547 break;
548 case PROP_NETBOOK_MODE:
549 g_value_set_boolean (value,
550 prop_dlg->priv->netbook_mode);
551 break;
552 default:
553 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id,
554 pspec);
555 break;
556 }
557 }
558
559 static void
eom_properties_dialog_dispose(GObject * object)560 eom_properties_dialog_dispose (GObject *object)
561 {
562 EomPropertiesDialog *prop_dlg;
563 EomPropertiesDialogPrivate *priv;
564
565 g_return_if_fail (object != NULL);
566 g_return_if_fail (EOM_IS_PROPERTIES_DIALOG (object));
567
568 prop_dlg = EOM_PROPERTIES_DIALOG (object);
569 priv = prop_dlg->priv;
570
571 if (priv->thumbview) {
572 g_object_unref (priv->thumbview);
573 priv->thumbview = NULL;
574 }
575
576 g_free (priv->folder_button_uri);
577 priv->folder_button_uri = NULL;
578
579 G_OBJECT_CLASS (eom_properties_dialog_parent_class)->dispose (object);
580 }
581
582 static void
eom_properties_dialog_class_init(EomPropertiesDialogClass * klass)583 eom_properties_dialog_class_init (EomPropertiesDialogClass *klass)
584 {
585 GObjectClass *g_object_class = (GObjectClass *) klass;
586
587 g_object_class->dispose = eom_properties_dialog_dispose;
588 g_object_class->set_property = eom_properties_dialog_set_property;
589 g_object_class->get_property = eom_properties_dialog_get_property;
590
591 g_object_class_install_property (g_object_class,
592 PROP_THUMBVIEW,
593 g_param_spec_object ("thumbview",
594 "Thumbview",
595 "Thumbview",
596 EOM_TYPE_THUMB_VIEW,
597 G_PARAM_READWRITE |
598 G_PARAM_CONSTRUCT_ONLY |
599 G_PARAM_STATIC_NAME |
600 G_PARAM_STATIC_NICK |
601 G_PARAM_STATIC_BLURB));
602 g_object_class_install_property (g_object_class, PROP_NETBOOK_MODE,
603 g_param_spec_boolean ("netbook-mode",
604 "Netbook Mode",
605 "Netbook Mode",
606 FALSE,
607 G_PARAM_READWRITE |
608 G_PARAM_STATIC_STRINGS));
609
610 GtkWidgetClass *wklass = (GtkWidgetClass*) klass;
611
612 gtk_widget_class_set_template_from_resource (wklass,
613 "/org/mate/eom/ui/eom-image-properties-dialog.ui");
614
615 gtk_widget_class_bind_template_child_private(wklass,
616 EomPropertiesDialog,
617 notebook);
618 gtk_widget_class_bind_template_child_private(wklass,
619 EomPropertiesDialog,
620 previous_button);
621 gtk_widget_class_bind_template_child_private(wklass,
622 EomPropertiesDialog,
623 next_button);
624 gtk_widget_class_bind_template_child_private(wklass,
625 EomPropertiesDialog,
626 close_button);
627 gtk_widget_class_bind_template_child_private(wklass,
628 EomPropertiesDialog,
629 thumbnail_image);
630 gtk_widget_class_bind_template_child_private(wklass,
631 EomPropertiesDialog,
632 general_box);
633 gtk_widget_class_bind_template_child_private(wklass,
634 EomPropertiesDialog,
635 name_label);
636 gtk_widget_class_bind_template_child_private(wklass,
637 EomPropertiesDialog,
638 width_label);
639 gtk_widget_class_bind_template_child_private(wklass,
640 EomPropertiesDialog,
641 height_label);
642 gtk_widget_class_bind_template_child_private(wklass,
643 EomPropertiesDialog,
644 type_label);
645 gtk_widget_class_bind_template_child_private(wklass,
646 EomPropertiesDialog,
647 bytes_label);
648 gtk_widget_class_bind_template_child_private(wklass,
649 EomPropertiesDialog,
650 folder_button);
651
652 #if HAVE_EXIF
653 gtk_widget_class_bind_template_child_private(wklass,
654 EomPropertiesDialog,
655 exif_aperture_label);
656 gtk_widget_class_bind_template_child_private(wklass,
657 EomPropertiesDialog,
658 exif_exposure_label);
659 gtk_widget_class_bind_template_child_private(wklass,
660 EomPropertiesDialog,
661 exif_focal_label);
662 gtk_widget_class_bind_template_child_private(wklass,
663 EomPropertiesDialog,
664 exif_flash_label);
665 gtk_widget_class_bind_template_child_private(wklass,
666 EomPropertiesDialog,
667 exif_iso_label);
668 gtk_widget_class_bind_template_child_private(wklass,
669 EomPropertiesDialog,
670 exif_metering_label);
671 gtk_widget_class_bind_template_child_private(wklass,
672 EomPropertiesDialog,
673 exif_model_label);
674 gtk_widget_class_bind_template_child_private(wklass,
675 EomPropertiesDialog,
676 exif_date_label);
677 #endif
678 #if HAVE_EXEMPI
679 gtk_widget_class_bind_template_child_private(wklass,
680 EomPropertiesDialog,
681 xmp_location_label);
682 gtk_widget_class_bind_template_child_private(wklass,
683 EomPropertiesDialog,
684 xmp_description_label);
685 gtk_widget_class_bind_template_child_private(wklass,
686 EomPropertiesDialog,
687 xmp_keywords_label);
688 gtk_widget_class_bind_template_child_private(wklass,
689 EomPropertiesDialog,
690 xmp_creator_label);
691 gtk_widget_class_bind_template_child_private(wklass,
692 EomPropertiesDialog,
693 xmp_rights_label);
694 #else
695 gtk_widget_class_bind_template_child_private(wklass,
696 EomPropertiesDialog,
697 xmp_box);
698 gtk_widget_class_bind_template_child_private(wklass,
699 EomPropertiesDialog,
700 xmp_box_label);
701 #endif
702 #ifdef HAVE_METADATA
703 gtk_widget_class_bind_template_child_private(wklass,
704 EomPropertiesDialog,
705 metadata_box);
706 gtk_widget_class_bind_template_child_private(wklass,
707 EomPropertiesDialog,
708 metadata_details_expander);
709 gtk_widget_class_bind_template_child_private(wklass,
710 EomPropertiesDialog,
711 metadata_details_box);
712
713 gtk_widget_class_bind_template_callback(wklass,
714 pd_exif_details_activated_cb);
715 #endif
716 gtk_widget_class_bind_template_callback(wklass,
717 eom_properties_dialog_page_switch);
718 gtk_widget_class_bind_template_callback(wklass,
719 pd_folder_button_clicked_cb);
720 }
721
722 static void
eom_properties_dialog_init(EomPropertiesDialog * prop_dlg)723 eom_properties_dialog_init (EomPropertiesDialog *prop_dlg)
724 {
725 EomPropertiesDialogPrivate *priv;
726 #if HAVE_METADATA
727 GtkWidget *sw;
728 #endif
729
730 prop_dlg->priv = eom_properties_dialog_get_instance_private (prop_dlg);
731
732 priv = prop_dlg->priv;
733
734 priv->update_page = FALSE;
735
736 gtk_widget_init_template (GTK_WIDGET (prop_dlg));
737
738 g_signal_connect (prop_dlg,
739 "delete-event",
740 G_CALLBACK (gtk_widget_hide_on_delete),
741 prop_dlg);
742
743 g_signal_connect_swapped (priv->close_button,
744 "clicked",
745 G_CALLBACK (gtk_widget_hide_on_delete),
746 prop_dlg);
747
748 gtk_widget_set_size_request (priv->thumbnail_image, 100, 100);
749
750 #ifdef HAVE_METADATA
751 sw = gtk_scrolled_window_new (NULL, NULL);
752
753 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
754 GTK_SHADOW_IN);
755
756 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
757 GTK_POLICY_AUTOMATIC,
758 GTK_POLICY_AUTOMATIC);
759
760 priv->metadata_details = eom_metadata_details_new ();
761 gtk_widget_set_size_request (priv->metadata_details, -1, 170);
762 gtk_container_set_border_width (GTK_CONTAINER (sw), 6);
763 gtk_widget_set_vexpand (priv->metadata_details, TRUE);
764
765 gtk_container_add (GTK_CONTAINER (sw), priv->metadata_details);
766 gtk_widget_show_all (sw);
767
768 priv->metadata_details_sw = sw;
769
770 if (priv->netbook_mode) {
771 gtk_widget_hide (priv->metadata_details_expander);
772 gtk_box_pack_start (GTK_BOX (priv->metadata_details_box),
773 sw, TRUE, TRUE, 6);
774 } else {
775 gtk_container_add (GTK_CONTAINER (priv->metadata_details_expander),
776 sw);
777 }
778
779 #ifndef HAVE_EXEMPI
780 gtk_widget_hide (priv->xmp_box);
781 gtk_widget_hide (priv->xmp_box_label);
782 #endif
783
784 #else
785 /* Remove pages from back to front. Otherwise the page index
786 * needs to be adjusted when deleting the next page. */
787 gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook),
788 EOM_PROPERTIES_DIALOG_PAGE_DETAILS);
789 gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook),
790 EOM_PROPERTIES_DIALOG_PAGE_EXIF);
791 #endif
792
793 /* Add tab scrolling support for GTK3 */
794 gtk_widget_add_events (priv->notebook, GDK_SCROLL_MASK);
795 g_signal_connect (priv->notebook,
796 "scroll-event",
797 G_CALLBACK (eom_notebook_scroll_event_cb),
798 NULL);
799 }
800
801 /**
802 * eom_properties_dialog_new:
803 * @parent: the dialog's parent window
804 * @thumbview:
805 * @next_image_action:
806 * @previous_image_action:
807 *
808 *
809 *
810 * Returns: (transfer full) (type EomPropertiesDialog): a new #EomPropertiesDialog
811 **/
812
813 GtkWidget *
eom_properties_dialog_new(GtkWindow * parent,EomThumbView * thumbview,GtkAction * next_image_action,GtkAction * previous_image_action)814 eom_properties_dialog_new (GtkWindow *parent,
815 EomThumbView *thumbview,
816 GtkAction *next_image_action,
817 GtkAction *previous_image_action)
818 {
819 GObject *prop_dlg;
820
821 g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
822 g_return_val_if_fail (EOM_IS_THUMB_VIEW (thumbview), NULL);
823 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
824 g_return_val_if_fail (GTK_IS_ACTION (next_image_action), NULL);
825 g_return_val_if_fail (GTK_IS_ACTION (previous_image_action), NULL);
826
827 prop_dlg = g_object_new (EOM_TYPE_PROPERTIES_DIALOG,
828 "thumbview", thumbview,
829 NULL);
830
831 if (parent) {
832 gtk_window_set_transient_for (GTK_WINDOW (prop_dlg), parent);
833 }
834
835 gtk_activatable_set_related_action (GTK_ACTIVATABLE (EOM_PROPERTIES_DIALOG (prop_dlg)->priv->next_button), next_image_action);
836
837 gtk_activatable_set_related_action (GTK_ACTIVATABLE (EOM_PROPERTIES_DIALOG (prop_dlg)->priv->previous_button), previous_image_action);
838 G_GNUC_END_IGNORE_DEPRECATIONS;
839
840 return GTK_WIDGET (prop_dlg);
841 }
842
843 void
eom_properties_dialog_update(EomPropertiesDialog * prop_dlg,EomImage * image)844 eom_properties_dialog_update (EomPropertiesDialog *prop_dlg,
845 EomImage *image)
846 {
847 g_return_if_fail (EOM_IS_PROPERTIES_DIALOG (prop_dlg));
848
849 prop_dlg->priv->update_page = FALSE;
850
851 pd_update_general_tab (prop_dlg, image);
852
853 #ifdef HAVE_METADATA
854 pd_update_metadata_tab (prop_dlg, image);
855 #endif
856 gtk_notebook_set_current_page (GTK_NOTEBOOK (prop_dlg->priv->notebook),
857 prop_dlg->priv->current_page);
858
859 prop_dlg->priv->update_page = TRUE;
860 }
861
862 void
eom_properties_dialog_set_page(EomPropertiesDialog * prop_dlg,EomPropertiesDialogPage page)863 eom_properties_dialog_set_page (EomPropertiesDialog *prop_dlg,
864 EomPropertiesDialogPage page)
865 {
866 g_return_if_fail (EOM_IS_PROPERTIES_DIALOG (prop_dlg));
867
868 prop_dlg->priv->current_page = page;
869
870 gtk_notebook_set_current_page (GTK_NOTEBOOK (prop_dlg->priv->notebook),
871 page);
872 }
873