comparison pidgin/gtkconv.c @ 32711:dc44bb639e8e

propagate from branch 'im.pidgin.pidgin' (head 069350831810b6f4bd534a26fed03260a9b4adcd) to branch 'im.pidgin.cpw.qulogic.gtk3' (head cf49f6cfd58e227b28dc1822e5ab543bbabd80b7)
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Wed, 04 Jan 2012 02:37:25 +0000
parents 9e72389456f6 48d35c0c6224
children 7df79e0d1150
comparison
equal deleted inserted replaced
32444:8436fb68930e 32711:dc44bb639e8e
78 #include "pidgintooltip.h" 78 #include "pidgintooltip.h"
79 #include "smileyparser.h" 79 #include "smileyparser.h"
80 80
81 #include "gtknickcolors.h" 81 #include "gtknickcolors.h"
82 82
83 #if !GTK_CHECK_VERSION(2,20,0)
84 #define gtk_widget_get_realized(x) GTK_WIDGET_REALIZED(x)
85
86 #if !GTK_CHECK_VERSION(2,18,0)
87 #define gtk_widget_get_visible(x) GTK_WIDGET_VISIBLE(x)
88 #define gtk_widget_is_drawable(x) GTK_WIDGET_DRAWABLE(x)
89 #endif
90 #endif
91
83 /** 92 /**
84 * A GTK+ Instant Message pane. 93 * A GTK+ Instant Message pane.
85 */ 94 */
86 struct _PidginImPane 95 struct _PidginImPane
87 { 96 {
196 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type); 205 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type);
197 static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state); 206 static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state);
198 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state); 207 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
199 static void update_typing_icon(PidginConversation *gtkconv); 208 static void update_typing_icon(PidginConversation *gtkconv);
200 static void update_typing_message(PidginConversation *gtkconv, const char *message); 209 static void update_typing_message(PidginConversation *gtkconv, const char *message);
201 static const char *item_factory_translate_func (const char *path, gpointer func_data);
202 gboolean pidgin_conv_has_focus(PurpleConversation *conv); 210 gboolean pidgin_conv_has_focus(PurpleConversation *conv);
203 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background); 211 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
204 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 212 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
205 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, gboolean create); 213 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, gboolean create);
206 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); 214 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
941 949
942 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog), 950 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog),
943 GTK_RESPONSE_OK); 951 GTK_RESPONSE_OK);
944 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE); 952 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE);
945 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE); 953 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE);
954 #if !GTK_CHECK_VERSION(2,22,0)
946 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE); 955 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE);
956 #endif
947 957
948 info->window = GTK_WIDGET(invite_dialog); 958 info->window = GTK_WIDGET(invite_dialog);
949 959
950 /* Setup the outside spacing. */ 960 /* Setup the outside spacing. */
951 vbox = GTK_DIALOG(invite_dialog)->vbox; 961 vbox = GTK_DIALOG(invite_dialog)->vbox;
1038 if (info != NULL) 1048 if (info != NULL)
1039 gtk_widget_grab_focus(info->entry); 1049 gtk_widget_grab_focus(info->entry);
1040 } 1050 }
1041 1051
1042 static void 1052 static void
1043 menu_new_conv_cb(gpointer data, guint action, GtkWidget *widget) 1053 menu_new_conv_cb(GtkAction *action, gpointer data)
1044 { 1054 {
1045 pidgin_dialogs_im(); 1055 pidgin_dialogs_im();
1046 } 1056 }
1047 1057
1048 static void 1058 static void
1049 menu_join_chat_cb(gpointer data, guint action, GtkWidget *widget) 1059 menu_join_chat_cb(GtkAction *action, gpointer data)
1050 { 1060 {
1051 pidgin_blist_joinchat_show(); 1061 pidgin_blist_joinchat_show();
1052 } 1062 }
1053 1063
1054 static void 1064 static void
1088 /* 1098 /*
1089 * It would be kinda cool if this gave the option of saving a 1099 * It would be kinda cool if this gave the option of saving a
1090 * plaintext v. HTML file. 1100 * plaintext v. HTML file.
1091 */ 1101 */
1092 static void 1102 static void
1093 menu_save_as_cb(gpointer data, guint action, GtkWidget *widget) 1103 menu_save_as_cb(GtkAction *action, gpointer data)
1094 { 1104 {
1095 PidginWindow *win = data; 1105 PidginWindow *win = data;
1096 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1106 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1097 PurpleAccount *account = purple_conversation_get_account(conv); 1107 PurpleAccount *account = purple_conversation_get_account(conv);
1098 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); 1108 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
1119 1129
1120 g_free(buf); 1130 g_free(buf);
1121 } 1131 }
1122 1132
1123 static void 1133 static void
1124 menu_view_log_cb(gpointer data, guint action, GtkWidget *widget) 1134 menu_view_log_cb(GtkAction *action, gpointer data)
1125 { 1135 {
1126 PidginWindow *win = data; 1136 PidginWindow *win = data;
1127 PurpleConversation *conv; 1137 PurpleConversation *conv;
1128 PurpleLogType type; 1138 PurpleLogType type;
1129 PidginBuddyList *gtkblist; 1139 PidginBuddyList *gtkblist;
1146 1156
1147 cursor = gdk_cursor_new(GDK_WATCH); 1157 cursor = gdk_cursor_new(GDK_WATCH);
1148 gdk_window_set_cursor(gtkblist->window->window, cursor); 1158 gdk_window_set_cursor(gtkblist->window->window, cursor);
1149 gdk_window_set_cursor(win->window->window, cursor); 1159 gdk_window_set_cursor(win->window->window, cursor);
1150 gdk_cursor_unref(cursor); 1160 gdk_cursor_unref(cursor);
1151 gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
1152 1161
1153 name = purple_conversation_get_name(conv); 1162 name = purple_conversation_get_name(conv);
1154 account = purple_conversation_get_account(conv); 1163 account = purple_conversation_get_account(conv);
1155 1164
1156 buddies = purple_find_buddies(account, name); 1165 buddies = purple_find_buddies(account, name);
1173 gdk_window_set_cursor(gtkblist->window->window, NULL); 1182 gdk_window_set_cursor(gtkblist->window->window, NULL);
1174 gdk_window_set_cursor(win->window->window, NULL); 1183 gdk_window_set_cursor(win->window->window, NULL);
1175 } 1184 }
1176 1185
1177 static void 1186 static void
1178 menu_clear_cb(gpointer data, guint action, GtkWidget *widget) 1187 menu_clear_cb(GtkAction *action, gpointer data)
1179 { 1188 {
1180 PidginWindow *win = data; 1189 PidginWindow *win = data;
1181 PurpleConversation *conv; 1190 PurpleConversation *conv;
1182 1191
1183 conv = pidgin_conv_window_get_active_conversation(win); 1192 conv = pidgin_conv_window_get_active_conversation(win);
1184 purple_conversation_clear_message_history(conv); 1193 purple_conversation_clear_message_history(conv);
1185 } 1194 }
1186 1195
1187 static void 1196 static void
1188 menu_find_cb(gpointer data, guint action, GtkWidget *widget) 1197 menu_find_cb(GtkAction *action, gpointer data)
1189 { 1198 {
1190 PidginWindow *gtkwin = data; 1199 PidginWindow *gtkwin = data;
1191 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin); 1200 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin);
1192 gtk_widget_show_all(gtkconv->quickfind.container); 1201 gtk_widget_show_all(gtkconv->quickfind.container);
1193 gtk_widget_grab_focus(gtkconv->quickfind.entry); 1202 gtk_widget_grab_focus(gtkconv->quickfind.entry);
1194 } 1203 }
1195 1204
1196 #ifdef USE_VV 1205 #ifdef USE_VV
1197 static void 1206 static void
1198 menu_initiate_media_call_cb(gpointer data, guint action, GtkWidget *widget) 1207 menu_initiate_media_call_cb(GtkAction *action, gpointer data)
1199 { 1208 {
1200 PidginWindow *win = (PidginWindow *)data; 1209 PidginWindow *win = (PidginWindow *)data;
1201 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1210 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1202 PurpleAccount *account = purple_conversation_get_account(conv); 1211 PurpleAccount *account = purple_conversation_get_account(conv);
1203 1212
1204 purple_prpl_initiate_media(account, 1213 purple_prpl_initiate_media(account,
1205 purple_conversation_get_name(conv), 1214 purple_conversation_get_name(conv),
1206 action == 0 ? PURPLE_MEDIA_AUDIO : 1215 action == win->audio_call ? PURPLE_MEDIA_AUDIO :
1207 action == 1 ? PURPLE_MEDIA_VIDEO : 1216 action == win->video_call ? PURPLE_MEDIA_VIDEO :
1208 action == 2 ? PURPLE_MEDIA_AUDIO | 1217 action == win->audio_video_call ? PURPLE_MEDIA_AUDIO |
1209 PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE); 1218 PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE);
1210 } 1219 }
1211 #endif 1220 #endif
1212 1221
1213 static void 1222 static void
1214 menu_send_file_cb(gpointer data, guint action, GtkWidget *widget) 1223 menu_send_file_cb(GtkAction *action, gpointer data)
1215 { 1224 {
1216 PidginWindow *win = data; 1225 PidginWindow *win = data;
1217 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1226 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1218 1227
1219 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 1228 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
1221 } 1230 }
1222 1231
1223 } 1232 }
1224 1233
1225 static void 1234 static void
1226 menu_get_attention_cb(gpointer data, guint action, GtkWidget *widget) 1235 menu_get_attention_cb(GObject *obj, gpointer data)
1227 { 1236 {
1228 PidginWindow *win = data; 1237 PidginWindow *win = data;
1229 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1238 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1230 1239
1231 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 1240 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
1232 int index; 1241 int index;
1233 if (widget == win->menu.get_attention) 1242 if ((GtkAction *)obj == win->menu.get_attention)
1234 index = 0; 1243 index = 0;
1235 else 1244 else
1236 index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "index")); 1245 index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(obj), "index"));
1237 purple_prpl_send_attention(purple_conversation_get_connection(conv), 1246 purple_prpl_send_attention(purple_conversation_get_connection(conv),
1238 purple_conversation_get_name(conv), index); 1247 purple_conversation_get_name(conv), index);
1239 } 1248 }
1240 } 1249 }
1241 1250
1242 static void 1251 static void
1243 menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget) 1252 menu_add_pounce_cb(GtkAction *action, gpointer data)
1244 { 1253 {
1245 PidginWindow *win = data; 1254 PidginWindow *win = data;
1246 PurpleConversation *conv; 1255 PurpleConversation *conv;
1247 1256
1248 conv = pidgin_conv_window_get_active_gtkconv(win)->active_conv; 1257 conv = pidgin_conv_window_get_active_gtkconv(win)->active_conv;
1250 pidgin_pounce_editor_show(purple_conversation_get_account(conv), 1259 pidgin_pounce_editor_show(purple_conversation_get_account(conv),
1251 purple_conversation_get_name(conv), NULL); 1260 purple_conversation_get_name(conv), NULL);
1252 } 1261 }
1253 1262
1254 static void 1263 static void
1255 menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget) 1264 menu_insert_link_cb(GtkAction *action, gpointer data)
1256 { 1265 {
1257 PidginWindow *win = data; 1266 PidginWindow *win = data;
1258 PidginConversation *gtkconv; 1267 PidginConversation *gtkconv;
1259 GtkIMHtmlToolbar *toolbar; 1268 GtkIMHtmlToolbar *toolbar;
1260 1269
1264 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->link), 1273 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->link),
1265 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->link))); 1274 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->link)));
1266 } 1275 }
1267 1276
1268 static void 1277 static void
1269 menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget) 1278 menu_insert_image_cb(GtkAction *action, gpointer data)
1270 { 1279 {
1271 PidginWindow *win = data; 1280 PidginWindow *win = data;
1272 PidginConversation *gtkconv; 1281 PidginConversation *gtkconv;
1273 GtkIMHtmlToolbar *toolbar; 1282 GtkIMHtmlToolbar *toolbar;
1274 1283
1279 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->image))); 1288 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->image)));
1280 } 1289 }
1281 1290
1282 1291
1283 static void 1292 static void
1284 menu_alias_cb(gpointer data, guint action, GtkWidget *widget) 1293 menu_alias_cb(GtkAction *action, gpointer data)
1285 { 1294 {
1286 PidginWindow *win = data; 1295 PidginWindow *win = data;
1287 PurpleConversation *conv; 1296 PurpleConversation *conv;
1288 PurpleAccount *account; 1297 PurpleAccount *account;
1289 const char *name; 1298 const char *name;
1306 pidgin_dialogs_alias_chat(c); 1315 pidgin_dialogs_alias_chat(c);
1307 } 1316 }
1308 } 1317 }
1309 1318
1310 static void 1319 static void
1311 menu_get_info_cb(gpointer data, guint action, GtkWidget *widget) 1320 menu_get_info_cb(GtkAction *action, gpointer data)
1312 { 1321 {
1313 PidginWindow *win = data; 1322 PidginWindow *win = data;
1314 PurpleConversation *conv; 1323 PurpleConversation *conv;
1315 1324
1316 conv = pidgin_conv_window_get_active_conversation(win); 1325 conv = pidgin_conv_window_get_active_conversation(win);
1317 1326
1318 info_cb(NULL, PIDGIN_CONVERSATION(conv)); 1327 info_cb(NULL, PIDGIN_CONVERSATION(conv));
1319 } 1328 }
1320 1329
1321 static void 1330 static void
1322 menu_invite_cb(gpointer data, guint action, GtkWidget *widget) 1331 menu_invite_cb(GtkAction *action, gpointer data)
1323 { 1332 {
1324 PidginWindow *win = data; 1333 PidginWindow *win = data;
1325 PurpleConversation *conv; 1334 PurpleConversation *conv;
1326 1335
1327 conv = pidgin_conv_window_get_active_conversation(win); 1336 conv = pidgin_conv_window_get_active_conversation(win);
1328 1337
1329 invite_cb(NULL, PIDGIN_CONVERSATION(conv)); 1338 invite_cb(NULL, PIDGIN_CONVERSATION(conv));
1330 } 1339 }
1331 1340
1332 static void 1341 static void
1333 menu_block_cb(gpointer data, guint action, GtkWidget *widget) 1342 menu_block_cb(GtkAction *action, gpointer data)
1334 { 1343 {
1335 PidginWindow *win = data; 1344 PidginWindow *win = data;
1336 PurpleConversation *conv; 1345 PurpleConversation *conv;
1337 1346
1338 conv = pidgin_conv_window_get_active_conversation(win); 1347 conv = pidgin_conv_window_get_active_conversation(win);
1339 1348
1340 block_cb(NULL, PIDGIN_CONVERSATION(conv)); 1349 block_cb(NULL, PIDGIN_CONVERSATION(conv));
1341 } 1350 }
1342 1351
1343 static void 1352 static void
1344 menu_unblock_cb(gpointer data, guint action, GtkWidget *widget) 1353 menu_unblock_cb(GtkAction *action, gpointer data)
1345 { 1354 {
1346 PidginWindow *win = data; 1355 PidginWindow *win = data;
1347 PurpleConversation *conv; 1356 PurpleConversation *conv;
1348 1357
1349 conv = pidgin_conv_window_get_active_conversation(win); 1358 conv = pidgin_conv_window_get_active_conversation(win);
1350 1359
1351 unblock_cb(NULL, PIDGIN_CONVERSATION(conv)); 1360 unblock_cb(NULL, PIDGIN_CONVERSATION(conv));
1352 } 1361 }
1353 1362
1354 static void 1363 static void
1355 menu_add_remove_cb(gpointer data, guint action, GtkWidget *widget) 1364 menu_add_remove_cb(GtkAction *action, gpointer data)
1356 { 1365 {
1357 PidginWindow *win = data; 1366 PidginWindow *win = data;
1358 PurpleConversation *conv; 1367 PurpleConversation *conv;
1359 1368
1360 conv = pidgin_conv_window_get_active_conversation(win); 1369 conv = pidgin_conv_window_get_active_conversation(win);
1395 #endif 1404 #endif
1396 } 1405 }
1397 } 1406 }
1398 1407
1399 static void 1408 static void
1400 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) 1409 menu_close_conv_cb(GtkAction *action, gpointer data)
1401 { 1410 {
1402 PidginWindow *win = data; 1411 PidginWindow *win = data;
1403 1412
1404 close_conv_cb(NULL, PIDGIN_CONVERSATION(pidgin_conv_window_get_active_conversation(win))); 1413 close_conv_cb(NULL, PIDGIN_CONVERSATION(pidgin_conv_window_get_active_conversation(win)));
1405 } 1414 }
1406 1415
1407 static void 1416 static void
1408 menu_logging_cb(gpointer data, guint action, GtkWidget *widget) 1417 menu_logging_cb(GtkAction *action, gpointer data)
1409 { 1418 {
1410 PidginWindow *win = data; 1419 PidginWindow *win = data;
1411 PurpleConversation *conv; 1420 PurpleConversation *conv;
1412 gboolean logging; 1421 gboolean logging;
1413 PurpleBlistNode *node; 1422 PurpleBlistNode *node;
1415 conv = pidgin_conv_window_get_active_conversation(win); 1424 conv = pidgin_conv_window_get_active_conversation(win);
1416 1425
1417 if (conv == NULL) 1426 if (conv == NULL)
1418 return; 1427 return;
1419 1428
1420 logging = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); 1429 logging = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
1421 1430
1422 if (logging == purple_conversation_is_logging(conv)) 1431 if (logging == purple_conversation_is_logging(conv))
1423 return; 1432 return;
1424 1433
1425 node = get_conversation_blist_node(conv); 1434 node = get_conversation_blist_node(conv);
1466 break; 1475 break;
1467 } 1476 }
1468 } 1477 }
1469 1478
1470 static void 1479 static void
1471 menu_toolbar_cb(gpointer data, guint action, GtkWidget *widget) 1480 menu_toolbar_cb(GtkAction *action, gpointer data)
1472 { 1481 {
1473 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar", 1482 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar",
1474 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))); 1483 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
1475 } 1484 }
1476 1485
1477 static void 1486 static void
1478 menu_sounds_cb(gpointer data, guint action, GtkWidget *widget) 1487 menu_sounds_cb(GtkAction *action, gpointer data)
1479 { 1488 {
1480 PidginWindow *win = data; 1489 PidginWindow *win = data;
1481 PurpleConversation *conv; 1490 PurpleConversation *conv;
1482 PidginConversation *gtkconv; 1491 PidginConversation *gtkconv;
1483 PurpleBlistNode *node; 1492 PurpleBlistNode *node;
1488 return; 1497 return;
1489 1498
1490 gtkconv = PIDGIN_CONVERSATION(conv); 1499 gtkconv = PIDGIN_CONVERSATION(conv);
1491 1500
1492 gtkconv->make_sound = 1501 gtkconv->make_sound =
1493 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); 1502 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
1494 node = get_conversation_blist_node(conv); 1503 node = get_conversation_blist_node(conv);
1495 if (node) 1504 if (node)
1496 purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound); 1505 purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound);
1497 } 1506 }
1498 1507
1499 static void 1508 static void
1500 menu_timestamps_cb(gpointer data, guint action, GtkWidget *widget) 1509 menu_timestamps_cb(GtkAction *action, gpointer data)
1501 { 1510 {
1502 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps", 1511 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps",
1503 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))); 1512 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
1504 } 1513 }
1505 1514
1506 static void 1515 static void
1507 chat_do_im(PidginConversation *gtkconv, const char *who) 1516 chat_do_im(PidginConversation *gtkconv, const char *who)
1508 { 1517 {
2297 2306
2298 purple_conversation_close_logs(old_conv); 2307 purple_conversation_close_logs(old_conv);
2299 gtkconv->active_conv = conv; 2308 gtkconv->active_conv = conv;
2300 2309
2301 purple_conversation_set_logging(conv, 2310 purple_conversation_set_logging(conv,
2302 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging))); 2311 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging)));
2303 2312
2304 entry = GTK_IMHTML(gtkconv->entry); 2313 entry = GTK_IMHTML(gtkconv->entry);
2305 protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv)); 2314 protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv));
2306 gtk_imhtml_set_protocol_name(entry, protocol_name); 2315 gtk_imhtml_set_protocol_name(entry, protocol_name);
2307 /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */ 2316 /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */
3112 { 3121 {
3113 g_return_val_if_fail(gtkconv != NULL, NULL); 3122 g_return_val_if_fail(gtkconv != NULL, NULL);
3114 return gtkconv->win; 3123 return gtkconv->win;
3115 } 3124 }
3116 3125
3117 static GtkItemFactoryEntry menu_items[] = 3126 static GtkActionEntry menu_entries[] =
3127 /* TODO: fill out tooltips... */
3118 { 3128 {
3119 /* Conversation menu */ 3129 /* Conversation menu */
3120 { N_("/_Conversation"), NULL, NULL, 0, "<Branch>", NULL }, 3130 { "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL },
3121 3131 { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) },
3122 { N_("/Conversation/New Instant _Message..."), "<CTL>M", menu_new_conv_cb, 3132 { "JoinAChat", PIDGIN_STOCK_CHAT, N_("Join a _Chat..."), NULL, NULL, G_CALLBACK(menu_join_chat_cb) },
3123 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW }, 3133 { "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) },
3124 { N_("/Conversation/Join a _Chat..."), NULL, menu_join_chat_cb, 3134 { "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) },
3125 0, "<StockItem>", PIDGIN_STOCK_CHAT }, 3135 { "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) },
3126 3136 { "ClearScrollback", GTK_STOCK_CLEAR, N_("Clea_r Scrollback"), "<control>L", NULL, G_CALLBACK(menu_clear_cb) },
3127 { "/Conversation/sep0", NULL, NULL, 0, "<Separator>", NULL },
3128
3129 { N_("/Conversation/_Find..."), NULL, menu_find_cb, 0,
3130 "<StockItem>", GTK_STOCK_FIND },
3131 { N_("/Conversation/View _Log"), NULL, menu_view_log_cb, 0, "<Item>", NULL },
3132 { N_("/Conversation/_Save As..."), NULL, menu_save_as_cb, 0,
3133 "<StockItem>", GTK_STOCK_SAVE_AS },
3134 { N_("/Conversation/Clea_r Scrollback"), "<CTL>L", menu_clear_cb, 0, "<StockItem>", GTK_STOCK_CLEAR },
3135
3136 { "/Conversation/sep1", NULL, NULL, 0, "<Separator>", NULL },
3137 3137
3138 #ifdef USE_VV 3138 #ifdef USE_VV
3139 { N_("/Conversation/M_edia"), NULL, NULL, 0, "<Branch>", NULL }, 3139 { "MediaMenu", NULL, N_("M_edia"), NULL, NULL, NULL },
3140 3140 { "AudioCall", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL, N_("_Audio Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3141 { N_("/Conversation/Media/_Audio Call"), NULL, menu_initiate_media_call_cb, 0, 3141 { "VideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("_Video Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3142 "<StockItem>", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL }, 3142 { "AudioVideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("Audio/Video _Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3143 { N_("/Conversation/Media/_Video Call"), NULL, menu_initiate_media_call_cb, 1,
3144 "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL },
3145 { N_("/Conversation/Media/Audio\\/Video _Call"), NULL, menu_initiate_media_call_cb, 2,
3146 "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL },
3147 #endif 3143 #endif
3148 3144
3149 { N_("/Conversation/Se_nd File..."), NULL, menu_send_file_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_FILE }, 3145 { "SendFile", PIDGIN_STOCK_TOOLBAR_SEND_FILE, N_("Se_nd File..."), NULL, NULL, G_CALLBACK(menu_send_file_cb) },
3150 { N_("/Conversation/Get _Attention"), NULL, menu_get_attention_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION }, 3146 { "GetAttention", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, N_("Get _Attention"), NULL, NULL, G_CALLBACK(menu_get_attention_cb) },
3151 { N_("/Conversation/Add Buddy _Pounce..."), NULL, menu_add_pounce_cb, 3147 { "AddBuddyPounce", NULL, N_("Add Buddy _Pounce..."), NULL, NULL, G_CALLBACK(menu_add_pounce_cb) },
3152 0, "<Item>", NULL }, 3148 { "GetInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("_Get Info"), "<control>O", NULL, G_CALLBACK(menu_get_info_cb) },
3153 { N_("/Conversation/_Get Info"), "<CTL>O", menu_get_info_cb, 0, 3149 { "Invite", NULL, N_("In_vite..."), NULL, NULL, G_CALLBACK(menu_invite_cb) },
3154 "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO }, 3150 { "MoreMenu", NULL, N_("M_ore"), NULL, NULL, NULL },
3155 { N_("/Conversation/In_vite..."), NULL, menu_invite_cb, 0, 3151 { "Alias", NULL, N_("Al_ias..."), NULL, NULL, G_CALLBACK(menu_alias_cb) },
3156 "<Item>", NULL }, 3152 { "Block", PIDGIN_STOCK_TOOLBAR_BLOCK, N_("_Block..."), NULL, NULL, G_CALLBACK(menu_block_cb) },
3157 { N_("/Conversation/M_ore"), NULL, NULL, 0, "<Branch>", NULL }, 3153 { "Unblock", PIDGIN_STOCK_TOOLBAR_UNBLOCK, N_("_Unblock..."), NULL, NULL, G_CALLBACK(menu_unblock_cb) },
3158 3154 { "Add", GTK_STOCK_ADD, N_("_Add..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
3159 { "/Conversation/sep2", NULL, NULL, 0, "<Separator>", NULL }, 3155 { "Remove", GTK_STOCK_REMOVE, N_("_Remove..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
3160 3156 { "InsertLink", PIDGIN_STOCK_TOOLBAR_INSERT_LINK, N_("Insert Lin_k..."), NULL, NULL, G_CALLBACK(menu_insert_link_cb) },
3161 { N_("/Conversation/Al_ias..."), NULL, menu_alias_cb, 0, 3157 { "InsertImage", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, N_("Insert Imag_e..."), NULL, NULL, G_CALLBACK(menu_insert_image_cb) },
3162 "<Item>", NULL }, 3158 { "Close", GTK_STOCK_CLOSE, N_("_Close"), NULL, NULL, G_CALLBACK(menu_close_conv_cb) },
3163 { N_("/Conversation/_Block..."), NULL, menu_block_cb, 0,
3164 "<StockItem>", PIDGIN_STOCK_TOOLBAR_BLOCK },
3165 { N_("/Conversation/_Unblock..."), NULL, menu_unblock_cb, 0,
3166 "<StockItem>", PIDGIN_STOCK_TOOLBAR_UNBLOCK },
3167 { N_("/Conversation/_Add..."), NULL, menu_add_remove_cb, 0,
3168 "<StockItem>", GTK_STOCK_ADD },
3169 { N_("/Conversation/_Remove..."), NULL, menu_add_remove_cb, 0,
3170 "<StockItem>", GTK_STOCK_REMOVE },
3171
3172 { "/Conversation/sep3", NULL, NULL, 0, "<Separator>", NULL },
3173
3174 { N_("/Conversation/Insert Lin_k..."), NULL, menu_insert_link_cb, 0,
3175 "<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_LINK },
3176 { N_("/Conversation/Insert Imag_e..."), NULL, menu_insert_image_cb, 0,
3177 "<StockItem>", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE },
3178
3179 { "/Conversation/sep4", NULL, NULL, 0, "<Separator>", NULL },
3180
3181
3182 { N_("/Conversation/_Close"), NULL, menu_close_conv_cb, 0,
3183 "<StockItem>", GTK_STOCK_CLOSE },
3184 3159
3185 /* Options */ 3160 /* Options */
3186 { N_("/_Options"), NULL, NULL, 0, "<Branch>", NULL }, 3161 { "OptionsMenu", NULL, N_("_Options"), NULL, NULL, NULL },
3187 { N_("/Options/Enable _Logging"), NULL, menu_logging_cb, 0, "<CheckItem>", NULL },
3188 { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL },
3189 { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL },
3190 { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL },
3191 { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL },
3192 }; 3162 };
3193 3163
3194 static const int menu_item_count = 3164 /* Toggle items */
3195 sizeof(menu_items) / sizeof(*menu_items); 3165 static const GtkToggleActionEntry menu_toggle_entries[] = {
3196 3166 { "EnableLogging", NULL, N_("Enable _Logging"), NULL, NULL, G_CALLBACK(menu_logging_cb), FALSE },
3197 static const char * 3167 { "EnableSounds", NULL, N_("Enable _Sounds"), NULL, NULL, G_CALLBACK(menu_sounds_cb), FALSE },
3198 item_factory_translate_func (const char *path, gpointer func_data) 3168 { "ShowFormattingToolbars", NULL, N_("Show Formatting _Toolbars"), NULL, NULL, G_CALLBACK(menu_toolbar_cb), FALSE },
3199 { 3169 { "ShowTimestamps", NULL, N_("Show Ti_mestamps"), NULL, NULL, G_CALLBACK(menu_timestamps_cb), FALSE },
3200 return _(path); 3170 };
3201 } 3171
3172 static const char *conversation_menu =
3173 "<ui>"
3174 "<menubar name='Conversation'>"
3175 "<menu action='ConversationMenu'>"
3176 "<menuitem action='NewInstantMessage'/>"
3177 "<menuitem action='JoinAChat'/>"
3178 "<separator/>"
3179 "<menuitem action='Find'/>"
3180 "<menuitem action='ViewLog'/>"
3181 "<menuitem action='SaveAs'/>"
3182 "<menuitem action='ClearScrollback'/>"
3183 "<separator/>"
3184 #ifdef USE_VV
3185 "<menu action='MediaMenu'>"
3186 "<menuitem action='AudioCall'/>"
3187 "<menuitem action='VideoCall'/>"
3188 "<menuitem action='AudioVideoCall'/>"
3189 "</menu>"
3190 #endif
3191 "<menuitem action='SendFile'/>"
3192 "<menuitem action='GetAttention'/>"
3193 "<menuitem action='AddBuddyPounce'/>"
3194 "<menuitem action='GetInfo'/>"
3195 "<menuitem action='Invite'/>"
3196 "<menu action='MoreMenu'/>"
3197 "<separator/>"
3198 "<menuitem action='Alias'/>"
3199 "<menuitem action='Block'/>"
3200 "<menuitem action='Unblock'/>"
3201 "<menuitem action='Add'/>"
3202 "<menuitem action='Remove'/>"
3203 "<separator/>"
3204 "<menuitem action='InsertLink'/>"
3205 "<menuitem action='InsertImage'/>"
3206 "<separator/>"
3207 "<menuitem action='Close'/>"
3208 "</menu>"
3209 "<menu action='OptionsMenu'>"
3210 "<menuitem action='EnableLogging'/>"
3211 "<menuitem action='EnableSounds'/>"
3212 "<separator/>"
3213 "<menuitem action='ShowFormattingToolbars'/>"
3214 "<menuitem action='ShowTimestamps'/>"
3215 "</menu>"
3216 "</menubar>"
3217 "</ui>";
3202 3218
3203 static void 3219 static void
3204 sound_method_pref_changed_cb(const char *name, PurplePrefType type, 3220 sound_method_pref_changed_cb(const char *name, PurplePrefType type,
3205 gconstpointer value, gpointer data) 3221 gconstpointer value, gpointer data)
3206 { 3222 {
3207 PidginWindow *win = data; 3223 PidginWindow *win = data;
3208 const char *method = value; 3224 const char *method = value;
3209 3225
3210 if (!strcmp(method, "none")) 3226 if (!strcmp(method, "none"))
3211 { 3227 {
3212 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3228 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3213 FALSE); 3229 FALSE);
3214 gtk_widget_set_sensitive(win->menu.sounds, FALSE); 3230 gtk_action_set_sensitive(win->menu.sounds, FALSE);
3215 } 3231 }
3216 else 3232 else
3217 { 3233 {
3218 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3234 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3219 3235
3220 if (gtkconv != NULL) 3236 if (gtkconv != NULL)
3221 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3237 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3222 gtkconv->make_sound); 3238 gtkconv->make_sound);
3223 gtk_widget_set_sensitive(win->menu.sounds, TRUE); 3239 gtk_action_set_sensitive(win->menu.sounds, TRUE);
3224
3225 } 3240 }
3226 } 3241 }
3227 3242
3228 /* Returns TRUE if some items were added to the menu, FALSE otherwise */ 3243 /* Returns TRUE if some items were added to the menu, FALSE otherwise */
3229 static gboolean 3244 static gboolean
3349 == PURPLE_CONV_TYPE_IM) { 3364 == PURPLE_CONV_TYPE_IM) {
3350 PurpleMediaCaps caps = 3365 PurpleMediaCaps caps =
3351 purple_prpl_get_media_caps(account, 3366 purple_prpl_get_media_caps(account,
3352 purple_conversation_get_name(conv)); 3367 purple_conversation_get_name(conv));
3353 3368
3354 gtk_widget_set_sensitive(win->audio_call, 3369 gtk_action_set_sensitive(win->audio_call,
3355 caps & PURPLE_MEDIA_CAPS_AUDIO 3370 caps & PURPLE_MEDIA_CAPS_AUDIO
3356 ? TRUE : FALSE); 3371 ? TRUE : FALSE);
3357 gtk_widget_set_sensitive(win->video_call, 3372 gtk_action_set_sensitive(win->video_call,
3358 caps & PURPLE_MEDIA_CAPS_VIDEO 3373 caps & PURPLE_MEDIA_CAPS_VIDEO
3359 ? TRUE : FALSE); 3374 ? TRUE : FALSE);
3360 gtk_widget_set_sensitive(win->audio_video_call, 3375 gtk_action_set_sensitive(win->audio_video_call,
3361 caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO 3376 caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO
3362 ? TRUE : FALSE); 3377 ? TRUE : FALSE);
3363 } else if (purple_conversation_get_type(conv) 3378 } else if (purple_conversation_get_type(conv)
3364 == PURPLE_CONV_TYPE_CHAT) { 3379 == PURPLE_CONV_TYPE_CHAT) {
3365 /* for now, don't care about chats... */ 3380 /* for now, don't care about chats... */
3366 gtk_widget_set_sensitive(win->audio_call, FALSE); 3381 gtk_action_set_sensitive(win->audio_call, FALSE);
3367 gtk_widget_set_sensitive(win->video_call, FALSE); 3382 gtk_action_set_sensitive(win->video_call, FALSE);
3368 gtk_widget_set_sensitive(win->audio_video_call, FALSE); 3383 gtk_action_set_sensitive(win->audio_video_call, FALSE);
3369 } else { 3384 } else {
3370 gtk_widget_set_sensitive(win->audio_call, FALSE); 3385 gtk_action_set_sensitive(win->audio_call, FALSE);
3371 gtk_widget_set_sensitive(win->video_call, FALSE); 3386 gtk_action_set_sensitive(win->video_call, FALSE);
3372 gtk_widget_set_sensitive(win->audio_video_call, FALSE); 3387 gtk_action_set_sensitive(win->audio_video_call, FALSE);
3373 } 3388 }
3374 #endif 3389 #endif
3375 } 3390 }
3376 3391
3377 static void 3392 static void
3432 regenerate_options_items(PidginWindow *win) 3447 regenerate_options_items(PidginWindow *win)
3433 { 3448 {
3434 GtkWidget *menu; 3449 GtkWidget *menu;
3435 PidginConversation *gtkconv; 3450 PidginConversation *gtkconv;
3436 GList *list; 3451 GList *list;
3452 GtkWidget *more_menu;
3437 3453
3438 gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3454 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3439 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More")); 3455 more_menu = gtk_ui_manager_get_widget(win->menu.ui,
3456 "/Conversation/ConversationMenu/MoreMenu");
3457 gtk_widget_show(more_menu);
3458 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(more_menu));
3440 3459
3441 /* Remove the previous entries */ 3460 /* Remove the previous entries */
3442 for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; ) 3461 for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; )
3443 { 3462 {
3444 GtkWidget *w = list->data; 3463 GtkWidget *w = list->data;
3490 G_CALLBACK(remove_from_list), win); 3509 G_CALLBACK(remove_from_list), win);
3491 gtk_widget_destroy(action_items->data); 3510 gtk_widget_destroy(action_items->data);
3492 action_items = g_list_delete_link(action_items, action_items); 3511 action_items = g_list_delete_link(action_items, action_items);
3493 } 3512 }
3494 3513
3495 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options")); 3514 item = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/OptionsMenu");
3515 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(item));
3496 3516
3497 list = purple_conversation_get_extended_menu(conv); 3517 list = purple_conversation_get_extended_menu(conv);
3498 if (list) { 3518 if (list) {
3499 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu))); 3519 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu)));
3500 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); 3520 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win);
3527 static void 3547 static void
3528 focus_out_from_menubar(GtkWidget *wid, PidginWindow *win) 3548 focus_out_from_menubar(GtkWidget *wid, PidginWindow *win)
3529 { 3549 {
3530 /* The menubar has been deactivated. Make sure the 'More' submenu is regenerated next time 3550 /* The menubar has been deactivated. Make sure the 'More' submenu is regenerated next time
3531 * the 'Conversation' menu pops up. */ 3551 * the 'Conversation' menu pops up. */
3532 GtkWidget *menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation")); 3552 GtkWidget *menuitem = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/ConversationMenu");
3533 g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), G_CALLBACK(menubar_activated), win); 3553 g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), G_CALLBACK(menubar_activated), win);
3534 g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar), 3554 g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar),
3535 G_CALLBACK(focus_out_from_menubar), win); 3555 G_CALLBACK(focus_out_from_menubar), win);
3536 } 3556 }
3537 3557
3538 static GtkWidget * 3558 static GtkWidget *
3539 setup_menubar(PidginWindow *win) 3559 setup_menubar(PidginWindow *win)
3540 { 3560 {
3541 GtkAccelGroup *accel_group; 3561 GtkAccelGroup *accel_group;
3542 const char *method; 3562 const char *method;
3563 GtkActionGroup *action_group;
3564 GError *error;
3543 GtkWidget *menuitem; 3565 GtkWidget *menuitem;
3544 3566
3545 accel_group = gtk_accel_group_new (); 3567 action_group = gtk_action_group_new("ConversationActions");
3568 gtk_action_group_add_actions(action_group,
3569 menu_entries,
3570 G_N_ELEMENTS(menu_entries),
3571 win);
3572 gtk_action_group_add_toggle_actions(action_group,
3573 menu_toggle_entries,
3574 G_N_ELEMENTS(menu_toggle_entries),
3575 win);
3576 #ifdef ENABLE_NLS
3577 gtk_action_group_set_translation_domain(action_group,
3578 PACKAGE);
3579 #endif
3580
3581 win->menu.ui = gtk_ui_manager_new();
3582 gtk_ui_manager_insert_action_group(win->menu.ui, action_group, 0);
3583
3584 accel_group = gtk_ui_manager_get_accel_group(win->menu.ui);
3546 gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group); 3585 gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group);
3547 g_object_unref(accel_group);
3548
3549 win->menu.item_factory =
3550 gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
3551
3552 gtk_item_factory_set_translate_func(win->menu.item_factory,
3553 (GtkTranslateFunc)item_factory_translate_func,
3554 NULL, NULL);
3555
3556 gtk_item_factory_create_items(win->menu.item_factory, menu_item_count,
3557 menu_items, win);
3558 g_signal_connect(G_OBJECT(accel_group), "accel-changed", 3586 g_signal_connect(G_OBJECT(accel_group), "accel-changed",
3559 G_CALLBACK(pidgin_save_accels_cb), NULL); 3587 G_CALLBACK(pidgin_save_accels_cb), NULL);
3560 3588
3561 /* Make sure the 'Conversation -> More' menuitems are regenerated whenever 3589 error = NULL;
3562 * the 'Conversation' menu pops up because the entries can change after the 3590 if (!gtk_ui_manager_add_ui_from_string(win->menu.ui, conversation_menu, -1, &error))
3563 * conversation is created. */ 3591 {
3564 menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation")); 3592 g_message("building menus failed: %s", error->message);
3593 g_error_free(error);
3594 exit(EXIT_FAILURE);
3595 }
3596
3597 win->menu.menubar =
3598 gtk_ui_manager_get_widget(win->menu.ui, "/Conversation");
3599
3600 menuitem = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/ConversationMenu");
3565 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win); 3601 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win);
3566 3602
3567 win->menu.menubar =
3568 gtk_item_factory_get_widget(win->menu.item_factory, "<main>");
3569
3570 win->menu.view_log = 3603 win->menu.view_log =
3571 gtk_item_factory_get_widget(win->menu.item_factory, 3604 gtk_ui_manager_get_action(win->menu.ui,
3572 N_("/Conversation/View Log")); 3605 "/Conversation/ConversationMenu/ViewLog");
3573 3606
3574 #ifdef USE_VV 3607 #ifdef USE_VV
3575 win->audio_call = 3608 win->audio_call =
3576 gtk_item_factory_get_widget(win->menu.item_factory, 3609 gtk_ui_manager_get_action(win->menu.ui,
3577 N_("/Conversation/Media/Audio Call")); 3610 "/Conversation/ConversationMenu/MediaMenu/AudioCall");
3578 win->video_call = 3611 win->video_call =
3579 gtk_item_factory_get_widget(win->menu.item_factory, 3612 gtk_ui_manager_get_action(win->menu.ui,
3580 N_("/Conversation/Media/Video Call")); 3613 "/Conversation/ConversationMenu/MediaMenu/VideoCall");
3581 win->audio_video_call = 3614 win->audio_video_call =
3582 gtk_item_factory_get_widget(win->menu.item_factory, 3615 gtk_ui_manager_get_action(win->menu.ui,
3583 N_("/Conversation/Media/Audio\\/Video Call")); 3616 "/Conversation/ConversationMenu/MediaMenu/AudioVideoCall");
3584 #endif 3617 #endif
3585 3618
3586 /* --- */ 3619 /* --- */
3587 3620
3588 win->menu.send_file = 3621 win->menu.send_file =
3589 gtk_item_factory_get_widget(win->menu.item_factory, 3622 gtk_ui_manager_get_action(win->menu.ui,
3590 N_("/Conversation/Send File...")); 3623 "/Conversation/ConversationMenu/SendFile");
3591 3624
3592 win->menu.get_attention = 3625 win->menu.get_attention =
3593 gtk_item_factory_get_widget(win->menu.item_factory, 3626 gtk_ui_manager_get_action(win->menu.ui,
3594 N_("/Conversation/Get Attention")); 3627 "/Conversation/ConversationMenu/GetAttention");
3595 3628
3596 win->menu.add_pounce = 3629 win->menu.add_pounce =
3597 gtk_item_factory_get_widget(win->menu.item_factory, 3630 gtk_ui_manager_get_action(win->menu.ui,
3598 N_("/Conversation/Add Buddy Pounce...")); 3631 "/Conversation/ConversationMenu/AddBuddyPounce");
3599 3632
3600 /* --- */ 3633 /* --- */
3601 3634
3602 win->menu.get_info = 3635 win->menu.get_info =
3603 gtk_item_factory_get_widget(win->menu.item_factory, 3636 gtk_ui_manager_get_action(win->menu.ui,
3604 N_("/Conversation/Get Info")); 3637 "/Conversation/ConversationMenu/GetInfo");
3605 3638
3606 win->menu.invite = 3639 win->menu.invite =
3607 gtk_item_factory_get_widget(win->menu.item_factory, 3640 gtk_ui_manager_get_action(win->menu.ui,
3608 N_("/Conversation/Invite...")); 3641 "/Conversation/ConversationMenu/Invite");
3609 3642
3610 /* --- */ 3643 /* --- */
3611 3644
3612 win->menu.alias = 3645 win->menu.alias =
3613 gtk_item_factory_get_widget(win->menu.item_factory, 3646 gtk_ui_manager_get_action(win->menu.ui,
3614 N_("/Conversation/Alias...")); 3647 "/Conversation/ConversationMenu/Alias");
3615 3648
3616 win->menu.block = 3649 win->menu.block =
3617 gtk_item_factory_get_widget(win->menu.item_factory, 3650 gtk_ui_manager_get_action(win->menu.ui,
3618 N_("/Conversation/Block...")); 3651 "/Conversation/ConversationMenu/Block");
3619 3652
3620 win->menu.unblock = 3653 win->menu.unblock =
3621 gtk_item_factory_get_widget(win->menu.item_factory, 3654 gtk_ui_manager_get_action(win->menu.ui,
3622 N_("/Conversation/Unblock...")); 3655 "/Conversation/ConversationMenu/Unblock");
3623 3656
3624 win->menu.add = 3657 win->menu.add =
3625 gtk_item_factory_get_widget(win->menu.item_factory, 3658 gtk_ui_manager_get_action(win->menu.ui,
3626 N_("/Conversation/Add...")); 3659 "/Conversation/ConversationMenu/Add");
3627 3660
3628 win->menu.remove = 3661 win->menu.remove =
3629 gtk_item_factory_get_widget(win->menu.item_factory, 3662 gtk_ui_manager_get_action(win->menu.ui,
3630 N_("/Conversation/Remove...")); 3663 "/Conversation/ConversationMenu/Remove");
3631 3664
3632 /* --- */ 3665 /* --- */
3633 3666
3634 win->menu.insert_link = 3667 win->menu.insert_link =
3635 gtk_item_factory_get_widget(win->menu.item_factory, 3668 gtk_ui_manager_get_action(win->menu.ui,
3636 N_("/Conversation/Insert Link...")); 3669 "/Conversation/ConversationMenu/InsertLink");
3637 3670
3638 win->menu.insert_image = 3671 win->menu.insert_image =
3639 gtk_item_factory_get_widget(win->menu.item_factory, 3672 gtk_ui_manager_get_action(win->menu.ui,
3640 N_("/Conversation/Insert Image...")); 3673 "/Conversation/ConversationMenu/InsertImage");
3641 3674
3642 /* --- */ 3675 /* --- */
3643 3676
3644 win->menu.logging = 3677 win->menu.logging =
3645 gtk_item_factory_get_widget(win->menu.item_factory, 3678 gtk_ui_manager_get_action(win->menu.ui,
3646 N_("/Options/Enable Logging")); 3679 "/Conversation/OptionsMenu/EnableLogging");
3647 win->menu.sounds = 3680 win->menu.sounds =
3648 gtk_item_factory_get_widget(win->menu.item_factory, 3681 gtk_ui_manager_get_action(win->menu.ui,
3649 N_("/Options/Enable Sounds")); 3682 "/Conversation/OptionsMenu/EnableSounds");
3650 method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); 3683 method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
3651 if (method != NULL && !strcmp(method, "none")) 3684 if (method != NULL && !strcmp(method, "none"))
3652 { 3685 {
3653 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3686 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3654 FALSE); 3687 FALSE);
3655 gtk_widget_set_sensitive(win->menu.sounds, FALSE); 3688 gtk_action_set_sensitive(win->menu.sounds, FALSE);
3656 } 3689 }
3657 purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method", 3690 purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method",
3658 sound_method_pref_changed_cb, win); 3691 sound_method_pref_changed_cb, win);
3659 3692
3660 win->menu.show_formatting_toolbar = 3693 win->menu.show_formatting_toolbar =
3661 gtk_item_factory_get_widget(win->menu.item_factory, 3694 gtk_ui_manager_get_action(win->menu.ui,
3662 N_("/Options/Show Formatting Toolbars")); 3695 "/Conversation/OptionsMenu/ShowFormattingToolbars");
3663 win->menu.show_timestamps = 3696 win->menu.show_timestamps =
3664 gtk_item_factory_get_widget(win->menu.item_factory, 3697 gtk_ui_manager_get_action(win->menu.ui,
3665 N_("/Options/Show Timestamps")); 3698 "/Conversation/OptionsMenu/ShowTimestamps");
3666 win->menu.show_icon = NULL; 3699 win->menu.show_icon = NULL;
3667 3700
3668 win->menu.tray = pidgin_menu_tray_new(); 3701 win->menu.tray = pidgin_menu_tray_new();
3669 gtk_menu_shell_append(GTK_MENU_SHELL(win->menu.menubar), 3702 gtk_menu_shell_append(GTK_MENU_SHELL(win->menu.menubar),
3670 win->menu.tray); 3703 win->menu.tray);
3843 if (win->menu.send_to == NULL) 3876 if (win->menu.send_to == NULL)
3844 return FALSE; 3877 return FALSE;
3845 3878
3846 if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv)))) 3879 if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv))))
3847 return FALSE; 3880 return FALSE;
3848
3849 3881
3850 gtk_widget_show(win->menu.send_to); 3882 gtk_widget_show(win->menu.send_to);
3851 3883
3852 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to)); 3884 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to));
3853 3885
5015 5047
5016 gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0); 5048 gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0);
5017 5049
5018 close = pidgin_create_small_button(gtk_label_new("×")); 5050 close = pidgin_create_small_button(gtk_label_new("×"));
5019 gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0); 5051 gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0);
5052 #if GTK_CHECK_VERSION(2,12,0)
5053 gtk_widget_set_tooltip_text(close, _("Close Find bar"));
5054 #else
5020 gtk_tooltips_set_tip(gtkconv->tooltips, close, 5055 gtk_tooltips_set_tip(gtkconv->tooltips, close,
5021 _("Close Find bar"), NULL); 5056 _("Close Find bar"), NULL);
5057 #endif
5022 5058
5023 label = gtk_label_new(_("Find:")); 5059 label = gtk_label_new(_("Find:"));
5024 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10); 5060 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10);
5025 5061
5026 entry = gtk_entry_new(); 5062 entry = gtk_entry_new();
5689 gtkconv->active_conv = conv; 5725 gtkconv->active_conv = conv;
5690 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); 5726 gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
5691 gtkconv->send_history = g_list_append(NULL, NULL); 5727 gtkconv->send_history = g_list_append(NULL, NULL);
5692 5728
5693 /* Setup some initial variables. */ 5729 /* Setup some initial variables. */
5730 #if !GTK_CHECK_VERSION(2,12,0)
5694 gtkconv->tooltips = gtk_tooltips_new(); 5731 gtkconv->tooltips = gtk_tooltips_new();
5732 #endif
5695 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; 5733 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
5696 gtkconv->unseen_count = 0; 5734 gtkconv->unseen_count = 0;
5697 theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation"); 5735 theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation");
5698 if (!theme) 5736 if (!theme)
5699 theme = purple_theme_manager_find_theme("Default", "conversation"); 5737 theme = purple_theme_manager_find_theme("Default", "conversation");
5888 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 5926 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
5889 purple_signals_disconnect_by_handle(gtkconv->u.chat); 5927 purple_signals_disconnect_by_handle(gtkconv->u.chat);
5890 g_free(gtkconv->u.chat); 5928 g_free(gtkconv->u.chat);
5891 } 5929 }
5892 5930
5931 #if !GTK_CHECK_VERSION(2,12,0)
5893 gtk_object_sink(GTK_OBJECT(gtkconv->tooltips)); 5932 gtk_object_sink(GTK_OBJECT(gtkconv->tooltips));
5933 #endif
5894 5934
5895 gtkconv->send_history = g_list_first(gtkconv->send_history); 5935 gtkconv->send_history = g_list_first(gtkconv->send_history);
5896 g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL); 5936 g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL);
5897 g_list_free(gtkconv->send_history); 5937 g_list_free(gtkconv->send_history);
5898 5938
6992 */ 7032 */
6993 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 7033 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
6994 /* Show stuff that applies to IMs, hide stuff that applies to chats */ 7034 /* Show stuff that applies to IMs, hide stuff that applies to chats */
6995 7035
6996 /* Deal with menu items */ 7036 /* Deal with menu items */
6997 gtk_widget_show(win->menu.view_log); 7037 gtk_action_set_visible(win->menu.view_log, TRUE);
6998 gtk_widget_show(win->menu.send_file); 7038 gtk_action_set_visible(win->menu.send_file, TRUE);
6999 gtk_widget_show(win->menu.get_attention); 7039 gtk_action_set_visible(win->menu.get_attention, TRUE);
7000 gtk_widget_show(win->menu.add_pounce); 7040 gtk_action_set_visible(win->menu.add_pounce, TRUE);
7001 gtk_widget_show(win->menu.get_info); 7041 gtk_action_set_visible(win->menu.get_info, TRUE);
7002 gtk_widget_hide(win->menu.invite); 7042 gtk_action_set_visible(win->menu.invite, FALSE);
7003 gtk_widget_show(win->menu.alias); 7043 gtk_action_set_visible(win->menu.alias, TRUE);
7004 if (purple_privacy_check(account, purple_conversation_get_name(conv))) { 7044 if (purple_privacy_check(account, purple_conversation_get_name(conv))) {
7005 gtk_widget_hide(win->menu.unblock); 7045 gtk_action_set_visible(win->menu.unblock, FALSE);
7006 gtk_widget_show(win->menu.block); 7046 gtk_action_set_visible(win->menu.block, TRUE);
7007 } else { 7047 } else {
7008 gtk_widget_hide(win->menu.block); 7048 gtk_action_set_visible(win->menu.block, FALSE);
7009 gtk_widget_show(win->menu.unblock); 7049 gtk_action_set_visible(win->menu.unblock, TRUE);
7010 } 7050 }
7011 7051
7012 if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) { 7052 if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
7013 gtk_widget_show(win->menu.add); 7053 gtk_action_set_visible(win->menu.add, TRUE);
7014 gtk_widget_hide(win->menu.remove); 7054 gtk_action_set_visible(win->menu.remove, FALSE);
7015 } else { 7055 } else {
7016 gtk_widget_show(win->menu.remove); 7056 gtk_action_set_visible(win->menu.remove, TRUE);
7017 gtk_widget_hide(win->menu.add); 7057 gtk_action_set_visible(win->menu.add, FALSE);
7018 } 7058 }
7019 7059
7020 gtk_widget_show(win->menu.insert_link); 7060 gtk_action_set_visible(win->menu.insert_link, TRUE);
7021 gtk_widget_show(win->menu.insert_image); 7061 gtk_action_set_visible(win->menu.insert_image, TRUE);
7022 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 7062 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
7023 /* Show stuff that applies to Chats, hide stuff that applies to IMs */ 7063 /* Show stuff that applies to Chats, hide stuff that applies to IMs */
7024 7064
7025 /* Deal with menu items */ 7065 /* Deal with menu items */
7026 gtk_widget_show(win->menu.view_log); 7066 gtk_action_set_visible(win->menu.view_log, TRUE);
7027 gtk_widget_hide(win->menu.send_file); 7067 gtk_action_set_visible(win->menu.send_file, FALSE);
7028 gtk_widget_hide(win->menu.get_attention); 7068 gtk_action_set_visible(win->menu.get_attention, FALSE);
7029 gtk_widget_hide(win->menu.add_pounce); 7069 gtk_action_set_visible(win->menu.add_pounce, FALSE);
7030 gtk_widget_hide(win->menu.get_info); 7070 gtk_action_set_visible(win->menu.get_info, FALSE);
7031 gtk_widget_show(win->menu.invite); 7071 gtk_action_set_visible(win->menu.invite, TRUE);
7032 gtk_widget_show(win->menu.alias); 7072 gtk_action_set_visible(win->menu.alias, TRUE);
7033 gtk_widget_hide(win->menu.block); 7073 gtk_action_set_visible(win->menu.block, FALSE);
7034 gtk_widget_hide(win->menu.unblock); 7074 gtk_action_set_visible(win->menu.unblock, FALSE);
7035 7075
7036 if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) { 7076 if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) {
7037 /* If the chat is NOT in the buddy list */ 7077 /* If the chat is NOT in the buddy list */
7038 gtk_widget_show(win->menu.add); 7078 gtk_action_set_visible(win->menu.add, TRUE);
7039 gtk_widget_hide(win->menu.remove); 7079 gtk_action_set_visible(win->menu.remove, FALSE);
7040 } else { 7080 } else {
7041 /* If the chat IS in the buddy list */ 7081 /* If the chat IS in the buddy list */
7042 gtk_widget_hide(win->menu.add); 7082 gtk_action_set_visible(win->menu.add, FALSE);
7043 gtk_widget_show(win->menu.remove); 7083 gtk_action_set_visible(win->menu.remove, TRUE);
7044 } 7084 }
7045 7085
7046 gtk_widget_show(win->menu.insert_link); 7086 gtk_action_set_visible(win->menu.insert_link, TRUE);
7047 gtk_widget_show(win->menu.insert_image); 7087 gtk_action_set_visible(win->menu.insert_image, TRUE);
7048 } 7088 }
7049 7089
7050 /* 7090 /*
7051 * Handle graying stuff out based on whether an account is connected 7091 * Handle graying stuff out based on whether an account is connected
7052 * and what features that account supports. 7092 * and what features that account supports.
7091 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons); 7131 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons);
7092 if (account != NULL) 7132 if (account != NULL)
7093 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account)); 7133 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account));
7094 7134
7095 /* Deal with menu items */ 7135 /* Deal with menu items */
7096 gtk_widget_set_sensitive(win->menu.view_log, TRUE); 7136 gtk_action_set_sensitive(win->menu.view_log, TRUE);
7097 gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); 7137 gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
7098 gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL)); 7138 gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
7099 gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL)); 7139 gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
7100 gtk_widget_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML)); 7140 gtk_action_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML));
7101 gtk_widget_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES)); 7141 gtk_action_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES));
7102 7142
7103 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 7143 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
7104 { 7144 {
7105 gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL)); 7145 gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
7106 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL)); 7146 gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
7107 gtk_widget_set_sensitive(win->menu.send_file, 7147 gtk_action_set_sensitive(win->menu.send_file,
7108 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || 7148 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
7109 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); 7149 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv)))));
7110 gtk_widget_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL)); 7150 gtk_action_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL));
7111 gtk_widget_set_sensitive(win->menu.alias, 7151 gtk_action_set_sensitive(win->menu.alias,
7112 (account != NULL) && 7152 (account != NULL) &&
7113 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL)); 7153 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
7114 } 7154 }
7115 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) 7155 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
7116 { 7156 {
7117 gtk_widget_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL)); 7157 gtk_action_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
7118 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL)); 7158 gtk_action_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
7119 gtk_widget_set_sensitive(win->menu.alias, 7159 gtk_action_set_sensitive(win->menu.alias,
7120 (account != NULL) && 7160 (account != NULL) &&
7121 (purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL)); 7161 (purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL));
7122 } 7162 }
7123 7163
7124 } else { 7164 } else {
7125 /* Account is offline */ 7165 /* Account is offline */
7126 /* Or it's a chat that we've left. */ 7166 /* Or it's a chat that we've left. */
7127 7167
7128 /* Then deal with menu items */ 7168 /* Then deal with menu items */
7129 gtk_widget_set_sensitive(win->menu.view_log, TRUE); 7169 gtk_action_set_sensitive(win->menu.view_log, TRUE);
7130 gtk_widget_set_sensitive(win->menu.send_file, FALSE); 7170 gtk_action_set_sensitive(win->menu.send_file, FALSE);
7131 gtk_widget_set_sensitive(win->menu.get_attention, FALSE); 7171 gtk_action_set_sensitive(win->menu.get_attention, FALSE);
7132 gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); 7172 gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
7133 gtk_widget_set_sensitive(win->menu.get_info, FALSE); 7173 gtk_action_set_sensitive(win->menu.get_info, FALSE);
7134 gtk_widget_set_sensitive(win->menu.invite, FALSE); 7174 gtk_action_set_sensitive(win->menu.invite, FALSE);
7135 gtk_widget_set_sensitive(win->menu.alias, FALSE); 7175 gtk_action_set_sensitive(win->menu.alias, FALSE);
7136 gtk_widget_set_sensitive(win->menu.add, FALSE); 7176 gtk_action_set_sensitive(win->menu.add, FALSE);
7137 gtk_widget_set_sensitive(win->menu.remove, FALSE); 7177 gtk_action_set_sensitive(win->menu.remove, FALSE);
7138 gtk_widget_set_sensitive(win->menu.insert_link, TRUE); 7178 gtk_action_set_sensitive(win->menu.insert_link, TRUE);
7139 gtk_widget_set_sensitive(win->menu.insert_image, FALSE); 7179 gtk_action_set_sensitive(win->menu.insert_image, FALSE);
7140 } 7180 }
7141 7181
7142 /* 7182 /*
7143 * Update the window's icon 7183 * Update the window's icon
7144 */ 7184 */
7215 if (gtkchat->topic_text != NULL) 7255 if (gtkchat->topic_text != NULL)
7216 { 7256 {
7217 topic = purple_conv_chat_get_topic(chat); 7257 topic = purple_conv_chat_get_topic(chat);
7218 7258
7219 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : ""); 7259 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
7260 #if GTK_CHECK_VERSION(2,12,0)
7261 gtk_widget_set_tooltip_text(gtkchat->topic_text,
7262 topic ? topic : "");
7263 #else
7220 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text, 7264 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text,
7221 topic ? topic : "", NULL); 7265 topic ? topic : "", NULL);
7266 #endif
7222 } 7267 }
7223 } 7268 }
7224 7269
7225 #if 0 7270 #if 0
7226 if (fields & PIDGIN_CONV_SMILEY_THEME) 7271 if (fields & PIDGIN_CONV_SMILEY_THEME)
7278 gtk_widget_queue_draw(gtkconv->infopane); 7323 gtk_widget_queue_draw(gtkconv->infopane);
7279 7324
7280 if (title != markup) 7325 if (title != markup)
7281 g_free(markup); 7326 g_free(markup);
7282 7327
7283 if (!GTK_WIDGET_REALIZED(gtkconv->tab_label)) 7328 if (!gtk_widget_get_realized(gtkconv->tab_label))
7284 gtk_widget_realize(gtkconv->tab_label); 7329 gtk_widget_realize(gtkconv->tab_label);
7285 7330
7286 accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont); 7331 accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont);
7287 if (im != NULL && 7332 if (im != NULL &&
7288 purple_conv_im_get_typing_state(im) == PURPLE_TYPING) { 7333 purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
7672 7717
7673 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i); 7718 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
7674 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page); 7719 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
7675 7720
7676 /* Make sure the tab is not hidden beyond an arrow */ 7721 /* Make sure the tab is not hidden beyond an arrow */
7677 if (!GTK_WIDGET_DRAWABLE(tab) && gtk_notebook_get_show_tabs(notebook)) 7722 if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook))
7678 continue; 7723 continue;
7679 7724
7680 if (horiz) { 7725 if (horiz) {
7681 if (x_rel >= tab->allocation.x - PIDGIN_HIG_BOX_SPACE && 7726 if (x_rel >= tab->allocation.x - PIDGIN_HIG_BOX_SPACE &&
7682 x_rel <= tab->allocation.x + tab->allocation.width + PIDGIN_HIG_BOX_SPACE) { 7727 x_rel <= tab->allocation.x + tab->allocation.width + PIDGIN_HIG_BOX_SPACE) {
7797 continue; 7842 continue;
7798 7843
7799 gtkconv = PIDGIN_CONVERSATION(conv); 7844 gtkconv = PIDGIN_CONVERSATION(conv);
7800 win = gtkconv->win; 7845 win = gtkconv->win;
7801 7846
7802 gtk_check_menu_item_set_active( 7847 gtk_toggle_action_set_active(
7803 GTK_CHECK_MENU_ITEM(win->menu.show_timestamps), 7848 GTK_TOGGLE_ACTION(win->menu.show_timestamps),
7804 (gboolean)GPOINTER_TO_INT(value)); 7849 (gboolean)GPOINTER_TO_INT(value));
7805 7850
7806 /* TODO WEBKIT: Use WebKit version of this. */ 7851 /* TODO WEBKIT: Use WebKit version of this. */
7807 #if 0 7852 #if 0
7808 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), 7853 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
7828 continue; 7873 continue;
7829 7874
7830 gtkconv = PIDGIN_CONVERSATION(conv); 7875 gtkconv = PIDGIN_CONVERSATION(conv);
7831 win = gtkconv->win; 7876 win = gtkconv->win;
7832 7877
7833 gtk_check_menu_item_set_active( 7878 gtk_toggle_action_set_active(
7834 GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar), 7879 GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
7835 (gboolean)GPOINTER_TO_INT(value)); 7880 (gboolean)GPOINTER_TO_INT(value));
7836 7881
7837 if ((gboolean)GPOINTER_TO_INT(value)) 7882 if ((gboolean)GPOINTER_TO_INT(value))
7838 gtk_widget_show(gtkconv->toolbar); 7883 gtk_widget_show(gtkconv->toolbar);
7839 else 7884 else
8793 GTK_RESPONSE_OK); 8838 GTK_RESPONSE_OK);
8794 8839
8795 gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog), 8840 gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog),
8796 6); 8841 6);
8797 gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE); 8842 gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE);
8798 gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), 8843 #if !GTK_CHECK_VERSION(2,22,0)
8799 FALSE); 8844 gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), FALSE);
8845 #endif
8800 8846
8801 /* Setup the outside spacing. */ 8847 /* Setup the outside spacing. */
8802 vbox = GTK_DIALOG(warn_close_dialog)->vbox; 8848 vbox = GTK_DIALOG(warn_close_dialog)->vbox;
8803 8849
8804 gtk_box_set_spacing(GTK_BOX(vbox), 12); 8850 gtk_box_set_spacing(GTK_BOX(vbox), 12);
9096 9142
9097 if (e->button == 3) { 9143 if (e->button == 3) {
9098 /* Right click was pressed. Popup the context menu. */ 9144 /* Right click was pressed. Popup the context menu. */
9099 GtkWidget *menu = gtk_menu_new(), *sub; 9145 GtkWidget *menu = gtk_menu_new(), *sub;
9100 gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE); 9146 gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE);
9147
9101 sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to)); 9148 sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
9102 9149 if (sub && gtk_widget_is_sensitive(gtkconv->win->menu.send_to)) {
9103 if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) {
9104 GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To")); 9150 GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To"));
9105 if (populated) 9151 if (populated)
9106 pidgin_separator(menu); 9152 pidgin_separator(menu);
9107 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); 9153 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
9108 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), sub); 9154 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), sub);
9531 { 9577 {
9532 GtkWidget *entry = NULL; 9578 GtkWidget *entry = NULL;
9533 PurpleConversation *conv = gtkconv->active_conv; 9579 PurpleConversation *conv = gtkconv->active_conv;
9534 const char *text = NULL; 9580 const char *text = NULL;
9535 9581
9536 if (!GTK_WIDGET_VISIBLE(gtkconv->infopane)) { 9582 if (!gtk_widget_get_visible(gtkconv->infopane)) {
9537 /* There's already an entry for alias. Let's not create another one. */ 9583 /* There's already an entry for alias. Let's not create another one. */
9538 return FALSE; 9584 return FALSE;
9539 } 9585 }
9540 9586
9541 if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) { 9587 if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) {
9615 gtkconv_set_unseen(gtkconv, PIDGIN_UNSEEN_NONE); 9661 gtkconv_set_unseen(gtkconv, PIDGIN_UNSEEN_NONE);
9616 } 9662 }
9617 9663
9618 /* Update the menubar */ 9664 /* Update the menubar */
9619 9665
9620 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging), 9666 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging),
9621 purple_conversation_is_logging(conv)); 9667 purple_conversation_is_logging(conv));
9622 9668
9623 generate_send_to_items(win); 9669 generate_send_to_items(win);
9624 regenerate_options_items(win); 9670 regenerate_options_items(win);
9625 regenerate_plugins_items(win); 9671 regenerate_plugins_items(win);
9626 9672
9627 pidgin_conv_switch_active_conversation(conv); 9673 pidgin_conv_switch_active_conversation(conv);
9628 9674
9629 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); 9675 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
9630 if (strcmp(sound_method, "none") != 0) 9676 if (strcmp(sound_method, "none") != 0)
9631 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 9677 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
9632 gtkconv->make_sound); 9678 gtkconv->make_sound);
9633 9679
9634 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar), 9680 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
9635 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")); 9681 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
9636 9682
9637 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_timestamps), 9683 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_timestamps),
9638 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps")); 9684 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
9639 9685
9640 /* 9686 /*
9641 * We pause icons when they are not visible. If this icon should 9687 * We pause icons when they are not visible. If this icon should
9642 * be animated then start it back up again. 9688 * be animated then start it back up again.
9643 */ 9689 */
9691 } 9737 }
9692 9738
9693 static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) { 9739 static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
9694 int x, y; 9740 int x, y;
9695 9741
9696 if (GTK_WIDGET_VISIBLE(w)) 9742 if (gtk_widget_get_visible(w))
9697 gtk_window_get_position(GTK_WINDOW(w), &x, &y); 9743 gtk_window_get_position(GTK_WINDOW(w), &x, &y);
9698 else 9744 else
9699 return FALSE; /* carry on normally */ 9745 return FALSE; /* carry on normally */
9700 9746
9701 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired 9747 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired
9726 int conv_width, int conv_height) 9772 int conv_width, int conv_height)
9727 { 9773 {
9728 /* if the window exists, is hidden, we're saving positions, and the 9774 /* if the window exists, is hidden, we're saving positions, and the
9729 * position is sane... */ 9775 * position is sane... */
9730 if (win && win->window && 9776 if (win && win->window &&
9731 !GTK_WIDGET_VISIBLE(win->window) && conv_width != 0) { 9777 !gtk_widget_get_visible(win->window) && conv_width != 0) {
9732 9778
9733 #ifdef _WIN32 /* only override window manager placement on Windows */ 9779 #ifdef _WIN32 /* only override window manager placement on Windows */
9734 /* ...check position is on screen... */ 9780 /* ...check position is on screen... */
9735 if (conv_x >= gdk_screen_width()) 9781 if (conv_x >= gdk_screen_width())
9736 conv_x = gdk_screen_width() - 100; 9782 conv_x = gdk_screen_width() - 100;
9881 } 9927 }
9882 return; 9928 return;
9883 } 9929 }
9884 gtk_widget_destroy(win->window); 9930 gtk_widget_destroy(win->window);
9885 9931
9886 g_object_unref(G_OBJECT(win->menu.item_factory)); 9932 g_object_unref(G_OBJECT(win->menu.ui));
9887 9933
9888 purple_notify_close_with_handle(win); 9934 purple_notify_close_with_handle(win);
9889 purple_signals_disconnect_by_handle(win); 9935 purple_signals_disconnect_by_handle(win);
9890 9936
9891 g_free(win); 9937 g_free(win);
9959 pidgin_conv_tab_pack(win, ((PidginConversation*)win->gtkconvs->data)); 10005 pidgin_conv_tab_pack(win, ((PidginConversation*)win->gtkconvs->data));
9960 10006
9961 10007
9962 /* Close button. */ 10008 /* Close button. */
9963 gtkconv->close = pidgin_create_small_button(gtk_label_new("×")); 10009 gtkconv->close = pidgin_create_small_button(gtk_label_new("×"));
10010 #if GTK_CHECK_VERSION(2,12,0)
10011 gtk_widget_set_tooltip_text(gtkconv->close, _("Close conversation"));
10012 #else
9964 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close, 10013 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
9965 _("Close conversation"), NULL); 10014 _("Close conversation"), NULL);
10015 #endif
9966 10016
9967 g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv); 10017 g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv);
9968 10018
9969 /* Status icon. */ 10019 /* Status icon. */
9970 gtkconv->icon = gtk_image_new(); 10020 gtkconv->icon = gtk_image_new();
10096 10146
10097 /* Reset the tabs label to the new version */ 10147 /* Reset the tabs label to the new version */
10098 gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox); 10148 gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox);
10099 } 10149 }
10100 10150
10101 gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, 10151 gtk_container_child_set(GTK_CONTAINER(win->notebook), gtkconv->tab_cont,
10102 !tabs_side && !angle, 10152 "tab-expand", !tabs_side && !angle,
10103 TRUE, GTK_PACK_START); 10153 "tab-fill", TRUE, NULL);
10104 10154
10105 if (pidgin_conv_window_get_gtkconv_count(win) == 1) 10155 if (pidgin_conv_window_get_gtkconv_count(win) == 1)
10106 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), 10156 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
10107 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") && 10157 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") &&
10108 (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") || 10158 (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") ||
10122 { 10172 {
10123 unsigned int index; 10173 unsigned int index;
10124 10174
10125 index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont); 10175 index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont);
10126 10176
10127 g_object_ref(gtkconv->tab_cont); 10177 g_object_ref_sink(G_OBJECT(gtkconv->tab_cont));
10128 gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont));
10129 10178
10130 gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index); 10179 gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index);
10131 10180
10132 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv); 10181 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv);
10133 10182
10328 { 10377 {
10329 int x, y; 10378 int x, y;
10330 PurpleConversationType type = purple_conversation_get_type(conv->active_conv); 10379 PurpleConversationType type = purple_conversation_get_type(conv->active_conv);
10331 GList *all; 10380 GList *all;
10332 10381
10333 if (GTK_WIDGET_VISIBLE(w)) 10382 if (gtk_widget_get_visible(w))
10334 gtk_window_get_position(GTK_WINDOW(w), &x, &y); 10383 gtk_window_get_position(GTK_WINDOW(w), &x, &y);
10335 else 10384 else
10336 return FALSE; /* carry on normally */ 10385 return FALSE; /* carry on normally */
10337 10386
10338 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired 10387 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired