[epiphany-extensions] Add initial version of SoupFly.



commit 0cde8f4711996a50d91ca097e52799f3dab17c9d
Author: Xan Lopez <xan gnome org>
Date:   Thu Jul 2 09:23:43 2009 +0300

    Add initial version of SoupFly.
    
    A simple extension to monitor the SoupSession being used by Epiphany.

 configure.ac                                      |    9 +-
 extensions/soup-fly/Makefile.am                   |   40 +++
 extensions/soup-fly/ephy-soup-fly-extension.c     |  244 +++++++++++++++
 extensions/soup-fly/ephy-soup-fly-extension.h     |   55 ++++
 extensions/soup-fly/extension.c                   |   46 +++
 extensions/soup-fly/soup-fly.c                    |  334 +++++++++++++++++++++
 extensions/soup-fly/soup-fly.ephy-extension.in.in |   11 +
 extensions/soup-fly/soup-fly.h                    |   60 ++++
 8 files changed, 795 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 6370ac4..b02b304 100644
--- a/configure.ac
+++ b/configure.ac
@@ -168,9 +168,9 @@ AM_CONDITIONAL([HAVE_OPENSP],[test "x$enable_opensp" = "xyes"])
 
 AC_MSG_CHECKING([which extensions to build])
 
-ALL_EXTENSIONS="actions adblock auto-reload auto-scroller certificates error-viewer extensions-manager-ui gestures greasemonkey java-console livehttpheaders page-info permissions push-scroller rss sample select-stylesheet sidebar smart-bookmarks tab-groups tab-states"
-USEFUL_EXTENSIONS="actions adblock auto-reload auto-scroller certificates error-viewer extensions-manager-ui gestures java-console page-info push-scroller select-stylesheet sidebar smart-bookmarks tab-groups tab-states"
-DEFAULT_EXTENSIONS="actions adblock auto-scroller certificates error-viewer extensions-manager-ui gestures java-console page-info push-scroller select-stylesheet sidebar smart-bookmarks tab-groups tab-states greasemonkey"
+ALL_EXTENSIONS="actions adblock auto-reload auto-scroller certificates error-viewer extensions-manager-ui gestures greasemonkey java-console livehttpheaders page-info permissions push-scroller rss sample select-stylesheet sidebar smart-bookmarks soup-fly tab-groups tab-states"
+USEFUL_EXTENSIONS="actions adblock auto-reload auto-scroller certificates error-viewer extensions-manager-ui gestures java-console page-info push-scroller select-stylesheet sidebar smart-bookmarks soup-fly tab-groups tab-states"
+DEFAULT_EXTENSIONS="actions adblock auto-scroller certificates error-viewer extensions-manager-ui gestures java-console page-info push-scroller select-stylesheet sidebar smart-bookmarks soup-fly tab-groups tab-states greasemonkey"
 
 MOZILLA_ALL_EXTENSIONS="error-viewer java-console livehttpheaders page-info select-stylesheet smart-bookmarks"
 
@@ -188,7 +188,7 @@ AC_ARG_WITH([extensions],
 			  gestures, greasemonkey, java-console, livehttpheaders, page-info,
 			  permissions, push-scroller, rss, sample,
 			  select-stylesheet, sidebar,
-			  smart-bookmarks, tab-groups, tab-states,
+			  smart-bookmarks, soup-fly, tab-groups, tab-states,
 			  as well as the aliases default, all, and really-all],
 			  [extensions=$with_extensions],
 			  [extensions="default"])
@@ -314,6 +314,7 @@ extensions/select-stylesheet/mozilla/Makefile
 extensions/sidebar/Makefile
 extensions/smart-bookmarks/Makefile
 extensions/smart-bookmarks/mozilla/Makefile
+extensions/soup-fly/Makefile
 extensions/tab-states/Makefile
 extensions/tab-groups/Makefile
 extensions/java-console/Makefile
diff --git a/extensions/soup-fly/Makefile.am b/extensions/soup-fly/Makefile.am
new file mode 100644
index 0000000..4ca4535
--- /dev/null
+++ b/extensions/soup-fly/Makefile.am
@@ -0,0 +1,40 @@
+extensiondir = $(EXTENSIONS_DIR)
+extension_LTLIBRARIES = libsoupflyextension.la
+
+libsoupflyextension_la_SOURCES = \
+	ephy-soup-fly-extension.c	\
+	ephy-soup-fly-extension.h	\
+	soup-fly.c \
+	soup-fly.h \
+	extension.c
+
+libsoupflyextension_la_CPPFLAGS = \
+	-I$(top_srcdir)/include				\
+	-DSHARE_DIR=\"$(pkgdatadir)\"			\
+	-DEPHY_EXTENSIONS_LOCALEDIR=\"$(datadir)/locale\"  \
+	$(AM_CPPFLAGS)
+
+libsoupflyextension_la_CFLAGS = \
+	$(EPIPHANY_DEPENDENCY_CFLAGS)	\
+	$(AM_CFLAGS)
+
+libsoupflyextension_la_LDFLAGS = \
+	-module -avoid-version \
+	-export-symbols $(top_srcdir)/ephy-extension.symbols \
+	$(AM_LDFLAGS)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = soup-fly.ephy-extension.in.in
+extensionini_DATA = $(extensionini_in_files:.ephy-extension.in.in=.ephy-extension)
+
+%.ephy-extension.in: %.ephy-extension.in.in $(extension_LTLIBRARIES)
+	sed -e "s|%LIBRARY%|`. ./$(extension_LTLIBRARIES) && echo $$dlname`|" \
+	    -e "s|%EXTENSION_DIR%|$(extensiondir)|" \
+	$< > $@
+
+ EPIPHANY_EXTENSION_RULE@
+
+CLEANFILES = $(extensionini_DATA)
+DISTCLEANFILES = $(extensionini_DATA)
+
+EXTRA_DIST = $(extensionini_in_files)
diff --git a/extensions/soup-fly/ephy-soup-fly-extension.c b/extensions/soup-fly/ephy-soup-fly-extension.c
new file mode 100644
index 0000000..0fd3daf
--- /dev/null
+++ b/extensions/soup-fly/ephy-soup-fly-extension.c
@@ -0,0 +1,244 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2009 Igalia S.L.
+ *
+ *  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, 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "ephy-soup-fly-extension.h"
+#include "soup-fly.h"
+#include "ephy-debug.h"
+
+#include <epiphany/epiphany.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#define WINDOW_DATA_KEY "EphySoupFlyExtWindowData"
+
+#define EPHY_SOUP_FLY_EXTENSION_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SOUP_FLY_EXTENSION, EphySoupFlyExtensionPrivate))
+
+typedef struct
+{
+  EphySoupFlyExtension *extension;
+  EphyWindow *window;
+} SoupFlyCBData;
+
+typedef struct
+{
+  GtkActionGroup *action_group;
+  guint ui_id;
+} WindowData;
+
+struct _EphySoupFlyExtensionPrivate
+{
+  SoupFly *fly;
+
+  gboolean is_logging;
+};
+
+static void ephy_soup_fly_extension_class_init  (EphySoupFlyExtensionClass *klass);
+static void ephy_soup_fly_extension_iface_init  (EphyExtensionIface *iface);
+static void ephy_soup_fly_extension_init    (EphySoupFlyExtension *extension);
+
+static void ephy_soup_fly_extension_show_viewer (GtkAction *action,
+                                                 SoupFlyCBData *data);
+
+static const GtkActionEntry action_entries [] = {
+  { "SoupFly",
+    GTK_STOCK_DIALOG_INFO,
+    N_("_Soup Fly"),
+    NULL, /* shortcut key */
+    N_("Show information about the SoupSession used by the browser"),
+    G_CALLBACK (ephy_soup_fly_extension_show_viewer) }
+};
+
+static GObjectClass *parent_class = NULL;
+
+static GType type = 0;
+
+GType
+ephy_soup_fly_extension_get_type (void)
+{
+  return type;
+}
+
+GType
+ephy_soup_fly_extension_register_type (GTypeModule *module)
+{
+  static volatile gsize type_volatile = 0;
+
+  if (g_once_init_enter (&type_volatile)) {
+    const GTypeInfo our_info = {
+      sizeof (EphySoupFlyExtensionClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) ephy_soup_fly_extension_class_init,
+      NULL,
+      NULL, /* class_data */
+      sizeof (EphySoupFlyExtension),
+      0, /* n_preallocs */
+      (GInstanceInitFunc) ephy_soup_fly_extension_init
+    };
+
+    const GInterfaceInfo extension_info = {
+      (GInterfaceInitFunc) ephy_soup_fly_extension_iface_init,
+      NULL,
+      NULL
+    };
+
+    type = g_type_module_register_type (module,
+                                        G_TYPE_OBJECT,
+                                        "EphySoupFlyExtension",
+                                        &our_info, 0);
+
+    g_type_module_add_interface (module,
+                                 type,
+                                 EPHY_TYPE_EXTENSION,
+                                 &extension_info);
+
+    g_once_init_leave (&type_volatile, type);
+  }
+
+  return type_volatile;
+}
+
+static void
+ephy_soup_fly_extension_init (EphySoupFlyExtension *extension)
+{
+  LOG ("EphySoupFlyExtension initialising");
+
+  extension->priv = EPHY_SOUP_FLY_EXTENSION_GET_PRIVATE (extension);
+
+  extension->priv->fly = soup_fly_new ();
+}
+
+static void
+ephy_soup_fly_extension_finalize (GObject *object)
+{
+  EphySoupFlyExtension *extension =
+    EPHY_SOUP_FLY_EXTENSION (object);
+
+  LOG ("EphySoupFlyExtension finalizing");
+
+  gtk_widget_destroy (extension->priv->fly);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+ephy_soup_fly_extension_class_init (EphySoupFlyExtensionClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize = ephy_soup_fly_extension_finalize;
+
+  g_type_class_add_private (object_class, sizeof (EphySoupFlyExtensionPrivate));
+}
+
+static void
+ephy_soup_fly_extension_show_viewer (GtkAction *action,
+                                     SoupFlyCBData *data)
+{
+  gtk_widget_show_all (GTK_WIDGET (data->extension->priv->fly));
+}
+
+static void
+free_window_data (WindowData *data)
+{
+  if (data) {
+    g_object_unref (data->action_group);
+    g_free (data);
+  }
+}
+
+static void
+impl_attach_window (EphyExtension *extension,
+                    EphyWindow *window)
+{
+  SoupFlyCBData *cb_data;
+  GtkActionGroup *action_group;
+  GtkUIManager *manager;
+  guint merge_id;
+  WindowData *data;
+  EphySoupFlyExtensionPrivate *priv = EPHY_SOUP_FLY_EXTENSION (extension)->priv;
+
+  LOG ("EphySoupFlyExtension attach_window");
+
+  cb_data = g_new (SoupFlyCBData, 1);
+  cb_data->extension = EPHY_SOUP_FLY_EXTENSION (extension);
+  cb_data->window = window;
+
+  data = g_new (WindowData, 1);
+
+  data->action_group = action_group =
+    gtk_action_group_new ("EphySoupFlyExtensionActions");
+  gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
+  gtk_action_group_add_actions_full (action_group, action_entries,
+                                     G_N_ELEMENTS (action_entries), cb_data,
+                                     g_free);
+
+  manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window));
+  gtk_ui_manager_insert_action_group (manager, action_group, 0);
+  data->ui_id = merge_id = gtk_ui_manager_new_merge_id (manager);
+
+  g_object_set_data_full (G_OBJECT (window), WINDOW_DATA_KEY, data,
+                          (GDestroyNotify) free_window_data);
+
+  gtk_ui_manager_add_ui (manager, merge_id, "/menubar/ToolsMenu",
+                         "SoupFlySep", NULL,
+                         GTK_UI_MANAGER_SEPARATOR, FALSE);
+  gtk_ui_manager_add_ui (manager, merge_id, "/menubar/ToolsMenu",
+                         "SoupFly", "SoupFly",
+                         GTK_UI_MANAGER_MENUITEM, FALSE);
+
+  if (priv->is_logging == FALSE) {
+    soup_fly_start (priv->fly);
+    priv->is_logging = TRUE;
+  }
+}
+
+static void
+impl_detach_window (EphyExtension *extension,
+                    EphyWindow *window)
+{
+  GtkUIManager *manager;
+  WindowData *data;
+
+  /* Remove UI */
+  manager = GTK_UI_MANAGER (ephy_window_get_ui_manager (window));
+
+  data = (WindowData *) g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY);
+  g_return_if_fail (data != NULL);
+
+  gtk_ui_manager_remove_ui (manager, data->ui_id);
+  gtk_ui_manager_remove_action_group (manager, data->action_group);
+
+  g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL);
+
+}
+
+static void
+ephy_soup_fly_extension_iface_init (EphyExtensionIface *iface)
+{
+  iface->attach_window = impl_attach_window;
+  iface->detach_window = impl_detach_window;
+}
diff --git a/extensions/soup-fly/ephy-soup-fly-extension.h b/extensions/soup-fly/ephy-soup-fly-extension.h
new file mode 100644
index 0000000..1880a7d
--- /dev/null
+++ b/extensions/soup-fly/ephy-soup-fly-extension.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2009 Igalia S.L.
+ *
+ *  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, 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef EPHY_SOUP_FLY_EXTENSION_H
+#define EPHY_SOUP_FLY_EXTENSION_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_SOUP_FLY_EXTENSION          (ephy_soup_fly_extension_get_type ())
+#define EPHY_SOUP_FLY_EXTENSION(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_SOUP_FLY_EXTENSION, EphySoupFlyExtension))
+#define EPHY_SOUP_FLY_EXTENSION_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_SOUP_FLY_EXTENSION, EphySoupFlyExtensionClass))
+#define EPHY_IS_SOUP_FLY_EXTENSION(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_SOUP_FLY_EXTENSION))
+#define EPHY_IS_SOUP_FLY_EXTENSION_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_SOUP_FLY_EXTENSION))
+#define EPHY_SOUP_FLY_EXTENSION_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_SOUP_FLY_EXTENSION, EphySoupFlyExtensionClass))
+
+typedef struct _EphySoupFlyExtension          EphySoupFlyExtension;
+typedef struct _EphySoupFlyExtensionClass   EphySoupFlyExtensionClass;
+typedef struct _EphySoupFlyExtensionPrivate EphySoupFlyExtensionPrivate;
+
+struct _EphySoupFlyExtensionClass {
+  GObjectClass parent_class;
+};
+
+struct _EphySoupFlyExtension {
+  GObject parent_instance;
+
+  /*< private >*/
+  EphySoupFlyExtensionPrivate *priv;
+};
+
+GType ephy_soup_fly_extension_get_type      (void);
+GType ephy_soup_fly_extension_register_type (GTypeModule *module);
+
+G_END_DECLS
+
+#endif
diff --git a/extensions/soup-fly/extension.c b/extensions/soup-fly/extension.c
new file mode 100644
index 0000000..aba326b
--- /dev/null
+++ b/extensions/soup-fly/extension.c
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2009 Igalia S.L.
+ *
+ *  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, 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "ephy-debug.h"
+#include "ephy-soup-fly-extension.h"
+#include "soup-fly.h"
+
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+
+G_MODULE_EXPORT GType register_module (GTypeModule *module);
+
+G_MODULE_EXPORT GType
+register_module (GTypeModule *module)
+{
+  LOG ("Registering EphySoupLogger");
+
+#ifdef ENABLE_NLS
+  /* Initialise the i18n stuff */
+  bindtextdomain (GETTEXT_PACKAGE, EPHY_EXTENSIONS_LOCALEDIR);
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif /* ENABLE_NLS */
+
+  soup_fly_register_type (module);
+
+  return ephy_soup_fly_extension_register_type (module);
+}
diff --git a/extensions/soup-fly/soup-fly.c b/extensions/soup-fly/soup-fly.c
new file mode 100644
index 0000000..83860ca
--- /dev/null
+++ b/extensions/soup-fly/soup-fly.c
@@ -0,0 +1,334 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2009 Igalia S.L.
+ *
+ *  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, 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "ephy-debug.h"
+#include "ephy-soup-fly-extension.h"
+#include "soup-fly.h"
+
+#include <gtk/gtk.h>
+
+#define SOUP_FLY_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), TYPE_SOUP_FLY, SoupFlyPrivate))
+
+struct _SoupFlyPrivate {
+  GtkTreeModel *model;
+  GtkWidget *treeview;
+  GtkWidget *clear_button;
+
+  guint nth;
+  gboolean clean_finished;
+};
+
+enum {
+    COL_NUMBER,
+    COL_STATE,
+    COL_URL,
+    N_COLUMNS
+};
+
+static void soup_fly_class_init (SoupFlyClass *klass);
+static void soup_fly_init       (SoupFly *logger);
+
+static GObjectClass *parent_class = NULL;
+static GType type = 0;
+
+GType
+soup_fly_get_type (void)
+{
+  return type;
+}
+
+GType
+soup_fly_register_type (GTypeModule *module)
+{
+  static volatile gsize type_volatile = 0;
+
+  if (g_once_init_enter (&type_volatile)) {
+    const GTypeInfo our_info = {
+        sizeof (SoupFlyClass),
+        NULL, /* base_init */
+        NULL, /* base_finalize */
+        (GClassInitFunc) soup_fly_class_init,
+        NULL,
+        NULL, /* class_data */
+        sizeof (SoupFly),
+        0, /* n_preallocs */
+        (GInstanceInitFunc) soup_fly_init
+    };
+
+    type = g_type_module_register_type (module,
+                                        GTK_TYPE_WINDOW,
+                                        "SoupFly",
+                                        &our_info, 0);
+    g_once_init_leave (&type_volatile, type);
+  }
+
+  return type_volatile;
+}
+
+static void
+soup_fly_class_init (SoupFlyClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  g_type_class_add_private (object_class, sizeof (SoupFlyPrivate));
+}
+
+static void
+clear_button_clicked_cb (GtkButton *button, SoupFly *logger)
+{
+  GtkTreeIter iter;
+  gboolean valid;
+  SoupFlyPrivate *priv = logger->priv;
+
+  valid = gtk_tree_model_get_iter_first (priv->model, &iter);
+
+  while (valid) {
+    char *state;
+
+    gtk_tree_model_get (priv->model, &iter,
+                        COL_STATE, &state,
+                        -1);
+
+    if (g_str_equal (state, "Finished"))
+      valid = gtk_list_store_remove (GTK_LIST_STORE (priv->model), &iter);
+    else
+      valid = gtk_tree_model_iter_next (priv->model, &iter);
+
+    g_free (state);
+  }
+}
+
+static void
+check_button_toggled_cb (GtkToggleButton *toggle, SoupFly *logger)
+{
+  SoupFlyPrivate *priv = logger->priv;
+
+  priv->clean_finished = gtk_toggle_button_get_active (toggle);
+}
+
+static void
+state_data_func (GtkTreeViewColumn *column, GtkCellRenderer *cell,
+                 GtkTreeModel *model, GtkTreeIter *iter,
+                 gpointer data)
+{
+  char *state;
+
+  gtk_tree_model_get (model, iter, COL_STATE, &state, -1);
+  if (g_str_equal (state, "Queued"))
+    g_object_set (G_OBJECT (cell), "background", "orange", NULL);
+  else if (g_str_equal (state, "Finished"))
+    g_object_set (G_OBJECT (cell), "background", "green", NULL);
+
+  g_free (state);
+}
+
+static void
+construct_ui (SoupFly *logger)
+{
+  GtkListStore *store;
+  GtkWidget *treeview;
+  GtkCellRenderer *renderer;
+  GtkWidget *scrolled, *hbox, *vbox, *button, *check_button;
+  GtkTreeViewColumn *column;
+  SoupFlyPrivate *priv = logger->priv;
+
+  gtk_window_set_icon_name (GTK_WINDOW (logger),
+                            GTK_STOCK_DIALOG_INFO);
+
+  g_signal_connect (logger, "delete-event",
+                    G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+
+  treeview = gtk_tree_view_new ();
+  gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
+
+  store = gtk_list_store_new (N_COLUMNS,
+                              G_TYPE_UINT,
+                              G_TYPE_STRING,
+                              G_TYPE_STRING);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
+                                               COL_NUMBER, "#",
+                                               renderer,
+                                               "text", COL_NUMBER,
+                                               NULL);
+
+  column = gtk_tree_view_column_new ();
+  gtk_tree_view_column_set_title (column, "State");
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_column_pack_start (column, renderer, FALSE);
+  gtk_tree_view_column_set_attributes (column, renderer,
+                                       "text", COL_STATE,
+                                       NULL);
+  gtk_tree_view_column_set_cell_data_func (column, renderer,
+                                           state_data_func,
+                                           NULL, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); 
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
+                                               COL_URL, "URL",
+                                               renderer,
+                                               "text", COL_URL,
+                                               NULL);
+
+  scrolled = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+                                  GTK_POLICY_AUTOMATIC,
+                                  GTK_POLICY_AUTOMATIC);
+  gtk_container_add (GTK_CONTAINER (scrolled), treeview);
+
+  hbox = gtk_hbox_new (FALSE, 10);
+  button = gtk_button_new_with_label ("Clear finished");
+  g_signal_connect (button, "clicked", G_CALLBACK (clear_button_clicked_cb), logger);
+  gtk_container_add (GTK_CONTAINER (hbox), button);
+
+  check_button = gtk_check_button_new_with_label ("Automatically remove finished messages");
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), priv->clean_finished);
+  g_signal_connect (check_button, "toggled", G_CALLBACK (check_button_toggled_cb), logger);
+  gtk_container_add (GTK_CONTAINER (hbox), check_button);
+
+  vbox = gtk_vbox_new (FALSE, 10);
+  gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+  gtk_container_add (GTK_CONTAINER (logger), vbox);
+
+  gtk_window_set_title (GTK_WINDOW (logger), "Soup Fly");
+  gtk_container_set_border_width (GTK_CONTAINER (logger), 5);
+  gtk_window_set_default_size (GTK_WINDOW (logger), 640, 480);
+
+  priv->model = GTK_TREE_MODEL (store);
+  priv->treeview = treeview;
+  priv->clear_button = button;
+}
+
+static void
+soup_fly_init (SoupFly *logger)
+{
+  logger->priv = SOUP_FLY_GET_PRIVATE (logger);
+  
+  logger->priv->nth = 0;
+
+  construct_ui (logger);
+}
+
+typedef struct
+{
+  GtkTreeIter iter;
+  SoupFly *logger;
+} MessageFinishedCBData;
+
+static void
+message_finished_cb (SoupMessage *message, MessageFinishedCBData *data)
+{
+  SoupFlyPrivate *priv = data->logger->priv;
+
+  if (priv->clean_finished)
+    gtk_list_store_remove (GTK_LIST_STORE (priv->model), &data->iter);
+  else
+    gtk_list_store_set (GTK_LIST_STORE (priv->model), &data->iter,
+                        COL_STATE, "Finished",
+                        -1);
+  g_slice_free (MessageFinishedCBData, data);
+}
+
+static void
+request_queued_cb (SoupSession *session, SoupMessage *message, SoupFly *logger)
+{
+  GtkTreeIter iter;
+  SoupURI *uri;
+  char *uri_string;
+  MessageFinishedCBData *data;
+  SoupFlyPrivate *priv = logger->priv;
+
+  uri = soup_message_get_uri (message);
+  uri_string = soup_uri_to_string (uri, FALSE);
+
+  gtk_list_store_append (GTK_LIST_STORE (priv->model), &iter);
+  gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
+                      COL_NUMBER, priv->nth++,
+                      COL_URL, uri_string,
+                      COL_STATE, "Queued",
+                      -1);
+  g_free (uri_string);
+  
+  data = g_slice_new (MessageFinishedCBData);
+  data->iter = iter;
+  data->logger = logger;
+  g_signal_connect (message, "finished", G_CALLBACK (message_finished_cb), data);
+}
+
+/* Public API */
+
+/**
+ * soup_fly_start:
+ * @logger: a #SoupFly
+ * 
+ * 
+ **/
+void
+soup_fly_start (SoupFly *logger)
+{
+  SoupSession *session;
+  SoupFlyPrivate *priv;
+
+  g_return_if_fail (IS_SOUP_FLY (logger));
+  
+  priv = logger->priv;
+  session = webkit_get_default_session ();
+  g_return_if_fail (session);
+  g_signal_connect (session, "request-queued", G_CALLBACK (request_queued_cb), logger);
+}
+
+/**
+ * soup_fly_stop:
+ * @logger: a #SoupFly
+ * 
+ * 
+ **/
+void
+soup_fly_stop (SoupFly *logger)
+{
+  SoupSession *session;
+
+  g_return_if_fail (IS_SOUP_FLY (logger));
+  
+  session = webkit_get_default_session ();
+  g_signal_handlers_disconnect_by_func (session, G_CALLBACK (request_queued_cb), logger);
+}
+
+/**
+ * soup_fly_new:
+ * @void: 
+ * 
+ * Returns: a new #SoupFly
+ **/
+SoupFly *
+soup_fly_new (void)
+{
+  return SOUP_FLY (g_object_new (TYPE_SOUP_FLY, NULL));
+}
+
diff --git a/extensions/soup-fly/soup-fly.ephy-extension.in.in b/extensions/soup-fly/soup-fly.ephy-extension.in.in
new file mode 100644
index 0000000..52f39c8
--- /dev/null
+++ b/extensions/soup-fly/soup-fly.ephy-extension.in.in
@@ -0,0 +1,11 @@
+[Epiphany Extension]
+_Name=Soup Fly
+_Description=A tool to debug the SoupSession WebKit uses.
+Authors=Xan López <xan gnome org>
+Version=1
+URL=http://www.gnome.org/projects/epiphany/extensions.html
+
+
+[Loader]
+Type=shlib
+Library=%EXTENSION_DIR%/%LIBRARY%
diff --git a/extensions/soup-fly/soup-fly.h b/extensions/soup-fly/soup-fly.h
new file mode 100644
index 0000000..1ddf34f
--- /dev/null
+++ b/extensions/soup-fly/soup-fly.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2009 Igalia S.L.
+ *
+ *  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, 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOUP_FLY_H
+#define SOUP_FLY_H
+
+#include <glib-object.h>
+#include <gmodule.h>
+
+#include <epiphany/epiphany.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_SOUP_FLY         (soup_fly_get_type ())
+#define SOUP_FLY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_SOUP_FLY, SoupFly))
+#define SOUP_FLY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), TYPE_SOUP_FLY, SoupFlyClass))
+#define IS_SOUP_FLY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_SOUP_FLY))
+#define IS_SOUP_FLY_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_SOUP_FLY))
+#define SOUP_FLY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_SOUP_FLY, SoupFlyClass))
+
+typedef struct _SoupFly   SoupFly;
+typedef struct _SoupFlyClass    SoupFlyClass;
+typedef struct _SoupFlyPrivate  SoupFlyPrivate;
+
+struct _SoupFly {
+  GtkWindow parent;
+
+  /*< private >*/
+  SoupFlyPrivate *priv;
+};
+
+struct _SoupFlyClass {
+  GtkWindowClass parent_class;
+};
+
+GType       soup_fly_get_type      (void);
+GType       soup_fly_register_type (GTypeModule *module);
+SoupFly    *soup_fly_new           (void);
+void        soup_fly_start         (SoupFly     *logger);
+void        soup_fly_stop          (SoupFly     *logger);
+
+G_END_DECLS
+
+#endif



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