[gimp] libgimp: better organization of gimp_image_metadata_*() API.



commit 1b4834126f96a9327d45b28789d3609bea560a5f
Author: Jehan <jehan girinstud io>
Date:   Sun Sep 13 13:09:59 2020 +0200

    libgimp: better organization of gimp_image_metadata_*() API.
    
    gimpimagemetadata.[ch] was built into libgimpui because GTK+ was used
    for dialog query for rotation metadata. gimpimagemetadata-save.c only
    was built into libgimp, which made no sense as the declaration for its
    public function was inside gimpimagemetadata.h!
    That was a weird situation and somehow only made visible in the build
    system because GIR build was complaining about missing annotations to
    gimp_image_metadata_save_prepare() (the annotation was actually present
    but in the implementation which was not in the same library as the
    header, how weird!):
    
    > Warning: GimpUi: gimp_image_metadata_save_prepare: return value: Missing (transfer) annotation
    
    Moreover it means that only plug-ins linking libgimpui had access to the
    gimp_image_metadata*() API, which is obviously not cool (that should be
    a core API).
    
    Instead I moved everything into libgimp and replaced
    gimp_image_metadata_load_finish() with
    gimp_image_metadata_load_finish_batch(), which is essentially the same
    function except that it's not interactive (it will proceed to rotate the
    image without user confirmation, provided the right flag is present).
    Then I add gimpimagemetadata-interactive.[ch] which contains only
    gimp_image_metadata_load_finish() and is the alternative interactive
    version of gimp_image_metadata_load_finish_batch(). Most plug-ins won't
    even have to be changed (at least none in core GIMP) and would still
    work as before, whereas now a non-interactive version exists, which
    doesn't mandate to link GTK+.

 libgimp/Makefile.gi                     |   6 +-
 libgimp/gimp.h                          |   1 +
 libgimp/gimpimagemetadata-interactive.c | 351 ++++++++++++++++++++++++++++++++
 libgimp/gimpimagemetadata-interactive.h |  36 ++++
 libgimp/gimpimagemetadata.c             | 306 +++-------------------------
 libgimp/gimpimagemetadata.h             |  14 +-
 libgimp/gimpui.h                        |   2 +-
 libgimp/meson.build                     |   6 +-
 8 files changed, 428 insertions(+), 294 deletions(-)
---
diff --git a/libgimp/Makefile.gi b/libgimp/Makefile.gi
index eb6875c516..4ad1e3eefc 100644
--- a/libgimp/Makefile.gi
+++ b/libgimp/Makefile.gi
@@ -119,6 +119,7 @@ libgimp_introspectable_headers = \
        ../libgimp/gimpgradientselect.h         \
        ../libgimp/gimpimage.h                  \
        ../libgimp/gimpimagecolorprofile.h      \
+       ../libgimp/gimpimagemetadata.h          \
        ../libgimp/gimpimageprocedure.h         \
        ../libgimp/gimpitem.h                   \
        ../libgimp/gimplayer.h                  \
@@ -152,6 +153,7 @@ libgimp_introspectable = \
        ../libgimp/gimpgradientselect.c         \
        ../libgimp/gimpimage.c                  \
        ../libgimp/gimpimagecolorprofile.c      \
+       ../libgimp/gimpimagemetadata.c          \
        ../libgimp/gimpimagemetadata-save.c     \
        ../libgimp/gimpimageprocedure.c         \
        ../libgimp/gimpitem.c                   \
@@ -181,7 +183,7 @@ libgimpui_introspectable_headers = \
        ../libgimp/gimpfontselectbutton.h       \
        ../libgimp/gimpgradientselectbutton.h   \
        ../libgimp/gimpimagecombobox.h          \
-       ../libgimp/gimpimagemetadata.h          \
+       ../libgimp/gimpimagemetadata-interactive.h      \
        ../libgimp/gimpitemcombobox.h           \
        ../libgimp/gimppaletteselectbutton.h    \
        ../libgimp/gimppatternselectbutton.h    \
@@ -202,7 +204,7 @@ libgimpui_introspectable = \
        ../libgimp/gimpfontselectbutton.c       \
        ../libgimp/gimpgradientselectbutton.c   \
        ../libgimp/gimpimagecombobox.c          \
-       ../libgimp/gimpimagemetadata.c          \
+       ../libgimp/gimpimagemetadata-interactive.c      \
        ../libgimp/gimpitemcombobox.c           \
        ../libgimp/gimppaletteselectbutton.c    \
        ../libgimp/gimppatternselectbutton.c    \
diff --git a/libgimp/gimp.h b/libgimp/gimp.h
index 0578715da1..71649bd026 100644
--- a/libgimp/gimp.h
+++ b/libgimp/gimp.h
@@ -45,6 +45,7 @@
 #include <libgimp/gimpgradientselect.h>
 #include <libgimp/gimpimage.h>
 #include <libgimp/gimpimagecolorprofile.h>
+#include <libgimp/gimpimagemetadata.h>
 #include <libgimp/gimpimageprocedure.h>
 #include <libgimp/gimpitem.h>
 #include <libgimp/gimplayer.h>
diff --git a/libgimp/gimpimagemetadata-interactive.c b/libgimp/gimpimagemetadata-interactive.c
new file mode 100644
index 0000000000..bff4667610
--- /dev/null
+++ b/libgimp/gimpimagemetadata-interactive.c
@@ -0,0 +1,351 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
+ *
+ * gimpimagemetadata-interactive.c
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <sys/time.h>
+
+#include <gtk/gtk.h>
+#include <gexiv2/gexiv2.h>
+
+#include "gimp.h"
+#include "gimpui.h"
+#include "gimpimagemetadata.h"
+
+#include "libgimp-intl.h"
+
+
+static gboolean    gimp_image_metadata_rotate_query  (GimpImage         *image,
+                                                      const gchar       *mime_type,
+                                                      GimpMetadata      *metadata);
+static gboolean    gimp_image_metadata_rotate_dialog (GimpImage         *image,
+                                                      GExiv2Orientation  orientation,
+                                                      const gchar       *parasite_name);
+static GdkPixbuf * gimp_image_metadata_rotate_pixbuf (GdkPixbuf         *pixbuf,
+                                                      GExiv2Orientation  orientation);
+
+
+/*  public functions  */
+
+/**
+ * gimp_image_metadata_load_finish:
+ * @image:       The image
+ * @mime_type:   The loaded file's mime-type
+ * @metadata:    The metadata to set on the image
+ * @flags:       Flags to specify what of the metadata to apply to the image
+ * @interactive: Whether this function is allowed to query info with dialogs
+ *
+ * Applies the @metadata previously loaded with
+ * gimp_image_metadata_load_prepare() to the image, taking into account
+ * the passed @flags.
+ *
+ * This function is the interactive alternative to
+ * gimp_image_metadata_load_finish_batch() which is allowed to query
+ * info with dialogs. For instance, if GIMP_METADATA_LOAD_ORIENTATION
+ * flag is set, it will popup a dialog asking whether one wants to
+ * rotate the image according to the orientation set in the metadata
+ * (displaying small previews of both versions).
+ * If @interactive is %FALSE, this behaves exactly the same as
+ * gimp_image_metadata_load_finish_batch().
+ *
+ * Since: 2.10
+ */
+void
+gimp_image_metadata_load_finish (GimpImage             *image,
+                                 const gchar           *mime_type,
+                                 GimpMetadata          *metadata,
+                                 GimpMetadataLoadFlags  flags,
+                                 gboolean               interactive)
+{
+  g_return_if_fail (GIMP_IS_IMAGE (image));
+  g_return_if_fail (mime_type != NULL);
+  g_return_if_fail (GEXIV2_IS_METADATA (metadata));
+
+  if (interactive)
+    {
+      if (flags & GIMP_METADATA_LOAD_ORIENTATION)
+        {
+          if (! gimp_image_metadata_rotate_query (image, mime_type,
+                                                  metadata))
+            flags &= ~GIMP_METADATA_LOAD_ORIENTATION;
+        }
+    }
+
+  gimp_image_metadata_load_finish_batch (image, mime_type, metadata, flags);
+}
+
+
+/*  private functions  */
+
+static gboolean
+gimp_image_metadata_rotate_query (GimpImage    *image,
+                                  const gchar  *mime_type,
+                                  GimpMetadata *metadata)
+{
+  GimpParasite      *parasite;
+  gchar             *parasite_name;
+  GExiv2Orientation  orientation;
+  gboolean           query = TRUE;
+
+  orientation = gexiv2_metadata_get_orientation (GEXIV2_METADATA (metadata));
+
+  if (orientation <= GEXIV2_ORIENTATION_NORMAL ||
+      orientation >  GEXIV2_ORIENTATION_MAX)
+    return FALSE;
+
+  parasite_name = g_strdup_printf ("gimp-metadata-exif-rotate(%s)", mime_type);
+
+  parasite = gimp_get_parasite (parasite_name);
+
+  if (parasite)
+    {
+      if (strncmp (gimp_parasite_data (parasite), "yes",
+                   gimp_parasite_data_size (parasite)) == 0)
+        {
+          query = FALSE;
+        }
+      else if (strncmp (gimp_parasite_data (parasite), "no",
+                        gimp_parasite_data_size (parasite)) == 0)
+        {
+          gimp_parasite_free (parasite);
+          g_free (parasite_name);
+          return FALSE;
+        }
+
+      gimp_parasite_free (parasite);
+    }
+
+  if (query && ! gimp_image_metadata_rotate_dialog (image,
+                                                    orientation,
+                                                    parasite_name))
+    {
+      g_free (parasite_name);
+      return FALSE;
+    }
+
+  g_free (parasite_name);
+  return TRUE;
+}
+
+static gboolean
+gimp_image_metadata_rotate_dialog (GimpImage         *image,
+                                   GExiv2Orientation  orientation,
+                                   const gchar       *parasite_name)
+{
+  GtkWidget *dialog;
+  GtkWidget *main_vbox;
+  GtkWidget *vbox;
+  GtkWidget *label;
+  GtkWidget *toggle;
+  GdkPixbuf *pixbuf;
+  gchar     *name;
+  gchar     *title;
+  gint       response;
+
+  name = gimp_image_get_name (image);
+  title = g_strdup_printf (_("Rotate %s?"), name);
+  g_free (name);
+
+  dialog = gimp_dialog_new (title, "gimp-metadata-rotate-dialog",
+                            NULL, 0, NULL, NULL,
+
+                            _("_Keep Original"), GTK_RESPONSE_CANCEL,
+                            _("_Rotate"),        GTK_RESPONSE_OK,
+
+                            NULL);
+
+  g_free (title);
+
+  gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
+                                           GTK_RESPONSE_OK,
+                                           GTK_RESPONSE_CANCEL,
+                                           -1);
+
+  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+  gimp_window_set_transient (GTK_WINDOW (dialog));
+
+  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
+  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+                      main_vbox, FALSE, FALSE, 0);
+  gtk_widget_show (main_vbox);
+
+#define THUMBNAIL_SIZE 128
+
+  pixbuf = gimp_image_get_thumbnail (image,
+                                     THUMBNAIL_SIZE, THUMBNAIL_SIZE,
+                                     GIMP_PIXBUF_SMALL_CHECKS);
+
+  if (pixbuf)
+    {
+      GdkPixbuf *rotated;
+      GtkWidget *hbox;
+      GtkWidget *image;
+
+      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+      gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
+      gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
+      gtk_widget_show (hbox);
+
+      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+      gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+      gtk_widget_show (vbox);
+
+      label = gtk_label_new (_("Original"));
+      gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
+      gimp_label_set_attributes (GTK_LABEL (label),
+                                 PANGO_ATTR_STYLE,  PANGO_STYLE_ITALIC,
+                                 -1);
+      gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      gtk_widget_show (label);
+
+      image = gtk_image_new_from_pixbuf (pixbuf);
+      gtk_box_pack_end (GTK_BOX (vbox), image, FALSE, FALSE, 0);
+      gtk_widget_show (image);
+
+      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+      gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+      gtk_widget_show (vbox);
+
+      label = gtk_label_new (_("Rotated"));
+      gimp_label_set_attributes (GTK_LABEL (label),
+                                 PANGO_ATTR_STYLE,  PANGO_STYLE_ITALIC,
+                                 -1);
+      gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      gtk_widget_show (label);
+
+      rotated = gimp_image_metadata_rotate_pixbuf (pixbuf, orientation);
+      g_object_unref (pixbuf);
+
+      image = gtk_image_new_from_pixbuf (rotated);
+      g_object_unref (rotated);
+
+      gtk_box_pack_end (GTK_BOX (vbox), image, FALSE, FALSE, 0);
+      gtk_widget_show (image);
+    }
+
+  label = g_object_new (GTK_TYPE_LABEL,
+                        "label",   _("This image contains Exif orientation "
+                                     "metadata."),
+                        "wrap",    TRUE,
+                        "justify", GTK_JUSTIFY_LEFT,
+                        "xalign",  0.0,
+                        "yalign",  0.5,
+                        NULL);
+  gimp_label_set_attributes (GTK_LABEL (label),
+                             PANGO_ATTR_SCALE,  PANGO_SCALE_LARGE,
+                             PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
+                             -1);
+  /* eek */
+  gtk_widget_set_size_request (GTK_WIDGET (label),
+                               2 * THUMBNAIL_SIZE + 12, -1);
+  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  label = g_object_new (GTK_TYPE_LABEL,
+                        "label",   _("Would you like to rotate the image?"),
+                        "wrap",    TRUE,
+                        "justify", GTK_JUSTIFY_LEFT,
+                        "xalign",  0.0,
+                        "yalign",  0.5,
+                        NULL);
+  /* eek */
+  gtk_widget_set_size_request (GTK_WIDGET (label),
+                               2 * THUMBNAIL_SIZE + 12, -1);
+  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  toggle = gtk_check_button_new_with_mnemonic (_("_Don't ask me again"));
+  gtk_box_pack_end (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
+  gtk_widget_show (toggle);
+
+  response = gimp_dialog_run (GIMP_DIALOG (dialog));
+
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
+    {
+      GimpParasite *parasite;
+      const gchar  *str = (response == GTK_RESPONSE_OK) ? "yes" : "no";
+
+      parasite = gimp_parasite_new (parasite_name,
+                                    GIMP_PARASITE_PERSISTENT,
+                                    strlen (str), str);
+      gimp_attach_parasite (parasite);
+      gimp_parasite_free (parasite);
+    }
+
+  gtk_widget_destroy (dialog);
+
+  return (response == GTK_RESPONSE_OK);
+}
+
+static GdkPixbuf *
+gimp_image_metadata_rotate_pixbuf (GdkPixbuf         *pixbuf,
+                                   GExiv2Orientation  orientation)
+{
+  GdkPixbuf *rotated = NULL;
+  GdkPixbuf *temp;
+
+  switch (orientation)
+    {
+    case GEXIV2_ORIENTATION_UNSPECIFIED:
+    case GEXIV2_ORIENTATION_NORMAL:  /* standard orientation, do nothing */
+      rotated = g_object_ref (pixbuf);
+      break;
+
+    case GEXIV2_ORIENTATION_HFLIP:
+      rotated = gdk_pixbuf_flip (pixbuf, TRUE);
+      break;
+
+    case GEXIV2_ORIENTATION_ROT_180:
+      rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
+      break;
+
+    case GEXIV2_ORIENTATION_VFLIP:
+      rotated = gdk_pixbuf_flip (pixbuf, FALSE);
+      break;
+
+    case GEXIV2_ORIENTATION_ROT_90_HFLIP:  /* flipped diagonally around '\' */
+      temp = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
+      rotated = gdk_pixbuf_flip (temp, TRUE);
+      g_object_unref (temp);
+      break;
+
+    case GEXIV2_ORIENTATION_ROT_90:  /* 90 CW */
+      rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
+      break;
+
+    case GEXIV2_ORIENTATION_ROT_90_VFLIP:  /* flipped diagonally around '/' */
+      temp = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
+      rotated = gdk_pixbuf_flip (temp, FALSE);
+      g_object_unref (temp);
+      break;
+
+    case GEXIV2_ORIENTATION_ROT_270:  /* 90 CCW */
+      rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
+      break;
+
+    default: /* shouldn't happen */
+      break;
+    }
+
+  return rotated;
+}
diff --git a/libgimp/gimpimagemetadata-interactive.h b/libgimp/gimpimagemetadata-interactive.h
new file mode 100644
index 0000000000..6c972b062d
--- /dev/null
+++ b/libgimp/gimpimagemetadata-interactive.h
@@ -0,0 +1,36 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
+ *
+ * gimpimagemetadata-interactive.h
+ *
+ * This library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
+#error "Only <libgimp/gimpui.h> can be included directly."
+#endif
+
+#ifndef __GIMP_IMAGE_METADATA_INTERACTIVE_H__
+#define __GIMP_IMAGE_METADATA_INTERACTIVE_H__
+
+
+void   gimp_image_metadata_load_finish (GimpImage             *image,
+                                        const gchar           *mime_type,
+                                        GimpMetadata          *metadata,
+                                        GimpMetadataLoadFlags  flags,
+                                        gboolean               interactive);
+
+
+#endif /* __GIMP_IMAGE_METADATA_INTERACTIVE_H__ */
diff --git a/libgimp/gimpimagemetadata.c b/libgimp/gimpimagemetadata.c
index 9e999e2781..be19ad0898 100644
--- a/libgimp/gimpimagemetadata.c
+++ b/libgimp/gimpimagemetadata.c
@@ -23,11 +23,9 @@
 #include <string.h>
 #include <sys/time.h>
 
-#include <gtk/gtk.h>
 #include <gexiv2/gexiv2.h>
 
 #include "gimp.h"
-#include "gimpui.h"
 #include "gimpimagemetadata.h"
 
 #include "libgimp-intl.h"
@@ -42,16 +40,6 @@ typedef struct
 
 static void        gimp_image_metadata_rotate        (GimpImage         *image,
                                                       GExiv2Orientation  orientation);
-static GdkPixbuf * gimp_image_metadata_rotate_pixbuf (GdkPixbuf         *pixbuf,
-                                                      GExiv2Orientation  orientation);
-static void        gimp_image_metadata_rotate_query  (GimpImage         *image,
-                                                      const gchar       *mime_type,
-                                                      GimpMetadata      *metadata,
-                                                      gboolean           interactive);
-static gboolean    gimp_image_metadata_rotate_dialog (GimpImage         *image,
-                                                      GExiv2Orientation  orientation,
-                                                      const gchar       *parasite_name);
-
 
 /*  public functions  */
 
@@ -63,7 +51,8 @@ static gboolean    gimp_image_metadata_rotate_dialog (GimpImage         *image,
  * @error:     Return location for error
  *
  * Loads and returns metadata from @file to be passed into
- * gimp_image_metadata_load_finish().
+ * gimp_image_metadata_load_finish() or
+ * gimp_image_metadata_load_finish_batch().
  *
  * Returns: (transfer full): The file's metadata.
  *
@@ -93,25 +82,34 @@ gimp_image_metadata_load_prepare (GimpImage    *image,
 }
 
 /**
- * gimp_image_metadata_load_finish:
+ * gimp_image_metadata_load_finish_batch:
  * @image:       The image
  * @mime_type:   The loaded file's mime-type
  * @metadata:    The metadata to set on the image
  * @flags:       Flags to specify what of the metadata to apply to the image
- * @interactive: Whether this function is allowed to query info with dialogs
  *
  * Applies the @metadata previously loaded with
  * gimp_image_metadata_load_prepare() to the image, taking into account
  * the passed @flags.
  *
- * Since: 2.10
+ * Some metadata may involve some image changes and are better asked for
+ * confirmation. For instance the orientation metadata may be wrong at
+ * times (because it depends usually on camera sensors and the rotated
+ * image may not be what one expects). If the related flag is set (i.e.
+ * GIMP_METADATA_LOAD_ORIENTATION for orientation), then the change will
+ * be automatically executed (i.e. the image will be rotated) without
+ * any human interaction.
+ *
+ * If you wish such edit to be queried interactively with dialogs, use
+ * gimp_image_metadata_load_finish() instead, from libgimpui.
+ *
+ * Since: 3.0
  */
 void
-gimp_image_metadata_load_finish (GimpImage             *image,
-                                 const gchar           *mime_type,
-                                 GimpMetadata          *metadata,
-                                 GimpMetadataLoadFlags  flags,
-                                 gboolean               interactive)
+gimp_image_metadata_load_finish_batch (GimpImage             *image,
+                                       const gchar           *mime_type,
+                                       GimpMetadata          *metadata,
+                                       GimpMetadataLoadFlags  flags)
 {
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (mime_type != NULL);
@@ -157,8 +155,11 @@ gimp_image_metadata_load_finish (GimpImage             *image,
 
   if (flags & GIMP_METADATA_LOAD_ORIENTATION)
     {
-      gimp_image_metadata_rotate_query (image, mime_type,
-                                        metadata, interactive);
+      gimp_image_metadata_rotate (image,
+                                  gexiv2_metadata_get_orientation (GEXIV2_METADATA (metadata)));
+
+      gexiv2_metadata_set_orientation (GEXIV2_METADATA (metadata),
+                                       GEXIV2_ORIENTATION_NORMAL);
     }
 
   if (flags & GIMP_METADATA_LOAD_COLORSPACE)
@@ -315,262 +316,3 @@ gimp_image_metadata_rotate (GimpImage         *image,
       break;
     }
 }
-
-static GdkPixbuf *
-gimp_image_metadata_rotate_pixbuf (GdkPixbuf         *pixbuf,
-                                   GExiv2Orientation  orientation)
-{
-  GdkPixbuf *rotated = NULL;
-  GdkPixbuf *temp;
-
-  switch (orientation)
-    {
-    case GEXIV2_ORIENTATION_UNSPECIFIED:
-    case GEXIV2_ORIENTATION_NORMAL:  /* standard orientation, do nothing */
-      rotated = g_object_ref (pixbuf);
-      break;
-
-    case GEXIV2_ORIENTATION_HFLIP:
-      rotated = gdk_pixbuf_flip (pixbuf, TRUE);
-      break;
-
-    case GEXIV2_ORIENTATION_ROT_180:
-      rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
-      break;
-
-    case GEXIV2_ORIENTATION_VFLIP:
-      rotated = gdk_pixbuf_flip (pixbuf, FALSE);
-      break;
-
-    case GEXIV2_ORIENTATION_ROT_90_HFLIP:  /* flipped diagonally around '\' */
-      temp = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
-      rotated = gdk_pixbuf_flip (temp, TRUE);
-      g_object_unref (temp);
-      break;
-
-    case GEXIV2_ORIENTATION_ROT_90:  /* 90 CW */
-      rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
-      break;
-
-    case GEXIV2_ORIENTATION_ROT_90_VFLIP:  /* flipped diagonally around '/' */
-      temp = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
-      rotated = gdk_pixbuf_flip (temp, FALSE);
-      g_object_unref (temp);
-      break;
-
-    case GEXIV2_ORIENTATION_ROT_270:  /* 90 CCW */
-      rotated = gdk_pixbuf_rotate_simple (pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
-      break;
-
-    default: /* shouldn't happen */
-      break;
-    }
-
-  return rotated;
-}
-
-static void
-gimp_image_metadata_rotate_query (GimpImage    *image,
-                                  const gchar  *mime_type,
-                                  GimpMetadata *metadata,
-                                  gboolean      interactive)
-{
-  GimpParasite      *parasite;
-  gchar             *parasite_name;
-  GExiv2Orientation  orientation;
-  gboolean           query = interactive;
-
-  orientation = gexiv2_metadata_get_orientation (GEXIV2_METADATA (metadata));
-
-  if (orientation <= GEXIV2_ORIENTATION_NORMAL ||
-      orientation >  GEXIV2_ORIENTATION_MAX)
-    return;
-
-  parasite_name = g_strdup_printf ("gimp-metadata-exif-rotate(%s)", mime_type);
-
-  parasite = gimp_get_parasite (parasite_name);
-
-  if (parasite)
-    {
-      if (strncmp (gimp_parasite_data (parasite), "yes",
-                   gimp_parasite_data_size (parasite)) == 0)
-        {
-          query = FALSE;
-        }
-      else if (strncmp (gimp_parasite_data (parasite), "no",
-                        gimp_parasite_data_size (parasite)) == 0)
-        {
-          gimp_parasite_free (parasite);
-          g_free (parasite_name);
-          return;
-        }
-
-      gimp_parasite_free (parasite);
-    }
-
-  if (query && ! gimp_image_metadata_rotate_dialog (image,
-                                                    orientation,
-                                                    parasite_name))
-    {
-      g_free (parasite_name);
-      return;
-    }
-
-  g_free (parasite_name);
-
-  gimp_image_metadata_rotate (image, orientation);
-  gexiv2_metadata_set_orientation (GEXIV2_METADATA (metadata),
-                                   GEXIV2_ORIENTATION_NORMAL);
-}
-
-static gboolean
-gimp_image_metadata_rotate_dialog (GimpImage         *image,
-                                   GExiv2Orientation  orientation,
-                                   const gchar       *parasite_name)
-{
-  GtkWidget *dialog;
-  GtkWidget *main_vbox;
-  GtkWidget *vbox;
-  GtkWidget *label;
-  GtkWidget *toggle;
-  GdkPixbuf *pixbuf;
-  gchar     *name;
-  gchar     *title;
-  gint       response;
-
-  name = gimp_image_get_name (image);
-  title = g_strdup_printf (_("Rotate %s?"), name);
-  g_free (name);
-
-  dialog = gimp_dialog_new (title, "gimp-metadata-rotate-dialog",
-                            NULL, 0, NULL, NULL,
-
-                            _("_Keep Original"), GTK_RESPONSE_CANCEL,
-                            _("_Rotate"),        GTK_RESPONSE_OK,
-
-                            NULL);
-
-  g_free (title);
-
-  gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
-                                           GTK_RESPONSE_OK,
-                                           GTK_RESPONSE_CANCEL,
-                                           -1);
-
-  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-  gimp_window_set_transient (GTK_WINDOW (dialog));
-
-  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
-  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
-  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
-                      main_vbox, FALSE, FALSE, 0);
-  gtk_widget_show (main_vbox);
-
-#define THUMBNAIL_SIZE 128
-
-  pixbuf = gimp_image_get_thumbnail (image,
-                                     THUMBNAIL_SIZE, THUMBNAIL_SIZE,
-                                     GIMP_PIXBUF_SMALL_CHECKS);
-
-  if (pixbuf)
-    {
-      GdkPixbuf *rotated;
-      GtkWidget *hbox;
-      GtkWidget *image;
-
-      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
-      gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
-      gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
-      gtk_widget_show (hbox);
-
-      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-      gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
-      gtk_widget_show (vbox);
-
-      label = gtk_label_new (_("Original"));
-      gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
-      gimp_label_set_attributes (GTK_LABEL (label),
-                                 PANGO_ATTR_STYLE,  PANGO_STYLE_ITALIC,
-                                 -1);
-      gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-      gtk_widget_show (label);
-
-      image = gtk_image_new_from_pixbuf (pixbuf);
-      gtk_box_pack_end (GTK_BOX (vbox), image, FALSE, FALSE, 0);
-      gtk_widget_show (image);
-
-      vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-      gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
-      gtk_widget_show (vbox);
-
-      label = gtk_label_new (_("Rotated"));
-      gimp_label_set_attributes (GTK_LABEL (label),
-                                 PANGO_ATTR_STYLE,  PANGO_STYLE_ITALIC,
-                                 -1);
-      gtk_box_pack_end (GTK_BOX (vbox), label, FALSE, FALSE, 0);
-      gtk_widget_show (label);
-
-      rotated = gimp_image_metadata_rotate_pixbuf (pixbuf, orientation);
-      g_object_unref (pixbuf);
-
-      image = gtk_image_new_from_pixbuf (rotated);
-      g_object_unref (rotated);
-
-      gtk_box_pack_end (GTK_BOX (vbox), image, FALSE, FALSE, 0);
-      gtk_widget_show (image);
-    }
-
-  label = g_object_new (GTK_TYPE_LABEL,
-                        "label",   _("This image contains Exif orientation "
-                                     "metadata."),
-                        "wrap",    TRUE,
-                        "justify", GTK_JUSTIFY_LEFT,
-                        "xalign",  0.0,
-                        "yalign",  0.5,
-                        NULL);
-  gimp_label_set_attributes (GTK_LABEL (label),
-                             PANGO_ATTR_SCALE,  PANGO_SCALE_LARGE,
-                             PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
-                             -1);
-  /* eek */
-  gtk_widget_set_size_request (GTK_WIDGET (label),
-                               2 * THUMBNAIL_SIZE + 12, -1);
-  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
-
-  label = g_object_new (GTK_TYPE_LABEL,
-                        "label",   _("Would you like to rotate the image?"),
-                        "wrap",    TRUE,
-                        "justify", GTK_JUSTIFY_LEFT,
-                        "xalign",  0.0,
-                        "yalign",  0.5,
-                        NULL);
-  /* eek */
-  gtk_widget_set_size_request (GTK_WIDGET (label),
-                               2 * THUMBNAIL_SIZE + 12, -1);
-  gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
-
-  toggle = gtk_check_button_new_with_mnemonic (_("_Don't ask me again"));
-  gtk_box_pack_end (GTK_BOX (main_vbox), toggle, FALSE, FALSE, 0);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
-  gtk_widget_show (toggle);
-
-  response = gimp_dialog_run (GIMP_DIALOG (dialog));
-
-  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
-    {
-      GimpParasite *parasite;
-      const gchar  *str = (response == GTK_RESPONSE_OK) ? "yes" : "no";
-
-      parasite = gimp_parasite_new (parasite_name,
-                                    GIMP_PARASITE_PERSISTENT,
-                                    strlen (str), str);
-      gimp_attach_parasite (parasite);
-      gimp_parasite_free (parasite);
-    }
-
-  gtk_widget_destroy (dialog);
-
-  return (response == GTK_RESPONSE_OK);
-}
diff --git a/libgimp/gimpimagemetadata.h b/libgimp/gimpimagemetadata.h
index 2f1cec6ddb..8aac8f372b 100644
--- a/libgimp/gimpimagemetadata.h
+++ b/libgimp/gimpimagemetadata.h
@@ -18,10 +18,11 @@
  * <https://www.gnu.org/licenses/>.
  */
 
-#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
-#error "Only <libgimp/gimpui.h> can be included directly."
+#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
+#error "Only <libgimp/gimp.h> can be included directly."
 #endif
 
+
 #ifndef __GIMP_IMAGE_METADATA_H__
 #define __GIMP_IMAGE_METADATA_H__
 
@@ -34,11 +35,10 @@ GimpMetadata * gimp_image_metadata_load_prepare   (GimpImage             *image,
                                                    const gchar           *mime_type,
                                                    GFile                 *file,
                                                    GError               **error);
-void           gimp_image_metadata_load_finish    (GimpImage             *image,
-                                                   const gchar           *mime_type,
-                                                   GimpMetadata          *metadata,
-                                                   GimpMetadataLoadFlags  flags,
-                                                   gboolean               interactive);
+void           gimp_image_metadata_load_finish_batch (GimpImage             *image,
+                                                      const gchar           *mime_type,
+                                                      GimpMetadata          *metadata,
+                                                      GimpMetadataLoadFlags  flags);
 
 GimpMetadata * gimp_image_metadata_save_prepare   (GimpImage             *image,
                                                    const gchar           *mime_type,
diff --git a/libgimp/gimpui.h b/libgimp/gimpui.h
index 2d3db085e4..a4ac9e53aa 100644
--- a/libgimp/gimpui.h
+++ b/libgimp/gimpui.h
@@ -36,7 +36,7 @@
 #include <libgimp/gimpfontselectbutton.h>
 #include <libgimp/gimpgradientselectbutton.h>
 #include <libgimp/gimpimagecombobox.h>
-#include <libgimp/gimpimagemetadata.h>
+#include <libgimp/gimpimagemetadata-interactive.h>
 #include <libgimp/gimpitemcombobox.h>
 #include <libgimp/gimppaletteselectbutton.h>
 #include <libgimp/gimppatternselectbutton.h>
diff --git a/libgimp/meson.build b/libgimp/meson.build
index 3ac6a6b2c8..3245c44ba1 100644
--- a/libgimp/meson.build
+++ b/libgimp/meson.build
@@ -146,6 +146,7 @@ libgimp_sources_introspectable = [
   'gimpgradientselect.c',
   'gimpimage.c',
   'gimpimagecolorprofile.c',
+  'gimpimagemetadata.c',
   'gimpimagemetadata-save.c',
   'gimpimageprocedure.c',
   'gimpitem.c',
@@ -200,6 +201,7 @@ libgimp_headers_introspectable = [
   'gimpgradientselect.h',
   'gimpimage.h',
   'gimpimagecolorprofile.h',
+  'gimpimagemetadata.h',
   'gimpimageprocedure.h',
   'gimpitem.h',
   'gimplayer.h',
@@ -233,7 +235,7 @@ libgimpui_sources_introspectable = [
   'gimpfontselectbutton.c',
   'gimpgradientselectbutton.c',
   'gimpimagecombobox.c',
-  'gimpimagemetadata.c',
+  'gimpimagemetadata-interactive.c',
   'gimpitemcombobox.c',
   'gimppaletteselectbutton.c',
   'gimppatternselectbutton.c',
@@ -264,7 +266,7 @@ libgimpui_headers_introspectable = [
   'gimpfontselectbutton.h',
   'gimpgradientselectbutton.h',
   'gimpimagecombobox.h',
-  'gimpimagemetadata.h',
+  'gimpimagemetadata-interactive.h',
   'gimpitemcombobox.h',
   'gimppaletteselectbutton.h',
   'gimppatternselectbutton.h',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]