/* Puts last 4k of log in new conversations a la Everybuddy (and then * stolen by Trillian "Pro") */ #include "conversation.h" #define HISTORY_PLUGIN_ID "gtk-history" #define HISTORY_SIZE (4 * 1024) static gboolean _scroll_webview_to_end(gpointer data) PidginWebView *webview = data; pidgin_webview_scroll_to_end(PIDGIN_WEBVIEW(webview), FALSE); g_object_unref(G_OBJECT(webview)); static void historize(PurpleConversation *c) PurpleAccount *account = purple_conversation_get_account(c); const char *name = purple_conversation_get_name(c); const char *alias = name; PidginConversation *gtkconv; /* FIXME: WebView has no options */ GtkIMHtmlOptions options = GTK_IMHTML_NO_COLOURS; /* FIXME: WebView has no protocol setting */ gtkconv = PIDGIN_CONVERSATION(c); g_return_if_fail(gtkconv != NULL); /* An IM which is the first active conversation. */ g_return_if_fail(gtkconv->convs != NULL); if (PURPLE_IS_IM_CONVERSATION(c) && !gtkconv->convs->next) /* If we're not logging, don't show anything. * Otherwise, we might show a very old log. */ if (!purple_prefs_get_bool("/purple/logging/log_ims")) /* Find buddies for this conversation. */ buddies = purple_blist_find_buddies(account, name); /* If we found at least one buddy, save the first buddy's alias. */ alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(buddies->data)); for (cur = buddies; cur != NULL; cur = cur->next) PurpleBlistNode *node = cur->data; PurpleBlistNode *prev = purple_blist_node_get_sibling_prev(node); PurpleBlistNode *next = purple_blist_node_get_sibling_next(node); if ((node != NULL) && ((prev != NULL) || (next != NULL))) PurpleBlistNode *parent = purple_blist_node_get_parent(node); PurpleBlistNode *child = purple_blist_node_get_first_child(parent); alias = purple_buddy_get_contact_alias(PURPLE_BUDDY(node)); /* We've found a buddy that matches this conversation. It's part of a * PurpleContact with more than one PurpleBuddy. Loop through the PurpleBuddies * in the contact and get all the logs. */ for (node2 = child ; node2 != NULL ; node2 = purple_blist_node_get_sibling_next(node2)) logs = g_list_concat(purple_log_get_logs(PURPLE_LOG_IM, purple_buddy_get_name(PURPLE_BUDDY(node2)), purple_buddy_get_account(PURPLE_BUDDY(node2))), logs = purple_log_get_logs(PURPLE_LOG_IM, name, account); logs = g_list_sort(logs, purple_log_compare); else if (PURPLE_IS_CHAT_CONVERSATION(c)) /* If we're not logging, don't show anything. * Otherwise, we might show a very old log. */ if (!purple_prefs_get_bool("/purple/logging/log_chats")) logs = purple_log_get_logs(PURPLE_LOG_CHAT, name, account); history = purple_log_read((PurpleLog*)logs->data, &flags); gtkconv = PIDGIN_CONVERSATION(c); /* FIXME: WebView has no options */ if (flags & PURPLE_LOG_READ_NO_NEWLINE) options |= GTK_IMHTML_NO_NEWLINE; /* FIXME: WebView has no protocol setting */ protocol = g_strdup(gtk_imhtml_get_protocol_name(GTK_IMHTML(gtkconv->imhtml))); gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), purple_account_get_protocol_name(((PurpleLog*)logs->data)->account)); /* TODO WebKit: Do this properly... */ if (!pidgin_webview_is_empty(PIDGIN_WEBVIEW(gtkconv->webview))) pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), "<BR>"); escaped_alias = g_markup_escape_text(alias, -1); dt = g_date_time_to_local(((PurpleLog *)logs->data)->time); header_date = g_date_time_format(dt, "%c"); header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias, header_date); pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), header); pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), history); pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), "<hr>"); /* FIXME: WebView has no protocol setting */ gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol); g_object_ref(G_OBJECT(gtkconv->webview)); g_idle_add(_scroll_webview_to_end, gtkconv->webview); g_list_free_full(logs, (GDestroyNotify)purple_log_free); history_prefs_check(PurplePlugin *plugin) if (!purple_prefs_get_bool("/purple/logging/log_ims") && !purple_prefs_get_bool("/purple/logging/log_chats")) /* Translators: Please maintain the use of ⇦ or ⇨ to represent the menu hierarchy */ purple_notify_warning(plugin, NULL, _("History Plugin Requires Logging"), _("Logging can be enabled from Tools ⇨ Preferences ⇨ Logging.\n\n" "Enabling logs for instant messages and/or chats will activate " "history for the same conversation type(s)."), NULL); static void history_prefs_cb(const char *name, PurplePrefType type, gconstpointer val, gpointer data) history_prefs_check((PurplePlugin *)data); static PidginPluginInfo * plugin_query(GError **error) const gchar * const authors[] = { "Sean Egan <seanegan@gmail.com>", return pidgin_plugin_info_new( "version", DISPLAY_VERSION, "category", N_("User interface"), "summary", N_("Shows recently logged conversations in new " "description", N_("When a new conversation is opened this plugin will " "insert the last conversation into the current " "website", PURPLE_WEBSITE, "abi-version", PURPLE_ABI_VERSION, plugin_load(PurplePlugin *plugin, GError **error) purple_signal_connect(purple_conversations_get_handle(), plugin, PURPLE_CALLBACK(historize), NULL); /* XXX: Do we want to listen to pidgin's "conversation-displayed" signal? */ purple_prefs_connect_callback(plugin, "/purple/logging/log_ims", history_prefs_cb, plugin); purple_prefs_connect_callback(plugin, "/purple/logging/log_chats", history_prefs_cb, plugin); history_prefs_check(plugin); plugin_unload(PurplePlugin *plugin, GError **error) PURPLE_PLUGIN_INIT(history, plugin_query, plugin_load, plugin_unload);