[nautilus] general: reimplement image properties as an extension



commit 14ee0f1cdc9c02e6fc49024786eb6ef47be5a176
Author: Ernestas Kulik <ernestask gnome org>
Date:   Wed Jan 31 10:24:07 2018 +0200

    general: reimplement image properties as an extension
    
    The image property page is already implemented using the extension API,
    but it’s not an extension and relies on a library that is not essential
    to Nautilus. This commit builds the image properties as an extension and
    introduces some minor refactoring to the code.

 extensions/image-properties/meson.build            |  15 +
 .../nautilus-image-properties-module.c             |  54 +++
 .../nautilus-image-properties-page-provider.c      | 136 ++++++
 .../nautilus-image-properties-page-provider.h      |  33 ++
 .../nautilus-image-properties-page.c               | 465 ++++++++-------------
 .../nautilus-image-properties-page.h               |  20 +-
 extensions/meson.build                             |   1 +
 meson.build                                        |   6 +-
 src/meson.build                                    |   3 -
 src/nautilus-application.c                         |   4 -
 10 files changed, 428 insertions(+), 309 deletions(-)
---
diff --git a/extensions/image-properties/meson.build b/extensions/image-properties/meson.build
new file mode 100644
index 000000000..82cdd42ad
--- /dev/null
+++ b/extensions/image-properties/meson.build
@@ -0,0 +1,15 @@
+shared_library (
+  'nautilus-image-properties', [
+    'nautilus-image-properties-module.c',
+    'nautilus-image-properties-page.c',
+    'nautilus-image-properties-page.h',
+    'nautilus-image-properties-page-provider.c',
+    'nautilus-image-properties-page-provider.h'
+  ],
+  dependencies: [
+    gexiv,
+    nautilus_extension
+  ],
+  install: true,
+  install_dir: extensiondir
+)
diff --git a/extensions/image-properties/nautilus-image-properties-module.c 
b/extensions/image-properties/nautilus-image-properties-module.c
new file mode 100644
index 000000000..0ce02e973
--- /dev/null
+++ b/extensions/image-properties/nautilus-image-properties-module.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 2018 Ernestas Kulik <ernestask gnome org>
+ *
+ * This file is part of Nautilus.
+ *
+ * Nautilus 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.
+ *
+ * Nautilus 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 Nautilus.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "nautilus-image-properties-page-provider.h"
+
+#include <glib/gi18n-lib.h>
+
+#include <nautilus-extension.h>
+
+void
+nautilus_module_initialize (GTypeModule *module)
+{
+    bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+    nautilus_image_properties_page_provider_load (module);
+}
+
+void
+nautilus_module_shutdown (void)
+{
+}
+
+void
+nautilus_module_list_types (const GType **types,
+                            int          *num_types)
+{
+    static GType type_list[1] = { 0 };
+
+    g_assert (types != NULL);
+    g_assert (num_types != NULL);
+
+    type_list[0] = NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE_PROVIDER;
+
+    *types = type_list;
+    *num_types = G_N_ELEMENTS (type_list);
+}
diff --git a/extensions/image-properties/nautilus-image-properties-page-provider.c 
b/extensions/image-properties/nautilus-image-properties-page-provider.c
new file mode 100644
index 000000000..99e495bb7
--- /dev/null
+++ b/extensions/image-properties/nautilus-image-properties-page-provider.c
@@ -0,0 +1,136 @@
+/* Copyright (C) 2004 Red Hat, Inc
+ * Copyright (c) 2007 Novell, Inc.
+ * Copyright (c) 2017 Thomas Bechtold <thomasbechtold jpberlin de>
+ * Copyright (c) 2018 Ernestas Kulik <ernestask gnome org>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ * XMP support by Hubert Figuiere <hfiguiere novell com>
+ */
+
+#include "nautilus-image-properties-page-provider.h"
+
+#include "nautilus-image-properties-page.h"
+
+#include <glib/gi18n.h>
+
+#include <nautilus-extension.h>
+
+#define NAUTILUS_IMAGE_PROPERTIES_PAGE_NAME "NautilusImagePropertiesPage::property_page"
+
+struct _NautilusImagesPropertiesPageProvider
+{
+    GObject parent_instance;
+};
+
+static void property_page_provider_iface_init (NautilusPropertyPageProviderInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (NautilusImagesPropertiesPageProvider,
+                                nautilus_image_properties_page_provider,
+                                G_TYPE_OBJECT,
+                                0,
+                                G_IMPLEMENT_INTERFACE_DYNAMIC (NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER,
+                                                               property_page_provider_iface_init))
+
+static gboolean
+is_mime_type_supported (const char *mime_type)
+{
+    g_autoptr (GSList) formats = NULL;
+
+    if (mime_type == NULL)
+    {
+        return FALSE;
+    }
+
+    formats = gdk_pixbuf_get_formats ();
+
+    for (GSList *l = formats; l != NULL; l = l->next)
+    {
+        g_auto (GStrv) mime_types = NULL;
+
+        mime_types = gdk_pixbuf_format_get_mime_types (l->data);
+        if (mime_types == NULL)
+        {
+            continue;
+        }
+
+        if (g_strv_contains ((const char *const *) mime_types, mime_type))
+        {
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+static GList *
+get_pages (NautilusPropertyPageProvider *provider,
+           GList                        *files)
+{
+    NautilusFileInfo *file_info;
+    g_autofree char *mime_type = NULL;
+    NautilusImagesPropertiesPage *image_properties_page;
+    NautilusPropertyPage *property_page;
+
+    if (files == NULL || files->next != NULL)
+    {
+        return NULL;
+    }
+
+    file_info = NAUTILUS_FILE_INFO (files->data);
+    mime_type = nautilus_file_info_get_mime_type (file_info);
+    if (!is_mime_type_supported (mime_type))
+    {
+        return NULL;
+    }
+    image_properties_page = nautilus_image_properties_page_new ();
+    property_page = nautilus_property_page_new (NAUTILUS_IMAGE_PROPERTIES_PAGE_NAME,
+                                                gtk_label_new (_("Image")),
+                                                GTK_WIDGET (image_properties_page));
+
+    nautilus_image_properties_page_load_from_file_info (image_properties_page, file_info);
+
+    return g_list_prepend (NULL, property_page);
+}
+
+static void
+property_page_provider_iface_init (NautilusPropertyPageProviderInterface *iface)
+{
+    iface->get_pages = get_pages;
+}
+
+static void
+nautilus_image_properties_page_provider_init (NautilusImagesPropertiesPageProvider *self)
+{
+    (void) self;
+}
+
+static void
+nautilus_image_properties_page_provider_class_init (NautilusImagesPropertiesPageProviderClass *klass)
+{
+    (void) klass;
+}
+
+static void
+nautilus_image_properties_page_provider_class_finalize (NautilusImagesPropertiesPageProviderClass *klass)
+{
+    (void) klass;
+}
+
+void
+nautilus_image_properties_page_provider_load (GTypeModule *module)
+{
+    nautilus_image_properties_page_provider_register_type (module);
+}
diff --git a/extensions/image-properties/nautilus-image-properties-page-provider.h 
b/extensions/image-properties/nautilus-image-properties-page-provider.h
new file mode 100644
index 000000000..90e41597a
--- /dev/null
+++ b/extensions/image-properties/nautilus-image-properties-page-provider.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2018 Ernestas Kulik <ernestask gnome org>
+ *
+ * This file is part of Nautilus.
+ *
+ * Nautilus 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.
+ *
+ * Nautilus 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 Nautilus.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef NAUTILUS_IMAGE_PROPERTIES_PAGE_PROVIDER_H
+#define NAUTILUS_IMAGE_PROPERTIES_PAGE_PROVIDER_H
+
+#include <glib-object.h>
+
+#define NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE_PROVIDER (nautilus_image_properties_page_provider_get_type ())
+
+G_DECLARE_FINAL_TYPE (NautilusImagesPropertiesPageProvider,
+                      nautilus_image_properties_page_provider,
+                      NAUTILUS, IMAGE_PROPERTIES_PAGE_PROVIDER,
+                      GObject)
+
+void nautilus_image_properties_page_provider_load (GTypeModule *module);
+
+#endif
diff --git a/src/nautilus-image-properties-page.c 
b/extensions/image-properties/nautilus-image-properties-page.c
similarity index 56%
rename from src/nautilus-image-properties-page.c
rename to extensions/image-properties/nautilus-image-properties-page.c
index 0276b3661..bca0b56e8 100644
--- a/src/nautilus-image-properties-page.c
+++ b/extensions/image-properties/nautilus-image-properties-page.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (C) 2004 Red Hat, Inc
+/* Copyright (C) 2004 Red Hat, Inc
  * Copyright (c) 2007 Novell, Inc.
  * Copyright (c) 2017 Thomas Bechtold <thomasbechtold jpberlin de>
  *
@@ -20,30 +19,23 @@
  * XMP support by Hubert Figuiere <hfiguiere novell com>
  */
 
-#include <config.h>
 #include "nautilus-image-properties-page.h"
 
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <gio/gio.h>
-#include <eel/eel-vfs-extensions.h>
-#include <libnautilus-extension/nautilus-property-page-provider.h>
-#include "nautilus-module.h"
-#include <string.h>
-
 #include <gexiv2/gexiv2.h>
+#include <glib/gi18n.h>
 
 #define LOAD_BUFFER_SIZE 8192
 
-struct _NautilusImagePropertiesPage
+struct _NautilusImagesPropertiesPage
 {
-    GtkBox parent;
+    GtkGrid parent;
+
     GCancellable *cancellable;
     GtkWidget *grid;
     GdkPixbufLoader *loader;
     gboolean got_size;
     gboolean pixbuf_still_loading;
-    char buffer[LOAD_BUFFER_SIZE];
+    unsigned char buffer[LOAD_BUFFER_SIZE];
     int width;
     int height;
 
@@ -51,163 +43,163 @@ struct _NautilusImagePropertiesPage
     gboolean md_ready;
 };
 
-enum
-{
-    PROP_URI
-};
-
-typedef struct
-{
-    GObject parent;
-} NautilusImagePropertiesPageProvider;
-
-typedef struct
-{
-    GObjectClass parent;
-} NautilusImagePropertiesPageProviderClass;
-
-
-static GType nautilus_image_properties_page_provider_get_type (void);
-static void  property_page_provider_iface_init (NautilusPropertyPageProviderIface *iface);
-
-
-G_DEFINE_TYPE (NautilusImagePropertiesPage, nautilus_image_properties_page, GTK_TYPE_BOX);
-
-G_DEFINE_TYPE_WITH_CODE (NautilusImagePropertiesPageProvider, nautilus_image_properties_page_provider, 
G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER,
-                                                property_page_provider_iface_init));
+G_DEFINE_TYPE (NautilusImagesPropertiesPage,
+               nautilus_image_properties_page,
+               GTK_TYPE_GRID);
 
 static void
-nautilus_image_properties_page_finalize (GObject *object)
+finalize (GObject *object)
 {
-    NautilusImagePropertiesPage *page;
+    NautilusImagesPropertiesPage *page;
 
     page = NAUTILUS_IMAGE_PROPERTIES_PAGE (object);
 
-    if (page->cancellable)
+    if (page->cancellable != NULL)
     {
         g_cancellable_cancel (page->cancellable);
-        g_object_unref (page->cancellable);
-        page->cancellable = NULL;
+        g_clear_object (&page->cancellable);
     }
 
     G_OBJECT_CLASS (nautilus_image_properties_page_parent_class)->finalize (object);
 }
 
 static void
-file_close_callback (GObject      *object,
-                     GAsyncResult *res,
-                     gpointer      data)
+nautilus_image_properties_page_class_init (NautilusImagesPropertiesPageClass *klass)
 {
-    NautilusImagePropertiesPage *page;
-    GInputStream *stream;
+    GObjectClass *object_class;
 
-    page = NAUTILUS_IMAGE_PROPERTIES_PAGE (data);
-    stream = G_INPUT_STREAM (object);
+    object_class = G_OBJECT_CLASS (klass);
 
-    g_input_stream_close_finish (stream, res, NULL);
-
-    g_object_unref (page->cancellable);
-    page->cancellable = NULL;
+    object_class->finalize = finalize;
 }
 
 static void
-append_item (NautilusImagePropertiesPage *page,
-             const char                  *name,
-             const char                  *value)
+append_item (NautilusImagesPropertiesPage *page,
+             const char                   *name,
+             const char                   *value)
 {
     GtkWidget *name_label;
-    GtkWidget *label;
     PangoAttrList *attrs;
 
     name_label = gtk_label_new (name);
     attrs = pango_attr_list_new ();
+
     pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
     gtk_label_set_attributes (GTK_LABEL (name_label), attrs);
     pango_attr_list_unref (attrs);
-    gtk_label_set_xalign (GTK_LABEL (name_label), 0);
-    gtk_label_set_yalign (GTK_LABEL (name_label), 0);
     gtk_container_add (GTK_CONTAINER (page->grid), name_label);
+    gtk_widget_set_halign (name_label, GTK_ALIGN_START);
     gtk_widget_show (name_label);
 
     if (value != NULL)
     {
-        label = gtk_label_new (value);
-        gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
-        gtk_label_set_xalign (GTK_LABEL (label), 0);
-        gtk_label_set_yalign (GTK_LABEL (label), 0);
-        gtk_grid_attach_next_to (GTK_GRID (page->grid), label,
+        GtkWidget *value_label;
+
+        value_label = gtk_label_new (value);
+
+        gtk_label_set_line_wrap (GTK_LABEL (value_label), TRUE);
+        gtk_grid_attach_next_to (GTK_GRID (page->grid), value_label,
                                  name_label, GTK_POS_RIGHT,
                                  1, 1);
-        gtk_widget_show (label);
+        gtk_widget_set_halign (value_label, GTK_ALIGN_START);
+        gtk_widget_set_hexpand (value_label, TRUE);
+        gtk_widget_show (value_label);
     }
 }
 
 static void
-append_basic_info (NautilusImagePropertiesPage *page)
+nautilus_image_properties_page_init (NautilusImagesPropertiesPage *self)
+{
+    GtkWidget *scrolled_window;
+
+    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+
+    gtk_widget_set_vexpand (GTK_WIDGET (scrolled_window), TRUE);
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                    GTK_POLICY_NEVER,
+                                    GTK_POLICY_AUTOMATIC);
+
+    gtk_container_add (GTK_CONTAINER (self), scrolled_window);
+
+    self->grid = gtk_grid_new ();
+
+    gtk_orientable_set_orientation (GTK_ORIENTABLE (self->grid), GTK_ORIENTATION_VERTICAL);
+    gtk_grid_set_row_spacing (GTK_GRID (self->grid), 6);
+    gtk_grid_set_column_spacing (GTK_GRID (self->grid), 18);
+    append_item (self, _("Loading…"), NULL);
+    gtk_container_add (GTK_CONTAINER (scrolled_window), self->grid);
+
+    gtk_widget_show_all (GTK_WIDGET (self));
+}
+
+static void
+append_basic_info (NautilusImagesPropertiesPage *page)
 {
     GdkPixbufFormat *format;
-    char *name;
-    char *desc;
-    char *value;
+    g_autofree char *name = NULL;
+    g_autofree char *desc = NULL;
+    g_autofree char *value = NULL;
 
     format = gdk_pixbuf_loader_get_format (page->loader);
-
     name = gdk_pixbuf_format_get_name (format);
     desc = gdk_pixbuf_format_get_description (format);
     value = g_strdup_printf ("%s (%s)", name, desc);
-    g_free (name);
-    g_free (desc);
+
     append_item (page, _("Image Type"), value);
+
     g_free (value);
     value = g_strdup_printf (ngettext ("%d pixel",
                                        "%d pixels",
                                        page->width),
                              page->width);
+
     append_item (page, _("Width"), value);
+
     g_free (value);
     value = g_strdup_printf (ngettext ("%d pixel",
                                        "%d pixels",
                                        page->height),
                              page->height);
+
     append_item (page, _("Height"), value);
-    g_free (value);
 }
 
 static void
-append_gexiv2_tag (NautilusImagePropertiesPage  *page,
-                   const gchar                 **tag_names,
-                   const gchar                  *description)
+append_gexiv2_tag (NautilusImagesPropertiesPage  *page,
+                   const char                   **tag_names,
+                   const char                    *description)
 {
-    gchar *tag_value;
+    g_assert (tag_names != NULL);
 
-    while (*tag_names)
+    for (const char **i = tag_names; *i != NULL; i++)
     {
-        if (gexiv2_metadata_has_tag (page->md, *tag_names))
+        if (gexiv2_metadata_has_tag (page->md, *i))
         {
-            tag_value = gexiv2_metadata_get_tag_interpreted_string (page->md, *tag_names);
-            if (!description)
+            g_autofree char *tag_value = NULL;
+
+            tag_value = gexiv2_metadata_get_tag_interpreted_string (page->md, *i);
+
+            if (description == NULL)
             {
-                description = gexiv2_metadata_get_tag_description (*tag_names);
+                description = gexiv2_metadata_get_tag_description (*i);
             }
+
             /* don't add empty tags - try next one */
             if (strlen (tag_value) > 0)
             {
                 append_item (page, description, tag_value);
-                g_free (tag_value);
                 break;
             }
-            g_free (tag_value);
         }
-        tag_names++;
     }
 }
 
 static void
-append_gexiv2_info(NautilusImagePropertiesPage *page)
+append_gexiv2_info (NautilusImagesPropertiesPage *page)
 {
-    gdouble longitude, latitude, altitude;
-    gchar *gps_coords;
+    double longitude;
+    double latitude;
+    double altitude;
 
     /* define tags and its alternatives */
     const char *title[] = { "Xmp.dc.title", NULL };
@@ -253,15 +245,17 @@ append_gexiv2_info(NautilusImagePropertiesPage *page)
 
     if (gexiv2_metadata_get_gps_info (page->md, &longitude, &latitude, &altitude))
     {
+        g_autofree char *gps_coords = NULL;
+
         /* Translators: These are the coordinates of a position where a picture was taken. */
         gps_coords = g_strdup_printf (_("%f N / %f W (%.0f m)"), latitude, longitude, altitude);
+
         append_item (page, _("Coordinates"), gps_coords);
-        g_free (gps_coords);
     }
 }
 
 static void
-load_finished (NautilusImagePropertiesPage *page)
+load_finished (NautilusImagesPropertiesPage *page)
 {
     GtkWidget *label;
 
@@ -292,23 +286,37 @@ load_finished (NautilusImagePropertiesPage *page)
     g_clear_object (&page->md);
 }
 
+static void
+file_close_callback (GObject      *object,
+                     GAsyncResult *res,
+                     gpointer      data)
+{
+    NautilusImagesPropertiesPage *page;
+    GInputStream *stream;
+
+    page = data;
+    stream = G_INPUT_STREAM (object);
+
+    g_input_stream_close_finish (stream, res, NULL);
+
+    g_clear_object (&page->cancellable);
+}
+
 static void
 file_read_callback (GObject      *object,
                     GAsyncResult *res,
                     gpointer      data)
 {
-    NautilusImagePropertiesPage *page;
+    NautilusImagesPropertiesPage *page;
     GInputStream *stream;
+    g_autoptr (GError) error = NULL;
     gssize count_read;
-    GError *error;
     gboolean done_reading;
 
-    page = NAUTILUS_IMAGE_PROPERTIES_PAGE (data);
+    page = data;
     stream = G_INPUT_STREAM (object);
-
-    error = NULL;
-    done_reading = FALSE;
     count_read = g_input_stream_read_finish (stream, res, &error);
+    done_reading = FALSE;
 
     if (count_read > 0)
     {
@@ -317,7 +325,7 @@ file_read_callback (GObject      *object,
         if (page->pixbuf_still_loading)
         {
             if (!gdk_pixbuf_loader_write (page->loader,
-                                          (const guchar *) page->buffer,
+                                          page->buffer,
                                           count_read,
                                           NULL))
             {
@@ -330,7 +338,7 @@ file_read_callback (GObject      *object,
             g_input_stream_read_async (G_INPUT_STREAM (stream),
                                        page->buffer,
                                        sizeof (page->buffer),
-                                       0,
+                                       G_PRIORITY_DEFAULT,
                                        page->cancellable,
                                        file_read_callback,
                                        page);
@@ -348,17 +356,18 @@ file_read_callback (GObject      *object,
 
     if (error != NULL)
     {
-        char *uri = g_file_get_uri (G_FILE (object));
+        g_autofree char *uri = NULL;
+
+        uri = g_file_get_uri (G_FILE (object));
+
         g_warning ("Error reading %s: %s", uri, error->message);
-        g_free (uri);
-        g_clear_error (&error);
     }
 
     if (done_reading)
     {
         load_finished (page);
         g_input_stream_close_async (stream,
-                                    0,
+                                    G_PRIORITY_DEFAULT,
                                     page->cancellable,
                                     file_close_callback,
                                     page);
@@ -371,9 +380,9 @@ size_prepared_callback (GdkPixbufLoader *loader,
                         int              height,
                         gpointer         callback_data)
 {
-    NautilusImagePropertiesPage *page;
+    NautilusImagesPropertiesPage *page;
 
-    page = NAUTILUS_IMAGE_PROPERTIES_PAGE (callback_data);
+    page = callback_data;
 
     page->height = height;
     page->width = width;
@@ -383,8 +392,8 @@ size_prepared_callback (GdkPixbufLoader *loader,
 
 typedef struct
 {
-    NautilusImagePropertiesPage *page;
-    NautilusFileInfo *info;
+    NautilusImagesPropertiesPage *page;
+    NautilusFileInfo *file_info;
 } FileOpenData;
 
 static void
@@ -392,33 +401,32 @@ file_open_callback (GObject      *object,
                     GAsyncResult *res,
                     gpointer      user_data)
 {
-    FileOpenData *data = user_data;
-    NautilusImagePropertiesPage *page = data->page;
+    g_autofree FileOpenData *data = NULL;
+    NautilusImagesPropertiesPage *page;
     GFile *file;
-    GFileInputStream *stream;
-    GError *error;
-    char *uri;
+    g_autofree char *uri = NULL;
+    g_autoptr (GError) error = NULL;
+    g_autoptr (GFileInputStream) stream = NULL;
 
+    data = user_data;
+    page = data->page;
     file = G_FILE (object);
     uri = g_file_get_uri (file);
-
-    error = NULL;
     stream = g_file_read_finish (file, res, &error);
-    if (stream)
+    if (stream != NULL)
     {
-        char *mime_type;
+        g_autofree char *mime_type = NULL;
+
+        mime_type = nautilus_file_info_get_mime_type (data->file_info);
 
-        mime_type = nautilus_file_info_get_mime_type (data->info);
         page->loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, &error);
         if (error != NULL)
         {
             g_warning ("Error creating loader for %s: %s", uri, error->message);
-            g_clear_error (&error);
         }
         page->pixbuf_still_loading = TRUE;
         page->width = 0;
         page->height = 0;
-        g_free (mime_type);
 
         g_signal_connect (page->loader,
                           "size-prepared",
@@ -428,211 +436,80 @@ file_open_callback (GObject      *object,
         g_input_stream_read_async (G_INPUT_STREAM (stream),
                                    page->buffer,
                                    sizeof (page->buffer),
-                                   0,
+                                   G_PRIORITY_DEFAULT,
                                    page->cancellable,
                                    file_read_callback,
                                    page);
-
-        g_object_unref (stream);
     }
     else
     {
         g_warning ("Error reading %s: %s", uri, error->message);
-        g_clear_error (&error);
         load_finished (page);
     }
-
-    g_free (uri);
-    g_free (data);
 }
 
-static void
-load_location (NautilusImagePropertiesPage *page,
-               NautilusFileInfo            *info)
+void
+nautilus_image_properties_page_load_from_file_info (NautilusImagesPropertiesPage *self,
+                                                    NautilusFileInfo             *file_info)
 {
-    GFile *file;
-    char *uri;
-    gchar *file_path;
+    g_autofree char *uri = NULL;
+    g_autoptr (GFile) file = NULL;
+    g_autofree char *path = NULL;
     FileOpenData *data;
-    GError *err;
 
-    g_assert (NAUTILUS_IS_IMAGE_PROPERTIES_PAGE (page));
-    g_assert (info != NULL);
+    g_return_if_fail (NAUTILUS_IS_IMAGE_PROPERTIES_PAGE (self));
+    g_return_if_fail (file_info != NULL);
 
-    err = NULL;
-    page->cancellable = g_cancellable_new ();
+    self->cancellable = g_cancellable_new ();
 
-    uri = nautilus_file_info_get_uri (info);
+    uri = nautilus_file_info_get_uri (file_info);
     file = g_file_new_for_uri (uri);
-    file_path = g_file_get_path (file);
+    path = g_file_get_path (file);
 
     /* gexiv2 metadata init */
-    page->md_ready = gexiv2_initialize ();
-    if (!page->md_ready)
-      {
+    self->md_ready = gexiv2_initialize ();
+    if (!self->md_ready)
+    {
         g_warning ("Unable to initialize gexiv2");
-      }
+    }
     else
-      {
-        page->md = gexiv2_metadata_new ();
-        if (file_path)
-          {
-            if (!gexiv2_metadata_open_path (page->md, file_path, &err))
-              {
-                g_warning ("gexiv2 metadata not supported for '%s': %s", file_path, err->message);
-                g_clear_error (&err);
-                page->md_ready = FALSE;
-              }
-          }
-        else
-          {
-            page->md_ready = FALSE;
-          }
-      }
-
-    data = g_new0 (FileOpenData, 1);
-    data->page = page;
-    data->info = info;
-
-    g_file_read_async (file,
-                       0,
-                       page->cancellable,
-                       file_open_callback,
-                       data);
-
-    g_object_unref (file);
-    g_free (uri);
-    g_free (file_path);
-}
-
-static void
-nautilus_image_properties_page_class_init (NautilusImagePropertiesPageClass *class)
-{
-    GObjectClass *object_class;
-
-    object_class = G_OBJECT_CLASS (class);
-
-    object_class->finalize = nautilus_image_properties_page_finalize;
-}
-
-static void
-nautilus_image_properties_page_init (NautilusImagePropertiesPage *page)
-{
-    GtkWidget *sw;
-
-    gtk_orientable_set_orientation (GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
-    gtk_box_set_homogeneous (GTK_BOX (page), FALSE);
-    gtk_box_set_spacing (GTK_BOX (page), 0);
-    gtk_container_set_border_width (GTK_CONTAINER (page), 0);
-
-    sw = gtk_scrolled_window_new (NULL, NULL);
-    gtk_container_set_border_width (GTK_CONTAINER (sw), 0);
-    gtk_widget_set_vexpand (GTK_WIDGET (sw), TRUE);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
-                                    GTK_POLICY_NEVER,
-                                    GTK_POLICY_AUTOMATIC);
-    gtk_box_pack_start (GTK_BOX (page), sw, FALSE, TRUE, 2);
-
-    page->grid = gtk_grid_new ();
-    gtk_container_set_border_width (GTK_CONTAINER (page->grid), 6);
-    gtk_orientable_set_orientation (GTK_ORIENTABLE (page->grid), GTK_ORIENTATION_VERTICAL);
-    gtk_grid_set_row_spacing (GTK_GRID (page->grid), 6);
-    gtk_grid_set_column_spacing (GTK_GRID (page->grid), 20);
-    append_item (page, _("Loading…"), NULL);
-    gtk_container_add (GTK_CONTAINER (sw), page->grid);
-
-    gtk_widget_show_all (GTK_WIDGET (page));
-}
-
-static gboolean
-is_mime_type_supported (const char *mime_type)
-{
-    gboolean supported;
-    GSList *formats;
-    GSList *l;
-
-    supported = FALSE;
-    formats = gdk_pixbuf_get_formats ();
-
-    for (l = formats; supported == FALSE && l != NULL; l = l->next)
     {
-        GdkPixbufFormat *format = l->data;
-        char **mime_types = gdk_pixbuf_format_get_mime_types (format);
-        int i;
-
-        for (i = 0; mime_types[i] != NULL; i++)
+        self->md = gexiv2_metadata_new ();
+        if (path != NULL)
         {
-            if (strcmp (mime_types[i], mime_type) == 0)
+            g_autoptr (GError) error = NULL;
+
+            if (!gexiv2_metadata_open_path (self->md, path, &error))
             {
-                supported = TRUE;
-                break;
+                g_warning ("gexiv2 metadata not supported for '%s': %s", path, error->message);
+                self->md_ready = FALSE;
             }
         }
-        g_strfreev (mime_types);
-    }
-    g_slist_free (formats);
-
-    return supported;
-}
-
-static GList *
-get_property_pages (NautilusPropertyPageProvider *provider,
-                    GList                        *files)
-{
-    GList *pages;
-    NautilusFileInfo *file;
-    char *mime_type;
-
-    /* Only show the property page if 1 file is selected */
-    if (!files || files->next != NULL)
-    {
-        return NULL;
-    }
-
-    pages = NULL;
-    file = NAUTILUS_FILE_INFO (files->data);
-
-    mime_type = nautilus_file_info_get_mime_type (file);
-    if (mime_type != NULL
-        && is_mime_type_supported (mime_type))
-    {
-        NautilusImagePropertiesPage *page;
-        NautilusPropertyPage *real_page;
-
-        page = g_object_new (nautilus_image_properties_page_get_type (), NULL);
-        load_location (page, file);
-
-        real_page = nautilus_property_page_new
-                        ("NautilusImagePropertiesPage::property_page",
-                        gtk_label_new (_("Image")),
-                        GTK_WIDGET (page));
-        pages = g_list_append (pages, real_page);
+        else
+        {
+            self->md_ready = FALSE;
+        }
     }
 
-    g_free (mime_type);
-
-    return pages;
-}
-
-static void
-property_page_provider_iface_init (NautilusPropertyPageProviderIface *iface)
-{
-    iface->get_pages = get_property_pages;
-}
-
+    data = g_new0 (FileOpenData, 1);
 
-static void
-nautilus_image_properties_page_provider_init (NautilusImagePropertiesPageProvider *sidebar)
-{
-}
+    data->page = self;
+    data->file_info = file_info;
 
-static void
-nautilus_image_properties_page_provider_class_init (NautilusImagePropertiesPageProviderClass *class)
-{
+    g_file_read_async (file,
+                       G_PRIORITY_DEFAULT,
+                       self->cancellable,
+                       file_open_callback,
+                       data);
 }
 
-void
-nautilus_image_properties_page_register (void)
+NautilusImagesPropertiesPage *
+nautilus_image_properties_page_new (void)
 {
-    nautilus_module_add_type (nautilus_image_properties_page_provider_get_type ());
+    return g_object_new (NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE,
+                         "margin-bottom", 6,
+                         "margin-end", 12,
+                         "margin-start", 12,
+                         "margin-top", 6,
+                         NULL);
 }
diff --git a/src/nautilus-image-properties-page.h 
b/extensions/image-properties/nautilus-image-properties-page.h
similarity index 54%
rename from src/nautilus-image-properties-page.h
rename to extensions/image-properties/nautilus-image-properties-page.h
index 2d651d05c..0b3c5db81 100644
--- a/src/nautilus-image-properties-page.h
+++ b/extensions/image-properties/nautilus-image-properties-page.h
@@ -1,6 +1,4 @@
-
-/* 
- * Copyright (C) 2004 Red Hat, Inc
+/* Copyright (C) 2004 Red Hat, Inc
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -23,10 +21,18 @@
 
 #include <gtk/gtk.h>
 
-#define NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE nautilus_image_properties_page_get_type()
-G_DECLARE_FINAL_TYPE (NautilusImagePropertiesPage, nautilus_image_properties_page, NAUTILUS, 
IMAGE_PROPERTIES_PAGE, GtkBox)
+#include <nautilus-extension.h>
+
+#define NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE (nautilus_image_properties_page_get_type ())
+
+G_DECLARE_FINAL_TYPE (NautilusImagesPropertiesPage,
+                      nautilus_image_properties_page,
+                      NAUTILUS, IMAGE_PROPERTIES_PAGE,
+                      GtkGrid)
 
+void                          nautilus_image_properties_page_load_from_file_info 
(NautilusImagesPropertiesPage *page,
+                                                                                  NautilusFileInfo           
  *file_info);
 
-void  nautilus_image_properties_page_register (void);
+NautilusImagesPropertiesPage *nautilus_image_properties_page_new                 (void);
 
-#endif /* NAUTILUS_IMAGE_PROPERTIES_PAGE_H */
+#endif
diff --git a/extensions/meson.build b/extensions/meson.build
new file mode 100644
index 000000000..f5057cf87
--- /dev/null
+++ b/extensions/meson.build
@@ -0,0 +1 @@
+subdir('image-properties')
diff --git a/meson.build b/meson.build
index 33b37dc9c..37fde5ed9 100644
--- a/meson.build
+++ b/meson.build
@@ -84,7 +84,10 @@ endif
 configure_file(output: 'config.h', configuration: conf)
 #
 
-nautilus_include_dirs = include_directories('.')
+nautilus_include_dirs = include_directories(
+  '.',
+  'libnautilus-extension'
+)
 
 subdir('eel')
 subdir('libnautilus-extension')
@@ -96,6 +99,7 @@ subdir('po')
 if get_option('docs')
   subdir('docs')
 endif
+subdir('extensions')
 if get_option('nst_extension')
   subdir('nautilus-sendto-extension')
 endif
diff --git a/src/meson.build b/src/meson.build
index 8db1367a7..c3e4b9999 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -81,8 +81,6 @@ libnautilus_sources = [
   'nautilus-floating-bar.h',
   'nautilus-freedesktop-dbus.c',
   'nautilus-freedesktop-dbus.h',
-  'nautilus-image-properties-page.c',
-  'nautilus-image-properties-page.h',
   'nautilus-list-model.c',
   'nautilus-list-model.h',
   'nautilus-list-view.c',
@@ -269,7 +267,6 @@ libnautilus_sources = [
 
 nautilus_deps = [
   eel_2,
-  gexiv,
   gmodule,
   gnome_autoar,
   gnome_desktop,
diff --git a/src/nautilus-application.c b/src/nautilus-application.c
index a73b77363..ea15a8ae0 100644
--- a/src/nautilus-application.c
+++ b/src/nautilus-application.c
@@ -31,7 +31,6 @@
 #include "nautilus-dbus-manager.h"
 #include "nautilus-file-undo-manager.h"
 #include "nautilus-freedesktop-dbus.h"
-#include "nautilus-image-properties-page.h"
 #include "nautilus-previewer.h"
 #include "nautilus-progress-persistence-handler.h"
 #include "nautilus-self-check-functions.h"
@@ -1262,9 +1261,6 @@ nautilus_application_startup_common (NautilusApplication *self)
     /* initialize preferences and create the global GSettings objects */
     nautilus_global_preferences_init ();
 
-    /* register property pages */
-    nautilus_image_properties_page_register ();
-
     /* initialize nautilus modules */
     nautilus_profile_start ("Modules");
     nautilus_module_setup ();


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