Mercurial > pidgin
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 { |