pidgin/pidgin

49be7bdacd56
Parents e6c82f6c2485
Children 6fe2af91fac4
Contactize the message history when re-attaching the pidgin ui.
--- a/libpurple/conversation.c Wed Sep 19 06:19:19 2007 +0000
+++ b/libpurple/conversation.c Wed Sep 19 06:48:59 2007 +0000
@@ -225,6 +225,7 @@
msg->flags = flags;
msg->what = g_strdup(message);
msg->when = when;
+ msg->conv = conv;
conv->message_history = g_list_prepend(conv->message_history, msg);
}
--- a/libpurple/conversation.h Wed Sep 19 06:19:19 2007 +0000
+++ b/libpurple/conversation.h Wed Sep 19 06:48:59 2007 +0000
@@ -293,6 +293,7 @@
char *what;
PurpleMessageFlags flags;
time_t when;
+ PurpleConversation *conv;
};
/**
--- a/pidgin/gtkconv.c Wed Sep 19 06:19:19 2007 +0000
+++ b/pidgin/gtkconv.c Wed Sep 19 06:48:59 2007 +0000
@@ -7362,6 +7362,17 @@
pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC);
}
+/* Message history stuff */
+
+/* Compare two PurpleConvMessage's, according to time in ascending order. */
+static int
+message_compare(gconstpointer p1, gconstpointer p2)
+{
+ const PurpleConvMessage *m1 = p1, *m2 = p2;
+ return (m1->when > m2->when);
+}
+
+/* Adds some message history to the gtkconv. This happens in a idle-callback. */
static gboolean
add_message_history_to_gtkconv(gpointer data)
{
@@ -7369,48 +7380,106 @@
int count = 0;
int timer = gtkconv->attach.timer;
time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time"));
+ gboolean im = (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM);
gtkconv->attach.timer = 0;
while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */
PurpleConvMessage *msg = gtkconv->attach.current->data;
- if (when && when < msg->when) {
+ if (!im && when && when < msg->when) {
gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0);
g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);
}
- pidgin_conv_write_conv(gtkconv->active_conv, msg->who, msg->who, msg->what, msg->flags, msg->when);
- gtkconv->attach.current = gtkconv->attach.current->prev;
+ pidgin_conv_write_conv(msg->conv, msg->who, msg->who, msg->what, msg->flags, msg->when);
+ if (im) {
+ gtkconv->attach.current = g_list_delete_link(gtkconv->attach.current, gtkconv->attach.current);
+ } else {
+ gtkconv->attach.current = gtkconv->attach.current->prev;
+ }
count++;
}
gtkconv->attach.timer = timer;
if (gtkconv->attach.current)
return TRUE;
+ g_source_remove(gtkconv->attach.timer);
+ gtkconv->attach.timer = 0;
+ if (im) {
+ /* Print any message that was sent while the old history was being added back. */
+ GList *msgs = NULL;
+ GList *iter = gtkconv->convs;
+ for (; iter; iter = iter->next) {
+ PurpleConversation *conv = iter->data;
+ GList *history = purple_conversation_get_message_history(conv);
+ for (; history; history = history->next) {
+ PurpleConvMessage *msg = history->data;
+ if (msg->when > when)
+ msgs = g_list_prepend(msgs, msg);
+ }
+ }
+ msgs = g_list_sort(msgs, message_compare);
+ for (; msgs; msgs = g_list_delete_link(msgs, msgs)) {
+ PurpleConvMessage *msg = msgs->data;
+ pidgin_conv_write_conv(msg->conv, msg->who, msg->who, msg->what, msg->flags, msg->when);
+ }
+ gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0);
+ g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);
+ }
+
+ g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL);
purple_signal_emit(pidgin_conversations_get_handle(),
"conversation-displayed", gtkconv);
- g_source_remove(gtkconv->attach.timer);
- gtkconv->attach.timer = 0;
return FALSE;
}
+static void
+pidgin_conv_attach(PurpleConversation *conv)
+{
+ int timer;
+ purple_conversation_set_data(conv, "unseen-count", NULL);
+ purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops());
+ private_gtkconv_new(conv, FALSE);
+ timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
+ if (timer)
+ purple_timeout_remove(timer);
+}
+
gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv)
{
GList *list;
PidginConversation *gtkconv;
- int timer;
if (PIDGIN_IS_PIDGIN_CONVERSATION(conv))
return FALSE;
- purple_conversation_set_data(conv, "unseen-count", NULL);
- purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops());
- private_gtkconv_new(conv, FALSE);
+ pidgin_conv_attach(conv);
gtkconv = PIDGIN_CONVERSATION(conv);
list = purple_conversation_get_message_history(conv);
if (list) {
+ switch (purple_conversation_get_type(conv)) {
+ case PURPLE_CONV_TYPE_IM:
+ {
+ GList *convs;
+ list = g_list_copy(list);
+ for (convs = purple_get_ims(); convs; convs = convs->next)
+ if (convs->data != conv &&
+ pidgin_conv_find_gtkconv(convs->data) == gtkconv) {
+ pidgin_conv_attach(convs->data);
+ list = g_list_concat(list, g_list_copy(purple_conversation_get_message_history(convs->data)));
+ }
+ list = g_list_sort(list, message_compare);
+ gtkconv->attach.current = list;
+ list = g_list_last(list);
+ break;
+ }
+ case PURPLE_CONV_TYPE_CHAT:
+ gtkconv->attach.current = g_list_last(list);
+ break;
+ default:
+ g_return_val_if_reached(TRUE);
+ }
g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time",
GINT_TO_POINTER(((PurpleConvMessage*)(list->data))->when));
- gtkconv->attach.current = g_list_last(list);
gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv);
} else {
purple_signal_emit(pidgin_conversations_get_handle(),
@@ -7422,10 +7491,6 @@
pidgin_conv_chat_add_users(conv, PURPLE_CONV_CHAT(conv)->in_room, TRUE);
}
- timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
- if (timer)
- purple_timeout_remove(timer);
-
return TRUE;
}