comparison src/gtkconv.c @ 10810:9a1ced2bc585

[gaim-migrate @ 12463] This makes conversations contact aware, or is a start to it anyway. All messages from the same contact will appear in the same IM tab. Whoever messaged you last is who your messages go to. Don't forget to run make install in the top level src directory, or some plugin will likely crash gaim, as I changed a struct they use. Known bugs include a crash if you close the convo window (clicking the X on the tab doesn't crash however [actually it used to, but i fixed that one already]), and the history plugin inserting history when it shouldn't. There's probably many more tiny bugs. If you're wondering "how does it handle X?" the answer is probably it doesn't. However, I think this is all stuff our CPWs can handle, if I don't have time to fix it first (and I probably won't til friday). committer: Tailor Script <tailor@pidgin.im>
author Tim Ringenbach <marv@pidgin.im>
date Mon, 11 Apr 2005 02:20:34 +0000
parents f9e01ccd6046
children d087e928ffd1
comparison
equal deleted inserted replaced
10809:f9e01ccd6046 10810:9a1ced2bc585
111 } InviteBuddyInfo; 111 } InviteBuddyInfo;
112 112
113 static GtkWidget *invite_dialog = NULL; 113 static GtkWidget *invite_dialog = NULL;
114 114
115 /* Prototypes. <-- because Paco-Paco hates this comment. */ 115 /* Prototypes. <-- because Paco-Paco hates this comment. */
116 static void got_typing_keypress(GaimConversation *conv, gboolean first); 116 static void got_typing_keypress(GaimGtkConversation *gtkconv, gboolean first);
117 static GList *generate_invite_user_names(GaimConnection *gc); 117 static GList *generate_invite_user_names(GaimConnection *gc);
118 static void add_chat_buddy_common(GaimConversation *conv, 118 static void add_chat_buddy_common(GaimConversation *conv,
119 const char *name); 119 const char *name);
120 static gboolean tab_complete(GaimConversation *conv); 120 static gboolean tab_complete(GaimConversation *conv);
121 static void update_typing_icon(GaimConversation *conv); 121 static void update_typing_icon(GaimGtkConversation *gtkconv);
122 static gboolean update_send_as_selection(GaimConvWindow *win); 122 static gboolean update_send_as_selection(GaimConvWindow *win);
123 static char *item_factory_translate_func (const char *path, gpointer func_data); 123 static char *item_factory_translate_func (const char *path, gpointer func_data);
124 124
125 /************************************************************************** 125 /**************************************************************************
126 * Callbacks 126 * Callbacks
134 134
135 return TRUE; 135 return TRUE;
136 } 136 }
137 137
138 static gint 138 static gint
139 close_conv_cb(GtkWidget *w, gpointer d) 139 close_conv_cb(GtkWidget *w, GaimGtkConversation *gtkconv)
140 { 140 {
141 GaimConversation *conv = (GaimConversation *)d; 141 GList *list = g_list_copy(gtkconv->convs), *l;
142 142
143 gaim_conversation_destroy(conv); 143 l = list;
144 144 while (l) {
145 GaimConversation *conv = l->data;
146 gaim_conversation_destroy(conv);
147 l = l->next;
148 }
149
150 g_list_free(list);
151
145 return TRUE; 152 return TRUE;
146 } 153 }
147 154
148 static gboolean 155 static gboolean
149 size_allocate_cb(GtkWidget *w, GtkAllocation *allocation, GaimConversation *conv) 156 size_allocate_cb(GtkWidget *w, GtkAllocation *allocation, GaimGtkConversation *gtkconv)
150 { 157 {
151 GaimGtkConversation *gtkconv; 158 GaimConversation *conv = gtkconv->active_conv;
152 GaimConvWindow *win = gaim_conversation_get_window(conv); 159 GaimConvWindow *win = gaim_conversation_get_window(conv);
153 160
154 if (!GTK_WIDGET_VISIBLE(w)) 161 if (!GTK_WIDGET_VISIBLE(w))
155 return FALSE; 162 return FALSE;
156 163
157 if (!GAIM_IS_GTK_CONVERSATION(conv)) 164 if (!GAIM_IS_GTK_CONVERSATION(conv))
158 return FALSE; 165 return FALSE;
159
160 gtkconv = GAIM_GTK_CONVERSATION(conv);
161 166
162 /* I find that I resize the window when it has a bunch of conversations in it, mostly so that the tab bar 167 /* I find that I resize the window when it has a bunch of conversations in it, mostly so that the tab bar
163 * will fit, but then I don't want new windows taking up the entire screen. I check to see if there is only one 168 * will fit, but then I don't want new windows taking up the entire screen. I check to see if there is only one
164 * conversation in the window. This way we'll be setting new windows to the size of the last resized new window. */ 169 * conversation in the window. This way we'll be setting new windows to the size of the last resized new window. */
165 170
194 if (GTK_WIDGET_STATE(widget) == GTK_STATE_ACTIVE) 199 if (GTK_WIDGET_STATE(widget) == GTK_STATE_ACTIVE)
195 gtk_widget_set_state(widget, GTK_STATE_NORMAL); 200 gtk_widget_set_state(widget, GTK_STATE_NORMAL);
196 } 201 }
197 202
198 static void 203 static void
199 default_formatize(GaimConversation *conv) 204 default_formatize(GaimGtkConversation *c)
200 { 205 {
201 GaimGtkConversation *c = GAIM_GTK_CONVERSATION(conv); 206 GaimConversation *conv = c->active_conv;
202 207
203 if (conv->features & GAIM_CONNECTION_HTML) 208 if (conv->features & GAIM_CONNECTION_HTML)
204 { 209 {
205 if (gaim_prefs_get_bool("/gaim/gtk/conversations/send_formatting")) 210 if (gaim_prefs_get_bool("/gaim/gtk/conversations/send_formatting"))
206 { 211 {
449 g_free(cmd); 454 g_free(cmd);
450 return FALSE; 455 return FALSE;
451 } 456 }
452 457
453 static void 458 static void
454 send_cb(GtkWidget *widget, GaimConversation *conv) 459 send_cb(GtkWidget *widget, GaimGtkConversation *gtkconv)
455 { 460 {
456 GaimGtkConversation *gtkconv; 461 GaimConversation *conv = gtkconv->active_conv;
457 GaimAccount *account; 462 GaimAccount *account;
458 GaimConnection *gc; 463 GaimConnection *gc;
459 char *buf, *clean; 464 char *buf, *clean;
460 465
461 gtkconv = GAIM_GTK_CONVERSATION(conv);
462 account = gaim_conversation_get_account(conv); 466 account = gaim_conversation_get_account(conv);
463 467
464 if (!gaim_account_is_connected(account)) 468 if (!gaim_account_is_connected(account))
465 return; 469 return;
466 470
468 gaim_conv_chat_has_left(GAIM_CONV_CHAT(conv))) 472 gaim_conv_chat_has_left(GAIM_CONV_CHAT(conv)))
469 return; 473 return;
470 474
471 if (check_for_and_do_command(conv)) { 475 if (check_for_and_do_command(conv)) {
472 gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry)); 476 gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry));
473 default_formatize(conv); 477 default_formatize(gtkconv);
474 return; 478 return;
475 } 479 }
476 480
477 buf = gtk_imhtml_get_markup(GTK_IMHTML(gtkconv->entry)); 481 buf = gtk_imhtml_get_markup(GTK_IMHTML(gtkconv->entry));
478 clean = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL); 482 clean = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL);
510 514
511 g_free(clean); 515 g_free(clean);
512 g_free(buf); 516 g_free(buf);
513 517
514 gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry)); 518 gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry));
515 default_formatize(conv); 519 default_formatize(gtkconv);
516 } 520 }
517 521
518 static void 522 static void
519 add_remove_cb(GtkWidget *widget, GaimConversation *conv) 523 add_remove_cb(GtkWidget *widget, GaimGtkConversation *gtkconv)
520 { 524 {
521 GaimAccount *account; 525 GaimAccount *account;
522 const char *name; 526 const char *name;
527 GaimConversation *conv = gtkconv->active_conv;
523 528
524 account = gaim_conversation_get_account(conv); 529 account = gaim_conversation_get_account(conv);
525 name = gaim_conversation_get_name(conv); 530 name = gaim_conversation_get_name(conv);
526 531
527 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) { 532 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) {
543 } 548 }
544 549
545 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); 550 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry);
546 } 551 }
547 552
548 static void chat_do_info(GaimConversation *conv, const char *who) 553 static void chat_do_info(GaimGtkConversation *gtkconv, const char *who)
549 { 554 {
555 GaimConversation *conv = gtkconv->active_conv;
550 GaimPluginProtocolInfo *prpl_info = NULL; 556 GaimPluginProtocolInfo *prpl_info = NULL;
551 GaimConnection *gc; 557 GaimConnection *gc;
552 558
553 if ((gc = gaim_conversation_get_gc(conv))) { 559 if ((gc = gaim_conversation_get_gc(conv))) {
554 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); 560 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
567 } 573 }
568 } 574 }
569 575
570 576
571 static void 577 static void
572 info_cb(GtkWidget *widget, GaimConversation *conv) 578 info_cb(GtkWidget *widget, GaimGtkConversation *gtkconv)
573 { 579 {
574 GaimGtkConversation *gtkconv; 580 GaimConversation *conv = gtkconv->active_conv;
575
576 gtkconv = GAIM_GTK_CONVERSATION(conv);
577 581
578 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) { 582 if (gaim_conversation_get_type(conv) == GAIM_CONV_IM) {
579 serv_get_info(gaim_conversation_get_gc(conv), 583 serv_get_info(gaim_conversation_get_gc(conv),
580 gaim_conversation_get_name(conv)); 584 gaim_conversation_get_name(conv));
581 585
596 if (gtk_tree_selection_get_selected(sel, NULL, &iter)) 600 if (gtk_tree_selection_get_selected(sel, NULL, &iter))
597 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &name, -1); 601 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &name, -1);
598 else 602 else
599 return; 603 return;
600 604
601 chat_do_info(conv, name); 605 chat_do_info(gtkconv, name);
602 g_free(name); 606 g_free(name);
603 } 607 }
604 } 608 }
605 609
606 static void 610 static void
607 block_cb(GtkWidget *widget, GaimConversation *conv) 611 block_cb(GtkWidget *widget, GaimGtkConversation *gtkconv)
608 { 612 {
613 GaimConversation *conv = gtkconv->active_conv;
609 GaimAccount *account; 614 GaimAccount *account;
610 615
611 account = gaim_conversation_get_account(conv); 616 account = gaim_conversation_get_account(conv);
612 617
613 if (account != NULL && gaim_account_is_connected(account)) 618 if (account != NULL && gaim_account_is_connected(account))
715 {"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, 0}, 720 {"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, 0},
716 {"application/x-im-contact", 0, 1} 721 {"application/x-im-contact", 0, 1}
717 }; 722 };
718 723
719 static void 724 static void
720 invite_cb(GtkWidget *widget, GaimConversation *conv) 725 invite_cb(GtkWidget *widget, GaimGtkConversation *gtkconv)
721 { 726 {
727 GaimConversation *conv = gtkconv->active_conv;
722 InviteBuddyInfo *info = NULL; 728 InviteBuddyInfo *info = NULL;
723 729
724 if (invite_dialog == NULL) { 730 if (invite_dialog == NULL) {
725 GaimConnection *gc; 731 GaimConnection *gc;
726 GaimConvWindow *win; 732 GaimConvWindow *win;
859 menu_new_conv_cb(gpointer data, guint action, GtkWidget *widget) 865 menu_new_conv_cb(gpointer data, guint action, GtkWidget *widget)
860 { 866 {
861 gaim_gtkdialogs_im(); 867 gaim_gtkdialogs_im();
862 } 868 }
863 869
870 /* XXX change how this works, unless someone can justify it, i think
871 * it's really stupid, lets just grab the text from the imhtml, not
872 * keep an extra copy of it! */
864 static void 873 static void
865 savelog_writefile_cb(void *user_data, const char *filename) 874 savelog_writefile_cb(void *user_data, const char *filename)
866 { 875 {
867 GaimConversation *conv = (GaimConversation *)user_data; 876 GaimConversation *conv = (GaimConversation *)user_data;
868 FILE *fp; 877 FILE *fp;
1117 GaimConvWindow *win = (GaimConvWindow *)data; 1126 GaimConvWindow *win = (GaimConvWindow *)data;
1118 GaimConversation *conv; 1127 GaimConversation *conv;
1119 1128
1120 conv = gaim_conv_window_get_active_conversation(win); 1129 conv = gaim_conv_window_get_active_conversation(win);
1121 1130
1122 info_cb(NULL, conv); 1131 info_cb(NULL, GAIM_GTK_CONVERSATION(conv));
1123 } 1132 }
1124 1133
1125 static void 1134 static void
1126 menu_invite_cb(gpointer data, guint action, GtkWidget *widget) 1135 menu_invite_cb(gpointer data, guint action, GtkWidget *widget)
1127 { 1136 {
1128 GaimConvWindow *win = (GaimConvWindow *)data; 1137 GaimConvWindow *win = (GaimConvWindow *)data;
1129 GaimConversation *conv; 1138 GaimConversation *conv;
1130 1139
1131 conv = gaim_conv_window_get_active_conversation(win); 1140 conv = gaim_conv_window_get_active_conversation(win);
1132 1141
1133 invite_cb(NULL, conv); 1142 invite_cb(NULL, GAIM_GTK_CONVERSATION(conv));
1134 } 1143 }
1135 1144
1136 static void 1145 static void
1137 menu_warn_cb(gpointer data, guint action, GtkWidget *widget) 1146 menu_warn_cb(gpointer data, guint action, GtkWidget *widget)
1138 { 1147 {
1154 GaimConvWindow *win = (GaimConvWindow *)data; 1163 GaimConvWindow *win = (GaimConvWindow *)data;
1155 GaimConversation *conv; 1164 GaimConversation *conv;
1156 1165
1157 conv = gaim_conv_window_get_active_conversation(win); 1166 conv = gaim_conv_window_get_active_conversation(win);
1158 1167
1159 block_cb(NULL, conv); 1168 block_cb(NULL, GAIM_GTK_CONVERSATION(conv));
1160 } 1169 }
1161 1170
1162 static void 1171 static void
1163 menu_add_remove_cb(gpointer data, guint action, GtkWidget *widget) 1172 menu_add_remove_cb(gpointer data, guint action, GtkWidget *widget)
1164 { 1173 {
1165 GaimConvWindow *win = (GaimConvWindow *)data; 1174 GaimConvWindow *win = (GaimConvWindow *)data;
1166 GaimConversation *conv; 1175 GaimConversation *conv;
1167 1176
1168 conv = gaim_conv_window_get_active_conversation(win); 1177 conv = gaim_conv_window_get_active_conversation(win);
1169 1178
1170 add_remove_cb(NULL, conv); 1179 add_remove_cb(NULL, GAIM_GTK_CONVERSATION(conv));
1171 } 1180 }
1172 1181
1173 static void 1182 static void
1174 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) 1183 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget)
1175 { 1184 {
1176 GaimConvWindow *win = (GaimConvWindow *)data; 1185 GaimConvWindow *win = (GaimConvWindow *)data;
1177 1186
1178 close_conv_cb(NULL, gaim_conv_window_get_active_conversation(win)); 1187 close_conv_cb(NULL, GAIM_GTK_CONVERSATION(gaim_conv_window_get_active_conversation(win)));
1179 } 1188 }
1180 1189
1181 static void 1190 static void
1182 menu_logging_cb(gpointer data, guint action, GtkWidget *widget) 1191 menu_logging_cb(gpointer data, guint action, GtkWidget *widget)
1183 { 1192 {
1248 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), 1257 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
1249 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))); 1258 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
1250 } 1259 }
1251 1260
1252 static void 1261 static void
1253 chat_do_im(GaimConversation *conv, const char *who) 1262 chat_do_im(GaimGtkConversation *gtkconv, const char *who)
1254 { 1263 {
1264 GaimConversation *conv = gtkconv->active_conv;
1255 GaimAccount *account; 1265 GaimAccount *account;
1256 GaimConnection *gc; 1266 GaimConnection *gc;
1257 GaimPluginProtocolInfo *prpl_info = NULL; 1267 GaimPluginProtocolInfo *prpl_info = NULL;
1258 char *real_who; 1268 char *real_who;
1259 1269
1278 1288
1279 g_free(real_who); 1289 g_free(real_who);
1280 } 1290 }
1281 1291
1282 static void 1292 static void
1283 chat_im_button_cb(GtkWidget *widget, GaimConversation *conv) 1293 chat_im_button_cb(GtkWidget *widget, GaimGtkConversation *gtkconv)
1284 { 1294 {
1285 GaimGtkConversation *gtkconv;
1286 GaimGtkChatPane *gtkchat; 1295 GaimGtkChatPane *gtkchat;
1287 GtkTreeIter iter; 1296 GtkTreeIter iter;
1288 GtkTreeModel *model; 1297 GtkTreeModel *model;
1289 GtkTreeSelection *sel; 1298 GtkTreeSelection *sel;
1290 char *name; 1299 char *name;
1291 1300
1292 gtkconv = GAIM_GTK_CONVERSATION(conv);
1293 gtkchat = gtkconv->u.chat; 1301 gtkchat = gtkconv->u.chat;
1294 1302
1295 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); 1303 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
1296 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); 1304 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list));
1297 1305
1298 if (gtk_tree_selection_get_selected(sel, NULL, &iter)) 1306 if (gtk_tree_selection_get_selected(sel, NULL, &iter))
1299 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &name, -1); 1307 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &name, -1);
1300 else 1308 else
1301 return; 1309 return;
1302 1310
1303 chat_do_im(conv, name); 1311 chat_do_im(gtkconv, name);
1304 g_free(name); 1312 g_free(name);
1305 } 1313 }
1306 1314
1307 static void 1315 static void
1308 ignore_cb(GtkWidget *w, GaimConversation *conv) 1316 ignore_cb(GtkWidget *w, GaimGtkConversation *gtkconv)
1309 { 1317 {
1310 GaimGtkConversation *gtkconv; 1318 GaimConversation *conv = gtkconv->active_conv;
1311 GaimGtkChatPane *gtkchat; 1319 GaimGtkChatPane *gtkchat;
1312 GaimConvChat *chat; 1320 GaimConvChat *chat;
1313 GtkTreeIter iter; 1321 GtkTreeIter iter;
1314 GtkTreeModel *model; 1322 GtkTreeModel *model;
1315 GtkTreeSelection *sel; 1323 GtkTreeSelection *sel;
1316 char *name; 1324 char *name;
1317 1325
1318 chat = GAIM_CONV_CHAT(conv); 1326 chat = GAIM_CONV_CHAT(conv);
1319 gtkconv = GAIM_GTK_CONVERSATION(conv);
1320 gtkchat = gtkconv->u.chat; 1327 gtkchat = gtkconv->u.chat;
1321 1328
1322 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); 1329 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
1323 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); 1330 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list));
1324 1331
1337 add_chat_buddy_common(conv, name); 1344 add_chat_buddy_common(conv, name);
1338 g_free(name); 1345 g_free(name);
1339 } 1346 }
1340 1347
1341 static void 1348 static void
1342 menu_chat_im_cb(GtkWidget *w, GaimConversation *conv) 1349 menu_chat_im_cb(GtkWidget *w, GaimGtkConversation *gtkconv)
1343 { 1350 {
1344 const char *who = g_object_get_data(G_OBJECT(w), "user_data"); 1351 const char *who = g_object_get_data(G_OBJECT(w), "user_data");
1345 1352
1346 chat_do_im(conv, who); 1353 chat_do_im(gtkconv, who);
1347 } 1354 }
1348 1355
1349 static void 1356 static void
1350 menu_chat_send_file_cb(GtkWidget *w, GaimConversation *conv) 1357 menu_chat_send_file_cb(GtkWidget *w, GaimGtkConversation *gtkconv)
1351 { 1358 {
1359 GaimConversation *conv = gtkconv->active_conv;
1352 const char *who = g_object_get_data(G_OBJECT(w), "user_data"); 1360 const char *who = g_object_get_data(G_OBJECT(w), "user_data");
1353 GaimConnection *gc = gaim_conversation_get_gc(conv); 1361 GaimConnection *gc = gaim_conversation_get_gc(conv);
1354 1362
1355 serv_send_file(gc, who, NULL); 1363 serv_send_file(gc, who, NULL);
1356 } 1364 }
1357 1365
1358 static void 1366 static void
1359 menu_chat_info_cb(GtkWidget *w, GaimConversation *conv) 1367 menu_chat_info_cb(GtkWidget *w, GaimGtkConversation *gtkconv)
1360 { 1368 {
1361 char *who; 1369 char *who;
1362 1370
1363 who = g_object_get_data(G_OBJECT(w), "user_data"); 1371 who = g_object_get_data(G_OBJECT(w), "user_data");
1364 1372
1365 chat_do_info(conv, who); 1373 chat_do_info(gtkconv, who);
1366 } 1374 }
1367 1375
1368 static void 1376 static void
1369 menu_chat_get_away_cb(GtkWidget *w, GaimConversation *conv) 1377 menu_chat_get_away_cb(GtkWidget *w, GaimGtkConversation *gtkconv)
1370 { 1378 {
1379 GaimConversation *conv = gtkconv->active_conv;
1371 GaimPluginProtocolInfo *prpl_info = NULL; 1380 GaimPluginProtocolInfo *prpl_info = NULL;
1372 GaimConnection *gc; 1381 GaimConnection *gc;
1373 char *who; 1382 char *who;
1374 1383
1375 gc = gaim_conversation_get_gc(conv); 1384 gc = gaim_conversation_get_gc(conv);
1389 } 1398 }
1390 } 1399 }
1391 } 1400 }
1392 1401
1393 static void 1402 static void
1394 menu_chat_add_remove_cb(GtkWidget *w, GaimConversation *conv) 1403 menu_chat_add_remove_cb(GtkWidget *w, GaimGtkConversation *gtkconv)
1395 { 1404 {
1405 GaimConversation *conv = gtkconv->active_conv;
1396 GaimAccount *account; 1406 GaimAccount *account;
1397 GaimBuddy *b; 1407 GaimBuddy *b;
1398 char *name; 1408 char *name;
1399 1409
1400 account = gaim_conversation_get_account(conv); 1410 account = gaim_conversation_get_account(conv);
1473 return menu; 1483 return menu;
1474 } 1484 }
1475 1485
1476 1486
1477 static gint 1487 static gint
1478 gtkconv_chat_popup_menu_cb(GtkWidget *widget, GaimConversation *conv) 1488 gtkconv_chat_popup_menu_cb(GtkWidget *widget, GaimGtkConversation *gtkconv)
1479 { 1489 {
1480 GaimGtkConversation *gtkconv; 1490 GaimConversation *conv = gtkconv->active_conv;
1481 GaimPluginProtocolInfo *prpl_info = NULL; 1491 GaimPluginProtocolInfo *prpl_info = NULL;
1482 GaimGtkChatPane *gtkchat; 1492 GaimGtkChatPane *gtkchat;
1483 GaimConnection *gc; 1493 GaimConnection *gc;
1484 GaimAccount *account; 1494 GaimAccount *account;
1485 GtkTreeSelection *sel; 1495 GtkTreeSelection *sel;
1513 } 1523 }
1514 1524
1515 1525
1516 static gint 1526 static gint
1517 right_click_chat_cb(GtkWidget *widget, GdkEventButton *event, 1527 right_click_chat_cb(GtkWidget *widget, GdkEventButton *event,
1518 GaimConversation *conv) 1528 GaimGtkConversation *gtkconv)
1519 { 1529 {
1520 GaimGtkConversation *gtkconv; 1530 GaimConversation *conv = gtkconv->active_conv;
1521 GaimPluginProtocolInfo *prpl_info = NULL; 1531 GaimPluginProtocolInfo *prpl_info = NULL;
1522 GaimGtkChatPane *gtkchat; 1532 GaimGtkChatPane *gtkchat;
1523 GaimConnection *gc; 1533 GaimConnection *gc;
1524 GaimAccount *account; 1534 GaimAccount *account;
1525 GtkTreePath *path; 1535 GtkTreePath *path;
1527 GtkTreeModel *model; 1537 GtkTreeModel *model;
1528 GtkTreeViewColumn *column; 1538 GtkTreeViewColumn *column;
1529 gchar *who; 1539 gchar *who;
1530 int x, y; 1540 int x, y;
1531 1541
1532 gtkconv = GAIM_GTK_CONVERSATION(conv);
1533 gtkchat = gtkconv->u.chat; 1542 gtkchat = gtkconv->u.chat;
1534 account = gaim_conversation_get_account(conv); 1543 account = gaim_conversation_get_account(conv);
1535 gc = account->gc; 1544 gc = account->gc;
1536 1545
1537 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); 1546 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
1550 1559
1551 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path); 1560 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
1552 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); 1561 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
1553 1562
1554 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { 1563 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
1555 chat_do_im(conv, who); 1564 chat_do_im(gtkconv, who);
1556 } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { 1565 } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
1557 GtkWidget *menu = create_chat_menu (conv, who, prpl_info, gc); 1566 GtkWidget *menu = create_chat_menu (conv, who, prpl_info, gc);
1558 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 1567 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
1559 event->button, event->time); 1568 event->button, event->time);
1560 } 1569 }
1630 GaimGtkConversation *gtkconv; 1639 GaimGtkConversation *gtkconv;
1631 GaimGtkWindow *gtkwin; 1640 GaimGtkWindow *gtkwin;
1632 int numconvs; 1641 int numconvs;
1633 int curconv; 1642 int curconv;
1634 1643
1635 conv = (GaimConversation *)data; 1644 gtkconv = (GaimGtkConversation *)data;
1636 gtkconv = GAIM_GTK_CONVERSATION(conv); 1645 conv = gtkconv->active_conv;;
1637 win = gaim_conversation_get_window(conv); 1646 win = gaim_conversation_get_window(conv);
1638 gtkwin = GAIM_GTK_WINDOW(win); 1647 gtkwin = GAIM_GTK_WINDOW(win);
1639 numconvs = gaim_conv_window_get_conversation_count(win); 1648 numconvs = gaim_conv_window_get_conversation_count(win);
1640 curconv = gaim_conversation_get_index(conv); 1649 curconv = gaim_conversation_get_index(conv);
1641 1650
1835 1844
1836 gaim_conversation_set_account(conv, account); 1845 gaim_conversation_set_account(conv, account);
1837 1846
1838 gtkconv = GAIM_GTK_CONVERSATION(conv); 1847 gtkconv = GAIM_GTK_CONVERSATION(conv);
1839 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), 1848 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
1840 gaim_account_get_protocol_name(conv->account)); 1849 gaim_account_get_protocol_name(conv->account));
1841 } 1850 }
1842 1851
1843 static void 1852 static void
1844 insert_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *position, 1853 insert_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *position,
1845 gchar *new_text, gint new_text_length, gpointer user_data) 1854 gchar *new_text, gint new_text_length, gpointer user_data)
1846 { 1855 {
1847 GaimConversation *conv = (GaimConversation *)user_data; 1856 GaimGtkConversation *gtkconv = (GaimGtkConversation *)user_data;
1848 1857 GaimConversation *conv;
1849 g_return_if_fail(conv != NULL); 1858
1859 g_return_if_fail(gtkconv != NULL);
1860
1861 conv = gtkconv->active_conv;
1850 1862
1851 if (!gaim_prefs_get_bool("/core/conversations/im/send_typing")) 1863 if (!gaim_prefs_get_bool("/core/conversations/im/send_typing"))
1852 return; 1864 return;
1853 1865
1854 got_typing_keypress(conv, (gtk_text_iter_is_start(position) && 1866 got_typing_keypress(gtkconv, (gtk_text_iter_is_start(position) &&
1855 gtk_text_iter_is_end(position))); 1867 gtk_text_iter_is_end(position)));
1856 } 1868 }
1857 1869
1858 static void 1870 static void
1859 delete_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *start_pos, 1871 delete_text_cb(GtkTextBuffer *textbuffer, GtkTextIter *start_pos,
1860 GtkTextIter *end_pos, gpointer user_data) 1872 GtkTextIter *end_pos, gpointer user_data)
1861 { 1873 {
1862 GaimConversation *conv = (GaimConversation *)user_data; 1874 GaimGtkConversation *gtkconv = (GaimGtkConversation *)user_data;
1875 GaimConversation *conv;
1863 GaimConvIm *im; 1876 GaimConvIm *im;
1864 1877
1865 g_return_if_fail(conv != NULL); 1878 g_return_if_fail(gtkconv != NULL);
1879
1880 conv = gtkconv->active_conv;
1866 1881
1867 if (!gaim_prefs_get_bool("/core/conversations/im/send_typing")) 1882 if (!gaim_prefs_get_bool("/core/conversations/im/send_typing"))
1868 return; 1883 return;
1869 1884
1870 im = GAIM_CONV_IM(conv); 1885 im = GAIM_CONV_IM(conv);
1879 gaim_conversation_get_name(conv), 1894 gaim_conversation_get_name(conv),
1880 GAIM_NOT_TYPING); 1895 GAIM_NOT_TYPING);
1881 } 1896 }
1882 else { 1897 else {
1883 /* We're deleting, but not all of it, so it counts as typing. */ 1898 /* We're deleting, but not all of it, so it counts as typing. */
1884 got_typing_keypress(conv, FALSE); 1899 got_typing_keypress(gtkconv, FALSE);
1885 } 1900 }
1886 } 1901 }
1887 1902
1888 static void 1903 static void
1889 notebook_init_grab(GaimGtkWindow *gtkwin, GtkWidget *widget) 1904 notebook_init_grab(GaimGtkWindow *gtkwin, GtkWidget *widget)
2367 } 2382 }
2368 2383
2369 static gboolean 2384 static gboolean
2370 redraw_icon(gpointer data) 2385 redraw_icon(gpointer data)
2371 { 2386 {
2372 GaimConversation *conv = (GaimConversation *)data; 2387 GaimGtkConversation *gtkconv = (GaimGtkConversation *)data;
2373 GaimGtkConversation *gtkconv; 2388 GaimConversation *conv = gtkconv->active_conv;
2374 GaimAccount *account; 2389 GaimAccount *account;
2375 GaimPluginProtocolInfo *prpl_info = NULL; 2390 GaimPluginProtocolInfo *prpl_info = NULL;
2376 2391
2377 GdkPixbuf *buf; 2392 GdkPixbuf *buf;
2378 GdkPixbuf *scale; 2393 GdkPixbuf *scale;
2425 2440
2426 return FALSE; 2441 return FALSE;
2427 } 2442 }
2428 2443
2429 static void 2444 static void
2430 start_anim(GtkObject *obj, GaimConversation *conv) 2445 start_anim(GtkObject *obj, GaimGtkConversation *gtkconv)
2431 { 2446 {
2432 GaimGtkConversation *gtkconv; 2447 GaimConversation *conv = gtkconv->active_conv;
2433 int delay; 2448 int delay;
2434
2435 if (!GAIM_IS_GTK_CONVERSATION(conv))
2436 return;
2437
2438 gtkconv = GAIM_GTK_CONVERSATION(conv);
2439 2449
2440 if (gtkconv->u.im->anim == NULL) 2450 if (gtkconv->u.im->anim == NULL)
2441 return; 2451 return;
2442 2452
2443 if (gtkconv->u.im->icon_timer != 0) 2453 if (gtkconv->u.im->icon_timer != 0)
2449 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter); 2459 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter);
2450 2460
2451 if (delay < 100) 2461 if (delay < 100)
2452 delay = 100; 2462 delay = 100;
2453 2463
2454 gtkconv->u.im->icon_timer = g_timeout_add(delay, redraw_icon, conv); 2464 gtkconv->u.im->icon_timer = g_timeout_add(delay, redraw_icon, conv);
2455 } 2465 }
2456 2466
2457 static void 2467 static void
2458 stop_anim(GtkObject *obj, GaimConversation *conv) 2468 stop_anim(GtkObject *obj, GaimGtkConversation *gtkconv)
2459 { 2469 {
2460 GaimGtkConversation *gtkconv;
2461
2462 if (!GAIM_IS_GTK_CONVERSATION(conv))
2463 return;
2464
2465 gtkconv = GAIM_GTK_CONVERSATION(conv);
2466
2467 if (gtkconv->u.im->icon_timer != 0) 2470 if (gtkconv->u.im->icon_timer != 0)
2468 g_source_remove(gtkconv->u.im->icon_timer); 2471 g_source_remove(gtkconv->u.im->icon_timer);
2469 2472
2470 gtkconv->u.im->icon_timer = 0; 2473 gtkconv->u.im->icon_timer = 0;
2471 } 2474 }
2472 2475
2473 static void 2476 static void
2474 toggle_icon_animate_cb(GtkWidget *w, GaimConversation *conv) 2477 toggle_icon_animate_cb(GtkWidget *w, GaimGtkConversation *gtkconv)
2475 { 2478 {
2476 GaimGtkConversation *gtkconv;
2477
2478 if (!GAIM_IS_GTK_CONVERSATION(conv))
2479 return;
2480
2481 gtkconv = GAIM_GTK_CONVERSATION(conv);
2482
2483 gtkconv->u.im->animate = 2479 gtkconv->u.im->animate =
2484 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); 2480 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w));
2485 2481
2486 if (gtkconv->u.im->animate) 2482 if (gtkconv->u.im->animate)
2487 start_anim(NULL, conv); 2483 start_anim(NULL, gtkconv);
2488 else 2484 else
2489 stop_anim(NULL, conv); 2485 stop_anim(NULL, gtkconv);
2490 } 2486 }
2491 2487
2492 static void 2488 static void
2493 remove_icon(GaimConversation *conv) 2489 remove_icon(GaimGtkConversation *gtkconv)
2494 { 2490 {
2495 GaimGtkConversation *gtkconv; 2491 GaimConversation *conv = gtkconv->active_conv;;
2496 GaimGtkWindow *gtkwin; 2492 GaimGtkWindow *gtkwin;
2497 2493
2498 g_return_if_fail(conv != NULL); 2494 g_return_if_fail(conv != NULL);
2499
2500 gtkconv = GAIM_GTK_CONVERSATION(conv);
2501 2495
2502 if (gtkconv->u.im->icon_container != NULL) 2496 if (gtkconv->u.im->icon_container != NULL)
2503 gtk_widget_destroy(gtkconv->u.im->icon_container); 2497 gtk_widget_destroy(gtkconv->u.im->icon_container);
2504 2498
2505 if (gtkconv->u.im->anim != NULL) 2499 if (gtkconv->u.im->anim != NULL)
2523 } 2517 }
2524 2518
2525 static void 2519 static void
2526 saveicon_writefile_cb(void *user_data, const char *filename) 2520 saveicon_writefile_cb(void *user_data, const char *filename)
2527 { 2521 {
2528 GaimConversation *conv = (GaimConversation *)user_data; 2522 GaimGtkConversation *gtkconv = (GaimGtkConversation *)user_data;
2523 GaimConversation *conv = gtkconv->active_conv;
2529 FILE *fp; 2524 FILE *fp;
2530 GaimBuddyIcon *icon; 2525 GaimBuddyIcon *icon;
2531 const void *data; 2526 const void *data;
2532 size_t len; 2527 size_t len;
2533 2528
2547 fwrite(data, 1, len, fp); 2542 fwrite(data, 1, len, fp);
2548 fclose(fp); 2543 fclose(fp);
2549 } 2544 }
2550 2545
2551 static void 2546 static void
2552 icon_menu_save_cb(GtkWidget *widget, GaimConversation *conv) 2547 icon_menu_save_cb(GtkWidget *widget, GaimGtkConversation *gtkconv)
2553 { 2548 {
2549 GaimConversation *conv = gtkconv->active_conv;
2554 gchar *buf; 2550 gchar *buf;
2555 2551
2556 g_return_if_fail(conv != NULL); 2552 g_return_if_fail(conv != NULL);
2557 2553
2558 /* 2554 /*
2566 2562
2567 g_free(buf); 2563 g_free(buf);
2568 } 2564 }
2569 2565
2570 static gboolean 2566 static gboolean
2571 icon_menu(GtkObject *obj, GdkEventButton *e, GaimConversation *conv) 2567 icon_menu(GtkObject *obj, GdkEventButton *e, GaimGtkConversation *gtkconv)
2572 { 2568 {
2573 GaimGtkConversation *gtkconv; 2569 GaimConversation *conv = gtkconv->active_conv;
2574 static GtkWidget *menu = NULL; 2570 static GtkWidget *menu = NULL;
2575 GtkWidget *button; 2571 GtkWidget *button;
2576 2572
2577 if (e->button != 3 || e->type != GDK_BUTTON_PRESS) 2573 if (e->button != 3 || e->type != GDK_BUTTON_PRESS)
2578 return FALSE; 2574 return FALSE;
2579
2580 gtkconv = GAIM_GTK_CONVERSATION(conv);
2581 2575
2582 /* 2576 /*
2583 * If a menu already exists, destroy it before creating a new one, 2577 * If a menu already exists, destroy it before creating a new one,
2584 * thus freeing-up the memory it occupied. 2578 * thus freeing-up the memory it occupied.
2585 */ 2579 */
2631 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); 2625 active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
2632 gtkconv->u.im->show_icon = active; 2626 gtkconv->u.im->show_icon = active;
2633 if (active) 2627 if (active)
2634 gaim_gtkconv_update_buddy_icon(conv); 2628 gaim_gtkconv_update_buddy_icon(conv);
2635 else 2629 else
2636 remove_icon(conv); 2630 remove_icon(gtkconv);
2637 } 2631 }
2638 2632
2639 /************************************************************************** 2633 /**************************************************************************
2640 * End of the bunch of buddy icon functions 2634 * End of the bunch of buddy icon functions
2641 **************************************************************************/ 2635 **************************************************************************/
2645 * Makes sure all the menu items and all the buttons are hidden/shown and 2639 * Makes sure all the menu items and all the buttons are hidden/shown and
2646 * sensitive/insensitive. This is called after changing tabs and when an 2640 * sensitive/insensitive. This is called after changing tabs and when an
2647 * account signs on or off. 2641 * account signs on or off.
2648 */ 2642 */
2649 static void 2643 static void
2650 gray_stuff_out(GaimConversation *conv) 2644 gray_stuff_out(GaimGtkConversation *gtkconv)
2651 { 2645 {
2652 GaimConvWindow *win; 2646 GaimConvWindow *win;
2653 GaimGtkWindow *gtkwin; 2647 GaimGtkWindow *gtkwin;
2654 GaimGtkConversation *gtkconv; 2648 GaimConversation *conv = gtkconv->active_conv;
2655 GaimConnection *gc; 2649 GaimConnection *gc;
2656 GaimPluginProtocolInfo *prpl_info = NULL; 2650 GaimPluginProtocolInfo *prpl_info = NULL;
2657 GdkPixbuf *window_icon = NULL; 2651 GdkPixbuf *window_icon = NULL;
2658 GtkIMHtmlButtons buttons; 2652 GtkIMHtmlButtons buttons;
2659 GaimAccount *account; 2653 GaimAccount *account;
2850 if (gaim_conversation_get_type(conv) != GAIM_CONV_IM) 2844 if (gaim_conversation_get_type(conv) != GAIM_CONV_IM)
2851 return; 2845 return;
2852 2846
2853 gtkconv = GAIM_GTK_CONVERSATION(conv); 2847 gtkconv = GAIM_GTK_CONVERSATION(conv);
2854 2848
2855 stop_anim(NULL, conv); 2849 stop_anim(NULL, gtkconv);
2856 } 2850 }
2857 2851
2858 static void 2852 static void
2859 switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num, 2853 switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num,
2860 gpointer user_data) 2854 gpointer user_data)
2873 gtkconv = GAIM_GTK_CONVERSATION(conv); 2867 gtkconv = GAIM_GTK_CONVERSATION(conv);
2874 2868
2875 gaim_conversation_set_unseen(conv, GAIM_UNSEEN_NONE); 2869 gaim_conversation_set_unseen(conv, GAIM_UNSEEN_NONE);
2876 2870
2877 /* Update the menubar */ 2871 /* Update the menubar */
2878 gray_stuff_out(conv); 2872 gray_stuff_out(gtkconv);
2879 2873
2880 update_typing_icon(conv); 2874 update_typing_icon(gtkconv);
2881 2875
2882 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkwin->menu.logging), 2876 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkwin->menu.logging),
2883 gaim_conversation_is_logging(conv)); 2877 gaim_conversation_is_logging(conv));
2884 2878
2885 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkwin->menu.sounds), 2879 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkwin->menu.sounds),
2899 * We pause icons when they are not visible. If this icon should 2893 * We pause icons when they are not visible. If this icon should
2900 * be animated then start it back up again. 2894 * be animated then start it back up again.
2901 */ 2895 */
2902 if ((gaim_conversation_get_type(conv) == GAIM_CONV_IM) && 2896 if ((gaim_conversation_get_type(conv) == GAIM_CONV_IM) &&
2903 (gtkconv->u.im->animate)) 2897 (gtkconv->u.im->animate))
2904 start_anim(NULL, conv); 2898 start_anim(NULL, gtkconv);
2905 2899
2906 gtk_window_set_title(GTK_WINDOW(gtkwin->window), 2900 gtk_window_set_title(GTK_WINDOW(gtkwin->window),
2907 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); 2901 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)));
2908 } 2902 }
2909 2903
2910 /************************************************************************** 2904 /**************************************************************************
2911 * Utility functions 2905 * Utility functions
2912 **************************************************************************/ 2906 **************************************************************************/
2913 2907
2914 static void 2908 static void
2915 got_typing_keypress(GaimConversation *conv, gboolean first) 2909 got_typing_keypress(GaimGtkConversation *gtkconv, gboolean first)
2916 { 2910 {
2911 GaimConversation *conv = gtkconv->active_conv;
2917 GaimConvIm *im; 2912 GaimConvIm *im;
2918 2913
2919 /* 2914 /*
2920 * We know we got something, so we at least have to make sure we don't 2915 * We know we got something, so we at least have to make sure we don't
2921 * send GAIM_TYPED any time soon. 2916 * send GAIM_TYPED any time soon.
2941 gaim_conv_im_set_type_again(im, 0); 2936 gaim_conv_im_set_type_again(im, 0);
2942 } 2937 }
2943 } 2938 }
2944 2939
2945 static void 2940 static void
2946 update_typing_icon(GaimConversation *conv) 2941 update_typing_icon(GaimGtkConversation *gtkconv)
2947 { 2942 {
2948 GaimGtkWindow *gtkwin; 2943 GaimGtkWindow *gtkwin;
2949 GaimConvIm *im = NULL; 2944 GaimConvIm *im = NULL;
2950 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv); 2945 GaimConversation *conv = gtkconv->active_conv;
2951 2946
2952 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(conv)); 2947 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(conv));
2953 2948
2954 if(gaim_conversation_get_type(conv) == GAIM_CONV_IM) 2949 if(gaim_conversation_get_type(conv) == GAIM_CONV_IM)
2955 im = GAIM_CONV_IM(conv); 2950 im = GAIM_CONV_IM(conv);
2956 2951
3708 gtk_widget_show(gtkwin->menu.menubar); 3703 gtk_widget_show(gtkwin->menu.menubar);
3709 3704
3710 return gtkwin->menu.menubar; 3705 return gtkwin->menu.menubar;
3711 } 3706 }
3712 3707
3713 static void topic_callback(GtkWidget *w, GaimConversation *conv) 3708 static void topic_callback(GtkWidget *w, GaimGtkConversation *gtkconv)
3714 { 3709 {
3715 GaimPluginProtocolInfo *prpl_info = NULL; 3710 GaimPluginProtocolInfo *prpl_info = NULL;
3716 GaimConnection *gc; 3711 GaimConnection *gc;
3717 GaimGtkConversation *gtkconv; 3712 GaimConversation *conv = gtkconv->active_conv;
3718 GaimGtkChatPane *gtkchat; 3713 GaimGtkChatPane *gtkchat;
3719 const char *new_topic; 3714 const char *new_topic;
3720 const char *current_topic; 3715 const char *current_topic;
3721 3716
3722 gc = gaim_conversation_get_gc(conv); 3717 gc = gaim_conversation_get_gc(conv);
3764 3759
3765 return ret; 3760 return ret;
3766 } 3761 }
3767 3762
3768 static GtkWidget * 3763 static GtkWidget *
3769 setup_chat_pane(GaimConversation *conv) 3764 setup_chat_pane(GaimGtkConversation *gtkconv)
3770 { 3765 {
3771 GaimPluginProtocolInfo *prpl_info = NULL; 3766 GaimPluginProtocolInfo *prpl_info = NULL;
3772 GaimGtkConversation *gtkconv; 3767 GaimConversation *conv = gtkconv->active_conv;
3773 GaimGtkChatPane *gtkchat; 3768 GaimGtkChatPane *gtkchat;
3774 GaimConnection *gc; 3769 GaimConnection *gc;
3775 GtkWidget *vpaned, *hpaned; 3770 GtkWidget *vpaned, *hpaned;
3776 GtkWidget *vbox, *hbox, *frame; 3771 GtkWidget *vbox, *hbox, *frame;
3777 GtkWidget *lbox, *bbox; 3772 GtkWidget *lbox, *bbox;
3782 GtkListStore *ls; 3777 GtkListStore *ls;
3783 GtkCellRenderer *rend; 3778 GtkCellRenderer *rend;
3784 GtkTreeViewColumn *col; 3779 GtkTreeViewColumn *col;
3785 GList *focus_chain = NULL; 3780 GList *focus_chain = NULL;
3786 3781
3787 gtkconv = GAIM_GTK_CONVERSATION(conv);
3788 gtkchat = gtkconv->u.chat; 3782 gtkchat = gtkconv->u.chat;
3789 gc = gaim_conversation_get_gc(conv); 3783 gc = gaim_conversation_get_gc(conv);
3790 3784
3791 /* Setup the outer pane. */ 3785 /* Setup the outer pane. */
3792 vpaned = gtk_vpaned_new(); 3786 vpaned = gtk_vpaned_new();
3814 3808
3815 if(prpl_info->set_chat_topic == NULL) { 3809 if(prpl_info->set_chat_topic == NULL) {
3816 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE); 3810 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE);
3817 } else { 3811 } else {
3818 g_signal_connect(GTK_OBJECT(gtkchat->topic_text), "activate", 3812 g_signal_connect(GTK_OBJECT(gtkchat->topic_text), "activate",
3819 G_CALLBACK(topic_callback), conv); 3813 G_CALLBACK(topic_callback), gtkconv);
3820 } 3814 }
3821 3815
3822 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); 3816 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0);
3823 gtk_widget_show(gtkchat->topic_text); 3817 gtk_widget_show(gtkchat->topic_text);
3824 } 3818 }
3837 3831
3838 gtk_widget_set_size_request(gtkconv->imhtml, 3832 gtk_widget_set_size_request(gtkconv->imhtml,
3839 gaim_prefs_get_int("/gaim/gtk/conversations/chat/default_width"), 3833 gaim_prefs_get_int("/gaim/gtk/conversations/chat/default_width"),
3840 gaim_prefs_get_int("/gaim/gtk/conversations/chat/default_height")); 3834 gaim_prefs_get_int("/gaim/gtk/conversations/chat/default_height"));
3841 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", 3835 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
3842 G_CALLBACK(size_allocate_cb), conv); 3836 G_CALLBACK(size_allocate_cb), gtkconv);
3843 3837
3844 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", 3838 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
3845 G_CALLBACK(entry_stop_rclick_cb), NULL); 3839 G_CALLBACK(entry_stop_rclick_cb), NULL);
3846 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", 3840 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
3847 G_CALLBACK(refocus_entry_cb), gtkconv); 3841 G_CALLBACK(refocus_entry_cb), gtkconv);
3916 gtkchat->userlist_im = button; 3910 gtkchat->userlist_im = button;
3917 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); 3911 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
3918 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); 3912 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
3919 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("IM the user"), NULL); 3913 gtk_tooltips_set_tip(gtkconv->tooltips, button, _("IM the user"), NULL);
3920 g_signal_connect(G_OBJECT(button), "clicked", 3914 g_signal_connect(G_OBJECT(button), "clicked",
3921 G_CALLBACK(chat_im_button_cb), conv); 3915 G_CALLBACK(chat_im_button_cb), gtkconv);
3922 3916
3923 gtk_widget_show(button); 3917 gtk_widget_show(button);
3924 3918
3925 /* Ignore */ 3919 /* Ignore */
3926 button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_IGNORE, 3920 button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_IGNORE,
3929 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); 3923 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
3930 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); 3924 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
3931 gtk_tooltips_set_tip(gtkconv->tooltips, button, 3925 gtk_tooltips_set_tip(gtkconv->tooltips, button,
3932 _("Ignore the user"), NULL); 3926 _("Ignore the user"), NULL);
3933 g_signal_connect(G_OBJECT(button), "clicked", 3927 g_signal_connect(G_OBJECT(button), "clicked",
3934 G_CALLBACK(ignore_cb), conv); 3928 G_CALLBACK(ignore_cb), gtkconv);
3935 gtk_widget_show(button); 3929 gtk_widget_show(button);
3936 3930
3937 /* Info */ 3931 /* Info */
3938 button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_INFO, 3932 button = gaim_pixbuf_button_from_stock(NULL, GAIM_STOCK_INFO,
3939 GAIM_BUTTON_VERTICAL); 3933 GAIM_BUTTON_VERTICAL);
3941 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); 3935 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
3942 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); 3936 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
3943 gtk_tooltips_set_tip(gtkconv->tooltips, button, 3937 gtk_tooltips_set_tip(gtkconv->tooltips, button,
3944 _("Get the user's information"), NULL); 3938 _("Get the user's information"), NULL);
3945 g_signal_connect(G_OBJECT(button), "clicked", 3939 g_signal_connect(G_OBJECT(button), "clicked",
3946 G_CALLBACK(info_cb), conv); 3940 G_CALLBACK(info_cb), gtkconv);
3947 3941
3948 gtk_widget_show(button); 3942 gtk_widget_show(button);
3949 3943
3950 /* Setup the bottom half of the conversation window */ 3944 /* Setup the bottom half of the conversation window */
3951 vbox = gtk_vbox_new(FALSE, 6); 3945 vbox = gtk_vbox_new(FALSE, 6);
3970 gaim_account_get_protocol_name(conv->account)); 3964 gaim_account_get_protocol_name(conv->account));
3971 gtk_widget_set_size_request(gtkconv->entry, -1, 3965 gtk_widget_set_size_request(gtkconv->entry, -1,
3972 gaim_prefs_get_int("/gaim/gtk/conversations/chat/entry_height")); 3966 gaim_prefs_get_int("/gaim/gtk/conversations/chat/entry_height"));
3973 gtkconv->entry_buffer = 3967 gtkconv->entry_buffer =
3974 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); 3968 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry));
3975 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", conv); 3969 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv);
3976 3970
3977 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", 3971 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event",
3978 G_CALLBACK(entry_key_press_cb), conv); 3972 G_CALLBACK(entry_key_press_cb), gtkconv);
3979 g_signal_connect(G_OBJECT(gtkconv->entry), "message_send", 3973 g_signal_connect(G_OBJECT(gtkconv->entry), "message_send",
3980 G_CALLBACK(send_cb), conv); 3974 G_CALLBACK(send_cb), gtkconv);
3981 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", 3975 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event",
3982 G_CALLBACK(entry_stop_rclick_cb), NULL); 3976 G_CALLBACK(entry_stop_rclick_cb), NULL);
3983 g_signal_connect(G_OBJECT(gtkconv->entry), "size-allocate", 3977 g_signal_connect(G_OBJECT(gtkconv->entry), "size-allocate",
3984 G_CALLBACK(size_allocate_cb), conv); 3978 G_CALLBACK(size_allocate_cb), gtkconv);
3985 3979
3986 default_formatize(conv); 3980 default_formatize(gtkconv);
3987 3981
3988 /* 3982 /*
3989 * Focus for chat windows should be as follows: 3983 * Focus for chat windows should be as follows:
3990 * Tab title -> chat topic -> conversation scrollback -> user list -> 3984 * Tab title -> chat topic -> conversation scrollback -> user list ->
3991 * user list buttons -> entry -> buttons at bottom 3985 * user list buttons -> entry -> buttons at bottom
3995 3989
3996 return vpaned; 3990 return vpaned;
3997 } 3991 }
3998 3992
3999 static GtkWidget * 3993 static GtkWidget *
4000 setup_im_pane(GaimConversation *conv) 3994 setup_im_pane(GaimGtkConversation *gtkconv)
4001 { 3995 {
4002 GaimGtkConversation *gtkconv; 3996 GaimConversation *conv = gtkconv->active_conv;
4003 GaimGtkImPane *gtkim;
4004 GtkWidget *frame; 3997 GtkWidget *frame;
4005 GtkWidget *paned; 3998 GtkWidget *paned;
4006 GtkWidget *vbox; 3999 GtkWidget *vbox;
4007 GtkWidget *vbox2; 4000 GtkWidget *vbox2;
4008 GList *focus_chain = NULL; 4001 GList *focus_chain = NULL;
4009
4010 gtkconv = GAIM_GTK_CONVERSATION(conv);
4011 gtkim = gtkconv->u.im;
4012 4002
4013 /* Setup the outer pane */ 4003 /* Setup the outer pane */
4014 paned = gtk_vpaned_new(); 4004 paned = gtk_vpaned_new();
4015 gtk_widget_show(paned); 4005 gtk_widget_show(paned);
4016 4006
4028 4018
4029 gtk_widget_set_size_request(gtkconv->imhtml, 4019 gtk_widget_set_size_request(gtkconv->imhtml,
4030 gaim_prefs_get_int("/gaim/gtk/conversations/im/default_width"), 4020 gaim_prefs_get_int("/gaim/gtk/conversations/im/default_width"),
4031 gaim_prefs_get_int("/gaim/gtk/conversations/im/default_height")); 4021 gaim_prefs_get_int("/gaim/gtk/conversations/im/default_height"));
4032 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", 4022 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
4033 G_CALLBACK(size_allocate_cb), conv); 4023 G_CALLBACK(size_allocate_cb), gtkconv);
4034 4024
4035 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", 4025 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
4036 G_CALLBACK(entry_stop_rclick_cb), NULL); 4026 G_CALLBACK(entry_stop_rclick_cb), NULL);
4037 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", 4027 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
4038 G_CALLBACK(refocus_entry_cb), gtkconv); 4028 G_CALLBACK(refocus_entry_cb), gtkconv);
4039 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", 4029 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
4040 G_CALLBACK(refocus_entry_cb), gtkconv); 4030 G_CALLBACK(refocus_entry_cb), gtkconv);
4041 4031
4042 /* Setup the bottom half of the conversation window */ 4032 /* Setup the bottom half of the conversation window */
4043 vbox2 = gtk_vbox_new(FALSE, 6); 4033 vbox2 = gtk_vbox_new(FALSE, 6);
4044 gtk_paned_pack2(GTK_PANED(paned), vbox2, FALSE, TRUE); 4034 gtk_paned_pack2(GTK_PANED(paned), vbox2, FALSE, TRUE);
4045 gtk_widget_show(vbox2); 4035 gtk_widget_show(vbox2);
4062 gaim_account_get_protocol_name(conv->account)); 4052 gaim_account_get_protocol_name(conv->account));
4063 gtk_widget_set_size_request(gtkconv->entry, -1, 4053 gtk_widget_set_size_request(gtkconv->entry, -1,
4064 gaim_prefs_get_int("/gaim/gtk/conversations/im/entry_height")); 4054 gaim_prefs_get_int("/gaim/gtk/conversations/im/entry_height"));
4065 gtkconv->entry_buffer = 4055 gtkconv->entry_buffer =
4066 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); 4056 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry));
4067 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", conv); 4057 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv);
4068 4058
4069 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", 4059 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event",
4070 G_CALLBACK(entry_key_press_cb), conv); 4060 G_CALLBACK(entry_key_press_cb), gtkconv);
4071 g_signal_connect(G_OBJECT(gtkconv->entry), "message_send", G_CALLBACK(send_cb), conv); 4061 g_signal_connect(G_OBJECT(gtkconv->entry), "message_send", G_CALLBACK(send_cb), gtkconv);
4072 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", 4062 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event",
4073 G_CALLBACK(entry_stop_rclick_cb), NULL); 4063 G_CALLBACK(entry_stop_rclick_cb), NULL);
4074 g_signal_connect(G_OBJECT(gtkconv->entry), "size-allocate", 4064 g_signal_connect(G_OBJECT(gtkconv->entry), "size-allocate",
4075 G_CALLBACK(size_allocate_cb), conv); 4065 G_CALLBACK(size_allocate_cb), gtkconv);
4076 4066
4077 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", 4067 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text",
4078 G_CALLBACK(insert_text_cb), conv); 4068 G_CALLBACK(insert_text_cb), gtkconv);
4079 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", 4069 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range",
4080 G_CALLBACK(delete_text_cb), conv); 4070 G_CALLBACK(delete_text_cb), gtkconv);
4081 4071
4082 /* had to move this after the imtoolbar is attached so that the 4072 /* had to move this after the imtoolbar is attached so that the
4083 * signals get fired to toggle the buttons on the toolbar as well. 4073 * signals get fired to toggle the buttons on the toolbar as well.
4084 */ 4074 */
4085 default_formatize(conv); 4075 default_formatize(gtkconv);
4086 4076
4087 gtkconv->u.im->animate = gaim_prefs_get_bool("/gaim/gtk/conversations/im/animate_buddy_icons"); 4077 gtkconv->u.im->animate = gaim_prefs_get_bool("/gaim/gtk/conversations/im/animate_buddy_icons");
4088 gtkconv->u.im->show_icon = TRUE; 4078 gtkconv->u.im->show_icon = TRUE;
4089 4079
4090 /* 4080 /*
4097 return paned; 4087 return paned;
4098 } 4088 }
4099 4089
4100 static void 4090 static void
4101 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, 4091 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
4102 GtkSelectionData *sd, guint info, guint t, 4092 GtkSelectionData *sd, guint info, guint t,
4103 GaimConversation *conv) 4093 GaimGtkConversation *gtkconv)
4104 { 4094 {
4095 GaimConversation *conv = gtkconv->active_conv;
4105 GaimConvWindow *win = conv->window; 4096 GaimConvWindow *win = conv->window;
4106 GaimConversation *c; 4097 GaimConversation *c;
4107 if (sd->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE)) 4098 if (sd->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE))
4108 { 4099 {
4109 GaimBlistNode *n = NULL; 4100 GaimBlistNode *n = NULL;
4311 GTK_IMHTML_DND_TARGETS, 4302 GTK_IMHTML_DND_TARGETS,
4312 {"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, GTK_IMHTML_DRAG_NUM}, 4303 {"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, GTK_IMHTML_DRAG_NUM},
4313 {"application/x-im-contact", 0, GTK_IMHTML_DRAG_NUM + 1} 4304 {"application/x-im-contact", 0, GTK_IMHTML_DRAG_NUM + 1}
4314 }; 4305 };
4315 4306
4307 static GaimGtkConversation *
4308 gaim_gtk_conv_find_gtkconv(GaimConversation * conv)
4309 {
4310 GaimBuddy *bud = gaim_find_buddy(conv->account, conv->name), *b;
4311 GaimContact *c;
4312 GaimBlistNode *cn;
4313
4314 if (!bud)
4315 return NULL;
4316
4317 if (!(c = gaim_buddy_get_contact(bud)))
4318 return NULL;
4319
4320 cn = (GaimBlistNode *)c;
4321 for (b = (GaimBuddy *)cn->child; b; b = (GaimBuddy *) ((GaimBlistNode *)b)->next) {
4322 GaimConversation *conv;
4323 if ((conv = gaim_find_conversation_with_account(GAIM_CONV_IM, b->name, b->account))) {
4324 if (conv->ui_data)
4325 return conv->ui_data;
4326 }
4327 }
4328
4329 return NULL;
4330 }
4331
4316 static void 4332 static void
4317 gaim_gtk_add_conversation(GaimConvWindow *win, GaimConversation *conv) 4333 gaim_gtk_add_conversation(GaimConvWindow *win, GaimConversation *conv)
4318 { 4334 {
4319 GaimGtkWindow *gtkwin; 4335 GaimGtkWindow *gtkwin;
4320 GaimGtkConversation *gtkconv, *focus_gtkconv; 4336 GaimGtkConversation *gtkconv, *focus_gtkconv;
4336 gtkconv = (GaimGtkConversation *)conv->ui_data; 4352 gtkconv = (GaimGtkConversation *)conv->ui_data;
4337 4353
4338 tab_cont = gtkconv->tab_cont; 4354 tab_cont = gtkconv->tab_cont;
4339 4355
4340 new_ui = FALSE; 4356 new_ui = FALSE;
4341 } 4357 } else if (conv_type == GAIM_CONV_IM && (gtkconv = gaim_gtk_conv_find_gtkconv(conv))) {
4342 else { 4358 conv->ui_data = gtkconv;
4359 gtkconv->active_conv = conv;
4360 if (!g_list_find(gtkconv->convs, conv))
4361 gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
4362 return;
4363 } else {
4343 gtkconv = g_malloc0(sizeof(GaimGtkConversation)); 4364 gtkconv = g_malloc0(sizeof(GaimGtkConversation));
4344 conv->ui_data = gtkconv; 4365 conv->ui_data = gtkconv;
4366 gtkconv->active_conv = conv;
4367 gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
4345 4368
4346 /* Setup some initial variables. */ 4369 /* Setup some initial variables. */
4347 gtkconv->sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); 4370 gtkconv->sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
4348 gtkconv->tooltips = gtk_tooltips_new(); 4371 gtkconv->tooltips = gtk_tooltips_new();
4349 4372
4350 if (conv_type == GAIM_CONV_IM) { 4373 if (conv_type == GAIM_CONV_IM) {
4351 gtkconv->u.im = g_malloc0(sizeof(GaimGtkImPane)); 4374 gtkconv->u.im = g_malloc0(sizeof(GaimGtkImPane));
4352 gtkconv->u.im->a_virgin = TRUE; 4375 gtkconv->u.im->a_virgin = TRUE;
4353 4376
4354 pane = setup_im_pane(conv); 4377 pane = setup_im_pane(gtkconv);
4355 } 4378 }
4356 else if (conv_type == GAIM_CONV_CHAT) { 4379 else if (conv_type == GAIM_CONV_CHAT) {
4357 gtkconv->u.chat = g_malloc0(sizeof(GaimGtkChatPane)); 4380 gtkconv->u.chat = g_malloc0(sizeof(GaimGtkChatPane));
4358 4381
4359 pane = setup_chat_pane(conv); 4382 pane = setup_chat_pane(gtkconv);
4360 } 4383 }
4361 4384
4362 if (pane == NULL) { 4385 if (pane == NULL) {
4363 if (conv_type == GAIM_CONV_CHAT) g_free(gtkconv->u.chat); 4386 if (conv_type == GAIM_CONV_CHAT) g_free(gtkconv->u.chat);
4364 else if (conv_type == GAIM_CONV_IM) g_free(gtkconv->u.im); 4387 else if (conv_type == GAIM_CONV_IM) g_free(gtkconv->u.im);
4387 gtk_drag_dest_set(gtkconv->entry, 0, 4410 gtk_drag_dest_set(gtkconv->entry, 0,
4388 te, sizeof(te) / sizeof(GtkTargetEntry), 4411 te, sizeof(te) / sizeof(GtkTargetEntry),
4389 GDK_ACTION_COPY); 4412 GDK_ACTION_COPY);
4390 4413
4391 g_signal_connect(G_OBJECT(pane), "drag_data_received", 4414 g_signal_connect(G_OBJECT(pane), "drag_data_received",
4392 G_CALLBACK(conv_dnd_recv), conv); 4415 G_CALLBACK(conv_dnd_recv), gtkconv);
4393 g_signal_connect(G_OBJECT(gtkconv->imhtml), "drag_data_received", 4416 g_signal_connect(G_OBJECT(gtkconv->imhtml), "drag_data_received",
4394 G_CALLBACK(conv_dnd_recv), conv); 4417 G_CALLBACK(conv_dnd_recv), gtkconv);
4395 g_signal_connect(G_OBJECT(gtkconv->entry), "drag_data_received", 4418 g_signal_connect(G_OBJECT(gtkconv->entry), "drag_data_received",
4396 G_CALLBACK(conv_dnd_recv), conv); 4419 G_CALLBACK(conv_dnd_recv), gtkconv);
4397 4420
4398 /* Setup the container for the tab. */ 4421 /* Setup the container for the tab. */
4399 gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, 6); 4422 gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, 6);
4400 gtk_container_set_border_width(GTK_CONTAINER(tab_cont), 6); 4423 gtk_container_set_border_width(GTK_CONTAINER(tab_cont), 6);
4401 gtk_container_add(GTK_CONTAINER(tab_cont), pane); 4424 gtk_container_add(GTK_CONTAINER(tab_cont), pane);
4412 4435
4413 gtkconv->show_timestamps = TRUE; 4436 gtkconv->show_timestamps = TRUE;
4414 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), TRUE); 4437 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), TRUE);
4415 4438
4416 g_signal_connect_swapped(G_OBJECT(pane), "focus", 4439 g_signal_connect_swapped(G_OBJECT(pane), "focus",
4417 G_CALLBACK(gtk_widget_grab_focus), 4440 G_CALLBACK(gtk_widget_grab_focus),
4418 gtkconv->entry); 4441 gtkconv->entry);
4419 } 4442 }
4420 4443
4421 gtkconv->tabby = tabby = gtk_hbox_new(FALSE, 6); 4444 gtkconv->tabby = tabby = gtk_hbox_new(FALSE, 6);
4422 gtkconv->menu_tabby = menu_tabby = gtk_hbox_new(FALSE, 6); 4445 gtkconv->menu_tabby = menu_tabby = gtk_hbox_new(FALSE, 6);
4423 4446
4443 gtk_container_add(GTK_CONTAINER(gtkconv->close), close_image); 4466 gtk_container_add(GTK_CONTAINER(gtkconv->close), close_image);
4444 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close, 4467 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
4445 _("Close conversation"), NULL); 4468 _("Close conversation"), NULL);
4446 4469
4447 g_signal_connect(G_OBJECT(gtkconv->close), "clicked", 4470 g_signal_connect(G_OBJECT(gtkconv->close), "clicked",
4448 G_CALLBACK(close_conv_cb), conv); 4471 G_CALLBACK(close_conv_cb), gtkconv);
4449 4472
4450 /* 4473 /*
4451 * I love Galeon. They have a fix for that stupid annoying visible 4474 * I love Galeon. They have a fix for that stupid annoying visible
4452 * border bug. I love you guys! -- ChipX86 4475 * border bug. I love you guys! -- ChipX86
4453 */ 4476 */
4454 g_signal_connect(G_OBJECT(gtkconv->close), "state_changed", 4477 g_signal_connect(G_OBJECT(gtkconv->close), "state_changed",
4455 G_CALLBACK(tab_close_button_state_changed_cb), NULL); 4478 G_CALLBACK(tab_close_button_state_changed_cb), NULL);
4456 4479
4457 /* Status icon. */ 4480 /* Status icon. */
4458 gtkconv->icon = gtk_image_new(); 4481 gtkconv->icon = gtk_image_new();
4459 gtkconv->menu_icon = gtk_image_new(); 4482 gtkconv->menu_icon = gtk_image_new();
4460 update_tab_icon(conv); 4483 update_tab_icon(conv);
4573 gtk_notebook_reorder_child(GTK_NOTEBOOK(gtkwin->notebook), 4596 gtk_notebook_reorder_child(GTK_NOTEBOOK(gtkwin->notebook),
4574 gtkconv->tab_cont, new_index); 4597 gtkconv->tab_cont, new_index);
4575 } 4598 }
4576 4599
4577 static int 4600 static int
4578 gaim_gtk_get_active_index(const GaimConvWindow *win) 4601 gaim_gtk_get_active_index(const GaimConvWindow *win) /* FIXME: XXX: This is wrong due to contact aware convo changes */
4579 { 4602 {
4580 GaimGtkWindow *gtkwin; 4603 GaimGtkWindow *gtkwin;
4581 int index; 4604 int index;
4582 4605
4583 gtkwin = GAIM_GTK_WINDOW(win); 4606 gtkwin = GAIM_GTK_WINDOW(win);
4632 static void 4655 static void
4633 gaim_gtkconv_destroy(GaimConversation *conv) 4656 gaim_gtkconv_destroy(GaimConversation *conv)
4634 { 4657 {
4635 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv); 4658 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv);
4636 4659
4660 gtkconv->convs = g_list_remove(gtkconv->convs, conv);
4661 /* Don't destroy ourselves until all our convos are gone */
4662 if (gtkconv->convs)
4663 return;
4664
4637 /* If the "Save Conversation" or "Save Icon" dialogs are open then close them */ 4665 /* If the "Save Conversation" or "Save Icon" dialogs are open then close them */
4638 gaim_request_close_with_handle(conv); 4666 gaim_request_close_with_handle(conv);
4639 4667
4640 gtk_widget_destroy(gtkconv->tab_cont); 4668 gtk_widget_destroy(gtkconv->tab_cont);
4641 g_object_unref(gtkconv->tab_cont); 4669 g_object_unref(gtkconv->tab_cont);
4667 GaimConvWindow *gaimwin; 4695 GaimConvWindow *gaimwin;
4668 GaimGtkWindow *gtkwin; 4696 GaimGtkWindow *gtkwin;
4669 gboolean has_focus; 4697 gboolean has_focus;
4670 4698
4671 gtkconv = GAIM_GTK_CONVERSATION(conv); 4699 gtkconv = GAIM_GTK_CONVERSATION(conv);
4700 gtkconv->active_conv = conv;
4672 gaimwin = gaim_conversation_get_window(conv); 4701 gaimwin = gaim_conversation_get_window(conv);
4673 gtkwin = GAIM_GTK_WINDOW(gaimwin); 4702 gtkwin = GAIM_GTK_WINDOW(gaimwin);
4674 4703
4675 g_object_get(G_OBJECT(gtkwin->window), "has-toplevel-focus", &has_focus, NULL); 4704 g_object_get(G_OBJECT(gtkwin->window), "has-toplevel-focus", &has_focus, NULL);
4676 4705
4704 GaimConvWindow *gaimwin; 4733 GaimConvWindow *gaimwin;
4705 GaimGtkWindow *gtkwin; 4734 GaimGtkWindow *gtkwin;
4706 gboolean has_focus; 4735 gboolean has_focus;
4707 4736
4708 gtkconv = GAIM_GTK_CONVERSATION(conv); 4737 gtkconv = GAIM_GTK_CONVERSATION(conv);
4738 gtkconv->active_conv = conv;
4709 gaimwin = gaim_conversation_get_window(conv); 4739 gaimwin = gaim_conversation_get_window(conv);
4710 gtkwin = GAIM_GTK_WINDOW(gaimwin); 4740 gtkwin = GAIM_GTK_WINDOW(gaimwin);
4711 4741
4712 g_object_get(G_OBJECT(gtkwin->window), "has-toplevel-focus", &has_focus, NULL); 4742 g_object_get(G_OBJECT(gtkwin->window), "has-toplevel-focus", &has_focus, NULL);
4713 4743
4752 char *with_font_tag; 4782 char *with_font_tag;
4753 char *sml_attrib = NULL; 4783 char *sml_attrib = NULL;
4754 size_t length = strlen(message) + 1; 4784 size_t length = strlen(message) + 1;
4755 4785
4756 gtkconv = GAIM_GTK_CONVERSATION(conv); 4786 gtkconv = GAIM_GTK_CONVERSATION(conv);
4787 gtkconv->active_conv = conv;
4757 gc = gaim_conversation_get_gc(conv); 4788 gc = gaim_conversation_get_gc(conv);
4758 4789
4759 win = gaim_conversation_get_window(conv); 4790 win = gaim_conversation_get_window(conv);
4760 4791
4761 if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)))) 4792 if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml))))
5298 g_return_if_fail(conv != NULL); 5329 g_return_if_fail(conv != NULL);
5299 5330
5300 win = gaim_conversation_get_window(conv); 5331 win = gaim_conversation_get_window(conv);
5301 gtkwin = GAIM_GTK_WINDOW(win); 5332 gtkwin = GAIM_GTK_WINDOW(win);
5302 gtkconv = GAIM_GTK_CONVERSATION(conv); 5333 gtkconv = GAIM_GTK_CONVERSATION(conv);
5334 conv = gtkconv->active_conv; /* Gross hack */
5303 5335
5304 if (type == GAIM_CONV_UPDATE_ACCOUNT) 5336 if (type == GAIM_CONV_UPDATE_ACCOUNT)
5305 { 5337 {
5306 gaim_conversation_autoset_title(conv); 5338 gaim_conversation_autoset_title(conv);
5307 5339
5375 } 5407 }
5376 else 5408 else
5377 gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title); 5409 gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title);
5378 5410
5379 if (conv == gaim_conv_window_get_active_conversation(win)) 5411 if (conv == gaim_conv_window_get_active_conversation(win))
5380 update_typing_icon(conv); 5412 update_typing_icon(gtkconv);
5381 5413
5382 if (type == GAIM_CONV_UPDATE_TITLE) { 5414 if (type == GAIM_CONV_UPDATE_TITLE) {
5383 gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title); 5415 gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title);
5384 if (conv == gaim_conv_window_get_active_conversation(win)) 5416 if (conv == gaim_conv_window_get_active_conversation(win))
5385 gtk_window_set_title(GTK_WINDOW(gtkwin->window), title); 5417 gtk_window_set_title(GTK_WINDOW(gtkwin->window), title);
5400 topic ? topic : "", NULL); 5432 topic ? topic : "", NULL);
5401 } 5433 }
5402 else if (type == GAIM_CONV_ACCOUNT_ONLINE || 5434 else if (type == GAIM_CONV_ACCOUNT_ONLINE ||
5403 type == GAIM_CONV_ACCOUNT_OFFLINE) 5435 type == GAIM_CONV_ACCOUNT_OFFLINE)
5404 { 5436 {
5405 gray_stuff_out(gaim_conv_window_get_active_conversation(win)); 5437 gray_stuff_out(GAIM_GTK_CONVERSATION(gaim_conv_window_get_active_conversation(win)));
5406 generate_send_as_items(win, NULL); 5438 generate_send_as_items(win, NULL);
5407 update_tab_icon(conv); 5439 update_tab_icon(conv);
5408 gaim_conversation_autoset_title(conv); 5440 gaim_conversation_autoset_title(conv);
5409 } 5441 }
5410 else if (type == GAIM_CONV_UPDATE_AWAY) 5442 else if (type == GAIM_CONV_UPDATE_AWAY)
5413 } 5445 }
5414 else if (type == GAIM_CONV_UPDATE_ADD || type == GAIM_CONV_UPDATE_REMOVE || 5446 else if (type == GAIM_CONV_UPDATE_ADD || type == GAIM_CONV_UPDATE_REMOVE ||
5415 type == GAIM_CONV_UPDATE_CHATLEFT) 5447 type == GAIM_CONV_UPDATE_CHATLEFT)
5416 { 5448 {
5417 gaim_conversation_autoset_title(conv); 5449 gaim_conversation_autoset_title(conv);
5418 gray_stuff_out(conv); 5450 gray_stuff_out(GAIM_GTK_CONVERSATION(conv));
5419 } 5451 }
5420 else if (type == GAIM_CONV_UPDATE_ICON) 5452 else if (type == GAIM_CONV_UPDATE_ICON)
5421 { 5453 {
5422 gaim_gtkconv_update_buddy_icon(conv); 5454 gaim_gtkconv_update_buddy_icon(conv);
5423 } 5455 }
5424 else if (type == GAIM_CONV_UPDATE_FEATURES) 5456 else if (type == GAIM_CONV_UPDATE_FEATURES)
5425 { 5457 {
5426 gray_stuff_out(conv); 5458 gray_stuff_out(GAIM_GTK_CONVERSATION(conv));
5427 } 5459 }
5428 } 5460 }
5429 5461
5430 static GaimConversationUiOps conversation_ui_ops = 5462 static GaimConversationUiOps conversation_ui_ops =
5431 { 5463 {
5556 } else { 5588 } else {
5557 gtkconv->u.im->iter = 5589 gtkconv->u.im->iter =
5558 gdk_pixbuf_animation_get_iter(gtkconv->u.im->anim, NULL); /* LEAK */ 5590 gdk_pixbuf_animation_get_iter(gtkconv->u.im->anim, NULL); /* LEAK */
5559 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); 5591 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter);
5560 if (gtkconv->u.im->animate) 5592 if (gtkconv->u.im->animate)
5561 start_anim(NULL, conv); 5593 start_anim(NULL, gtkconv);
5562 } 5594 }
5563 5595
5564 gaim_gtk_buddy_icon_get_scale_size(buf, prpl_info ? &prpl_info->icon_spec : 5596 gaim_gtk_buddy_icon_get_scale_size(buf, prpl_info ? &prpl_info->icon_spec :
5565 NULL, &scale_width, &scale_height); 5597 NULL, &scale_width, &scale_height);
5566 scale = gdk_pixbuf_scale_simple(buf, 5598 scale = gdk_pixbuf_scale_simple(buf,
5619 return; 5651 return;
5620 5652
5621 win = gaim_conversation_get_window(conv); 5653 win = gaim_conversation_get_window(conv);
5622 5654
5623 if (win != NULL && gaim_conv_window_get_active_conversation(win) == conv) 5655 if (win != NULL && gaim_conv_window_get_active_conversation(win) == conv)
5624 gray_stuff_out(conv); 5656 gray_stuff_out(GAIM_GTK_CONVERSATION(conv));
5625 } 5657 }
5626 5658
5627 GaimConvWindow * 5659 GaimConvWindow *
5628 gaim_gtkwin_get_at_xy(int x, int y) 5660 gaim_gtkwin_get_at_xy(int x, int y)
5629 { 5661 {