/soc/2015/igor.gajowiak/chatlog: ad0758165399: Implemented showi...
Igor Gajowiak
igor.gajowiak at gmail.com
Fri Jul 31 15:59:53 EDT 2015
Changeset: ad07581653998b3cd64ebd893ce1e63efd5cbca0
Author: Igor Gajowiak <igor.gajowiak at gmail.com>
Date: 2015-07-31 21:59 +0200
Branch: default
URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/ad0758165399
Description:
Implemented showing messages in log.
diffstat:
pidgin/gtkgenericlog.c | 316 ++++++++++++++++++++++++++++++++++++++++---
pidgin/gtkgenericlog.h | 3 +
pidgin/themes/Template.html | 5 +
3 files changed, 301 insertions(+), 23 deletions(-)
diffs (truncated from 441 to 300 lines):
diff --git a/pidgin/gtkgenericlog.c b/pidgin/gtkgenericlog.c
--- a/pidgin/gtkgenericlog.c
+++ b/pidgin/gtkgenericlog.c
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
+#include <string.h>
+
#include <sys/time.h>
#include "buddylist.h"
@@ -243,25 +245,24 @@ on_buddylist_row_changed(GtkTreeSelectio
GtkTreeModel *model;
GtkTreeIter row;
- /* No buddy selected */
- if (!gtk_tree_selection_get_selected(sel, &model, &row)) {
- gtk_tree_store_clear(viewer->calendar_tree_store);
- return;
+ PurpleBuddy *buddy = NULL;
+
+ if (gtk_tree_selection_get_selected(sel, &model, &row)) {
+ gtk_tree_model_get(model, &row, BLIST_TREE_STORE_COL_BUDDY, &buddy, -1);
+
+ if (buddy) {
+ g_object_ref(G_OBJECT(buddy));
+ viewer->current_buddy = buddy;
+ }
}
- gpointer buddy = NULL;
- gtk_tree_model_get(model, &row, BLIST_TREE_STORE_COL_BUDDY, &buddy, -1);
+ /* Unhook calendar model during updating to get better performance */
+ gtk_tree_view_set_model(viewer->calendar_tree_view, NULL);
- /* Group row activated */
- if (!buddy) {
- gtk_tree_store_clear(viewer->calendar_tree_store);
- return;
- }
+ populate_calendar_store(buddy, viewer->calendar_tree_store);
- g_object_ref(buddy);
- viewer->current_buddy = buddy;
-
- populate_calendar_store((PurpleBuddy*) buddy, viewer->calendar_tree_store);
+ gtk_tree_view_set_model(viewer->calendar_tree_view,
+ viewer->calendar_tree_store);
}
static void
@@ -365,13 +366,202 @@ static void
on_calendar_row_activated(GtkTreeView *tv, GtkTreePath *path,
GtkTreeViewColumn *col, gpointer data)
{
- printf("on_calendar_row_activated\n");
+ toggle_row_expansion(tv, path);
}
+/* TODO: Copied from gtkconv.c, try to refactor */
+static char *
+replace_message_tokens(
+ const char *text,
+ const char *messageId,
+ const char *name, /* author */
+ const char *alias, /* author's alias */
+ const char *message,
+ PurpleMessageFlags flags,
+ time_t mtime)
+{
+ GString *str;
+ const char *cur = text;
+ const char *prev = cur;
+ struct tm *tm = NULL;
+
+ if (text == NULL || *text == '\0')
+ return NULL;
+
+ str = g_string_new(NULL);
+ while ((cur = strchr(cur, '%'))) {
+ const char *replace = NULL;
+ const char *fin = NULL;
+ gpointer freeval = NULL;
+
+ if (g_str_has_prefix(cur, "%message%")) {
+ replace = message;
+
+ } else if (g_str_has_prefix(cur, "%messageClasses%")) {
+ char *user;
+ GString *classes = g_string_new(NULL);
+#define ADD_CLASS(f, class) \
+ if (flags & f) \
+ g_string_append(classes, class);
+ ADD_CLASS(PURPLE_MESSAGE_SEND, "outgoing ");
+ ADD_CLASS(PURPLE_MESSAGE_RECV, "incoming ");
+#undef ADD_CLASS
+ user = g_strconcat("-pidgin-user:", name, NULL);
+ g_string_append(classes, user);
+ g_free(user);
+
+ replace = freeval = g_string_free(classes, FALSE);
+
+ } else if (g_str_has_prefix(cur, "%time")) {
+ const char *tmp = cur + strlen("%time");
+
+ if (*tmp == '{') {
+ char *end;
+ tmp++;
+ end = strstr(tmp, "}%");
+ if (!end) /* Invalid string */
+ continue;
+ if (!tm)
+ tm = localtime(&mtime);
+ replace = freeval = purple_uts35_to_str(tmp, end - tmp, tm);
+ fin = end + 1;
+ } else {
+ if (!tm)
+ tm = localtime(&mtime);
+
+ replace = purple_utf8_strftime("%X", tm);
+ }
+
+ } else if (g_str_has_prefix(cur, "%shortTime%")) {
+ if (!tm)
+ tm = localtime(&mtime);
+
+ replace = purple_utf8_strftime("%H:%M", tm);
+ } else if (g_str_has_prefix(cur, "%senderScreenName%")) {
+ replace = name;
+
+ } else if (g_str_has_prefix(cur, "%sender%")) {
+ replace = alias;
+
+ } else if (g_str_has_prefix(cur, "%senderColor%")) {
+ replace = freeval = flags & PURPLE_MESSAGE_RECV ?
+ g_strdup("#000000") : g_strdup("#ed3240");
+ } else if (g_str_has_prefix(cur, "%messageDirection%")) {
+ replace = purple_markup_is_rtl(message) ? "rtl" : "ltr";
+
+ } else if (g_str_has_prefix(cur, "%status%")) {
+ GString *classes = g_string_new(NULL);
+
+ if (flags & PURPLE_MESSAGE_ERROR)
+ g_string_append(classes, "error ");
+
+ replace = freeval = g_string_free(classes, FALSE);
+ } else if (g_str_has_prefix(cur, "%messageId%")) {
+ replace = messageId;
+ } else {
+ cur++;
+ continue;
+ }
+
+ /* Here we have a replacement to make */
+ g_string_append_len(str, prev, cur - prev);
+ if (replace)
+ g_string_append(str, replace);
+ g_free(freeval);
+ replace = freeval = NULL;
+
+ /* And update the pointers */
+ if (fin) {
+ prev = cur = fin + 1;
+ } else {
+ prev = cur = strchr(cur + 1, '%') + 1;
+ }
+
+ }
+
+ /* And wrap it up */
+ g_string_append(str, prev);
+
+ return g_string_free(str, FALSE);
+}
+
+static gchar *
+prepare_script(PurpleMessage *msg, PidginConvTheme *theme)
+{
+ PurpleMessageFlags flags = purple_message_get_flags(msg);
+
+ const char *message_html = flags & PURPLE_MESSAGE_SEND ?
+ pidgin_conversation_theme_get_template(theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT) :
+ pidgin_conversation_theme_get_template(theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT);
+
+ char *message_id = g_strdup_printf("%u", purple_message_get_id(msg));
+ char *msg_tokenized = replace_message_tokens(message_html,
+ message_id,
+ purple_message_get_author(msg),
+ purple_message_get_author_alias(msg),
+ purple_message_get_contents(msg),
+ flags,
+ purple_message_get_time(msg));
+ char *escape = pidgin_webview_quote_js_string(msg_tokenized ?
+ msg_tokenized : "");
+
+ char *script = g_strdup_printf("appendMessage(%s)", escape);
+
+ g_free(message_id);
+ g_free(msg_tokenized);
+ g_free(escape);
+
+ return script;
+}
+
+static void
+clear_webview(PidginWebView *webview);
+
static void
on_calendar_row_changed(GtkTreeSelection *sel, gpointer data)
{
- printf("on_calendar_row_changed\n");
+ PidginGenericLogViewer *viewer = (PidginGenericLogViewer*) data;
+
+ clear_webview(PIDGIN_WEBVIEW(viewer->webview));
+
+ /* No buddy selected */
+ if (!viewer->current_buddy)
+ return;
+
+ GtkTreeModel *model;
+ GtkTreeIter row;
+
+ /* No row selected */
+ if (!gtk_tree_selection_get_selected(sel, &model, &row))
+ return;
+
+ /* Row with year selected */
+ if (gtk_tree_path_get_depth(gtk_tree_model_get_path(model, &row)) == 1)
+ return;
+
+ guint64 day;
+ gtk_tree_model_get(model, &row, CALENDAR_TREE_STORE_COL_DATE, &day, -1);
+
+ GList *messages = NULL;
+ if (!purple_genericlog_get_all_msgs(viewer->current_buddy,
+ day, &messages, NULL)) {
+ purple_debug_error(GTKGENERICLOG_DEBUG_CATEGORY,
+ "Getting all messages failed");
+ return;
+ }
+
+ /* Fill webview */
+ for (GList *it = messages; it != NULL; it = it->next) {
+ gchar *script = prepare_script(PURPLE_MESSAGE(it->data), viewer->theme);
+
+ pidgin_webview_safe_execute_script(PIDGIN_WEBVIEW(viewer->webview),
+ script);
+
+ g_free(script);
+ }
+ g_list_free_full(messages, g_object_unref);
}
static gboolean
@@ -410,11 +600,13 @@ append_new_calendar_group(GtkTreeStore *
static void
populate_calendar_store(PurpleBuddy *buddy, GtkTreeStore *store)
{
- g_assert(buddy);
g_assert(store);
gtk_tree_store_clear(store);
+ if (!buddy)
+ return;
+
GArray *days;
if (!purple_genericlog_get_all_days(buddy, &days, NULL)) {
purple_debug_error(GTKGENERICLOG_DEBUG_CATEGORY,
@@ -488,12 +680,86 @@ create_calendar_view(GtkTreeStore *store
/* Webview */
/******************************************************************************/
-static GtkWidget *
-create_webview(GtkWidget **webview, PidginGenericLogViewer *viewer)
+/* TODO: Copied from gtkconv.c, try to refactor */
+static char *
+replace_template_tokens(PidginConvTheme *theme, const char *header,
+ const char *footer)
+{
+ GString *str;
+ const char *text;
+ char **ms;
+ char *path;
+
+ text = pidgin_conversation_theme_get_template(theme,
+ PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN);
+ if (text == NULL)
+ return NULL;
+
+ ms = g_strsplit(text, "%@", 6);
+ if (ms[0] == NULL || ms[1] == NULL || ms[2] == NULL || ms[3] == NULL ||
+ ms[4] == NULL || ms[5] == NULL) {
+ g_strfreev(ms);
+ return NULL;
+ }
+
More information about the Commits
mailing list