changeset 14388:f4af666fafe3

[gaim-migrate @ 17094] Contactize the conversations. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Thu, 31 Aug 2006 04:39:21 +0000
parents 39b0124a455d
children 746d535e9053
files console/gntblist.c console/gntconv.c console/gntconv.h console/libgnt/gnt.h console/libgnt/gntbox.c console/libgnt/gntmain.c
diffstat 6 files changed, 97 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/console/gntblist.c	Thu Aug 31 03:13:54 2006 +0000
+++ b/console/gntblist.c	Thu Aug 31 04:39:21 2006 +0000
@@ -17,6 +17,7 @@
 #include "gnttree.h"
 
 #include "gntblist.h"
+#include "gntconv.h"
 #include "gntstatus.h"
 #include <string.h>
 
@@ -496,9 +497,10 @@
 	if (GAIM_BLIST_NODE_IS_BUDDY(node))
 	{
 		GaimBuddy *buddy = (GaimBuddy *)node;
-		gaim_conversation_new(GAIM_CONV_TYPE_IM,
-				gaim_buddy_get_account(buddy),
-				gaim_buddy_get_name(buddy));
+		GaimConversation *conv =  gaim_conversation_new(GAIM_CONV_TYPE_IM,
+					gaim_buddy_get_account(buddy),
+					gaim_buddy_get_name(buddy));
+		gg_conversation_set_active(conv);
 	}
 	else if (GAIM_BLIST_NODE_IS_CHAT(node))
 	{
--- a/console/gntconv.c	Thu Aug 31 03:13:54 2006 +0000
+++ b/console/gntconv.c	Thu Aug 31 04:39:21 2006 +0000
@@ -22,15 +22,15 @@
 
 #include "config.h"
 
-GHashTable *ggconvs;
-
 typedef struct _GGConv GGConv;
 typedef struct _GGConvChat GGConvChat;
 typedef struct _GGConvIm GGConvIm;
 
 struct _GGConv
 {
-	GaimConversation *conv;
+	GList *list;
+	GaimConversation *active_conv;
+	/*GaimConversation *conv;*/
 
 	GntWidget *window;        /* the container */
 	GntWidget *entry;         /* entry */
@@ -61,7 +61,7 @@
 		const char *text = gnt_entry_get_text(GNT_ENTRY(ggconv->entry));
 		if (*text == '/')
 		{
-			GaimConversation *conv = ggconv->conv;
+			GaimConversation *conv = ggconv->active_conv;
 			GaimCmdStatus status;
 			const char *cmdline = text + 1;
 			char *error = NULL, *escape;
@@ -112,13 +112,13 @@
 		else
 		{
 			char *escape = g_markup_escape_text(text, -1);
-			switch (gaim_conversation_get_type(ggconv->conv))
+			switch (gaim_conversation_get_type(ggconv->active_conv))
 			{
 				case GAIM_CONV_TYPE_IM:
-					gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), escape, GAIM_MESSAGE_SEND);
+					gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->active_conv), escape, GAIM_MESSAGE_SEND);
 					break;
 				case GAIM_CONV_TYPE_CHAT:
-					gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), escape);
+					gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->active_conv), escape);
 					break;
 				default:
 					g_free(escape);
@@ -151,8 +151,13 @@
 static void
 closing_window(GntWidget *window, GGConv *ggconv)
 {
+	GList *list = ggconv->list;
 	ggconv->window = NULL;
-	gaim_conversation_destroy(ggconv->conv);
+	while (list) {
+		GaimConversation *conv = list->data;
+		list = list->next;
+		gaim_conversation_destroy(conv);
+	}
 }
 
 static void
@@ -169,24 +174,55 @@
 	gaim_prefs_set_int(PREF_ROOT "/position/y", y);
 }
 
+static GaimConversation *
+find_conv_with_contact(GaimConversation *conv)
+{
+	GaimBlistNode *node;
+	GaimBuddy *buddy = gaim_find_buddy(conv->account, conv->name);
+	GaimConversation *ret = NULL;
+
+	if (!buddy)
+		return NULL;
+
+	for (node = ((GaimBlistNode*)buddy)->parent->child; node; node = node->next) {
+		if (node == (GaimBlistNode*)buddy)
+			continue;
+		if ((ret = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM,
+				((GaimBuddy*)node)->name, ((GaimBuddy*)node)->account)) != NULL)
+			break;
+	}
+	return ret;
+}
+
 static void
 gg_create_conversation(GaimConversation *conv)
 {
-	GGConv *ggc = g_hash_table_lookup(ggconvs, conv);
+	GGConv *ggc = conv->ui_data;
 	char *title;
 	GaimConversationType type;
+	GaimConversation *cc;
 
 	if (ggc)
 		return;
 
-	ggc = g_new0(GGConv, 1);
-	g_hash_table_insert(ggconvs, conv, ggc);
+	cc = find_conv_with_contact(conv);
+	if (cc && cc->ui_data)
+		ggc = cc->ui_data;
+	else
+		ggc = g_new0(GGConv, 1);
 
-	ggc->conv = conv;
+	ggc->list = g_list_prepend(ggc->list, conv);
+	ggc->active_conv = conv;
 	conv->ui_data = ggc;
 
+	if (cc && cc->ui_data) {
+		gg_conversation_set_active(conv);
+		return;
+	}
+
 	type = gaim_conversation_get_type(conv);
 	title = g_strdup_printf(_("%s"), gaim_conversation_get_title(conv));
+	
 	ggc->window = gnt_box_new(FALSE, TRUE);
 	gnt_box_set_title(GNT_BOX(ggc->window), title);
 	gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE);
@@ -222,20 +258,36 @@
 static void
 gg_destroy_conversation(GaimConversation *conv)
 {
-	g_hash_table_remove(ggconvs, conv);
+	/* do stuff here */
+	GGConv *ggc = conv->ui_data;
+	ggc->list = g_list_remove(ggc->list, conv);
+	if (ggc->list && conv == ggc->active_conv)
+		ggc->active_conv = ggc->list->data;
+	
+	if (ggc->list == NULL) {
+		gnt_widget_destroy(ggc->window);
+		g_free(ggc);
+	}
 }
 
 static void
 gg_write_common(GaimConversation *conv, const char *who, const char *message,
 		GaimMessageFlags flags, time_t mtime)
 {
-	GGConv *ggconv = g_hash_table_lookup(ggconvs, conv); /* XXX: ggconv = conv->ui_data; should do */
+	GGConv *ggconv = conv->ui_data;
 	char *strip, *newline;
 	GntTextFormatFlags fl = 0;
 	int pos;
 
 	g_return_if_fail(ggconv != NULL);
 
+	if (ggconv->active_conv != conv) {
+		if (flags & (GAIM_MESSAGE_SEND | GAIM_MESSAGE_RECV))
+			gg_conversation_set_active(conv);
+		else
+			return;
+	}
+
 	pos = gnt_text_view_get_lines_below(GNT_TEXT_VIEW(ggconv->tv));
 
 	gnt_text_view_next_line(GNT_TEXT_VIEW(ggconv->tv));
@@ -408,14 +460,6 @@
 	.custom_smiley_close = NULL
 };
 
-static void
-destroy_ggconv(gpointer data)
-{
-	GGConv *ggconv = data;
-	gnt_widget_destroy(ggconv->window);
-	g_free(ggconv);
-}
-
 GaimConversationUiOps *gg_conv_get_ui_ops()
 {
 	return &conv_ui_ops;
@@ -536,8 +580,6 @@
 
 void gg_conversation_init()
 {
-	ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv);
-
 	gaim_prefs_add_none(PREF_ROOT);
 	gaim_prefs_add_none(PREF_ROOT "/size");
 	gaim_prefs_add_int(PREF_ROOT "/size/width", 70);
@@ -586,7 +628,16 @@
 
 void gg_conversation_uninit()
 {
-	g_hash_table_destroy(ggconvs);
-	ggconvs = NULL;
 }
 
+void gg_conversation_set_active(GaimConversation *conv)
+{
+	GGConv *ggconv = conv->ui_data;
+
+	g_return_if_fail(ggconv);
+	g_return_if_fail(g_list_find(ggconv->list, conv));
+
+	ggconv->active_conv = conv;
+	gnt_screen_rename_widget(ggconv->window, gaim_conversation_get_title(conv));
+}
+
--- a/console/gntconv.h	Thu Aug 31 03:13:54 2006 +0000
+++ b/console/gntconv.h	Thu Aug 31 04:39:21 2006 +0000
@@ -9,4 +9,7 @@
 
 void gg_conversation_uninit(void);
 
+/* Set a conversation as active in a contactized conversation */
+void gg_conversation_set_active(GaimConversation *conv);
+
 #endif
--- a/console/libgnt/gnt.h	Thu Aug 31 03:13:54 2006 +0000
+++ b/console/libgnt/gnt.h	Thu Aug 31 04:39:21 2006 +0000
@@ -21,6 +21,8 @@
 
 void gnt_screen_move_widget(GntWidget *widget, int x, int y);
 
+void gnt_screen_rename_widget(GntWidget *widget, const char *text);
+
 gboolean gnt_widget_has_focus(GntWidget *widget);
 
 void gnt_widget_set_urgent(GntWidget *widget);
--- a/console/libgnt/gntbox.c	Thu Aug 31 03:13:54 2006 +0000
+++ b/console/libgnt/gntbox.c	Thu Aug 31 04:39:21 2006 +0000
@@ -41,6 +41,9 @@
 		gchar *title = g_strdup(box->title);
 		int pos = g_utf8_strlen(title, -1), right;
 
+		mvwhline(widget->window, 0, 1, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
+				widget->priv.width - 2);
+
 		if (pos >= widget->priv.width - 4)
 		{
 			g_utf8_strncpy(title, box->title, widget->priv.width - 4);
--- a/console/libgnt/gntmain.c	Thu Aug 31 03:13:54 2006 +0000
+++ b/console/libgnt/gntmain.c	Thu Aug 31 04:39:21 2006 +0000
@@ -1188,3 +1188,10 @@
 	update_screen(NULL);
 }
 
+void gnt_screen_rename_widget(GntWidget *widget, const char *text)
+{
+	gnt_box_set_title(GNT_BOX(widget), text);
+	gnt_widget_draw(widget);
+	draw_taskbar(FALSE);
+}
+