[gnome-flashback] desktop: add GfThumbnailFactory



commit 5076e2ef2a2c0b18506584d4166607c31e3ea508
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Mon Nov 18 02:37:48 2019 +0200

    desktop: add GfThumbnailFactory

 gnome-flashback/libdesktop/Makefile.am            |   2 +
 gnome-flashback/libdesktop/gf-icon-view.c         |  60 +++---
 gnome-flashback/libdesktop/gf-icon-view.h         |  35 ++--
 gnome-flashback/libdesktop/gf-thumbnail-factory.c | 217 ++++++++++++++++++++++
 gnome-flashback/libdesktop/gf-thumbnail-factory.h |  55 ++++++
 5 files changed, 329 insertions(+), 40 deletions(-)
---
diff --git a/gnome-flashback/libdesktop/Makefile.am b/gnome-flashback/libdesktop/Makefile.am
index 8667d0f..224f911 100644
--- a/gnome-flashback/libdesktop/Makefile.am
+++ b/gnome-flashback/libdesktop/Makefile.am
@@ -39,6 +39,8 @@ libdesktop_la_SOURCES = \
        gf-monitor-view.h \
        gf-rename-popover.c \
        gf-rename-popover.h \
+       gf-thumbnail-factory.c \
+       gf-thumbnail-factory.h \
        gf-utils.c \
        gf-utils.h \
        $(BUILT_SOURCES) \
diff --git a/gnome-flashback/libdesktop/gf-icon-view.c b/gnome-flashback/libdesktop/gf-icon-view.c
index c0937cd..814a42b 100644
--- a/gnome-flashback/libdesktop/gf-icon-view.c
+++ b/gnome-flashback/libdesktop/gf-icon-view.c
@@ -42,44 +42,46 @@ typedef struct
 
 struct _GfIconView
 {
-  GtkEventBox       parent;
+  GtkEventBox         parent;
 
-  GtkGesture       *multi_press;
-  GtkGesture       *drag;
+  GfThumbnailFactory *thumbnail_factory;
 
-  GFile            *desktop;
-  GFileMonitor     *monitor;
+  GtkGesture         *multi_press;
+  GtkGesture         *drag;
 
-  GSettings        *settings;
+  GFile              *desktop;
+  GFileMonitor       *monitor;
 
-  GfPlacement       placement;
-  GfSortBy          sort_by;
+  GSettings          *settings;
 
-  GtkWidget        *fixed;
+  GfPlacement         placement;
+  GfSortBy            sort_by;
 
-  GtkWidget        *dummy_icon;
+  GtkWidget          *fixed;
 
-  GCancellable     *cancellable;
+  GtkWidget          *dummy_icon;
 
-  GList            *icons;
+  GCancellable       *cancellable;
 
-  GfIconInfo       *home_info;
-  GfIconInfo       *trash_info;
+  GList              *icons;
 
-  GList            *selected_icons;
+  GfIconInfo         *home_info;
+  GfIconInfo         *trash_info;
 
-  GtkCssProvider   *rubberband_css;
-  GtkStyleContext  *rubberband_style;
-  GdkRectangle      rubberband_rect;
-  GList            *rubberband_icons;
+  GList              *selected_icons;
 
-  GfNautilusGen    *nautilus;
-  GfFileManagerGen *file_manager;
+  GtkCssProvider     *rubberband_css;
+  GtkStyleContext    *rubberband_style;
+  GdkRectangle        rubberband_rect;
+  GList              *rubberband_icons;
+
+  GfNautilusGen      *nautilus;
+  GfFileManagerGen   *file_manager;
 
-  GtkWidget        *create_folder_dialog;
+  GtkWidget          *create_folder_dialog;
 
-  GfIcon           *last_selected_icon;
-  GfIcon           *extend_from_icon;
+  GfIcon             *last_selected_icon;
+  GfIcon             *extend_from_icon;
 };
 
 enum
@@ -2279,6 +2281,8 @@ gf_icon_view_dispose (GObject *object)
 
   self = GF_ICON_VIEW (object);
 
+  g_clear_object (&self->thumbnail_factory);
+
   g_clear_object (&self->multi_press);
   g_clear_object (&self->drag);
 
@@ -2570,6 +2574,8 @@ gf_icon_view_init (GfIconView *self)
 
   add_event_filter (self);
 
+  self->thumbnail_factory = gf_thumbnail_factory_new ();
+
   self->multi_press = gtk_gesture_multi_press_new (GTK_WIDGET (self));
   self->drag = gtk_gesture_drag_new (GTK_WIDGET (self));
 
@@ -2689,6 +2695,12 @@ gf_icon_view_new (void)
                        NULL);
 }
 
+GfThumbnailFactory *
+gf_icon_view_get_thumbnail_factory (GfIconView *self)
+{
+  return self->thumbnail_factory;
+}
+
 char *
 gf_icon_view_get_file_attributes (GfIconView *self)
 {
diff --git a/gnome-flashback/libdesktop/gf-icon-view.h b/gnome-flashback/libdesktop/gf-icon-view.h
index b75bd9d..3f9f003 100644
--- a/gnome-flashback/libdesktop/gf-icon-view.h
+++ b/gnome-flashback/libdesktop/gf-icon-view.h
@@ -19,36 +19,39 @@
 #define GF_ICON_VIEW_H
 
 #include <gtk/gtk.h>
+#include "gf-thumbnail-factory.h"
 
 G_BEGIN_DECLS
 
 #define GF_TYPE_ICON_VIEW (gf_icon_view_get_type ())
 G_DECLARE_FINAL_TYPE (GfIconView, gf_icon_view, GF, ICON_VIEW, GtkEventBox)
 
-GtkWidget *gf_icon_view_new                      (void);
+GtkWidget          *gf_icon_view_new                      (void);
 
-char      *gf_icon_view_get_file_attributes      (GfIconView          *self);
+GfThumbnailFactory *gf_icon_view_get_thumbnail_factory    (GfIconView          *self);
 
-void       gf_icon_view_set_representative_color (GfIconView          *self,
-                                                  GdkRGBA             *color);
+char               *gf_icon_view_get_file_attributes      (GfIconView          *self);
 
-void       gf_icon_view_clear_selection          (GfIconView          *self);
+void                gf_icon_view_set_representative_color (GfIconView          *self,
+                                                           GdkRGBA             *color);
 
-GList     *gf_icon_view_get_selected_icons       (GfIconView          *self);
+void                gf_icon_view_clear_selection          (GfIconView          *self);
 
-void       gf_icon_view_show_item_properties     (GfIconView          *self,
-                                                  const char * const  *uris);
+GList              *gf_icon_view_get_selected_icons       (GfIconView          *self);
 
-void       gf_icon_view_empty_trash              (GfIconView          *self);
+void                gf_icon_view_show_item_properties     (GfIconView          *self,
+                                                           const char * const  *uris);
 
-gboolean   gf_icon_view_validate_new_name        (GfIconView          *self,
-                                                  GFileType            file_type,
-                                                  const char          *new_name,
-                                                  char               **message);
+void                gf_icon_view_empty_trash              (GfIconView          *self);
 
-void       gf_icon_view_rename_file              (GfIconView          *self,
-                                                  const char          *uri,
-                                                  const char          *new_name);
+gboolean            gf_icon_view_validate_new_name        (GfIconView          *self,
+                                                           GFileType            file_type,
+                                                           const char          *new_name,
+                                                           char               **message);
+
+void                gf_icon_view_rename_file              (GfIconView          *self,
+                                                           const char          *uri,
+                                                           const char          *new_name);
 
 G_END_DECLS
 
diff --git a/gnome-flashback/libdesktop/gf-thumbnail-factory.c 
b/gnome-flashback/libdesktop/gf-thumbnail-factory.c
new file mode 100644
index 0000000..df3246b
--- /dev/null
+++ b/gnome-flashback/libdesktop/gf-thumbnail-factory.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2019 Alberts Muktupāvels
+ *
+ * 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 3 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/>.
+ */
+
+#include "config.h"
+#include "gf-thumbnail-factory.h"
+
+#include <libgnome-desktop/gnome-desktop-thumbnail.h>
+
+typedef struct
+{
+  GfThumbnailFactory *self;
+
+  char               *uri;
+  char               *content_type;
+  guint64             time_modified;
+} GfLoadData;
+
+struct _GfThumbnailFactory
+{
+  GObject                       parent;
+
+  GnomeDesktopThumbnailFactory *factory;
+};
+
+G_DEFINE_QUARK (gf-thumbnail-error-quark, gf_thumbnail_error)
+
+G_DEFINE_TYPE (GfThumbnailFactory, gf_thumbnail_factory, G_TYPE_OBJECT)
+
+static GfLoadData *
+gf_load_data_new (GfThumbnailFactory *self,
+                  const char         *uri,
+                  const char         *content_type,
+                  guint64             time_modified)
+{
+  GfLoadData *data;
+
+  data = g_new0 (GfLoadData, 1);
+  data->self = g_object_ref (self);
+
+  data->uri = g_strdup (uri);
+  data->content_type = g_strdup (content_type);
+  data->time_modified = time_modified;
+
+  return data;
+}
+
+static void
+gf_load_data_free (gpointer data)
+{
+  GfLoadData *load_data;
+
+  load_data = data;
+
+  g_object_unref (load_data->self);
+  g_free (load_data->uri);
+  g_free (load_data->content_type);
+  g_free (load_data);
+}
+
+static void
+load_icon_in_thread (GTask        *task,
+                     gpointer      source_object,
+                     gpointer      task_data,
+                     GCancellable *cancellable)
+{
+  GfLoadData *data;
+  char *path;
+  GdkPixbuf *pixbuf;
+
+  data = g_task_get_task_data (task);
+
+  if (!gnome_desktop_thumbnail_factory_can_thumbnail (data->self->factory,
+                                                      data->uri,
+                                                      data->content_type,
+                                                      data->time_modified))
+    {
+      g_task_return_new_error (task,
+                               GF_THUMBNAIL_ERROR,
+                               GF_THUMBNAIL_ERROR_CAN_NOT_THUMBNAIL,
+                               "Can not thumbnail this file");
+      return;
+    }
+
+  path = gnome_desktop_thumbnail_factory_lookup (data->self->factory,
+                                                 data->uri,
+                                                 data->time_modified);
+
+  if (path != NULL)
+    {
+      GFile *file;
+
+      file = g_file_new_for_path (path);
+      g_free (path);
+
+      g_task_return_pointer (task, g_file_icon_new (file), g_object_unref);
+      g_object_unref (file);
+      return;
+    }
+
+  if (gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (data->self->factory,
+                                                                  data->uri,
+                                                                  data->time_modified))
+    {
+      g_task_return_new_error (task,
+                               GF_THUMBNAIL_ERROR,
+                               GF_THUMBNAIL_ERROR_HAS_FAILED_THUMBNAIL,
+                               "File has valid failed thumbnail");
+      return;
+    }
+
+  pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (data->self->factory,
+                                                               data->uri,
+                                                               data->content_type);
+
+  if (pixbuf != NULL)
+    {
+      gnome_desktop_thumbnail_factory_save_thumbnail (data->self->factory,
+                                                      pixbuf,
+                                                      data->uri,
+                                                      data->time_modified);
+
+      g_task_return_pointer (task, pixbuf, g_object_unref);
+      return;
+    }
+
+  gnome_desktop_thumbnail_factory_create_failed_thumbnail (data->self->factory,
+                                                           data->uri,
+                                                           data->time_modified);
+
+  g_task_return_new_error (task,
+                           GF_THUMBNAIL_ERROR,
+                           GF_THUMBNAIL_ERROR_GENERATION_FAILED,
+                           "Thumbnail generation failed");
+}
+
+static void
+gf_thumbnail_factory_dispose (GObject *object)
+{
+  GfThumbnailFactory *self;
+
+  self = GF_THUMBNAIL_FACTORY (object);
+
+  g_clear_object (&self->factory);
+
+  G_OBJECT_CLASS (gf_thumbnail_factory_parent_class)->dispose (object);
+}
+
+static void
+gf_thumbnail_factory_class_init (GfThumbnailFactoryClass *self_class)
+{
+  GObjectClass *object_class;
+
+  object_class = G_OBJECT_CLASS (self_class);
+
+  object_class->dispose = gf_thumbnail_factory_dispose;
+}
+
+static void
+gf_thumbnail_factory_init (GfThumbnailFactory *self)
+{
+  GnomeDesktopThumbnailSize thumbnail_size;
+
+  thumbnail_size = GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE;
+  self->factory = gnome_desktop_thumbnail_factory_new (thumbnail_size);
+}
+
+GfThumbnailFactory *
+gf_thumbnail_factory_new (void)
+{
+  return g_object_new (GF_TYPE_THUMBNAIL_FACTORY,
+                       NULL);
+}
+
+void
+gf_thumbnail_factory_load_async (GfThumbnailFactory  *self,
+                                 const char          *uri,
+                                 const char          *content_type,
+                                 guint64              time_modified,
+                                 GCancellable        *cancellable,
+                                 GAsyncReadyCallback  callback,
+                                 gpointer             user_data)
+{
+  GTask *task;
+  GfLoadData *data;
+
+  task = g_task_new (self, cancellable, callback, user_data);
+
+  data = gf_load_data_new (self, uri, content_type, time_modified);
+  g_task_set_task_data (task, data, gf_load_data_free);
+
+  g_task_run_in_thread (task, load_icon_in_thread);
+  g_object_unref (task);
+}
+
+GIcon *
+gf_thumbnail_factory_load_finish (GfThumbnailFactory  *self,
+                                  GAsyncResult        *result,
+                                  GError             **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, self), NULL);
+
+  return g_task_propagate_pointer (G_TASK (result), error);
+}
diff --git a/gnome-flashback/libdesktop/gf-thumbnail-factory.h 
b/gnome-flashback/libdesktop/gf-thumbnail-factory.h
new file mode 100644
index 0000000..18f76c3
--- /dev/null
+++ b/gnome-flashback/libdesktop/gf-thumbnail-factory.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Alberts Muktupāvels
+ *
+ * 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 3 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/>.
+ */
+
+#ifndef GF_THUMBNAIL_FACTORY_H
+#define GF_THUMBNAIL_FACTORY_H
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+  GF_THUMBNAIL_ERROR_CAN_NOT_THUMBNAIL,
+  GF_THUMBNAIL_ERROR_HAS_FAILED_THUMBNAIL,
+  GF_THUMBNAIL_ERROR_GENERATION_FAILED
+} GfThumbnailError;
+
+#define GF_THUMBNAIL_ERROR (gf_thumbnail_error_quark ())
+GQuark gf_thumbnail_error_quark (void);
+
+#define GF_TYPE_THUMBNAIL_FACTORY (gf_thumbnail_factory_get_type ())
+G_DECLARE_FINAL_TYPE (GfThumbnailFactory, gf_thumbnail_factory,
+                      GF, THUMBNAIL_FACTORY, GObject)
+
+GfThumbnailFactory *gf_thumbnail_factory_new         (void);
+
+void                gf_thumbnail_factory_load_async  (GfThumbnailFactory   *self,
+                                                      const char           *uri,
+                                                      const char           *content_type,
+                                                      guint64               time_modified,
+                                                      GCancellable         *cancellable,
+                                                      GAsyncReadyCallback   callback,
+                                                      gpointer              user_data);
+
+GIcon              *gf_thumbnail_factory_load_finish (GfThumbnailFactory   *self,
+                                                      GAsyncResult         *result,
+                                                      GError              **error);
+
+G_END_DECLS
+
+#endif


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