aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanielle Madeley <danielle.madeley@collabora.co.uk>2011-07-29 12:23:21 +0800
committerDanielle Madeley <danielle.madeley@collabora.co.uk>2011-07-29 12:23:21 +0800
commite1ae13450cf3ad12df82bd6a2111eedd6d169ef7 (patch)
treef924dbe81d9b1881af8ba6c574b1d0e4a348ece2
parente10a0655a4eb8c36f232d533078bcf6b8e7fdbd0 (diff)
downloadgsoc2013-empathy-e1ae13450cf3ad12df82bd6a2111eedd6d169ef7.tar
gsoc2013-empathy-e1ae13450cf3ad12df82bd6a2111eedd6d169ef7.tar.gz
gsoc2013-empathy-e1ae13450cf3ad12df82bd6a2111eedd6d169ef7.tar.bz2
gsoc2013-empathy-e1ae13450cf3ad12df82bd6a2111eedd6d169ef7.tar.lz
gsoc2013-empathy-e1ae13450cf3ad12df82bd6a2111eedd6d169ef7.tar.xz
gsoc2013-empathy-e1ae13450cf3ad12df82bd6a2111eedd6d169ef7.tar.zst
gsoc2013-empathy-e1ae13450cf3ad12df82bd6a2111eedd6d169ef7.zip
Add a webview widget for displaying the log
The widget is currently bolted in alongside the existing log display widget for comparison. This includes some debugging cruft like showing the secret notebook tabs. The webview is populated from the store_events treestore, allowing all of the existing node-management and ordering code to be used. Attempting to replace this logic in Javascript was demonstratably too hard. This approach keeps the Javascript code down to the 4 GtkTreeModel signals. TODO: - icons - pretty printed dates - expanders - supporting smileys, links, etc. - using the correct font, etc. - removing the debugging
-rw-r--r--data/Makefile.am5
-rw-r--r--data/empathy-log-window.html126
-rw-r--r--libempathy-gtk/empathy-log-window.c133
3 files changed, 263 insertions, 1 deletions
diff --git a/data/Makefile.am b/data/Makefile.am
index 88de4f09b..d652ca9e5 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -58,7 +58,10 @@ clientfile_DATA = \
Empathy.FileTransfer.client
htmldir = $(datadir)/empathy
-html_DATA = Template.html
+html_DATA = \
+ Template.html \
+ empathy-log-window.html \
+ $(NULL)
EXTRA_DIST = \
$(convert_DATA) \
diff --git a/data/empathy-log-window.html b/data/empathy-log-window.html
new file mode 100644
index 000000000..ef01df34b
--- /dev/null
+++ b/data/empathy-log-window.html
@@ -0,0 +1,126 @@
+<html>
+ <head>
+ <style type="text/css">
+html, body, div, p {
+ /* FIXME: how do we set the application font? */
+ padding: 0;
+ margin: 0;
+}
+
+div.row {
+ margin-left: 1em;
+}
+ </style>
+ <script type="text/javascript">
+function filterNodes (node, tagName)
+{
+ var out = new Array();
+
+ for (var i = 0; i < node.childNodes.length; i++)
+ {
+ var elem = node.childNodes[i];
+
+ if (elem.tagName == tagName)
+ out.push(elem);
+ }
+
+ return out;
+}
+
+function getNodes(node)
+{
+ return filterNodes(node, 'DIV');
+}
+
+function getContent(node)
+{
+ return filterNodes(node, 'P')[0];
+}
+
+function insertRow (path, text)
+{
+ var treeview = document.getElementById('treeview');
+ var parentnode = treeview;
+ var i;
+
+ // walk the tree
+ for (i = 0; i < path.length - 1; i++)
+ parentnode = getNodes(parentnode)[path[i]];
+
+ // create a new node
+ var newnode = document.createElement('div');
+ newnode.setAttribute('class', 'row');
+
+ // insert the new node into the tree
+ var nodes = getNodes(parentnode);
+
+ // console.log("path = " + path);
+ // console.log("i = " + i + ", path[i] = " + path[i] + ", nodes.length = " +
+ // nodes.length);
+
+ if (path[i] >= nodes.length)
+ parentnode.appendChild(newnode);
+ else
+ parentnode.insertBefore(newnode, nodes[path[i]]);
+
+ var contents = document.createElement('p');
+ newnode.appendChild(contents);
+ contents.innerHTML = text;
+}
+
+function changeRow (path, text)
+{
+ var treeview = document.getElementById('treeview');
+ var node = treeview;
+
+ // console.log("path = " + path + ", text = '" + text + "'");
+
+ // walk the tree
+ for (var i = 0; i < path.length; i++)
+ node = getNodes(node)[path[i]];
+
+ // set the contents
+ var contents = getContent(node);
+ contents.innerHTML = text;
+}
+
+function deleteRow (path)
+{
+ var treeview = document.getElementById('treeview');
+ var node = treeview;
+
+ // walk the tree
+ for (var i = 0; i < path.length; i++)
+ node = getNodes(node)[path[i]];
+
+ node.parentNode.removeChild(node);
+}
+
+function reorderRows (path, new_order)
+{
+ var treeview = document.getElementById('treeview');
+ var node = treeview;
+
+ // walk the tree
+ for (var i = 0; i < path.length; i++)
+ node = getNodes(node)[path[i]];
+
+ var nodes = getNodes(node);
+
+ // remove all the nodes from the DOM
+ for (var i = 0; i < nodes.length; i++)
+ node.removeChild(nodes[i]);
+
+ // put them back in the new order
+ // For reference: new_order[new_pos] = old_pos
+ for (var i = 0; i < nodes.length; i++)
+ node.appendChild(nodes[new_order[i]]);
+}
+ </script>
+ </head>
+
+ <body>
+ <div id="treeview">
+ </div>
+ </body>
+</html>
diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c
index e5c935011..04f224290 100644
--- a/libempathy-gtk/empathy-log-window.c
+++ b/libempathy-gtk/empathy-log-window.c
@@ -29,6 +29,7 @@
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
+#include <webkit/webkit.h>
#include <telepathy-glib/telepathy-glib.h>
#include <telepathy-glib/proxy-subclass.h>
@@ -83,6 +84,7 @@ struct _EmpathyLogWindowPriv
GtkWidget *treeview_what;
GtkWidget *treeview_when;
GtkWidget *treeview_events;
+ GtkWidget *webview;
GtkTreeStore *store_events;
@@ -360,6 +362,103 @@ toolbutton_av_clicked (GtkToolButton *toolbutton,
TRUE, video, gtk_get_current_event_time ());
}
+static void
+insert_or_change_row (EmpathyLogWindow *self,
+ const char *method,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter)
+{
+ char *str = gtk_tree_path_to_string (path);
+ char *script, *text;
+
+ gtk_tree_model_get (model, iter,
+ COL_EVENTS_TEXT, &text,
+ -1);
+
+ script = g_strdup_printf ("javascript:%s([%s], '%s');",
+ method,
+ g_strdelimit (str, ":", ','),
+ text);
+
+ // g_print ("%s\n", script);
+ webkit_web_view_execute_script (WEBKIT_WEB_VIEW (self->priv->webview),
+ script);
+
+ g_free (str);
+ g_free (text);
+ g_free (script);
+}
+
+static void
+store_events_row_inserted (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ EmpathyLogWindow *self)
+{
+ insert_or_change_row (self, "insertRow", model, path, iter);
+}
+
+static void
+store_events_row_changed (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ EmpathyLogWindow *self)
+{
+ insert_or_change_row (self, "changeRow", model, path, iter);
+}
+
+static void
+store_events_row_deleted (GtkTreeModel *model,
+ GtkTreePath *path,
+ EmpathyLogWindow *self)
+{
+ char *str = gtk_tree_path_to_string (path);
+ char *script;
+
+ script = g_strdup_printf ("javascript:deleteRow([%s]);",
+ g_strdelimit (str, ":", ','));
+
+ // g_print ("%s\n", script);
+ webkit_web_view_execute_script (WEBKIT_WEB_VIEW (self->priv->webview),
+ script);
+
+ g_free (str);
+ g_free (script);
+}
+
+static void
+store_events_rows_reordered (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ int *new_order,
+ EmpathyLogWindow *self)
+{
+ char *str = gtk_tree_path_to_string (path);
+ int i, children = gtk_tree_model_iter_n_children (model, iter);
+ char **new_order_strv, *new_order_s;
+ char *script;
+
+ new_order_strv = g_new0 (char *, children + 1);
+
+ for (i = 0; i < children; i++)
+ new_order_strv[i] = g_strdup_printf ("%i", new_order[i]);
+
+ new_order_s = g_strjoinv (",", new_order_strv);
+
+ script = g_strdup_printf ("javascript:reorderRows([%s], [%s]);",
+ str == NULL ? "" : g_strdelimit (str, ":", ','),
+ new_order_s);
+
+ webkit_web_view_execute_script (WEBKIT_WEB_VIEW (self->priv->webview),
+ script);
+
+ g_free (str);
+ g_free (script);
+ g_free (new_order_s);
+ g_strfreev (new_order_strv);
+}
+
static GObject *
empathy_log_window_constructor (GType type,
guint n_props,
@@ -444,7 +543,9 @@ empathy_log_window_init (EmpathyLogWindow *self)
EmpathyAccountChooser *account_chooser;
GtkBuilder *gui;
gchar *filename;
+ GFile *gfile;
GtkWidget *vbox, *accounts, *search, *label, *quit;
+ GtkWidget *sw;
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
EMPATHY_TYPE_LOG_WINDOW, EmpathyLogWindowPriv);
@@ -564,6 +665,38 @@ empathy_log_window_init (EmpathyLogWindow *self)
log_window_who_populate (self);
+ /* events */
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ self->priv->webview = webkit_web_view_new ();
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (sw), self->priv->webview);
+
+ filename = empathy_file_lookup ("empathy-log-window.html", "data");
+ gfile = g_file_new_for_path (filename);
+ g_free (filename);
+
+ webkit_web_view_load_uri (WEBKIT_WEB_VIEW (self->priv->webview),
+ g_file_get_uri (gfile));
+ g_object_unref (gfile);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
+ sw, gtk_label_new ("webview"));
+ gtk_widget_show_all (sw);
+
+ /* listen to changes to the treemodel */
+ g_signal_connect (self->priv->store_events, "row-inserted",
+ G_CALLBACK (store_events_row_inserted), self);
+ g_signal_connect (self->priv->store_events, "row-changed",
+ G_CALLBACK (store_events_row_changed), self);
+ g_signal_connect (self->priv->store_events, "row-deleted",
+ G_CALLBACK (store_events_row_deleted), self);
+ g_signal_connect (self->priv->store_events, "rows-reordered",
+ G_CALLBACK (store_events_rows_reordered), self);
+
+ // debug
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (self->priv->notebook), TRUE);
+
gtk_widget_show (GTK_WIDGET (self));
}