[gtk+/filesystemmodel: 21/28] add code for loading thumbnails



commit b92791023f00bf185a4c8c6480fce2627ea81bd2
Author: Benjamin Otte <otte gnome org>
Date:   Mon Jun 22 17:53:43 2009 +0200

    add code for loading thumbnails

 gtk/gtkfilechooserdefault.c |   60 +++++++++++++++++++++++++++-
 gtk/gtkfilesystemmodel.c    |   93 +++++++++++++++++++++++++++++++++++++------
 gtk/gtkfilesystemmodel.h    |    8 +++-
 3 files changed, 146 insertions(+), 15 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 70e7234..33424b1 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -6707,6 +6707,42 @@ my_g_format_time_for_display (glong secs)
   return date_str;
 }
 
+#define copy_attribute(to, from, attribute) G_STMT_START { \
+  GFileAttributeType type; \
+  gpointer value; \
+\
+  if (g_file_info_get_attribute_data (from, attribute, &type, &value, NULL)) \
+    g_file_info_set_attribute (to, attribute, type, value); \
+}G_STMT_END
+
+static void
+file_system_model_got_thumbnail (GObject *file, GAsyncResult *res, gpointer data)
+{
+  GtkFileSystemModel *model = data; /* might be unreffed if operation was cancelled */
+  GFileInfo *queried, *info;
+  GtkTreeIter iter;
+
+  queried = g_file_query_info_finish (G_FILE (file), res, NULL);
+  if (queried == NULL)
+    return;
+
+  /* now we know model is valid */
+
+  /* file was deleted */
+  if (!_gtk_file_system_model_get_iter_for_file (model, &iter, G_FILE (file)))
+    return;
+
+  info = g_file_info_dup (_gtk_file_system_model_get_info (model, &iter));
+
+  copy_attribute (info, queried, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
+  copy_attribute (info, queried, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED);
+  copy_attribute (info, queried, G_FILE_ATTRIBUTE_STANDARD_ICON);
+
+  _gtk_file_system_update_file (model, G_FILE (file), info, FALSE);
+
+  g_object_unref (info);
+}
+
 static void
 file_system_model_set (GtkFileSystemModel *model,
 		       GFile              *file,
@@ -6738,8 +6774,28 @@ file_system_model_set (GtkFileSystemModel *model,
       g_value_set_boolean (value, info == NULL || _gtk_file_info_consider_as_directory (info));
       break;
     case MODEL_COL_PIXBUF:
-      if (info && FALSE)
-        g_value_take_object (value, _gtk_file_info_render_icon (info, GTK_WIDGET (impl), impl->icon_size));
+      if (info)
+        {
+          if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH) ||
+              g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED) ||
+              g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_ICON))
+            {
+              g_value_take_object (value, _gtk_file_info_render_icon (info, GTK_WIDGET (impl), impl->icon_size));
+            }
+          else
+            {
+              g_value_set_object (value, NULL);
+              g_file_query_info_async (file,
+                                       G_FILE_ATTRIBUTE_THUMBNAIL_PATH ","
+                                       G_FILE_ATTRIBUTE_THUMBNAILING_FAILED ","
+                                       G_FILE_ATTRIBUTE_STANDARD_ICON,
+                                       0,
+                                       G_PRIORITY_DEFAULT,
+                                       _gtk_file_system_model_get_cancellable (model),
+                                       file_system_model_got_thumbnail,
+                                       model);
+            }
+        }
       else
         g_value_set_object (value, NULL);
       break;
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index e358a4a..abcffcf 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -1147,6 +1147,14 @@ _gtk_file_system_model_set_show_files (GtkFileSystemModel *model,
     }
 }
 
+GCancellable *
+_gtk_file_system_model_get_cancellable (GtkFileSystemModel *model)
+{
+  g_return_val_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model), NULL);
+
+  return model->cancellable;
+}
+
 /**
  * _gtk_file_system_model_get_info:
  * @model: a #GtkFileSystemModel
@@ -1244,6 +1252,24 @@ _gtk_file_system_model_get_value (GtkFileSystemModel *model,
   return &node->values[column];
 }
 
+static guint
+node_get_for_file (GtkFileSystemModel *model,
+                   GFile *             file)
+{
+  guint i;
+
+  /* node 0 is the editable row and has no associated file */
+  for (i = 1; i < model->files->len; i++)
+    {
+      FileModelNode *node = get_node (model, i);
+
+      if (g_file_equal (node->file, file))
+        return i;
+    }
+
+  return 0;
+}
+
 gboolean
 _gtk_file_system_model_get_iter_for_file (GtkFileSystemModel *model,
 					  GtkTreeIter        *iter,
@@ -1255,22 +1281,65 @@ _gtk_file_system_model_get_iter_for_file (GtkFileSystemModel *model,
   g_return_val_if_fail (iter != NULL, FALSE);
   g_return_val_if_fail (G_IS_FILE (file), FALSE);
 
-  /* node 0 is the editable row and has no associated file */
-  for (i = 1; i < model->files->len; i++)
-    {
-      FileModelNode *node = get_node (model, i);
+  i = node_get_for_file (model, file);
 
-      if (!node->visible)
-        continue;
+  if (i == 0)
+    return FALSE;
 
-      if (g_file_equal (node->file, file))
-        {
-          ITER_INIT_FROM_INDEX (model, iter, i);
-          return TRUE;
-        }
+  ITER_INIT_FROM_INDEX (model, iter, i);
+  return TRUE;
+}
+
+/**
+ * _gtk_file_system_update_file:
+ * @model: the model
+ * @file: the file, which must be part of the model
+ * @info: the new file info
+ * @requires_resort: FIXME: get rid of this argument
+ *
+ * Tells the file system model that the file changed and that the 
+ * new @info should be used for it now. 
+ **/
+void
+_gtk_file_system_update_file (GtkFileSystemModel *model,
+                              GFile              *file,
+                              GFileInfo          *info,
+                              gboolean            requires_resort)
+{
+  FileModelNode *node;
+  guint i, id;
+
+  g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
+  g_return_if_fail (G_IS_FILE (file));
+  g_return_if_fail (G_IS_FILE_INFO (info));
+
+  id = node_get_for_file (model, file);
+  if (id == 0)
+    g_assert_not_reached ();
+
+  node = get_node (model, id);
+  if (node->info)
+    g_object_unref (node->info);
+  node->info = g_object_ref (info);
+  for (i = 0; i < model->n_columns; i++)
+    {
+      if (G_VALUE_TYPE (&node->values[i]))
+        g_value_unset (&node->values[i]);
     }
 
-  return FALSE;
+  if (node->visible)
+    {
+      GtkTreePath *path;
+      GtkTreeIter iter;
+      
+      path = gtk_tree_path_new_from_node (model, id);
+      ITER_INIT_FROM_INDEX (model, &iter, id);
+      gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
+      gtk_tree_path_free (path);
+    }
+
+  if (requires_resort)
+    gtk_file_system_model_sort_node (model, id);
 }
 
 /**
diff --git a/gtk/gtkfilesystemmodel.h b/gtk/gtkfilesystemmodel.h
index fc50721..50a8003 100644
--- a/gtk/gtkfilesystemmodel.h
+++ b/gtk/gtkfilesystemmodel.h
@@ -47,16 +47,22 @@ GtkFileSystemModel *_gtk_file_system_model_new              (GFile *
                                                              gpointer            get_data,
                                                              guint               n_columns,
                                                              ...);
+GCancellable *      _gtk_file_system_model_get_cancellable  (GtkFileSystemModel *model);
 GFileInfo *         _gtk_file_system_model_get_info         (GtkFileSystemModel *model,
 							     GtkTreeIter        *iter);
 gboolean            _gtk_file_system_model_get_iter_for_file(GtkFileSystemModel *model,
 							     GtkTreeIter        *iter,
-							     GFile *             file);
+							     GFile              *file);
 GFile *             _gtk_file_system_model_get_file         (GtkFileSystemModel *model,
 							     GtkTreeIter        *iter);
 const GValue *      _gtk_file_system_model_get_value        (GtkFileSystemModel *model,
                                                              GtkTreeIter *       iter,
                                                              int                 column);
+void                _gtk_file_system_update_file            (GtkFileSystemModel *model,
+                                                             GFile              *file,
+                                                             GFileInfo          *info,
+                                                             gboolean            requires_resort);
+
 void                _gtk_file_system_model_set_show_hidden  (GtkFileSystemModel *model,
 							     gboolean            show_hidden);
 void                _gtk_file_system_model_set_show_folders (GtkFileSystemModel *model,



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