[epiphany/overview: 5/26] EphyOverviewStore: add ephy_overview_store_peek_snapshot()



commit 14adfe168b0d67a9d41809347c52b41630a959ac
Author: Claudio Saavedra <csaavedra igalia com>
Date:   Thu Feb 23 10:48:37 2012 +0200

    EphyOverviewStore: add ephy_overview_store_peek_snapshot()
    
    This method takes care of loading a snapshot from the service,
    asking for a new version when needed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=455173

 lib/widgets/ephy-overview-store.c |  174 +++++++++++++++++++++++++++++++++++++
 lib/widgets/ephy-overview-store.h |    4 +
 2 files changed, 178 insertions(+), 0 deletions(-)
---
diff --git a/lib/widgets/ephy-overview-store.c b/lib/widgets/ephy-overview-store.c
index cf55905..970bca1 100644
--- a/lib/widgets/ephy-overview-store.c
+++ b/lib/widgets/ephy-overview-store.c
@@ -19,13 +19,81 @@
  */
 
 #include "config.h"
+#include "ephy-history-service.h"
 #include "ephy-overview-store.h"
+#include "ephy-snapshot-service.h"
+
+#define EPHY_OVERVIEW_STORE_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_OVERVIEW_STORE, EphyOverviewStorePrivate))
+
+struct _EphyOverviewStorePrivate
+{
+  EphyHistoryService *history_service;
+};
+
+enum
+{
+  PROP_0,
+  PROP_HISTORY_SERVICE,
+};
 
 G_DEFINE_TYPE (EphyOverviewStore, ephy_overview_store, GTK_TYPE_LIST_STORE)
 
 static void
+ephy_overview_store_set_property (GObject *object,
+                                  guint prop_id,
+                                  const GValue *value,
+                                  GParamSpec *pspec)
+{
+  EphyOverviewStore *store = EPHY_OVERVIEW_STORE (object);
+
+  switch (prop_id)
+  {
+  case PROP_HISTORY_SERVICE:
+    store->priv->history_service = g_value_get_object (value);
+    g_object_notify (object, "history-service");
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+ephy_overview_store_get_property (GObject *object,
+                                  guint prop_id,
+                                  GValue *value,
+                                  GParamSpec *pspec)
+{
+  EphyOverviewStore *store = EPHY_OVERVIEW_STORE (object);
+
+  switch (prop_id)
+  {
+  case PROP_HISTORY_SERVICE:
+    g_value_set_object (value, store->priv->history_service);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
 ephy_overview_store_class_init (EphyOverviewStoreClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->set_property = ephy_overview_store_set_property;
+  object_class->get_property = ephy_overview_store_get_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_HISTORY_SERVICE,
+                                   g_param_spec_object ("history-service",
+                                                        "History service",
+                                                        "History Service",
+                                                        EPHY_TYPE_HISTORY_SERVICE,
+                                                        G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+
+  g_type_class_add_private (object_class, sizeof(EphyOverviewStorePrivate));
 }
 
 static void
@@ -43,4 +111,110 @@ ephy_overview_store_init (EphyOverviewStore *self)
 
   gtk_list_store_set_column_types (GTK_LIST_STORE (self),
                                    EPHY_OVERVIEW_STORE_NCOLS, types);
+
+  self->priv = EPHY_OVERVIEW_STORE_GET_PRIVATE (self);
+}
+
+typedef struct {
+  GtkTreeRowReference *ref;
+  char *url;
+} PeekContext;
+
+static void
+peek_context_free (PeekContext *ctx)
+{
+  g_free (ctx->url);
+  gtk_tree_row_reference_free (ctx->ref);
+
+  g_slice_free (PeekContext, ctx);
+}
+
+static void
+on_snapshot_retrieved_cb (GObject *object,
+                          GAsyncResult *res,
+                          PeekContext *ctx)
+{
+  GtkTreeModel *model;
+  GtkTreePath *path;
+  GtkTreeIter iter;
+  char *url;
+  GdkPixbuf *snapshot;
+  GError *error = NULL;
+
+  snapshot = ephy_snapshot_service_get_snapshot_finish (EPHY_SNAPSHOT_SERVICE (object),
+                                                        res, &error);
+
+  if (error) {
+    g_warning ("Error retrieving snapshot: %s\n", error->message);
+    g_error_free (error);
+    error = NULL;
+  } else if (gtk_tree_row_reference_valid (ctx->ref)) {
+    model = gtk_tree_row_reference_get_model (ctx->ref);
+    path = gtk_tree_row_reference_get_path (ctx->ref);
+    gtk_tree_model_get_iter (model, &iter, path);
+    gtk_tree_path_free (path);
+
+    /* Chances are that this callback is called after the URL in this
+       row has already replaced with a new one.  Make sure that this
+       is not the case. */
+    gtk_tree_model_get (model, &iter, EPHY_OVERVIEW_STORE_URI, &url, -1);
+    if (g_strcmp0 (url, ctx->url) == 0)
+      gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+                          EPHY_OVERVIEW_STORE_SNAPSHOT, snapshot,
+                          -1);
+
+    g_free (url);
+    g_object_unref (snapshot);
+  }
+  peek_context_free (ctx);
+}
+
+static void
+history_service_url_cb (gpointer service,
+                        gboolean success,
+                        EphyHistoryURL *url,
+                        PeekContext *ctx)
+{
+  EphySnapshotService *snapshot_service;
+  int timestamp;
+
+  snapshot_service = ephy_snapshot_service_get_default ();
+
+  /* This is a bit of an abuse of the semantics of the mtime
+   paramenter. Since the thumbnailing backend only takes the exact
+   mtime of the thumbnailed file, we will use the visit count to
+   generate a fake timestamp that will be increased every fifth
+   visit. This way, we'll update the thumbnail every other fifth
+   visit. */
+  timestamp = success ? (url->visit_count / 5) : 0;
+
+  ephy_snapshot_service_get_snapshot_async (snapshot_service, ctx->url, timestamp, NULL,
+                                            (GAsyncReadyCallback) on_snapshot_retrieved_cb,
+                                            ctx);
+  ephy_history_url_free (url);
+}
+
+void
+ephy_overview_store_peek_snapshot (EphyOverviewStore *self,
+                                   GtkTreeIter *iter)
+{
+  char *url;
+  GtkTreePath *path;
+  PeekContext *ctx;
+
+  gtk_tree_model_get (GTK_TREE_MODEL (self), iter,
+                      EPHY_OVERVIEW_STORE_URI, &url,
+                      -1);
+
+  if (url == NULL)
+    return;
+
+  ctx = g_slice_new (PeekContext);
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (self), iter);
+  ctx->ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (self), path);
+  ctx->url = url;
+  ephy_history_service_get_url (self->priv->history_service,
+                                url, NULL, (EphyHistoryJobCallback)history_service_url_cb,
+                                ctx);
+  gtk_tree_path_free (path);
 }
diff --git a/lib/widgets/ephy-overview-store.h b/lib/widgets/ephy-overview-store.h
index 34d22ce..e951722 100644
--- a/lib/widgets/ephy-overview-store.h
+++ b/lib/widgets/ephy-overview-store.h
@@ -41,6 +41,8 @@ typedef struct _EphyOverviewStorePrivate EphyOverviewStorePrivate;
 struct _EphyOverviewStore
 {
   GtkListStore parent;
+
+  EphyOverviewStorePrivate *priv;
 };
 
 struct _EphyOverviewStoreClass
@@ -61,6 +63,8 @@ enum {
 
 GType ephy_overview_store_get_type (void) G_GNUC_CONST;
 
+void ephy_overview_store_peek_snapshot (EphyOverviewStore *self,
+                                        GtkTreeIter *iter);
 G_END_DECLS
 
 #endif /* _EPHY_OVERVIEW_STORE_H */



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