pidgin/gtkconv.c

branch
cpw.qulogic.gtk3-required
changeset 33120
f6f1a27ade72
parent 32766
a9f37628ba5a
parent 32433
f539a2c083b2
child 33121
d3d820edd000
equal deleted inserted replaced
32771:681ca041d42b 33120:f6f1a27ade72
195 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type); 195 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type);
196 static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state); 196 static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state);
197 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state); 197 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
198 static void update_typing_icon(PidginConversation *gtkconv); 198 static void update_typing_icon(PidginConversation *gtkconv);
199 static void update_typing_message(PidginConversation *gtkconv, const char *message); 199 static void update_typing_message(PidginConversation *gtkconv, const char *message);
200 static const char *item_factory_translate_func (const char *path, gpointer func_data);
201 gboolean pidgin_conv_has_focus(PurpleConversation *conv); 200 gboolean pidgin_conv_has_focus(PurpleConversation *conv);
202 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background); 201 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
203 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 202 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
204 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, gboolean create); 203 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, gboolean create);
205 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); 204 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
838 GtkSelectionData *sd, guint inf, guint t, gpointer data) 837 GtkSelectionData *sd, guint inf, guint t, gpointer data)
839 { 838 {
840 InviteBuddyInfo *info = (InviteBuddyInfo *)data; 839 InviteBuddyInfo *info = (InviteBuddyInfo *)data;
841 const char *convprotocol; 840 const char *convprotocol;
842 gboolean success = TRUE; 841 gboolean success = TRUE;
842 GdkAtom target = gtk_selection_data_get_target(sd);
843 843
844 convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv)); 844 convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv));
845 845
846 if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) 846 if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
847 { 847 {
848 PurpleBlistNode *node = NULL; 848 PurpleBlistNode *node = NULL;
849 PurpleBuddy *buddy; 849 PurpleBuddy *buddy;
850 850 const guchar *data = gtk_selection_data_get_data(sd);
851 memcpy(&node, sd->data, sizeof(node)); 851
852 memcpy(&node, data, sizeof(node));
852 853
853 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) 854 if (PURPLE_BLIST_NODE_IS_CONTACT(node))
854 buddy = purple_contact_get_priority_buddy((PurpleContact *)node); 855 buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
855 else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) 856 else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
856 buddy = (PurpleBuddy *)node; 857 buddy = (PurpleBuddy *)node;
865 success = FALSE; 866 success = FALSE;
866 } 867 }
867 else 868 else
868 gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy)); 869 gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy));
869 870
870 gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t); 871 gtk_drag_finish(dc, success,
871 } 872 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
872 else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE)) 873 }
874 else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
873 { 875 {
874 char *protocol = NULL; 876 char *protocol = NULL;
875 char *username = NULL; 877 char *username = NULL;
876 PurpleAccount *account; 878 PurpleAccount *account;
877 879
878 if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, 880 if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
879 &protocol, &username, NULL)) 881 &protocol, &username, NULL))
880 { 882 {
881 if (account == NULL) 883 if (account == NULL)
882 { 884 {
883 purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL, 885 purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL,
898 } 900 }
899 901
900 g_free(username); 902 g_free(username);
901 g_free(protocol); 903 g_free(protocol);
902 904
903 gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t); 905 gtk_drag_finish(dc, success,
906 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
904 } 907 }
905 } 908 }
906 909
907 static const GtkTargetEntry dnd_targets[] = 910 static const GtkTargetEntry dnd_targets[] =
908 { 911 {
940 943
941 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog), 944 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog),
942 GTK_RESPONSE_OK); 945 GTK_RESPONSE_OK);
943 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE); 946 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE);
944 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE); 947 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE);
948 /* TODO: set no separator using GTK+ 3.0 */
949 #if 0
945 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE); 950 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE);
951 #endif
946 952
947 info->window = GTK_WIDGET(invite_dialog); 953 info->window = GTK_WIDGET(invite_dialog);
948 954
949 /* Setup the outside spacing. */ 955 /* Setup the outside spacing. */
950 vbox = GTK_DIALOG(invite_dialog)->vbox; 956 vbox = gtk_dialog_get_content_area(GTK_DIALOG(invite_dialog));
951 957
952 gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER); 958 gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER);
953 gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE); 959 gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE);
954 960
955 /* Setup the inner hbox and put the dialog's icon in it. */ 961 /* Setup the inner hbox and put the dialog's icon in it. */
1037 if (info != NULL) 1043 if (info != NULL)
1038 gtk_widget_grab_focus(info->entry); 1044 gtk_widget_grab_focus(info->entry);
1039 } 1045 }
1040 1046
1041 static void 1047 static void
1042 menu_new_conv_cb(gpointer data, guint action, GtkWidget *widget) 1048 menu_new_conv_cb(GtkAction *action, gpointer data)
1043 { 1049 {
1044 pidgin_dialogs_im(); 1050 pidgin_dialogs_im();
1045 } 1051 }
1046 1052
1047 static void 1053 static void
1087 /* 1093 /*
1088 * It would be kinda cool if this gave the option of saving a 1094 * It would be kinda cool if this gave the option of saving a
1089 * plaintext v. HTML file. 1095 * plaintext v. HTML file.
1090 */ 1096 */
1091 static void 1097 static void
1092 menu_save_as_cb(gpointer data, guint action, GtkWidget *widget) 1098 menu_save_as_cb(GtkAction *action, gpointer data)
1093 { 1099 {
1094 PidginWindow *win = data; 1100 PidginWindow *win = data;
1095 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1101 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1096 PurpleAccount *account = purple_conversation_get_account(conv); 1102 PurpleAccount *account = purple_conversation_get_account(conv);
1097 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); 1103 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
1118 1124
1119 g_free(buf); 1125 g_free(buf);
1120 } 1126 }
1121 1127
1122 static void 1128 static void
1123 menu_view_log_cb(gpointer data, guint action, GtkWidget *widget) 1129 menu_view_log_cb(GtkAction *action, gpointer data)
1124 { 1130 {
1125 PidginWindow *win = data; 1131 PidginWindow *win = data;
1126 PurpleConversation *conv; 1132 PurpleConversation *conv;
1127 PurpleLogType type; 1133 PurpleLogType type;
1128 PidginBuddyList *gtkblist; 1134 PidginBuddyList *gtkblist;
1142 return; 1148 return;
1143 1149
1144 gtkblist = pidgin_blist_get_default_gtk_blist(); 1150 gtkblist = pidgin_blist_get_default_gtk_blist();
1145 1151
1146 cursor = gdk_cursor_new(GDK_WATCH); 1152 cursor = gdk_cursor_new(GDK_WATCH);
1147 gdk_window_set_cursor(gtkblist->window->window, cursor); 1153 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), cursor);
1148 gdk_window_set_cursor(win->window->window, cursor); 1154 gdk_window_set_cursor(gtk_widget_get_window(win->window), cursor);
1149 gdk_cursor_unref(cursor); 1155 gdk_cursor_unref(cursor);
1156 #if GTK_CHECK_VERSION(2,4,0) && !GTK_CHECK_VERSION(2,6,0) //FIXME: What?
1150 gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window))); 1157 gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
1158 #endif
1151 1159
1152 name = purple_conversation_get_name(conv); 1160 name = purple_conversation_get_name(conv);
1153 account = purple_conversation_get_account(conv); 1161 account = purple_conversation_get_account(conv);
1154 1162
1155 buddies = purple_find_buddies(account, name); 1163 buddies = purple_find_buddies(account, name);
1158 PurpleBlistNode *node = cur->data; 1166 PurpleBlistNode *node = cur->data;
1159 if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL))) 1167 if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
1160 { 1168 {
1161 pidgin_log_show_contact((PurpleContact *)node->parent); 1169 pidgin_log_show_contact((PurpleContact *)node->parent);
1162 g_slist_free(buddies); 1170 g_slist_free(buddies);
1163 gdk_window_set_cursor(gtkblist->window->window, NULL); 1171 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
1164 gdk_window_set_cursor(win->window->window, NULL); 1172 gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
1165 return; 1173 return;
1166 } 1174 }
1167 } 1175 }
1168 g_slist_free(buddies); 1176 g_slist_free(buddies);
1169 1177
1170 pidgin_log_show(type, name, account); 1178 pidgin_log_show(type, name, account);
1171 1179
1172 gdk_window_set_cursor(gtkblist->window->window, NULL); 1180 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
1173 gdk_window_set_cursor(win->window->window, NULL); 1181 gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
1174 } 1182 }
1175 1183
1176 static void 1184 static void
1177 menu_clear_cb(gpointer data, guint action, GtkWidget *widget) 1185 menu_clear_cb(GtkAction *action, gpointer data)
1178 { 1186 {
1179 PidginWindow *win = data; 1187 PidginWindow *win = data;
1180 PurpleConversation *conv; 1188 PurpleConversation *conv;
1181 1189
1182 conv = pidgin_conv_window_get_active_conversation(win); 1190 conv = pidgin_conv_window_get_active_conversation(win);
1183 purple_conversation_clear_message_history(conv); 1191 purple_conversation_clear_message_history(conv);
1184 } 1192 }
1185 1193
1186 static void 1194 static void
1187 menu_find_cb(gpointer data, guint action, GtkWidget *widget) 1195 menu_find_cb(GtkAction *action, gpointer data)
1188 { 1196 {
1189 PidginWindow *gtkwin = data; 1197 PidginWindow *gtkwin = data;
1190 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin); 1198 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin);
1191 gtk_widget_show_all(gtkconv->quickfind.container); 1199 gtk_widget_show_all(gtkconv->quickfind.container);
1192 gtk_widget_grab_focus(gtkconv->quickfind.entry); 1200 gtk_widget_grab_focus(gtkconv->quickfind.entry);
1193 } 1201 }
1194 1202
1195 #ifdef USE_VV 1203 #ifdef USE_VV
1196 static void 1204 static void
1197 menu_initiate_media_call_cb(gpointer data, guint action, GtkWidget *widget) 1205 menu_initiate_media_call_cb(GtkAction *action, gpointer data)
1198 { 1206 {
1199 PidginWindow *win = (PidginWindow *)data; 1207 PidginWindow *win = (PidginWindow *)data;
1200 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1208 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1201 PurpleAccount *account = purple_conversation_get_account(conv); 1209 PurpleAccount *account = purple_conversation_get_account(conv);
1202 1210
1203 purple_prpl_initiate_media(account, 1211 purple_prpl_initiate_media(account,
1204 purple_conversation_get_name(conv), 1212 purple_conversation_get_name(conv),
1205 action == 0 ? PURPLE_MEDIA_AUDIO : 1213 action == win->audio_call ? PURPLE_MEDIA_AUDIO :
1206 action == 1 ? PURPLE_MEDIA_VIDEO : 1214 action == win->video_call ? PURPLE_MEDIA_VIDEO :
1207 action == 2 ? PURPLE_MEDIA_AUDIO | 1215 action == win->audio_video_call ? PURPLE_MEDIA_AUDIO |
1208 PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE); 1216 PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE);
1209 } 1217 }
1210 #endif 1218 #endif
1211 1219
1212 static void 1220 static void
1213 menu_send_file_cb(gpointer data, guint action, GtkWidget *widget) 1221 menu_send_file_cb(GtkAction *action, gpointer data)
1214 { 1222 {
1215 PidginWindow *win = data; 1223 PidginWindow *win = data;
1216 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1224 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1217 1225
1218 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 1226 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
1220 } 1228 }
1221 1229
1222 } 1230 }
1223 1231
1224 static void 1232 static void
1225 menu_get_attention_cb(gpointer data, guint action, GtkWidget *widget) 1233 menu_get_attention_cb(GtkAction *ation, gpointer data)
1226 { 1234 {
1227 PidginWindow *win = data; 1235 PidginWindow *win = data;
1228 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1236 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1229 1237
1230 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 1238 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
1237 purple_conversation_get_name(conv), index); 1245 purple_conversation_get_name(conv), index);
1238 } 1246 }
1239 } 1247 }
1240 1248
1241 static void 1249 static void
1242 menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget) 1250 menu_add_pounce_cb(GtkAction *action, gpointer data)
1243 { 1251 {
1244 PidginWindow *win = data; 1252 PidginWindow *win = data;
1245 PurpleConversation *conv; 1253 PurpleConversation *conv;
1246 1254
1247 conv = pidgin_conv_window_get_active_gtkconv(win)->active_conv; 1255 conv = pidgin_conv_window_get_active_gtkconv(win)->active_conv;
1249 pidgin_pounce_editor_show(purple_conversation_get_account(conv), 1257 pidgin_pounce_editor_show(purple_conversation_get_account(conv),
1250 purple_conversation_get_name(conv), NULL); 1258 purple_conversation_get_name(conv), NULL);
1251 } 1259 }
1252 1260
1253 static void 1261 static void
1254 menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget) 1262 menu_insert_link_cb(GtkAction *action, gpointer data)
1255 { 1263 {
1256 PidginWindow *win = data; 1264 PidginWindow *win = data;
1257 PidginConversation *gtkconv; 1265 PidginConversation *gtkconv;
1258 GtkIMHtmlToolbar *toolbar; 1266 GtkIMHtmlToolbar *toolbar;
1259 1267
1263 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->link), 1271 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->link),
1264 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->link))); 1272 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->link)));
1265 } 1273 }
1266 1274
1267 static void 1275 static void
1268 menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget) 1276 menu_insert_image_cb(GtkAction *action, gpointer data)
1269 { 1277 {
1270 PidginWindow *win = data; 1278 PidginWindow *win = data;
1271 PidginConversation *gtkconv; 1279 PidginConversation *gtkconv;
1272 GtkIMHtmlToolbar *toolbar; 1280 GtkIMHtmlToolbar *toolbar;
1273 1281
1278 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->image))); 1286 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->image)));
1279 } 1287 }
1280 1288
1281 1289
1282 static void 1290 static void
1283 menu_alias_cb(gpointer data, guint action, GtkWidget *widget) 1291 menu_alias_cb(GtkAction *action, gpointer data)
1284 { 1292 {
1285 PidginWindow *win = data; 1293 PidginWindow *win = data;
1286 PurpleConversation *conv; 1294 PurpleConversation *conv;
1287 PurpleAccount *account; 1295 PurpleAccount *account;
1288 const char *name; 1296 const char *name;
1305 pidgin_dialogs_alias_chat(c); 1313 pidgin_dialogs_alias_chat(c);
1306 } 1314 }
1307 } 1315 }
1308 1316
1309 static void 1317 static void
1310 menu_get_info_cb(gpointer data, guint action, GtkWidget *widget) 1318 menu_get_info_cb(GtkAction *action, gpointer data)
1311 { 1319 {
1312 PidginWindow *win = data; 1320 PidginWindow *win = data;
1313 PurpleConversation *conv; 1321 PurpleConversation *conv;
1314 1322
1315 conv = pidgin_conv_window_get_active_conversation(win); 1323 conv = pidgin_conv_window_get_active_conversation(win);
1316 1324
1317 info_cb(NULL, PIDGIN_CONVERSATION(conv)); 1325 info_cb(NULL, PIDGIN_CONVERSATION(conv));
1318 } 1326 }
1319 1327
1320 static void 1328 static void
1321 menu_invite_cb(gpointer data, guint action, GtkWidget *widget) 1329 menu_invite_cb(GtkAction *action, gpointer data)
1322 { 1330 {
1323 PidginWindow *win = data; 1331 PidginWindow *win = data;
1324 PurpleConversation *conv; 1332 PurpleConversation *conv;
1325 1333
1326 conv = pidgin_conv_window_get_active_conversation(win); 1334 conv = pidgin_conv_window_get_active_conversation(win);
1327 1335
1328 invite_cb(NULL, PIDGIN_CONVERSATION(conv)); 1336 invite_cb(NULL, PIDGIN_CONVERSATION(conv));
1329 } 1337 }
1330 1338
1331 static void 1339 static void
1332 menu_block_cb(gpointer data, guint action, GtkWidget *widget) 1340 menu_block_cb(GtkAction *action, gpointer data)
1333 { 1341 {
1334 PidginWindow *win = data; 1342 PidginWindow *win = data;
1335 PurpleConversation *conv; 1343 PurpleConversation *conv;
1336 1344
1337 conv = pidgin_conv_window_get_active_conversation(win); 1345 conv = pidgin_conv_window_get_active_conversation(win);
1338 1346
1339 block_cb(NULL, PIDGIN_CONVERSATION(conv)); 1347 block_cb(NULL, PIDGIN_CONVERSATION(conv));
1340 } 1348 }
1341 1349
1342 static void 1350 static void
1343 menu_unblock_cb(gpointer data, guint action, GtkWidget *widget) 1351 menu_unblock_cb(GtkAction *action, gpointer data)
1344 { 1352 {
1345 PidginWindow *win = data; 1353 PidginWindow *win = data;
1346 PurpleConversation *conv; 1354 PurpleConversation *conv;
1347 1355
1348 conv = pidgin_conv_window_get_active_conversation(win); 1356 conv = pidgin_conv_window_get_active_conversation(win);
1349 1357
1350 unblock_cb(NULL, PIDGIN_CONVERSATION(conv)); 1358 unblock_cb(NULL, PIDGIN_CONVERSATION(conv));
1351 } 1359 }
1352 1360
1353 static void 1361 static void
1354 menu_add_remove_cb(gpointer data, guint action, GtkWidget *widget) 1362 menu_add_remove_cb(GtkAction *action, gpointer data)
1355 { 1363 {
1356 PidginWindow *win = data; 1364 PidginWindow *win = data;
1357 PurpleConversation *conv; 1365 PurpleConversation *conv;
1358 1366
1359 conv = pidgin_conv_window_get_active_conversation(win); 1367 conv = pidgin_conv_window_get_active_conversation(win);
1394 #endif 1402 #endif
1395 } 1403 }
1396 } 1404 }
1397 1405
1398 static void 1406 static void
1399 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) 1407 menu_close_conv_cb(GtkAction *action, gpointer data)
1400 { 1408 {
1401 PidginWindow *win = data; 1409 PidginWindow *win = data;
1402 1410
1403 close_conv_cb(NULL, PIDGIN_CONVERSATION(pidgin_conv_window_get_active_conversation(win))); 1411 close_conv_cb(NULL, PIDGIN_CONVERSATION(pidgin_conv_window_get_active_conversation(win)));
1404 } 1412 }
1405 1413
1406 static void 1414 static void
1407 menu_logging_cb(gpointer data, guint action, GtkWidget *widget) 1415 menu_logging_cb(GtkAction *action, gpointer data)
1408 { 1416 {
1409 PidginWindow *win = data; 1417 PidginWindow *win = data;
1410 PurpleConversation *conv; 1418 PurpleConversation *conv;
1411 gboolean logging; 1419 gboolean logging;
1412 PurpleBlistNode *node; 1420 PurpleBlistNode *node;
1414 conv = pidgin_conv_window_get_active_conversation(win); 1422 conv = pidgin_conv_window_get_active_conversation(win);
1415 1423
1416 if (conv == NULL) 1424 if (conv == NULL)
1417 return; 1425 return;
1418 1426
1419 logging = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); 1427 logging = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
1420 1428
1421 if (logging == purple_conversation_is_logging(conv)) 1429 if (logging == purple_conversation_is_logging(conv))
1422 return; 1430 return;
1423 1431
1424 node = get_conversation_blist_node(conv); 1432 node = get_conversation_blist_node(conv);
1465 break; 1473 break;
1466 } 1474 }
1467 } 1475 }
1468 1476
1469 static void 1477 static void
1470 menu_toolbar_cb(gpointer data, guint action, GtkWidget *widget) 1478 menu_toolbar_cb(GtkAction *action, gpointer data)
1471 { 1479 {
1472 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar", 1480 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar",
1473 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))); 1481 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
1474 } 1482 }
1475 1483
1476 static void 1484 static void
1477 menu_sounds_cb(gpointer data, guint action, GtkWidget *widget) 1485 menu_sounds_cb(GtkAction *action, gpointer data)
1478 { 1486 {
1479 PidginWindow *win = data; 1487 PidginWindow *win = data;
1480 PurpleConversation *conv; 1488 PurpleConversation *conv;
1481 PidginConversation *gtkconv; 1489 PidginConversation *gtkconv;
1482 PurpleBlistNode *node; 1490 PurpleBlistNode *node;
1487 return; 1495 return;
1488 1496
1489 gtkconv = PIDGIN_CONVERSATION(conv); 1497 gtkconv = PIDGIN_CONVERSATION(conv);
1490 1498
1491 gtkconv->make_sound = 1499 gtkconv->make_sound =
1492 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); 1500 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
1493 node = get_conversation_blist_node(conv); 1501 node = get_conversation_blist_node(conv);
1494 if (node) 1502 if (node)
1495 purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound); 1503 purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound);
1496 } 1504 }
1497 1505
1498 static void 1506 static void
1499 menu_timestamps_cb(gpointer data, guint action, GtkWidget *widget) 1507 menu_timestamps_cb(GtkAction *action, gpointer data)
1500 { 1508 {
1501 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps", 1509 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps",
1502 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))); 1510 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
1503 } 1511 }
1504 1512
1505 static void 1513 static void
1506 chat_do_im(PidginConversation *gtkconv, const char *who) 1514 chat_do_im(PidginConversation *gtkconv, const char *who)
1507 { 1515 {
1965 pidgin_tooltip_destroy(); 1973 pidgin_tooltip_destroy();
1966 1974
1967 /* If CTRL was held down... */ 1975 /* If CTRL was held down... */
1968 if (event->state & GDK_CONTROL_MASK) { 1976 if (event->state & GDK_CONTROL_MASK) {
1969 switch (event->keyval) { 1977 switch (event->keyval) {
1970 case GDK_Page_Down: 1978 case GDK_KEY_Page_Down:
1971 case GDK_KP_Page_Down: 1979 case GDK_KEY_KP_Page_Down:
1972 case ']': 1980 case ']':
1973 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1)) 1981 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1))
1974 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); 1982 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0);
1975 else 1983 else
1976 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1); 1984 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1);
1977 return TRUE; 1985 return TRUE;
1978 break; 1986 break;
1979 1987
1980 case GDK_Page_Up: 1988 case GDK_KEY_Page_Up:
1981 case GDK_KP_Page_Up: 1989 case GDK_KEY_KP_Page_Up:
1982 case '[': 1990 case '[':
1983 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1)) 1991 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1))
1984 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1); 1992 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1);
1985 else 1993 else
1986 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1); 1994 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1);
1987 return TRUE; 1995 return TRUE;
1988 break; 1996 break;
1989 1997
1990 case GDK_Tab: 1998 case GDK_KEY_Tab:
1991 case GDK_KP_Tab: 1999 case GDK_KEY_KP_Tab:
1992 case GDK_ISO_Left_Tab: 2000 case GDK_KEY_ISO_Left_Tab:
1993 if (event->state & GDK_SHIFT_MASK) { 2001 if (event->state & GDK_SHIFT_MASK) {
1994 move_to_next_unread_tab(gtkconv, FALSE); 2002 move_to_next_unread_tab(gtkconv, FALSE);
1995 } else { 2003 } else {
1996 move_to_next_unread_tab(gtkconv, TRUE); 2004 move_to_next_unread_tab(gtkconv, TRUE);
1997 } 2005 }
1998 2006
1999 return TRUE; 2007 return TRUE;
2000 break; 2008 break;
2001 2009
2002 case GDK_comma: 2010 case GDK_KEY_comma:
2003 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), 2011 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
2004 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), 2012 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
2005 curconv - 1); 2013 curconv - 1);
2006 return TRUE; 2014 return TRUE;
2007 break; 2015 break;
2008 2016
2009 case GDK_period: 2017 case GDK_KEY_period:
2010 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), 2018 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
2011 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), 2019 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
2012 (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook))); 2020 (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook)));
2013 return TRUE; 2021 return TRUE;
2014 break; 2022 break;
2015 case GDK_F6: 2023 case GDK_KEY_F6:
2016 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) 2024 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
2017 return TRUE; 2025 return TRUE;
2018 break; 2026 break;
2019 } /* End of switch */ 2027 } /* End of switch */
2020 } 2028 }
2034 2042
2035 /* If neither CTRL nor ALT were held down... */ 2043 /* If neither CTRL nor ALT were held down... */
2036 else 2044 else
2037 { 2045 {
2038 switch (event->keyval) { 2046 switch (event->keyval) {
2039 case GDK_F2: 2047 case GDK_KEY_F2:
2040 if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) { 2048 if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) {
2041 infopane_entry_activate(gtkconv); 2049 infopane_entry_activate(gtkconv);
2042 return TRUE; 2050 return TRUE;
2043 } 2051 }
2044 break; 2052 break;
2045 case GDK_F6: 2053 case GDK_KEY_F6:
2046 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) 2054 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
2047 return TRUE; 2055 return TRUE;
2048 break; 2056 break;
2049 } 2057 }
2050 } 2058 }
2064 return TRUE; 2072 return TRUE;
2065 2073
2066 /* If CTRL was held down... */ 2074 /* If CTRL was held down... */
2067 if (event->state & GDK_CONTROL_MASK) { 2075 if (event->state & GDK_CONTROL_MASK) {
2068 switch (event->keyval) { 2076 switch (event->keyval) {
2069 case GDK_Up: 2077 case GDK_KEY_Up:
2070 if (!gtkconv->send_history) 2078 if (!gtkconv->send_history)
2071 break; 2079 break;
2072 2080
2073 if (gtkconv->entry != entry) 2081 if (gtkconv->entry != entry)
2074 break; 2082 break;
2115 } 2123 }
2116 2124
2117 return TRUE; 2125 return TRUE;
2118 break; 2126 break;
2119 2127
2120 case GDK_Down: 2128 case GDK_KEY_Down:
2121 if (!gtkconv->send_history) 2129 if (!gtkconv->send_history)
2122 break; 2130 break;
2123 2131
2124 if (gtkconv->entry != entry) 2132 if (gtkconv->entry != entry)
2125 break; 2133 break;
2168 } 2176 }
2169 2177
2170 /* If neither CTRL nor ALT were held down... */ 2178 /* If neither CTRL nor ALT were held down... */
2171 else { 2179 else {
2172 switch (event->keyval) { 2180 switch (event->keyval) {
2173 case GDK_Tab: 2181 case GDK_KEY_Tab:
2174 case GDK_KP_Tab: 2182 case GDK_KEY_KP_Tab:
2175 case GDK_ISO_Left_Tab: 2183 case GDK_KEY_ISO_Left_Tab:
2176 if (gtkconv->entry != entry) 2184 if (gtkconv->entry != entry)
2177 break; 2185 break;
2178 { 2186 {
2179 gint plugin_return; 2187 gint plugin_return;
2180 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( 2188 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
2182 conv, event->state & GDK_SHIFT_MASK)); 2190 conv, event->state & GDK_SHIFT_MASK));
2183 return plugin_return ? TRUE : tab_complete(conv); 2191 return plugin_return ? TRUE : tab_complete(conv);
2184 } 2192 }
2185 break; 2193 break;
2186 2194
2187 case GDK_Page_Up: 2195 case GDK_KEY_Page_Up:
2188 case GDK_KP_Page_Up: 2196 case GDK_KEY_KP_Page_Up:
2189 /* TODO WEBKIT: Write this. */ 2197 /* TODO WEBKIT: Write this. */
2190 #if 0 2198 #if 0
2191 gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); 2199 gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml));
2192 #endif /* if 0 */ 2200 #endif /* if 0 */
2193 return TRUE; 2201 return TRUE;
2194 break; 2202 break;
2195 2203
2196 case GDK_Page_Down: 2204 case GDK_KEY_Page_Down:
2197 case GDK_KP_Page_Down: 2205 case GDK_KEY_KP_Page_Down:
2198 /* TODO WEBKIT: Write this. */ 2206 /* TODO WEBKIT: Write this. */
2199 #if 0 2207 #if 0
2200 gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); 2208 gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml));
2201 #endif /* if 0 */ 2209 #endif /* if 0 */
2202 return TRUE; 2210 return TRUE;
2239 { 2247 {
2240 PidginConversation *gtkconv = data; 2248 PidginConversation *gtkconv = data;
2241 2249
2242 /* If we have a valid key for the conversation display, then exit */ 2250 /* If we have a valid key for the conversation display, then exit */
2243 if ((event->state & GDK_CONTROL_MASK) || 2251 if ((event->state & GDK_CONTROL_MASK) ||
2244 (event->keyval == GDK_F6) || 2252 (event->keyval == GDK_KEY_F6) ||
2245 (event->keyval == GDK_F10) || 2253 (event->keyval == GDK_KEY_F10) ||
2246 (event->keyval == GDK_Shift_L) || 2254 (event->keyval == GDK_KEY_Shift_L) ||
2247 (event->keyval == GDK_Shift_R) || 2255 (event->keyval == GDK_KEY_Shift_R) ||
2248 (event->keyval == GDK_Control_L) || 2256 (event->keyval == GDK_KEY_Control_L) ||
2249 (event->keyval == GDK_Control_R) || 2257 (event->keyval == GDK_KEY_Control_R) ||
2250 (event->keyval == GDK_Escape) || 2258 (event->keyval == GDK_KEY_Escape) ||
2251 (event->keyval == GDK_Up) || 2259 (event->keyval == GDK_KEY_Up) ||
2252 (event->keyval == GDK_Down) || 2260 (event->keyval == GDK_KEY_Down) ||
2253 (event->keyval == GDK_Left) || 2261 (event->keyval == GDK_KEY_Left) ||
2254 (event->keyval == GDK_Right) || 2262 (event->keyval == GDK_KEY_Right) ||
2255 (event->keyval == GDK_Page_Up) || 2263 (event->keyval == GDK_KEY_Page_Up) ||
2256 (event->keyval == GDK_KP_Page_Up) || 2264 (event->keyval == GDK_KEY_KP_Page_Up) ||
2257 (event->keyval == GDK_Page_Down) || 2265 (event->keyval == GDK_KEY_Page_Down) ||
2258 (event->keyval == GDK_KP_Page_Down) || 2266 (event->keyval == GDK_KEY_KP_Page_Down) ||
2259 (event->keyval == GDK_Home) || 2267 (event->keyval == GDK_KEY_Home) ||
2260 (event->keyval == GDK_End) || 2268 (event->keyval == GDK_KEY_End) ||
2261 (event->keyval == GDK_Tab) || 2269 (event->keyval == GDK_KEY_Tab) ||
2262 (event->keyval == GDK_KP_Tab) || 2270 (event->keyval == GDK_KEY_KP_Tab) ||
2263 (event->keyval == GDK_ISO_Left_Tab)) 2271 (event->keyval == GDK_KEY_ISO_Left_Tab))
2264 { 2272 {
2265 if (event->type == GDK_KEY_PRESS) 2273 if (event->type == GDK_KEY_PRESS)
2266 return conv_keypress_common(gtkconv, event); 2274 return conv_keypress_common(gtkconv, event);
2267 return FALSE; 2275 return FALSE;
2268 } 2276 }
2302 2310
2303 purple_conversation_close_logs(old_conv); 2311 purple_conversation_close_logs(old_conv);
2304 gtkconv->active_conv = conv; 2312 gtkconv->active_conv = conv;
2305 2313
2306 purple_conversation_set_logging(conv, 2314 purple_conversation_set_logging(conv,
2307 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging))); 2315 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging)));
2308 2316
2309 entry = GTK_IMHTML(gtkconv->entry); 2317 entry = GTK_IMHTML(gtkconv->entry);
2310 protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv)); 2318 protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv));
2311 gtk_imhtml_set_protocol_name(entry, protocol_name); 2319 gtk_imhtml_set_protocol_name(entry, protocol_name);
2312 /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */ 2320 /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */
2491 2499
2492 /* Use the buddy icon, if possible */ 2500 /* Use the buddy icon, if possible */
2493 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 2501 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
2494 PurpleBuddy *b = purple_find_buddy(account, name); 2502 PurpleBuddy *b = purple_find_buddy(account, name);
2495 if (b != NULL) { 2503 if (b != NULL) {
2496 PurplePresence *p; 2504 PurplePresence *p = purple_buddy_get_presence(b);
2497 p = purple_buddy_get_presence(b);
2498 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY)) 2505 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY))
2499 return away_list; 2506 return away_list;
2500 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE)) 2507 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE))
2501 return busy_list; 2508 return busy_list;
2502 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY)) 2509 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY))
2728 2735
2729 return FALSE; 2736 return FALSE;
2730 } 2737 }
2731 2738
2732 static void 2739 static void
2733 start_anim(GtkObject *obj, PidginConversation *gtkconv) 2740 start_anim(GtkWidget *widget, PidginConversation *gtkconv)
2734 { 2741 {
2735 int delay; 2742 int delay;
2736 2743
2737 if (gtkconv->u.im->anim == NULL) 2744 if (gtkconv->u.im->anim == NULL)
2738 return; 2745 return;
2901 2908
2902 g_free(buf); 2909 g_free(buf);
2903 } 2910 }
2904 2911
2905 static void 2912 static void
2906 stop_anim(GtkObject *obj, PidginConversation *gtkconv) 2913 stop_anim(GtkWidget *widget, PidginConversation *gtkconv)
2907 { 2914 {
2908 if (gtkconv->u.im->icon_timer != 0) 2915 if (gtkconv->u.im->icon_timer != 0)
2909 g_source_remove(gtkconv->u.im->icon_timer); 2916 g_source_remove(gtkconv->u.im->icon_timer);
2910 2917
2911 gtkconv->u.im->icon_timer = 0; 2918 gtkconv->u.im->icon_timer = 0;
2923 else 2930 else
2924 stop_anim(NULL, gtkconv); 2931 stop_anim(NULL, gtkconv);
2925 } 2932 }
2926 2933
2927 static gboolean 2934 static gboolean
2928 icon_menu(GtkObject *obj, GdkEventButton *e, PidginConversation *gtkconv) 2935 icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
2929 { 2936 {
2930 static GtkWidget *menu = NULL; 2937 static GtkWidget *menu = NULL;
2931 PurpleConversation *conv; 2938 PurpleConversation *conv;
2932 PurpleBuddy *buddy; 2939 PurpleBuddy *buddy;
2933 2940
3117 { 3124 {
3118 g_return_val_if_fail(gtkconv != NULL, NULL); 3125 g_return_val_if_fail(gtkconv != NULL, NULL);
3119 return gtkconv->win; 3126 return gtkconv->win;
3120 } 3127 }
3121 3128
3129 #if 1
3130
3131 static GtkActionEntry menu_entries[] =
3132 /* TODO: fill out tooltips... */
3133 {
3134 /* Conversation menu */
3135 { "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL },
3136 { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) },
3137 { "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) },
3138 { "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) },
3139 { "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) },
3140 { "ClearScrollback", GTK_STOCK_CLEAR, N_("Clea_r Scrollback"), "<control>L", NULL, G_CALLBACK(menu_clear_cb) },
3141
3142 #ifdef USE_VV
3143 { "MediaMenu", NULL, N_("M_edia"), NULL, NULL, NULL },
3144 { "AudioCall", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL, N_("_Audio Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3145 { "VideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("_Video Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3146 { "AudioVideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("Audio/Video _Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3147 #endif
3148
3149 { "SendFile", PIDGIN_STOCK_TOOLBAR_SEND_FILE, N_("Se_nd File..."), NULL, NULL, G_CALLBACK(menu_send_file_cb) },
3150 { "GetAttention", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, N_("Get _Attention"), NULL, NULL, G_CALLBACK(menu_get_attention_cb) },
3151 { "AddBuddyPounce", NULL, N_("Add Buddy _Pounce..."), NULL, NULL, G_CALLBACK(menu_add_pounce_cb) },
3152 { "GetInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("_Get Info"), "<control>O", NULL, G_CALLBACK(menu_get_info_cb) },
3153 { "Invite", NULL, N_("In_vite..."), NULL, NULL, G_CALLBACK(menu_invite_cb) },
3154 { "MoreMenu", NULL, N_("M_ore"), NULL, NULL, NULL },
3155 { "Alias", NULL, N_("Al_ias..."), NULL, NULL, G_CALLBACK(menu_alias_cb) },
3156 { "Block", PIDGIN_STOCK_TOOLBAR_BLOCK, N_("_Block..."), NULL, NULL, G_CALLBACK(menu_block_cb) },
3157 { "Unblock", PIDGIN_STOCK_TOOLBAR_UNBLOCK, N_("_Unblock..."), NULL, NULL, G_CALLBACK(menu_unblock_cb) },
3158 { "Add", GTK_STOCK_ADD, N_("_Add..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
3159 { "Remove", GTK_STOCK_REMOVE, N_("_Remove..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
3160 { "InsertLink", PIDGIN_STOCK_TOOLBAR_INSERT_LINK, N_("Insert Lin_k..."), NULL, NULL, G_CALLBACK(menu_insert_link_cb) },
3161 { "InsertImage", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, N_("Insert Imag_e..."), NULL, NULL, G_CALLBACK(menu_insert_image_cb) },
3162 { "Close", GTK_STOCK_CLOSE, N_("_Close"), NULL, NULL, G_CALLBACK(menu_close_conv_cb) },
3163
3164 /* Options */
3165 { "OptionsMenu", NULL, N_("_Options"), NULL, NULL, NULL },
3166 };
3167
3168 /* Toggle items */
3169 static const GtkToggleActionEntry menu_toggle_entries[] = {
3170 { "EnableLogging", NULL, N_("Enable _Logging"), NULL, NULL, G_CALLBACK(menu_logging_cb), FALSE },
3171 { "EnableSounds", NULL, N_("Enable _Sounds"), NULL, NULL, G_CALLBACK(menu_sounds_cb), FALSE },
3172 { "ShowFormattingToolbars", NULL, N_("Show Formatting _Toolbars"), NULL, NULL, G_CALLBACK(menu_toolbar_cb), FALSE },
3173 { "ShowTimestamps", NULL, N_("Show Ti_mestamps"), NULL, NULL, G_CALLBACK(menu_timestamps_cb), FALSE },
3174 };
3175
3176 static const char *conversation_menu =
3177 "<ui>"
3178 "<menubar name='Conversation'>"
3179 "<menu action='ConversationMenu'>"
3180 "<menuitem action='NewInstantMessage'/>"
3181 "<separator/>"
3182 "<menuitem action='Find'/>"
3183 "<menuitem action='ViewLog'/>"
3184 "<menuitem action='SaveAs'/>"
3185 "<menuitem action='ClearScrollback'/>"
3186 "<separator/>"
3187 #ifdef USE_VV
3188 "<menu action='MediaMenu'>"
3189 "<menuitem action='AudioCall'/>"
3190 "<menuitem action='VideoCall'/>"
3191 "<menuitem action='AudioVideoCall'/>"
3192 "</menu>"
3193 #endif
3194 "<menuitem action='SendFile'/>"
3195 "<menuitem action='GetAttention'/>"
3196 "<menuitem action='AddBuddyPounce'/>"
3197 "<menuitem action='GetInfo'/>"
3198 "<menuitem action='Invite'/>"
3199 "<menu action='MoreMenu'/>"
3200 "<separator/>"
3201 "<menuitem action='Alias'/>"
3202 "<menuitem action='Block'/>"
3203 "<menuitem action='Unblock'/>"
3204 "<menuitem action='Add'/>"
3205 "<menuitem action='Remove'/>"
3206 "<separator/>"
3207 "<menuitem action='InsertLink'/>"
3208 "<menuitem action='InsertImage'/>"
3209 "<separator/>"
3210 "<menuitem action='Close'/>"
3211 "</menu>"
3212 "<menu action='OptionsMenu'>"
3213 "<menuitem action='EnableLogging'/>"
3214 "<menuitem action='EnableSounds'/>"
3215 "<separator/>"
3216 "<menuitem action='ShowFormattingToolbars'/>"
3217 "<menuitem action='ShowTimestamps'/>"
3218 "</menu>"
3219 "</menubar>"
3220 "</ui>";
3221
3222 #else
3223
3122 static GtkItemFactoryEntry menu_items[] = 3224 static GtkItemFactoryEntry menu_items[] =
3123 { 3225 {
3124 /* Conversation menu */ 3226 /* Conversation menu */
3125 { N_("/_Conversation"), NULL, NULL, 0, "<Branch>", NULL }, 3227 { N_("/_Conversation"), NULL, NULL, 0, "<Branch>", NULL },
3126 3228
3193 { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL }, 3295 { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL },
3194 { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL }, 3296 { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL },
3195 { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL }, 3297 { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL },
3196 { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL }, 3298 { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL },
3197 }; 3299 };
3198 3300 #endif
3199 static const int menu_item_count =
3200 sizeof(menu_items) / sizeof(*menu_items);
3201
3202 static const char *
3203 item_factory_translate_func (const char *path, gpointer func_data)
3204 {
3205 return _(path);
3206 }
3207 3301
3208 static void 3302 static void
3209 sound_method_pref_changed_cb(const char *name, PurplePrefType type, 3303 sound_method_pref_changed_cb(const char *name, PurplePrefType type,
3210 gconstpointer value, gpointer data) 3304 gconstpointer value, gpointer data)
3211 { 3305 {
3212 PidginWindow *win = data; 3306 PidginWindow *win = data;
3213 const char *method = value; 3307 const char *method = value;
3214 3308
3215 if (!strcmp(method, "none")) 3309 if (!strcmp(method, "none"))
3216 { 3310 {
3217 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3311 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3218 FALSE); 3312 FALSE);
3219 gtk_widget_set_sensitive(win->menu.sounds, FALSE); 3313 gtk_action_set_sensitive(win->menu.sounds, FALSE);
3220 } 3314 }
3221 else 3315 else
3222 { 3316 {
3223 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3317 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3224 3318
3225 if (gtkconv != NULL) 3319 if (gtkconv != NULL)
3226 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3320 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3227 gtkconv->make_sound); 3321 gtkconv->make_sound);
3228 gtk_widget_set_sensitive(win->menu.sounds, TRUE); 3322 gtk_action_set_sensitive(win->menu.sounds, TRUE);
3229
3230 } 3323 }
3231 } 3324 }
3232 3325
3233 /* Returns TRUE if some items were added to the menu, FALSE otherwise */ 3326 /* Returns TRUE if some items were added to the menu, FALSE otherwise */
3234 static gboolean 3327 static gboolean
3354 == PURPLE_CONV_TYPE_IM) { 3447 == PURPLE_CONV_TYPE_IM) {
3355 PurpleMediaCaps caps = 3448 PurpleMediaCaps caps =
3356 purple_prpl_get_media_caps(account, 3449 purple_prpl_get_media_caps(account,
3357 purple_conversation_get_name(conv)); 3450 purple_conversation_get_name(conv));
3358 3451
3359 gtk_widget_set_sensitive(win->audio_call, 3452 gtk_action_set_sensitive(win->audio_call,
3360 caps & PURPLE_MEDIA_CAPS_AUDIO 3453 caps & PURPLE_MEDIA_CAPS_AUDIO
3361 ? TRUE : FALSE); 3454 ? TRUE : FALSE);
3362 gtk_widget_set_sensitive(win->video_call, 3455 gtk_action_set_sensitive(win->video_call,
3363 caps & PURPLE_MEDIA_CAPS_VIDEO 3456 caps & PURPLE_MEDIA_CAPS_VIDEO
3364 ? TRUE : FALSE); 3457 ? TRUE : FALSE);
3365 gtk_widget_set_sensitive(win->audio_video_call, 3458 gtk_action_set_sensitive(win->audio_video_call,
3366 caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO 3459 caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO
3367 ? TRUE : FALSE); 3460 ? TRUE : FALSE);
3368 } else if (purple_conversation_get_type(conv) 3461 } else if (purple_conversation_get_type(conv)
3369 == PURPLE_CONV_TYPE_CHAT) { 3462 == PURPLE_CONV_TYPE_CHAT) {
3370 /* for now, don't care about chats... */ 3463 /* for now, don't care about chats... */
3371 gtk_widget_set_sensitive(win->audio_call, FALSE); 3464 gtk_action_set_sensitive(win->audio_call, FALSE);
3372 gtk_widget_set_sensitive(win->video_call, FALSE); 3465 gtk_action_set_sensitive(win->video_call, FALSE);
3373 gtk_widget_set_sensitive(win->audio_video_call, FALSE); 3466 gtk_action_set_sensitive(win->audio_video_call, FALSE);
3374 } else { 3467 } else {
3375 gtk_widget_set_sensitive(win->audio_call, FALSE); 3468 gtk_action_set_sensitive(win->audio_call, FALSE);
3376 gtk_widget_set_sensitive(win->video_call, FALSE); 3469 gtk_action_set_sensitive(win->video_call, FALSE);
3377 gtk_widget_set_sensitive(win->audio_video_call, FALSE); 3470 gtk_action_set_sensitive(win->audio_video_call, FALSE);
3378 } 3471 }
3379 #endif 3472 #endif
3380 } 3473 }
3381 3474
3382 static void 3475 static void
3437 regenerate_options_items(PidginWindow *win) 3530 regenerate_options_items(PidginWindow *win)
3438 { 3531 {
3439 GtkWidget *menu; 3532 GtkWidget *menu;
3440 PidginConversation *gtkconv; 3533 PidginConversation *gtkconv;
3441 GList *list; 3534 GList *list;
3442 3535 #if GTK_CHECK_VERSION(2,6,0)
3536 GtkWidget *more_menu;
3537
3538 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3539 more_menu = gtk_ui_manager_get_widget(win->menu.ui,
3540 "/Conversation/ConversationMenu/MoreMenu");
3541 gtk_widget_show(more_menu);
3542 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(more_menu));
3543 #else
3443 gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3544 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3444 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More")); 3545 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More"));
3546 #endif
3445 3547
3446 /* Remove the previous entries */ 3548 /* Remove the previous entries */
3447 for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; ) 3549 for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; )
3448 { 3550 {
3449 GtkWidget *w = list->data; 3551 GtkWidget *w = list->data;
3495 G_CALLBACK(remove_from_list), win); 3597 G_CALLBACK(remove_from_list), win);
3496 gtk_widget_destroy(action_items->data); 3598 gtk_widget_destroy(action_items->data);
3497 action_items = g_list_delete_link(action_items, action_items); 3599 action_items = g_list_delete_link(action_items, action_items);
3498 } 3600 }
3499 3601
3602 #if GTK_CHECK_VERSION(2,6,0)
3603 item = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/OptionsMenu");
3604 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(item));
3605 #else
3500 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options")); 3606 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options"));
3607 #endif
3501 3608
3502 list = purple_conversation_get_extended_menu(conv); 3609 list = purple_conversation_get_extended_menu(conv);
3503 if (list) { 3610 if (list) {
3504 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu))); 3611 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu)));
3505 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); 3612 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win);
3532 static void 3639 static void
3533 focus_out_from_menubar(GtkWidget *wid, PidginWindow *win) 3640 focus_out_from_menubar(GtkWidget *wid, PidginWindow *win)
3534 { 3641 {
3535 /* The menubar has been deactivated. Make sure the 'More' submenu is regenerated next time 3642 /* The menubar has been deactivated. Make sure the 'More' submenu is regenerated next time
3536 * the 'Conversation' menu pops up. */ 3643 * the 'Conversation' menu pops up. */
3537 GtkWidget *menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation")); 3644 GtkWidget *menuitem = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/ConversationMenu");
3538 g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), G_CALLBACK(menubar_activated), win); 3645 g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), G_CALLBACK(menubar_activated), win);
3539 g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar), 3646 g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar),
3540 G_CALLBACK(focus_out_from_menubar), win); 3647 G_CALLBACK(focus_out_from_menubar), win);
3541 } 3648 }
3542 3649
3543 static GtkWidget * 3650 static GtkWidget *
3544 setup_menubar(PidginWindow *win) 3651 setup_menubar(PidginWindow *win)
3545 { 3652 {
3546 GtkAccelGroup *accel_group; 3653 GtkAccelGroup *accel_group;
3547 const char *method; 3654 const char *method;
3655 GtkActionGroup *action_group;
3656 GError *error;
3548 GtkWidget *menuitem; 3657 GtkWidget *menuitem;
3549 3658
3550 accel_group = gtk_accel_group_new (); 3659 action_group = gtk_action_group_new("ConversationActions");
3660 gtk_action_group_add_actions(action_group,
3661 menu_entries,
3662 G_N_ELEMENTS(menu_entries),
3663 win);
3664 gtk_action_group_add_toggle_actions(action_group,
3665 menu_toggle_entries,
3666 G_N_ELEMENTS(menu_toggle_entries),
3667 win);
3668 #ifdef ENABLE_NLS
3669 gtk_action_group_set_translation_domain(action_group,
3670 PACKAGE);
3671 #endif
3672
3673 win->menu.ui = gtk_ui_manager_new();
3674 gtk_ui_manager_insert_action_group(win->menu.ui, action_group, 0);
3675
3676 accel_group = gtk_ui_manager_get_accel_group(win->menu.ui);
3551 gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group); 3677 gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group);
3552 g_object_unref(accel_group);
3553
3554 win->menu.item_factory =
3555 gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
3556
3557 gtk_item_factory_set_translate_func(win->menu.item_factory,
3558 (GtkTranslateFunc)item_factory_translate_func,
3559 NULL, NULL);
3560
3561 gtk_item_factory_create_items(win->menu.item_factory, menu_item_count,
3562 menu_items, win);
3563 g_signal_connect(G_OBJECT(accel_group), "accel-changed", 3678 g_signal_connect(G_OBJECT(accel_group), "accel-changed",
3564 G_CALLBACK(pidgin_save_accels_cb), NULL); 3679 G_CALLBACK(pidgin_save_accels_cb), NULL);
3565 3680
3566 /* Make sure the 'Conversation -> More' menuitems are regenerated whenever 3681 error = NULL;
3567 * the 'Conversation' menu pops up because the entries can change after the 3682 if (!gtk_ui_manager_add_ui_from_string(win->menu.ui, conversation_menu, -1, &error))
3568 * conversation is created. */ 3683 {
3569 menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation")); 3684 g_message("building menus failed: %s", error->message);
3685 g_error_free(error);
3686 exit(EXIT_FAILURE);
3687 }
3688
3689 win->menu.menubar =
3690 gtk_ui_manager_get_widget(win->menu.ui, "/Conversation");
3691
3692 menuitem = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/ConversationMenu");
3570 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win); 3693 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win);
3571 3694
3572 win->menu.menubar =
3573 gtk_item_factory_get_widget(win->menu.item_factory, "<main>");
3574
3575 win->menu.view_log = 3695 win->menu.view_log =
3576 gtk_item_factory_get_widget(win->menu.item_factory, 3696 gtk_ui_manager_get_action(win->menu.ui,
3577 N_("/Conversation/View Log")); 3697 "/Conversation/ConversationMenu/ViewLog");
3578 3698
3579 #ifdef USE_VV 3699 #ifdef USE_VV
3580 win->audio_call = 3700 win->audio_call =
3581 gtk_item_factory_get_widget(win->menu.item_factory, 3701 gtk_ui_manager_get_action(win->menu.ui,
3582 N_("/Conversation/Media/Audio Call")); 3702 "/Conversation/ConversationMenu/MediaMenu/AudioCall");
3583 win->video_call = 3703 win->video_call =
3584 gtk_item_factory_get_widget(win->menu.item_factory, 3704 gtk_ui_manager_get_action(win->menu.ui,
3585 N_("/Conversation/Media/Video Call")); 3705 "/Conversation/ConversationMenu/MediaMenu/VideoCall");
3586 win->audio_video_call = 3706 win->audio_video_call =
3587 gtk_item_factory_get_widget(win->menu.item_factory, 3707 gtk_ui_manager_get_action(win->menu.ui,
3588 N_("/Conversation/Media/Audio\\/Video Call")); 3708 "/Conversation/ConversationMenu/MediaMenu/AudioVideoCall");
3589 #endif 3709 #endif
3590 3710
3591 /* --- */ 3711 /* --- */
3592 3712
3593 win->menu.send_file = 3713 win->menu.send_file =
3594 gtk_item_factory_get_widget(win->menu.item_factory, 3714 gtk_ui_manager_get_action(win->menu.ui,
3595 N_("/Conversation/Send File...")); 3715 "/Conversation/ConversationMenu/SendFile");
3596 3716
3597 win->menu.get_attention = 3717 win->menu.get_attention =
3598 gtk_item_factory_get_widget(win->menu.item_factory, 3718 gtk_ui_manager_get_action(win->menu.ui,
3599 N_("/Conversation/Get Attention")); 3719 "/Conversation/ConversationMenu/GetAttention");
3600 3720
3601 win->menu.add_pounce = 3721 win->menu.add_pounce =
3602 gtk_item_factory_get_widget(win->menu.item_factory, 3722 gtk_ui_manager_get_action(win->menu.ui,
3603 N_("/Conversation/Add Buddy Pounce...")); 3723 "/Conversation/ConversationMenu/AddBuddyPounce");
3604 3724
3605 /* --- */ 3725 /* --- */
3606 3726
3607 win->menu.get_info = 3727 win->menu.get_info =
3608 gtk_item_factory_get_widget(win->menu.item_factory, 3728 gtk_ui_manager_get_action(win->menu.ui,
3609 N_("/Conversation/Get Info")); 3729 "/Conversation/ConversationMenu/GetInfo");
3610 3730
3611 win->menu.invite = 3731 win->menu.invite =
3612 gtk_item_factory_get_widget(win->menu.item_factory, 3732 gtk_ui_manager_get_action(win->menu.ui,
3613 N_("/Conversation/Invite...")); 3733 "/Conversation/ConversationMenu/Invite");
3614 3734
3615 /* --- */ 3735 /* --- */
3616 3736
3617 win->menu.alias = 3737 win->menu.alias =
3618 gtk_item_factory_get_widget(win->menu.item_factory, 3738 gtk_ui_manager_get_action(win->menu.ui,
3619 N_("/Conversation/Alias...")); 3739 "/Conversation/ConversationMenu/Alias");
3620 3740
3621 win->menu.block = 3741 win->menu.block =
3622 gtk_item_factory_get_widget(win->menu.item_factory, 3742 gtk_ui_manager_get_action(win->menu.ui,
3623 N_("/Conversation/Block...")); 3743 "/Conversation/ConversationMenu/Block");
3624 3744
3625 win->menu.unblock = 3745 win->menu.unblock =
3626 gtk_item_factory_get_widget(win->menu.item_factory, 3746 gtk_ui_manager_get_action(win->menu.ui,
3627 N_("/Conversation/Unblock...")); 3747 "/Conversation/ConversationMenu/Unblock");
3628 3748
3629 win->menu.add = 3749 win->menu.add =
3630 gtk_item_factory_get_widget(win->menu.item_factory, 3750 gtk_ui_manager_get_action(win->menu.ui,
3631 N_("/Conversation/Add...")); 3751 "/Conversation/ConversationMenu/Add");
3632 3752
3633 win->menu.remove = 3753 win->menu.remove =
3634 gtk_item_factory_get_widget(win->menu.item_factory, 3754 gtk_ui_manager_get_action(win->menu.ui,
3635 N_("/Conversation/Remove...")); 3755 "/Conversation/ConversationMenu/Remove");
3636 3756
3637 /* --- */ 3757 /* --- */
3638 3758
3639 win->menu.insert_link = 3759 win->menu.insert_link =
3640 gtk_item_factory_get_widget(win->menu.item_factory, 3760 gtk_ui_manager_get_action(win->menu.ui,
3641 N_("/Conversation/Insert Link...")); 3761 "/Conversation/ConversationMenu/InsertLink");
3642 3762
3643 win->menu.insert_image = 3763 win->menu.insert_image =
3644 gtk_item_factory_get_widget(win->menu.item_factory, 3764 gtk_ui_manager_get_action(win->menu.ui,
3645 N_("/Conversation/Insert Image...")); 3765 "/Conversation/ConversationMenu/InsertImage");
3646 3766
3647 /* --- */ 3767 /* --- */
3648 3768
3649 win->menu.logging = 3769 win->menu.logging =
3650 gtk_item_factory_get_widget(win->menu.item_factory, 3770 gtk_ui_manager_get_action(win->menu.ui,
3651 N_("/Options/Enable Logging")); 3771 "/Conversation/OptionsMenu/EnableLogging");
3652 win->menu.sounds = 3772 win->menu.sounds =
3653 gtk_item_factory_get_widget(win->menu.item_factory, 3773 gtk_ui_manager_get_action(win->menu.ui,
3654 N_("/Options/Enable Sounds")); 3774 "/Conversation/OptionsMenu/EnableSounds");
3655 method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); 3775 method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
3656 if (method != NULL && !strcmp(method, "none")) 3776 if (method != NULL && !strcmp(method, "none"))
3657 { 3777 {
3658 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3778 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3659 FALSE); 3779 FALSE);
3660 gtk_widget_set_sensitive(win->menu.sounds, FALSE); 3780 gtk_action_set_sensitive(win->menu.sounds, FALSE);
3661 } 3781 }
3662 purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method", 3782 purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method",
3663 sound_method_pref_changed_cb, win); 3783 sound_method_pref_changed_cb, win);
3664 3784
3665 win->menu.show_formatting_toolbar = 3785 win->menu.show_formatting_toolbar =
3666 gtk_item_factory_get_widget(win->menu.item_factory, 3786 gtk_ui_manager_get_action(win->menu.ui,
3667 N_("/Options/Show Formatting Toolbars")); 3787 "/Conversation/OptionsMenu/ShowFormattingToolbars");
3668 win->menu.show_timestamps = 3788 win->menu.show_timestamps =
3669 gtk_item_factory_get_widget(win->menu.item_factory, 3789 gtk_ui_manager_get_action(win->menu.ui,
3670 N_("/Options/Show Timestamps")); 3790 "/Conversation/OptionsMenu/ShowTimestamps");
3671 win->menu.show_icon = NULL; 3791 win->menu.show_icon = NULL;
3672 3792
3673 win->menu.tray = pidgin_menu_tray_new(); 3793 win->menu.tray = pidgin_menu_tray_new();
3674 gtk_menu_shell_append(GTK_MENU_SHELL(win->menu.menubar), 3794 gtk_menu_shell_append(GTK_MENU_SHELL(win->menu.menubar),
3675 win->menu.tray); 3795 win->menu.tray);
3740 case 4: 3860 case 4:
3741 stock_id = PIDGIN_STOCK_ANIMATION_TYPING4; 3861 stock_id = PIDGIN_STOCK_ANIMATION_TYPING4;
3742 break; 3862 break;
3743 } 3863 }
3744 if (gtkwin->menu.typing_icon == NULL) { 3864 if (gtkwin->menu.typing_icon == NULL) {
3745 gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU); 3865 gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
3746 pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray), 3866 pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray),
3747 gtkwin->menu.typing_icon, 3867 gtkwin->menu.typing_icon,
3748 _("User is typing...")); 3868 _("User is typing..."));
3749 } else { 3869 } else {
3750 gtk_image_set_from_stock(GTK_IMAGE(gtkwin->menu.typing_icon), stock_id, GTK_ICON_SIZE_MENU); 3870 gtk_image_set_from_stock(GTK_IMAGE(gtkwin->menu.typing_icon), stock_id, GTK_ICON_SIZE_MENU);
3751 } 3871 }
3752 gtk_widget_show(gtkwin->menu.typing_icon); 3872 gtk_widget_show(gtkwin->menu.typing_icon);
3753 return TRUE; 3873 return TRUE;
3849 return FALSE; 3969 return FALSE;
3850 3970
3851 if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv)))) 3971 if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv))))
3852 return FALSE; 3972 return FALSE;
3853 3973
3854 3974 #if 0 /* TODO */
3855 gtk_widget_show(win->menu.send_to); 3975 gtk_widget_show(win->menu.send_to);
3856 3976
3857 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to)); 3977 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to));
3858 3978
3859 for (child = gtk_container_get_children(GTK_CONTAINER(menu)); 3979 for (child = gtk_container_get_children(GTK_CONTAINER(menu));
3871 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); 3991 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
3872 g_list_free(child); 3992 g_list_free(child);
3873 break; 3993 break;
3874 } 3994 }
3875 } 3995 }
3996 #endif
3876 3997
3877 return FALSE; 3998 return FALSE;
3878 } 3999 }
3879 4000
3880 static gboolean 4001 static gboolean
3980 } 4101 }
3981 4102
3982 static void 4103 static void
3983 generate_send_to_items(PidginWindow *win) 4104 generate_send_to_items(PidginWindow *win)
3984 { 4105 {
4106 #if 0 /* TODO */
3985 GtkWidget *menu; 4107 GtkWidget *menu;
3986 GSList *group = NULL; 4108 GSList *group = NULL;
3987 GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 4109 GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3988 PidginConversation *gtkconv; 4110 PidginConversation *gtkconv;
3989 GSList *l, *buds; 4111 GSList *l, *buds;
4065 gtk_widget_show(win->menu.send_to); 4187 gtk_widget_show(win->menu.send_to);
4066 /* TODO: This should never be insensitive. Possibly hidden or not. */ 4188 /* TODO: This should never be insensitive. Possibly hidden or not. */
4067 if (!group) 4189 if (!group)
4068 gtk_widget_set_sensitive(win->menu.send_to, FALSE); 4190 gtk_widget_set_sensitive(win->menu.send_to, FALSE);
4069 update_send_to_selection(win); 4191 update_send_to_selection(win);
4192 #endif
4070 } 4193 }
4071 4194
4072 static const char * 4195 static const char *
4073 get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvChatBuddyFlags flags) 4196 get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvChatBuddyFlags flags)
4074 { 4197 {
4717 GtkTextIter iter; 4840 GtkTextIter iter;
4718 int lines; 4841 int lines;
4719 GdkRectangle oneline; 4842 GdkRectangle oneline;
4720 int height, diff; 4843 int height, diff;
4721 int pad_top, pad_inside, pad_bottom; 4844 int pad_top, pad_inside, pad_bottom;
4722 int total_height = (gtkconv->webview->allocation.height + gtkconv->entry->allocation.height); 4845 int total_height;
4723 int max_height = total_height / 2; 4846 int max_height;
4724 int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines"); 4847 int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines");
4725 int min_height; 4848 int min_height;
4726 gboolean interior_focus; 4849 gboolean interior_focus;
4727 int focus_width; 4850 int focus_width;
4851 GtkAllocation webview_allocation;
4852 GtkAllocation entry_allocation;
4853 GtkAllocation lower_hbox_allocation;
4854
4855 gtk_widget_get_allocation(gtkconv->webview, &webview_allocation);
4856 gtk_widget_get_allocation(gtkconv->entry, &entry_allocation);
4857 gtk_widget_get_allocation(gtkconv->lower_hbox, &lower_hbox_allocation);
4858 total_height = webview_allocation.height + entry_allocation.height;
4859 max_height = total_height / 2;
4728 4860
4729 pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry)); 4861 pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry));
4730 pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry)); 4862 pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry));
4731 pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry)); 4863 pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry));
4732 4864
4756 "focus-line-width", &focus_width, 4888 "focus-line-width", &focus_width,
4757 NULL); 4889 NULL);
4758 if (!interior_focus) 4890 if (!interior_focus)
4759 height += 2 * focus_width; 4891 height += 2 * focus_width;
4760 4892
4761 diff = height - gtkconv->entry->allocation.height; 4893 diff = height - entry_allocation.height;
4762 if (ABS(diff) < oneline.height / 2) 4894 if (ABS(diff) < oneline.height / 2)
4763 return FALSE; 4895 return FALSE;
4764 4896
4897 purple_debug_info("pidgin", "resizing to %d, %d lines, diff %d\n",
4898 diff + lower_hbox_allocation.height, min_lines, diff);
4899
4765 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, 4900 gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
4766 diff + gtkconv->lower_hbox->allocation.height); 4901 diff + lower_hbox_allocation.height);
4767 4902
4768 return FALSE; 4903 return FALSE;
4769 } 4904 }
4770 4905
4771 static void 4906 static void
4808 gtk_widget_set_size_request(gtkchat->topic_text, -1, BUDDYICON_SIZE_MIN); 4943 gtk_widget_set_size_request(gtkchat->topic_text, -1, BUDDYICON_SIZE_MIN);
4809 4944
4810 if(prpl_info->set_chat_topic == NULL) { 4945 if(prpl_info->set_chat_topic == NULL) {
4811 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE); 4946 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE);
4812 } else { 4947 } else {
4813 g_signal_connect(GTK_OBJECT(gtkchat->topic_text), "activate", 4948 g_signal_connect(GTK_WIDGET(gtkchat->topic_text), "activate",
4814 G_CALLBACK(topic_callback), gtkconv); 4949 G_CALLBACK(topic_callback), gtkconv);
4815 } 4950 }
4816 4951
4817 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); 4952 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0);
4818 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", 4953 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event",
4979 pidgin_conv_end_quickfind(PidginConversation *gtkconv) 5114 pidgin_conv_end_quickfind(PidginConversation *gtkconv)
4980 { 5115 {
4981 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); 5116 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
4982 5117
4983 webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview)); 5118 webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview));
4984 gtk_widget_hide_all(gtkconv->quickfind.container); 5119 gtk_widget_hide(gtkconv->quickfind.container);
4985 5120
4986 gtk_widget_grab_focus(gtkconv->entry); 5121 gtk_widget_grab_focus(gtkconv->entry);
4987 return TRUE; 5122 return TRUE;
4988 } 5123 }
4989 5124
4990 static gboolean 5125 static gboolean
4991 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv) 5126 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv)
4992 { 5127 {
4993 switch (event->keyval) { 5128 switch (event->keyval) {
4994 case GDK_Return: 5129 case GDK_KEY_Return:
4995 case GDK_KP_Enter: 5130 case GDK_KEY_KP_Enter:
4996 if (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) { 5131 if (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) {
4997 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); 5132 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
4998 } else { 5133 } else {
4999 GdkColor col; 5134 GdkColor col;
5000 col.red = 0xffff; 5135 col.red = 0xffff;
5001 col.green = 0xafff; 5136 col.green = 0xafff;
5002 col.blue = 0xafff; 5137 col.blue = 0xafff;
5003 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col); 5138 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col);
5004 } 5139 }
5005 break; 5140 break;
5006 case GDK_Escape: 5141 case GDK_KEY_Escape:
5007 pidgin_conv_end_quickfind(gtkconv); 5142 pidgin_conv_end_quickfind(gtkconv);
5008 break; 5143 break;
5009 default: 5144 default:
5010 return FALSE; 5145 return FALSE;
5011 } 5146 }
5020 5155
5021 gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0); 5156 gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0);
5022 5157
5023 close = pidgin_create_small_button(gtk_label_new("×")); 5158 close = pidgin_create_small_button(gtk_label_new("×"));
5024 gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0); 5159 gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0);
5160 #if GTK_CHECK_VERSION(2,12,0)
5161 gtk_widget_set_tooltip_text(close, _("Close Find bar"));
5162 #else
5025 gtk_tooltips_set_tip(gtkconv->tooltips, close, 5163 gtk_tooltips_set_tip(gtkconv->tooltips, close,
5026 _("Close Find bar"), NULL); 5164 _("Close Find bar"), NULL);
5165 #endif
5027 5166
5028 label = gtk_label_new(_("Find:")); 5167 label = gtk_label_new(_("Find:"));
5029 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10); 5168 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10);
5030 5169
5031 entry = gtk_entry_new(); 5170 entry = gtk_entry_new();
5434 PidginWindow *win = gtkconv->win; 5573 PidginWindow *win = gtkconv->win;
5435 PurpleConversation *c; 5574 PurpleConversation *c;
5436 PurpleAccount *convaccount = purple_conversation_get_account(conv); 5575 PurpleAccount *convaccount = purple_conversation_get_account(conv);
5437 PurpleConnection *gc = purple_account_get_connection(convaccount); 5576 PurpleConnection *gc = purple_account_get_connection(convaccount);
5438 PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL; 5577 PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL;
5439 5578 GdkAtom target = gtk_selection_data_get_target(sd);
5440 if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) 5579 const guchar *data = gtk_selection_data_get_data(sd);
5580
5581 if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
5441 { 5582 {
5442 PurpleBlistNode *n = NULL; 5583 PurpleBlistNode *n = NULL;
5443 PurpleBuddy *b; 5584 PurpleBuddy *b;
5444 PidginConversation *gtkconv = NULL; 5585 PidginConversation *gtkconv = NULL;
5445 PurpleAccount *buddyaccount; 5586 PurpleAccount *buddyaccount;
5446 const char *buddyname; 5587 const char *buddyname;
5447 5588
5448 n = *(PurpleBlistNode **)sd->data; 5589 n = *(PurpleBlistNode **) data;
5449 5590
5450 if (PURPLE_BLIST_NODE_IS_CONTACT(n)) 5591 if (PURPLE_BLIST_NODE_IS_CONTACT(n))
5451 b = purple_contact_get_priority_buddy((PurpleContact*)n); 5592 b = purple_contact_get_priority_buddy((PurpleContact*)n);
5452 else if (PURPLE_BLIST_NODE_IS_BUDDY(n)) 5593 else if (PURPLE_BLIST_NODE_IS_BUDDY(n))
5453 b = (PurpleBuddy*)n; 5594 b = (PurpleBuddy*)n;
5491 5632
5492 /* Make this conversation the active conversation */ 5633 /* Make this conversation the active conversation */
5493 pidgin_conv_window_switch_gtkconv(win, gtkconv); 5634 pidgin_conv_window_switch_gtkconv(win, gtkconv);
5494 } 5635 }
5495 5636
5496 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); 5637 gtk_drag_finish(dc, TRUE,
5497 } 5638 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
5498 else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE)) 5639 }
5640 else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
5499 { 5641 {
5500 char *protocol = NULL; 5642 char *protocol = NULL;
5501 char *username = NULL; 5643 char *username = NULL;
5502 PurpleAccount *account; 5644 PurpleAccount *account;
5503 PidginConversation *gtkconv; 5645 PidginConversation *gtkconv;
5504 5646
5505 if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, 5647 if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
5506 &protocol, &username, NULL)) 5648 &protocol, &username, NULL))
5507 { 5649 {
5508 if (account == NULL) 5650 if (account == NULL)
5509 { 5651 {
5510 purple_notify_error(win, NULL, 5652 purple_notify_error(win, NULL,
5531 } 5673 }
5532 5674
5533 g_free(username); 5675 g_free(username);
5534 g_free(protocol); 5676 g_free(protocol);
5535 5677
5536 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); 5678 gtk_drag_finish(dc, TRUE,
5537 } 5679 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
5538 else if (sd->target == gdk_atom_intern("text/uri-list", FALSE)) { 5680 }
5681 else if (target == gdk_atom_intern("text/uri-list", FALSE)) {
5539 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 5682 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
5540 pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv)); 5683 pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv));
5541 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); 5684 gtk_drag_finish(dc, TRUE,
5685 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
5542 } 5686 }
5543 else 5687 else
5544 gtk_drag_finish(dc, FALSE, FALSE, t); 5688 gtk_drag_finish(dc, FALSE, FALSE, t);
5545 } 5689 }
5546 5690
5674 gtkconv->active_conv = conv; 5818 gtkconv->active_conv = conv;
5675 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); 5819 gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
5676 gtkconv->send_history = g_list_append(NULL, NULL); 5820 gtkconv->send_history = g_list_append(NULL, NULL);
5677 5821
5678 /* Setup some initial variables. */ 5822 /* Setup some initial variables. */
5823 #if !GTK_CHECK_VERSION(2,12,0)
5679 gtkconv->tooltips = gtk_tooltips_new(); 5824 gtkconv->tooltips = gtk_tooltips_new();
5825 #endif
5680 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; 5826 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
5681 gtkconv->unseen_count = 0; 5827 gtkconv->unseen_count = 0;
5682 theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation"); 5828 theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation");
5683 if (!theme) 5829 if (!theme)
5684 theme = purple_theme_manager_find_theme("Default", "conversation"); 5830 theme = purple_theme_manager_find_theme("Default", "conversation");
5873 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 6019 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
5874 purple_signals_disconnect_by_handle(gtkconv->u.chat); 6020 purple_signals_disconnect_by_handle(gtkconv->u.chat);
5875 g_free(gtkconv->u.chat); 6021 g_free(gtkconv->u.chat);
5876 } 6022 }
5877 6023
6024 #if !GTK_CHECK_VERSION(2,12,0)
5878 gtk_object_sink(GTK_OBJECT(gtkconv->tooltips)); 6025 gtk_object_sink(GTK_OBJECT(gtkconv->tooltips));
6026 #endif
5879 6027
5880 gtkconv->send_history = g_list_first(gtkconv->send_history); 6028 gtkconv->send_history = g_list_first(gtkconv->send_history);
5881 g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL); 6029 g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL);
5882 g_list_free(gtkconv->send_history); 6030 g_list_free(gtkconv->send_history);
5883 6031
5942 if (event->type == GDK_BUTTON_PRESS 6090 if (event->type == GDK_BUTTON_PRESS
5943 || event->type == GDK_2BUTTON_PRESS) { 6091 || event->type == GDK_2BUTTON_PRESS) {
5944 GdkEventButton *btn_event = (GdkEventButton*) event; 6092 GdkEventButton *btn_event = (GdkEventButton*) event;
5945 PurpleConversation *conv = data; 6093 PurpleConversation *conv = data;
5946 char *buddyname; 6094 char *buddyname;
6095 gchar *name;
6096
6097 g_object_get(G_OBJECT(tag), "name", &name, NULL);
5947 6098
5948 /* strlen("BUDDY " or "HILIT ") == 6 */ 6099 /* strlen("BUDDY " or "HILIT ") == 6 */
5949 g_return_val_if_fail((tag->name != NULL) 6100 g_return_val_if_fail((name != NULL) && (strlen(name) > 6), FALSE);
5950 && (strlen(tag->name) > 6), FALSE); 6101
5951 6102 buddyname = name + 6;
5952 buddyname = (tag->name) + 6;
5953 6103
5954 /* emit chat-nick-clicked signal */ 6104 /* emit chat-nick-clicked signal */
5955 if (event->type == GDK_BUTTON_PRESS) { 6105 if (event->type == GDK_BUTTON_PRESS) {
5956 gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( 6106 gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
5957 pidgin_conversations_get_handle(), "chat-nick-clicked", 6107 pidgin_conversations_get_handle(), "chat-nick-clicked",
5958 data, buddyname, btn_event->button)); 6108 data, buddyname, btn_event->button));
5959 if (plugin_return) 6109 if (plugin_return) {
6110 g_free(name);
5960 return TRUE; 6111 return TRUE;
5961 } 6112 }
5962 6113 }
5963 if (btn_event->button == 1 && 6114
5964 event->type == GDK_2BUTTON_PRESS) { 6115 if (btn_event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
5965 chat_do_im(PIDGIN_CONVERSATION(conv), buddyname); 6116 chat_do_im(PIDGIN_CONVERSATION(conv), buddyname);
6117 g_free(name);
6118
5966 return TRUE; 6119 return TRUE;
5967 } else if (btn_event->button == 2 6120 } else if (btn_event->button == 2 && event->type == GDK_2BUTTON_PRESS) {
5968 && event->type == GDK_2BUTTON_PRESS) {
5969 chat_do_info(PIDGIN_CONVERSATION(conv), buddyname); 6121 chat_do_info(PIDGIN_CONVERSATION(conv), buddyname);
6122 g_free(name);
5970 6123
5971 return TRUE; 6124 return TRUE;
5972 } else if (btn_event->button == 3 6125 } else if (btn_event->button == 3 && event->type == GDK_BUTTON_PRESS) {
5973 && event->type == GDK_BUTTON_PRESS) {
5974 GtkTextIter start, end; 6126 GtkTextIter start, end;
5975 6127
5976 /* we shouldn't display the popup 6128 /* we shouldn't display the popup
5977 * if the user has selected something: */ 6129 * if the user has selected something: */
5978 if (!gtk_text_buffer_get_selection_bounds( 6130 if (!gtk_text_buffer_get_selection_bounds(
5987 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, 6139 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
5988 NULL, GTK_WIDGET(imhtml), 6140 NULL, GTK_WIDGET(imhtml),
5989 btn_event->button, 6141 btn_event->button,
5990 btn_event->time); 6142 btn_event->time);
5991 6143
6144 g_free(name);
6145
5992 /* Don't propagate the event any further */ 6146 /* Don't propagate the event any further */
5993 return TRUE; 6147 return TRUE;
5994 } 6148 }
5995 } 6149 }
6150
6151 g_free(name);
5996 } 6152 }
5997 6153
5998 return FALSE; 6154 return FALSE;
5999 } 6155 }
6000 #endif 6156 #endif
6948 */ 7104 */
6949 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 7105 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
6950 /* Show stuff that applies to IMs, hide stuff that applies to chats */ 7106 /* Show stuff that applies to IMs, hide stuff that applies to chats */
6951 7107
6952 /* Deal with menu items */ 7108 /* Deal with menu items */
6953 gtk_widget_show(win->menu.view_log); 7109 gtk_action_set_visible(win->menu.view_log, TRUE);
6954 gtk_widget_show(win->menu.send_file); 7110 gtk_action_set_visible(win->menu.send_file, TRUE);
6955 gtk_widget_show(win->menu.get_attention); 7111 gtk_action_set_visible(win->menu.get_attention, TRUE);
6956 gtk_widget_show(win->menu.add_pounce); 7112 gtk_action_set_visible(win->menu.add_pounce, TRUE);
6957 gtk_widget_show(win->menu.get_info); 7113 gtk_action_set_visible(win->menu.get_info, TRUE);
6958 gtk_widget_hide(win->menu.invite); 7114 gtk_action_set_visible(win->menu.invite, FALSE);
6959 gtk_widget_show(win->menu.alias); 7115 gtk_action_set_visible(win->menu.alias, TRUE);
6960 if (purple_privacy_check(account, purple_conversation_get_name(conv))) { 7116 if (purple_privacy_check(account, purple_conversation_get_name(conv))) {
6961 gtk_widget_hide(win->menu.unblock); 7117 gtk_action_set_visible(win->menu.unblock, FALSE);
6962 gtk_widget_show(win->menu.block); 7118 gtk_action_set_visible(win->menu.block, TRUE);
6963 } else { 7119 } else {
6964 gtk_widget_hide(win->menu.block); 7120 gtk_action_set_visible(win->menu.block, FALSE);
6965 gtk_widget_show(win->menu.unblock); 7121 gtk_action_set_visible(win->menu.unblock, TRUE);
6966 } 7122 }
6967 7123
6968 if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) { 7124 if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
6969 gtk_widget_show(win->menu.add); 7125 gtk_action_set_visible(win->menu.add, TRUE);
6970 gtk_widget_hide(win->menu.remove); 7126 gtk_action_set_visible(win->menu.remove, FALSE);
6971 } else { 7127 } else {
6972 gtk_widget_show(win->menu.remove); 7128 gtk_action_set_visible(win->menu.remove, TRUE);
6973 gtk_widget_hide(win->menu.add); 7129 gtk_action_set_visible(win->menu.add, FALSE);
6974 } 7130 }
6975 7131
6976 gtk_widget_show(win->menu.insert_link); 7132 gtk_action_set_visible(win->menu.insert_link, TRUE);
6977 gtk_widget_show(win->menu.insert_image); 7133 gtk_action_set_visible(win->menu.insert_image, TRUE);
6978 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 7134 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
6979 /* Show stuff that applies to Chats, hide stuff that applies to IMs */ 7135 /* Show stuff that applies to Chats, hide stuff that applies to IMs */
6980 7136
6981 /* Deal with menu items */ 7137 /* Deal with menu items */
6982 gtk_widget_show(win->menu.view_log); 7138 gtk_action_set_visible(win->menu.view_log, TRUE);
6983 gtk_widget_hide(win->menu.send_file); 7139 gtk_action_set_visible(win->menu.send_file, FALSE);
6984 gtk_widget_hide(win->menu.get_attention); 7140 gtk_action_set_visible(win->menu.get_attention, FALSE);
6985 gtk_widget_hide(win->menu.add_pounce); 7141 gtk_action_set_visible(win->menu.add_pounce, FALSE);
6986 gtk_widget_hide(win->menu.get_info); 7142 gtk_action_set_visible(win->menu.get_info, FALSE);
6987 gtk_widget_show(win->menu.invite); 7143 gtk_action_set_visible(win->menu.invite, TRUE);
6988 gtk_widget_show(win->menu.alias); 7144 gtk_action_set_visible(win->menu.alias, TRUE);
6989 gtk_widget_hide(win->menu.block); 7145 gtk_action_set_visible(win->menu.block, FALSE);
6990 gtk_widget_hide(win->menu.unblock); 7146 gtk_action_set_visible(win->menu.unblock, FALSE);
6991 7147
6992 if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) { 7148 if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) {
6993 /* If the chat is NOT in the buddy list */ 7149 /* If the chat is NOT in the buddy list */
6994 gtk_widget_show(win->menu.add); 7150 gtk_action_set_visible(win->menu.add, TRUE);
6995 gtk_widget_hide(win->menu.remove); 7151 gtk_action_set_visible(win->menu.remove, FALSE);
6996 } else { 7152 } else {
6997 /* If the chat IS in the buddy list */ 7153 /* If the chat IS in the buddy list */
6998 gtk_widget_hide(win->menu.add); 7154 gtk_action_set_visible(win->menu.add, FALSE);
6999 gtk_widget_show(win->menu.remove); 7155 gtk_action_set_visible(win->menu.remove, TRUE);
7000 } 7156 }
7001 7157
7002 gtk_widget_show(win->menu.insert_link); 7158 gtk_action_set_visible(win->menu.insert_link, TRUE);
7003 gtk_widget_show(win->menu.insert_image); 7159 gtk_action_set_visible(win->menu.insert_image, TRUE);
7004 } 7160 }
7005 7161
7006 /* 7162 /*
7007 * Handle graying stuff out based on whether an account is connected 7163 * Handle graying stuff out based on whether an account is connected
7008 * and what features that account supports. 7164 * and what features that account supports.
7047 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons); 7203 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons);
7048 if (account != NULL) 7204 if (account != NULL)
7049 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account)); 7205 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account));
7050 7206
7051 /* Deal with menu items */ 7207 /* Deal with menu items */
7052 gtk_widget_set_sensitive(win->menu.view_log, TRUE); 7208 gtk_action_set_sensitive(win->menu.view_log, TRUE);
7053 gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); 7209 gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
7054 gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL)); 7210 gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
7055 gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL)); 7211 gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
7056 gtk_widget_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML)); 7212 gtk_action_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML));
7057 gtk_widget_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES)); 7213 gtk_action_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES));
7058 7214
7059 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 7215 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
7060 { 7216 {
7061 gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL)); 7217 gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
7062 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL)); 7218 gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
7063 gtk_widget_set_sensitive(win->menu.send_file, 7219 gtk_action_set_sensitive(win->menu.send_file,
7064 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || 7220 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
7065 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); 7221 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv)))));
7066 gtk_widget_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL)); 7222 gtk_action_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL));
7067 gtk_widget_set_sensitive(win->menu.alias, 7223 gtk_action_set_sensitive(win->menu.alias,
7068 (account != NULL) && 7224 (account != NULL) &&
7069 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL)); 7225 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
7070 } 7226 }
7071 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) 7227 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
7072 { 7228 {
7073 gtk_widget_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL)); 7229 gtk_action_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
7074 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL)); 7230 gtk_action_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
7075 gtk_widget_set_sensitive(win->menu.alias, 7231 gtk_action_set_sensitive(win->menu.alias,
7076 (account != NULL) && 7232 (account != NULL) &&
7077 (purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL)); 7233 (purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL));
7078 } 7234 }
7079 7235
7080 } else { 7236 } else {
7081 /* Account is offline */ 7237 /* Account is offline */
7082 /* Or it's a chat that we've left. */ 7238 /* Or it's a chat that we've left. */
7083 7239
7084 /* Then deal with menu items */ 7240 /* Then deal with menu items */
7085 gtk_widget_set_sensitive(win->menu.view_log, TRUE); 7241 gtk_action_set_sensitive(win->menu.view_log, TRUE);
7086 gtk_widget_set_sensitive(win->menu.send_file, FALSE); 7242 gtk_action_set_sensitive(win->menu.send_file, FALSE);
7087 gtk_widget_set_sensitive(win->menu.get_attention, FALSE); 7243 gtk_action_set_sensitive(win->menu.get_attention, FALSE);
7088 gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); 7244 gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
7089 gtk_widget_set_sensitive(win->menu.get_info, FALSE); 7245 gtk_action_set_sensitive(win->menu.get_info, FALSE);
7090 gtk_widget_set_sensitive(win->menu.invite, FALSE); 7246 gtk_action_set_sensitive(win->menu.invite, FALSE);
7091 gtk_widget_set_sensitive(win->menu.alias, FALSE); 7247 gtk_action_set_sensitive(win->menu.alias, FALSE);
7092 gtk_widget_set_sensitive(win->menu.add, FALSE); 7248 gtk_action_set_sensitive(win->menu.add, FALSE);
7093 gtk_widget_set_sensitive(win->menu.remove, FALSE); 7249 gtk_action_set_sensitive(win->menu.remove, FALSE);
7094 gtk_widget_set_sensitive(win->menu.insert_link, TRUE); 7250 gtk_action_set_sensitive(win->menu.insert_link, TRUE);
7095 gtk_widget_set_sensitive(win->menu.insert_image, FALSE); 7251 gtk_action_set_sensitive(win->menu.insert_image, FALSE);
7096 } 7252 }
7097 7253
7098 /* 7254 /*
7099 * Update the window's icon 7255 * Update the window's icon
7100 */ 7256 */
7171 if (gtkchat->topic_text != NULL) 7327 if (gtkchat->topic_text != NULL)
7172 { 7328 {
7173 topic = purple_conv_chat_get_topic(chat); 7329 topic = purple_conv_chat_get_topic(chat);
7174 7330
7175 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : ""); 7331 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
7332 #if GTK_CHECK_VERSION(2,12,0)
7333 gtk_widget_set_tooltip_text(gtkchat->topic_text,
7334 topic ? topic : "");
7335 #else
7176 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text, 7336 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text,
7177 topic ? topic : "", NULL); 7337 topic ? topic : "", NULL);
7338 #endif
7178 } 7339 }
7179 } 7340 }
7180 7341
7181 #if 0 7342 #if 0
7182 if (fields & PIDGIN_CONV_SMILEY_THEME) 7343 if (fields & PIDGIN_CONV_SMILEY_THEME)
7183 pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview); 7344 pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview);
7184 #endif 7345 #endif
7185 7346
7186 if ((fields & PIDGIN_CONV_COLORIZE_TITLE) || 7347 if ((fields & PIDGIN_CONV_COLORIZE_TITLE) ||
7187 (fields & PIDGIN_CONV_SET_TITLE) || 7348 (fields & PIDGIN_CONV_SET_TITLE) ||
7188 (fields & PIDGIN_CONV_TOPIC)) 7349 (fields & PIDGIN_CONV_TOPIC))
7189 { 7350 {
7190 char *title; 7351 char *title;
7191 PurpleConvIm *im = NULL; 7352 PurpleConvIm *im = NULL;
7192 PurpleAccount *account = purple_conversation_get_account(conv); 7353 PurpleAccount *account = purple_conversation_get_account(conv);
7193 PurpleBuddy *buddy = NULL; 7354 PurpleBuddy *buddy = NULL;
7234 gtk_widget_queue_draw(gtkconv->infopane); 7395 gtk_widget_queue_draw(gtkconv->infopane);
7235 7396
7236 if (title != markup) 7397 if (title != markup)
7237 g_free(markup); 7398 g_free(markup);
7238 7399
7239 if (!GTK_WIDGET_REALIZED(gtkconv->tab_label)) 7400 if (!gtk_widget_get_realized(gtkconv->tab_label))
7240 gtk_widget_realize(gtkconv->tab_label); 7401 gtk_widget_realize(gtkconv->tab_label);
7241 7402
7242 accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont); 7403 accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont);
7243 if (im != NULL && 7404 if (im != NULL &&
7244 purple_conv_im_get_typing_state(im) == PURPLE_TYPING) { 7405 purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
7549 7710
7550 event = gtk_event_box_new(); 7711 event = gtk_event_box_new();
7551 gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event); 7712 gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
7552 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), FALSE); 7713 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), FALSE);
7553 gtk_widget_add_events(event, 7714 gtk_widget_add_events(event,
7554 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); 7715 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
7555 g_signal_connect(G_OBJECT(event), "button-press-event", 7716 g_signal_connect(G_OBJECT(event), "button-press-event",
7556 G_CALLBACK(icon_menu), gtkconv); 7717 G_CALLBACK(icon_menu), gtkconv);
7557 7718
7558 pidgin_tooltip_setup_for_widget(event, gtkconv, pidgin_conv_create_tooltip, NULL); 7719 pidgin_tooltip_setup_for_widget(event, gtkconv, pidgin_conv_create_tooltip, NULL);
7559 gtk_widget_show(event); 7720 gtk_widget_show(event);
7591 static gboolean 7752 static gboolean
7592 pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y) 7753 pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y)
7593 { 7754 {
7594 gint pane_x, pane_y, x_rel; 7755 gint pane_x, pane_y, x_rel;
7595 PidginConversation *gtkconv; 7756 PidginConversation *gtkconv;
7596 7757 GtkAllocation allocation;
7597 gdk_window_get_origin(win->notebook->window, &pane_x, &pane_y); 7758
7759 gdk_window_get_origin(gtk_widget_get_window(win->notebook),
7760 &pane_x, &pane_y);
7598 x_rel = x - pane_x; 7761 x_rel = x - pane_x;
7599 gtkconv = pidgin_conv_window_get_active_gtkconv(win); 7762 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
7600 return (x_rel > gtkconv->infopane->allocation.x + gtkconv->infopane->allocation.width / 2); 7763 gtk_widget_get_allocation(gtkconv->infopane, &allocation);
7764 return (x_rel > allocation.x + allocation.width / 2);
7601 } 7765 }
7602 7766
7603 int 7767 int
7604 pidgin_conv_get_tab_at_xy(PidginWindow *win, int x, int y, gboolean *to_right) 7768 pidgin_conv_get_tab_at_xy(PidginWindow *win, int x, int y, gboolean *to_right)
7605 { 7769 {
7613 if (to_right) 7777 if (to_right)
7614 *to_right = FALSE; 7778 *to_right = FALSE;
7615 7779
7616 notebook = GTK_NOTEBOOK(win->notebook); 7780 notebook = GTK_NOTEBOOK(win->notebook);
7617 7781
7618 gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y); 7782 gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
7619 x_rel = x - nb_x; 7783 x_rel = x - nb_x;
7620 y_rel = y - nb_y; 7784 y_rel = y - nb_y;
7621 7785
7622 horiz = (gtk_notebook_get_tab_pos(notebook) == GTK_POS_TOP || 7786 horiz = (gtk_notebook_get_tab_pos(notebook) == GTK_POS_TOP ||
7623 gtk_notebook_get_tab_pos(notebook) == GTK_POS_BOTTOM); 7787 gtk_notebook_get_tab_pos(notebook) == GTK_POS_BOTTOM);
7624 7788
7625 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook)); 7789 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
7626 7790
7627 for (i = 0; i < count; i++) { 7791 for (i = 0; i < count; i++) {
7792 GtkAllocation allocation;
7628 7793
7629 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i); 7794 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
7630 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page); 7795 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
7796 gtk_widget_get_allocation(tab, &allocation);
7631 7797
7632 /* Make sure the tab is not hidden beyond an arrow */ 7798 /* Make sure the tab is not hidden beyond an arrow */
7633 if (!GTK_WIDGET_DRAWABLE(tab) && gtk_notebook_get_show_tabs(notebook)) 7799 if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook))
7634 continue; 7800 continue;
7635 7801
7636 if (horiz) { 7802 if (horiz) {
7637 if (x_rel >= tab->allocation.x - PIDGIN_HIG_BOX_SPACE && 7803 if (x_rel >= allocation.x - PIDGIN_HIG_BOX_SPACE &&
7638 x_rel <= tab->allocation.x + tab->allocation.width + PIDGIN_HIG_BOX_SPACE) { 7804 x_rel <= allocation.x + allocation.width + PIDGIN_HIG_BOX_SPACE) {
7639 page_num = i; 7805 page_num = i;
7640 7806
7641 if (to_right && x_rel >= tab->allocation.x + tab->allocation.width/2) 7807 if (to_right && x_rel >= allocation.x + allocation.width/2)
7642 *to_right = TRUE; 7808 *to_right = TRUE;
7643 7809
7644 break; 7810 break;
7645 } 7811 }
7646 } else { 7812 } else {
7647 if (y_rel >= tab->allocation.y - PIDGIN_HIG_BOX_SPACE && 7813 if (y_rel >= allocation.y - PIDGIN_HIG_BOX_SPACE &&
7648 y_rel <= tab->allocation.y + tab->allocation.height + PIDGIN_HIG_BOX_SPACE) { 7814 y_rel <= allocation.y + allocation.height + PIDGIN_HIG_BOX_SPACE) {
7649 page_num = i; 7815 page_num = i;
7650 7816
7651 if (to_right && y_rel >= tab->allocation.y + tab->allocation.height/2) 7817 if (to_right && y_rel >= allocation.y + allocation.height/2)
7652 *to_right = TRUE; 7818 *to_right = TRUE;
7653 7819
7654 break; 7820 break;
7655 } 7821 }
7656 } 7822 }
7753 continue; 7919 continue;
7754 7920
7755 gtkconv = PIDGIN_CONVERSATION(conv); 7921 gtkconv = PIDGIN_CONVERSATION(conv);
7756 win = gtkconv->win; 7922 win = gtkconv->win;
7757 7923
7758 gtk_check_menu_item_set_active( 7924 gtk_toggle_action_set_active(
7759 GTK_CHECK_MENU_ITEM(win->menu.show_timestamps), 7925 GTK_TOGGLE_ACTION(win->menu.show_timestamps),
7760 (gboolean)GPOINTER_TO_INT(value)); 7926 (gboolean)GPOINTER_TO_INT(value));
7761 7927
7762 /* TODO WEBKIT: Use WebKit version of this. */ 7928 /* TODO WEBKIT: Use WebKit version of this. */
7763 #if 0 7929 #if 0
7764 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), 7930 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
7784 continue; 7950 continue;
7785 7951
7786 gtkconv = PIDGIN_CONVERSATION(conv); 7952 gtkconv = PIDGIN_CONVERSATION(conv);
7787 win = gtkconv->win; 7953 win = gtkconv->win;
7788 7954
7789 gtk_check_menu_item_set_active( 7955 gtk_toggle_action_set_active(
7790 GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar), 7956 GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
7791 (gboolean)GPOINTER_TO_INT(value)); 7957 (gboolean)GPOINTER_TO_INT(value));
7792 7958
7793 if ((gboolean)GPOINTER_TO_INT(value)) 7959 if ((gboolean)GPOINTER_TO_INT(value))
7794 gtk_widget_show(gtkconv->toolbar); 7960 gtk_widget_show(gtkconv->toolbar);
7795 else 7961 else
8406 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons", 8572 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons",
8407 show_buddy_icons_pref_cb, NULL); 8573 show_buddy_icons_pref_cb, NULL);
8408 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons", 8574 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
8409 show_protocol_icons_pref_cb, NULL); 8575 show_protocol_icons_pref_cb, NULL);
8410 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new", 8576 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new",
8411 hide_new_pref_cb, NULL); 8577 hide_new_pref_cb, NULL);
8412 8578
8413 8579
8414 8580
8415 /********************************************************************** 8581 /**********************************************************************
8416 * Register signals 8582 * Register signals
8563 8729
8564 hidden_convwin = pidgin_conv_window_new(); 8730 hidden_convwin = pidgin_conv_window_new();
8565 window_list = g_list_remove(window_list, hidden_convwin); 8731 window_list = g_list_remove(window_list, hidden_convwin);
8566 8732
8567 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", 8733 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed",
8568 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); 8734 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
8569 8735
8570 /* Callbacks to update a conversation */ 8736 /* Callbacks to update a conversation */
8571 purple_signal_connect(blist_handle, "blist-node-added", handle, 8737 purple_signal_connect(blist_handle, "blist-node-added", handle,
8572 G_CALLBACK(buddy_update_cb), NULL); 8738 G_CALLBACK(buddy_update_cb), NULL);
8573 purple_signal_connect(blist_handle, "blist-node-removed", handle, 8739 purple_signal_connect(blist_handle, "blist-node-removed", handle,
8749 GTK_RESPONSE_OK); 8915 GTK_RESPONSE_OK);
8750 8916
8751 gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog), 8917 gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog),
8752 6); 8918 6);
8753 gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE); 8919 gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE);
8920
8921 /* TODO: figure out how to set no separator in GTK+ 3.0 */
8922 #if 0
8754 gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), 8923 gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog),
8755 FALSE); 8924 FALSE);
8925 #endif
8756 8926
8757 /* Setup the outside spacing. */ 8927 /* Setup the outside spacing. */
8758 vbox = GTK_DIALOG(warn_close_dialog)->vbox; 8928 vbox = gtk_dialog_get_content_area(GTK_DIALOG(warn_close_dialog));
8759 8929
8760 gtk_box_set_spacing(GTK_BOX(vbox), 12); 8930 gtk_box_set_spacing(GTK_BOX(vbox), 12);
8761 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); 8931 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
8762 8932
8763 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_WARNING, 8933 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_WARNING,
8907 #ifndef _WIN32 9077 #ifndef _WIN32
8908 /* Currently for win32 GTK+ (as of 2.2.1), gdk_pointer_is_grabbed will 9078 /* Currently for win32 GTK+ (as of 2.2.1), gdk_pointer_is_grabbed will
8909 always be true after a button press. */ 9079 always be true after a button press. */
8910 if (!gdk_pointer_is_grabbed()) 9080 if (!gdk_pointer_is_grabbed())
8911 #endif 9081 #endif
8912 gdk_pointer_grab(gtkwin->notebook->window, FALSE, 9082 gdk_pointer_grab(gtk_widget_get_window(gtkwin->notebook), FALSE,
8913 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, 9083 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
8914 NULL, cursor, GDK_CURRENT_TIME); 9084 NULL, cursor, GDK_CURRENT_TIME);
8915 } 9085 }
8916 9086
8917 static gboolean 9087 static gboolean
9027 if (e->type != GDK_BUTTON_PRESS) 9197 if (e->type != GDK_BUTTON_PRESS)
9028 return FALSE; 9198 return FALSE;
9029 9199
9030 if (e->button == 1) { 9200 if (e->button == 1) {
9031 int nb_x, nb_y; 9201 int nb_x, nb_y;
9202 GtkAllocation allocation;
9203
9204 gtk_widget_get_allocation(gtkconv->infopane_hbox, &allocation);
9032 9205
9033 if (gtkconv->win->in_drag) 9206 if (gtkconv->win->in_drag)
9034 return TRUE; 9207 return TRUE;
9035 9208
9036 gtkconv->win->in_predrag = TRUE; 9209 gtkconv->win->in_predrag = TRUE;
9037 gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont); 9210 gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont);
9038 9211
9039 gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y); 9212 gdk_window_get_origin(gtk_widget_get_window(gtkconv->infopane_hbox), &nb_x, &nb_y);
9040 9213
9041 gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x; 9214 gtkconv->win->drag_min_x = allocation.x + nb_x;
9042 gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y; 9215 gtkconv->win->drag_min_y = allocation.y + nb_y;
9043 gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x; 9216 gtkconv->win->drag_max_x = allocation.width + gtkconv->win->drag_min_x;
9044 gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y; 9217 gtkconv->win->drag_max_y = allocation.height + gtkconv->win->drag_min_y;
9045 9218
9046 gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event", 9219 gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event",
9047 G_CALLBACK(notebook_motion_cb), gtkconv->win); 9220 G_CALLBACK(notebook_motion_cb), gtkconv->win);
9048 gtkconv->win->drag_leave_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event", 9221 gtkconv->win->drag_leave_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event",
9049 G_CALLBACK(notebook_leave_cb), gtkconv->win); 9222 G_CALLBACK(notebook_leave_cb), gtkconv->win);
9052 9225
9053 if (e->button == 3) { 9226 if (e->button == 3) {
9054 /* Right click was pressed. Popup the context menu. */ 9227 /* Right click was pressed. Popup the context menu. */
9055 GtkWidget *menu = gtk_menu_new(), *sub; 9228 GtkWidget *menu = gtk_menu_new(), *sub;
9056 gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE); 9229 gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE);
9230 #if 0 /* TODO */
9057 sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to)); 9231 sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
9058 9232
9059 if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) { 9233 if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) {
9060 GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To")); 9234 GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To"));
9061 if (populated) 9235 if (populated)
9066 gtk_widget_show_all(sub); 9240 gtk_widget_show_all(sub);
9067 } else if (!populated) { 9241 } else if (!populated) {
9068 gtk_widget_destroy(menu); 9242 gtk_widget_destroy(menu);
9069 return FALSE; 9243 return FALSE;
9070 } 9244 }
9071 9245 #endif
9072 gtk_widget_show_all(menu); 9246 gtk_widget_show_all(menu);
9073 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time); 9247 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time);
9074 return TRUE; 9248 return TRUE;
9075 } 9249 }
9076 return FALSE; 9250 return FALSE;
9081 { 9255 {
9082 gint nb_x, nb_y; 9256 gint nb_x, nb_y;
9083 int tab_clicked; 9257 int tab_clicked;
9084 GtkWidget *page; 9258 GtkWidget *page;
9085 GtkWidget *tab; 9259 GtkWidget *tab;
9260 GtkAllocation allocation;
9086 9261
9087 if (e->button == 2 && e->type == GDK_BUTTON_PRESS) { 9262 if (e->button == 2 && e->type == GDK_BUTTON_PRESS) {
9088 PidginConversation *gtkconv; 9263 PidginConversation *gtkconv;
9089 tab_clicked = pidgin_conv_get_tab_at_xy(win, e->x_root, e->y_root, NULL); 9264 tab_clicked = pidgin_conv_get_tab_at_xy(win, e->x_root, e->y_root, NULL);
9090 9265
9118 9293
9119 /* 9294 /*
9120 * Get the relative position of the press event, with regards to 9295 * Get the relative position of the press event, with regards to
9121 * the position of the notebook. 9296 * the position of the notebook.
9122 */ 9297 */
9123 gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y); 9298 gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
9124 9299
9125 /* Reset the min/max x/y */ 9300 /* Reset the min/max x/y */
9126 win->drag_min_x = 0; 9301 win->drag_min_x = 0;
9127 win->drag_min_y = 0; 9302 win->drag_min_y = 0;
9128 win->drag_max_x = 0; 9303 win->drag_max_x = 0;
9130 9305
9131 /* Find out which tab was dragged. */ 9306 /* Find out which tab was dragged. */
9132 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked); 9307 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked);
9133 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page); 9308 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page);
9134 9309
9135 win->drag_min_x = tab->allocation.x + nb_x; 9310 gtk_widget_get_allocation(tab, &allocation);
9136 win->drag_min_y = tab->allocation.y + nb_y; 9311
9137 win->drag_max_x = tab->allocation.width + win->drag_min_x; 9312 win->drag_min_x = allocation.x + nb_x;
9138 win->drag_max_y = tab->allocation.height + win->drag_min_y; 9313 win->drag_min_y = allocation.y + nb_y;
9314 win->drag_max_x = allocation.width + win->drag_min_x;
9315 win->drag_max_y = allocation.height + win->drag_min_y;
9139 9316
9140 /* Make sure the click occurred in the tab. */ 9317 /* Make sure the click occurred in the tab. */
9141 if (e->x_root < win->drag_min_x || 9318 if (e->x_root < win->drag_min_x ||
9142 e->x_root >= win->drag_max_x || 9319 e->x_root >= win->drag_max_x ||
9143 e->y_root < win->drag_min_y || 9320 e->y_root < win->drag_min_y ||
9144 e->y_root >= win->drag_max_y) { 9321 e->y_root >= win->drag_max_y) {
9145 9322
9146 return FALSE; 9323 return FALSE;
9147 } 9324 }
9148 9325
9149 win->in_predrag = TRUE; 9326 win->in_predrag = TRUE;
9150 win->drag_tab = tab_clicked; 9327 win->drag_tab = tab_clicked;
9151 9328
9152 /* Connect the new motion signals. */ 9329 /* Connect the new motion signals. */
9370 9547
9371 if (gtkconv) 9548 if (gtkconv)
9372 close_conv_cb(NULL, gtkconv); 9549 close_conv_cb(NULL, gtkconv);
9373 } 9550 }
9374 9551
9552 /* TODO: I don't know if this doable in GTK+ 3.0 */
9553 #if 0
9375 static gboolean 9554 static gboolean
9376 right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win) 9555 right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win)
9377 { 9556 {
9378 GtkWidget *item, *menu; 9557 GtkWidget *item;
9379 PidginConversation *gtkconv; 9558 PidginConversation *gtkconv;
9559 GtkWidget *menu = gtk_notebook_get_menu
9380 9560
9381 if (event->type != GDK_BUTTON_PRESS || event->button != 3) 9561 if (event->type != GDK_BUTTON_PRESS || event->button != 3)
9382 return FALSE; 9562 return FALSE;
9383 9563
9384 gtkconv = pidgin_conv_window_get_gtkconv_at_index(win, 9564 gtkconv = pidgin_conv_window_get_gtkconv_at_index(win,
9421 g_signal_connect(G_OBJECT(item), "activate", 9601 g_signal_connect(G_OBJECT(item), "activate",
9422 G_CALLBACK(close_tab_cb), menu); 9602 G_CALLBACK(close_tab_cb), menu);
9423 9603
9424 return FALSE; 9604 return FALSE;
9425 } 9605 }
9606 #endif
9426 9607
9427 static void 9608 static void
9428 remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry) 9609 remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry)
9429 { 9610 {
9430 g_signal_handlers_disconnect_matched(G_OBJECT(entry), G_SIGNAL_MATCH_DATA, 9611 g_signal_handlers_disconnect_matched(G_OBJECT(entry), G_SIGNAL_MATCH_DATA,
9442 } 9623 }
9443 9624
9444 static gboolean 9625 static gboolean
9445 alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data) 9626 alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
9446 { 9627 {
9447 if (event->keyval == GDK_Escape) { 9628 if (event->keyval == GDK_KEY_Escape) {
9448 remove_edit_entry(user_data, widget); 9629 remove_edit_entry(user_data, widget);
9449 return TRUE; 9630 return TRUE;
9450 } 9631 }
9451 return FALSE; 9632 return FALSE;
9452 } 9633 }
9469 9650
9470 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 9651 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
9471 PurpleBuddy *buddy; 9652 PurpleBuddy *buddy;
9472 buddy = purple_find_buddy(account, name); 9653 buddy = purple_find_buddy(account, name);
9473 if (buddy != NULL) { 9654 if (buddy != NULL) {
9474 purple_blist_alias_buddy(buddy, 9655 purple_blist_alias_buddy(buddy, gtk_entry_get_text(entry));
9475 gtk_entry_get_text(entry));
9476 } 9656 }
9477 serv_alias_buddy(buddy); 9657 serv_alias_buddy(buddy);
9478 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 9658 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
9479 gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry)); 9659 gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry));
9480 topic_callback(NULL, gtkconv); 9660 topic_callback(NULL, gtkconv);
9487 { 9667 {
9488 GtkWidget *entry = NULL; 9668 GtkWidget *entry = NULL;
9489 PurpleConversation *conv = gtkconv->active_conv; 9669 PurpleConversation *conv = gtkconv->active_conv;
9490 const char *text = NULL; 9670 const char *text = NULL;
9491 9671
9492 if (!GTK_WIDGET_VISIBLE(gtkconv->infopane)) { 9672 if (!gtk_widget_get_visible(gtkconv->infopane)) {
9493 /* There's already an entry for alias. Let's not create another one. */ 9673 /* There's already an entry for alias. Let's not create another one. */
9494 return FALSE; 9674 return FALSE;
9495 } 9675 }
9496 9676
9497 if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) { 9677 if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) {
9571 gtkconv_set_unseen(gtkconv, PIDGIN_UNSEEN_NONE); 9751 gtkconv_set_unseen(gtkconv, PIDGIN_UNSEEN_NONE);
9572 } 9752 }
9573 9753
9574 /* Update the menubar */ 9754 /* Update the menubar */
9575 9755
9576 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging), 9756 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging),
9577 purple_conversation_is_logging(conv)); 9757 purple_conversation_is_logging(conv));
9578 9758
9579 generate_send_to_items(win); 9759 generate_send_to_items(win);
9580 regenerate_options_items(win); 9760 regenerate_options_items(win);
9581 regenerate_plugins_items(win); 9761 regenerate_plugins_items(win);
9582 9762
9583 pidgin_conv_switch_active_conversation(conv); 9763 pidgin_conv_switch_active_conversation(conv);
9584 9764
9585 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); 9765 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
9586 if (strcmp(sound_method, "none") != 0) 9766 if (strcmp(sound_method, "none") != 0)
9587 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 9767 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
9588 gtkconv->make_sound); 9768 gtkconv->make_sound);
9589 9769
9590 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar), 9770 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
9591 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")); 9771 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
9592 9772
9593 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_timestamps), 9773 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_timestamps),
9594 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps")); 9774 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
9595 9775
9596 /* 9776 /*
9597 * We pause icons when they are not visible. If this icon should 9777 * We pause icons when they are not visible. If this icon should
9598 * be animated then start it back up again. 9778 * be animated then start it back up again.
9599 */ 9779 */
9616 9796
9617 static GList* 9797 static GList*
9618 make_status_icon_list(const char *stock, GtkWidget *w) 9798 make_status_icon_list(const char *stock, GtkWidget *w)
9619 { 9799 {
9620 GList *l = NULL; 9800 GList *l = NULL;
9621 l = g_list_append(l, gtk_widget_render_icon (w, stock, 9801 l = g_list_append(l,
9622 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow")); 9802 gtk_widget_render_icon(w, stock,
9623 l = g_list_append(l, gtk_widget_render_icon (w, stock, 9803 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow"));
9624 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow")); 9804 l = g_list_append(l,
9625 l = g_list_append(l, gtk_widget_render_icon (w, stock, 9805 gtk_widget_render_icon(w, stock,
9626 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow")); 9806 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow"));
9627 l = g_list_append(l, gtk_widget_render_icon (w, stock, 9807 l = g_list_append(l,
9628 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow")); 9808 gtk_widget_render_icon(w, stock,
9809 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow"));
9810 l = g_list_append(l,
9811 gtk_widget_render_icon(w, stock,
9812 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow"));
9629 return l; 9813 return l;
9630 } 9814 }
9631 9815
9632 static void 9816 static void
9633 create_icon_lists(GtkWidget *w) 9817 create_icon_lists(GtkWidget *w)
9647 } 9831 }
9648 9832
9649 static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) { 9833 static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
9650 int x, y; 9834 int x, y;
9651 9835
9652 if (GTK_WIDGET_VISIBLE(w)) 9836 if (gtk_widget_get_visible(w))
9653 gtk_window_get_position(GTK_WINDOW(w), &x, &y); 9837 gtk_window_get_position(GTK_WINDOW(w), &x, &y);
9654 else 9838 else
9655 return FALSE; /* carry on normally */ 9839 return FALSE; /* carry on normally */
9656 9840
9657 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired 9841 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired
9658 * when the window is being maximized */ 9842 * when the window is being maximized */
9659 if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) 9843 if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
9660 return FALSE; 9844 return FALSE;
9661 9845
9662 /* don't save off-screen positioning */ 9846 /* don't save off-screen positioning */
9663 if (x + event->width < 0 || 9847 if (x + event->width < 0 ||
9664 y + event->height < 0 || 9848 y + event->height < 0 ||
9679 9863
9680 static void 9864 static void
9681 pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y, 9865 pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y,
9682 int conv_width, int conv_height) 9866 int conv_width, int conv_height)
9683 { 9867 {
9684 /* if the window exists, is hidden, we're saving positions, and the 9868 /* if the window exists, is hidden, we're saving positions, and the
9685 * position is sane... */ 9869 * position is sane... */
9686 if (win && win->window && 9870 if (win && win->window &&
9687 !GTK_WIDGET_VISIBLE(win->window) && conv_width != 0) { 9871 !gtk_widget_get_visible(win->window) && conv_width != 0) {
9688 9872
9689 #ifdef _WIN32 /* only override window manager placement on Windows */ 9873 #ifdef _WIN32 /* only override window manager placement on Windows */
9690 /* ...check position is on screen... */ 9874 /* ...check position is on screen... */
9691 if (conv_x >= gdk_screen_width()) 9875 if (conv_x >= gdk_screen_width())
9692 conv_x = gdk_screen_width() - 100; 9876 conv_x = gdk_screen_width() - 100;
9767 gtk_notebook_set_scrollable(GTK_NOTEBOOK(win->notebook), TRUE); 9951 gtk_notebook_set_scrollable(GTK_NOTEBOOK(win->notebook), TRUE);
9768 gtk_notebook_popup_enable(GTK_NOTEBOOK(win->notebook)); 9952 gtk_notebook_popup_enable(GTK_NOTEBOOK(win->notebook));
9769 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE); 9953 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
9770 gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE); 9954 gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE);
9771 9955
9956 /* TODO: figure out how to add custom stuff to the right-click menu in
9957 GtkNotebook in GTK+ 3.0 */
9958 #if 0
9772 g_signal_connect(G_OBJECT(win->notebook), "button-press-event", 9959 g_signal_connect(G_OBJECT(win->notebook), "button-press-event",
9773 G_CALLBACK(right_click_menu_cb), win); 9960 G_CALLBACK(right_click_menu_cb), win);
9961 #endif
9774 9962
9775 gtk_widget_show(win->notebook); 9963 gtk_widget_show(win->notebook);
9776 9964
9777 g_signal_connect(G_OBJECT(win->notebook), "switch_page", 9965 g_signal_connect(G_OBJECT(win->notebook), "switch_page",
9778 G_CALLBACK(before_switch_conv_cb), win); 9966 G_CALLBACK(before_switch_conv_cb), win);
9837 } 10025 }
9838 return; 10026 return;
9839 } 10027 }
9840 gtk_widget_destroy(win->window); 10028 gtk_widget_destroy(win->window);
9841 10029
9842 g_object_unref(G_OBJECT(win->menu.item_factory)); 10030 g_object_unref(G_OBJECT(win->menu.ui));
9843 10031
9844 purple_notify_close_with_handle(win); 10032 purple_notify_close_with_handle(win);
9845 purple_signals_disconnect_by_handle(win); 10033 purple_signals_disconnect_by_handle(win);
9846 10034
9847 g_free(win); 10035 g_free(win);
9860 } 10048 }
9861 10049
9862 void 10050 void
9863 pidgin_conv_window_raise(PidginWindow *win) 10051 pidgin_conv_window_raise(PidginWindow *win)
9864 { 10052 {
9865 gdk_window_raise(GDK_WINDOW(win->window->window)); 10053 gdk_window_raise(GDK_WINDOW(gtk_widget_get_window(win->window)));
9866 } 10054 }
9867 10055
9868 void 10056 void
9869 pidgin_conv_window_switch_gtkconv(PidginWindow *win, PidginConversation *gtkconv) 10057 pidgin_conv_window_switch_gtkconv(PidginWindow *win, PidginConversation *gtkconv)
9870 { 10058 {
9915 pidgin_conv_tab_pack(win, ((PidginConversation*)win->gtkconvs->data)); 10103 pidgin_conv_tab_pack(win, ((PidginConversation*)win->gtkconvs->data));
9916 10104
9917 10105
9918 /* Close button. */ 10106 /* Close button. */
9919 gtkconv->close = pidgin_create_small_button(gtk_label_new("×")); 10107 gtkconv->close = pidgin_create_small_button(gtk_label_new("×"));
10108 #if GTK_CHECK_VERSION(2,12,0)
10109 gtk_widget_set_tooltip_text(gtkconv->close, _("Close conversation"));
10110 #else
9920 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close, 10111 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
9921 _("Close conversation"), NULL); 10112 _("Close conversation"), NULL);
10113 #endif
9922 10114
9923 g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv); 10115 g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv);
9924 10116
9925 /* Status icon. */ 10117 /* Status icon. */
9926 gtkconv->icon = gtk_image_new(); 10118 gtkconv->icon = gtk_image_new();
10031 gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE); 10223 gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE);
10032 gtk_container_add(GTK_CONTAINER(ebox), gtkconv->tabby); 10224 gtk_container_add(GTK_CONTAINER(ebox), gtkconv->tabby);
10033 g_signal_connect(G_OBJECT(ebox), "enter-notify-event", 10225 g_signal_connect(G_OBJECT(ebox), "enter-notify-event",
10034 G_CALLBACK(gtkconv_tab_set_tip), gtkconv); 10226 G_CALLBACK(gtkconv_tab_set_tip), gtkconv);
10035 10227
10036 if (gtkconv->tab_label->parent == NULL) { 10228 if (gtk_widget_get_parent(gtkconv->tab_label) == NULL) {
10037 /* Pack if it's a new widget */ 10229 /* Pack if it's a new widget */
10038 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0); 10230 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0);
10039 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE, TRUE, 0); 10231 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE, TRUE, 0);
10040 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), third, FALSE, FALSE, 0); 10232 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), third, FALSE, FALSE, 0);
10041 10233
10052 10244
10053 /* Reset the tabs label to the new version */ 10245 /* Reset the tabs label to the new version */
10054 gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox); 10246 gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox);
10055 } 10247 }
10056 10248
10057 gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, 10249 g_object_set(G_OBJECT(win->notebook), "expand", !tabs_side && !angle, NULL);
10058 !tabs_side && !angle,
10059 TRUE, GTK_PACK_START);
10060 10250
10061 if (pidgin_conv_window_get_gtkconv_count(win) == 1) 10251 if (pidgin_conv_window_get_gtkconv_count(win) == 1)
10062 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), 10252 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
10063 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") && 10253 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") &&
10064 (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") || 10254 (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") ||
10078 { 10268 {
10079 unsigned int index; 10269 unsigned int index;
10080 10270
10081 index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont); 10271 index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont);
10082 10272
10273 #if GTK_CHECK_VERSION(2,10,0)
10274 g_object_ref_sink(G_OBJECT(gtkconv->tab_cont));
10275 #else
10083 g_object_ref(gtkconv->tab_cont); 10276 g_object_ref(gtkconv->tab_cont);
10084 gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont)); 10277 gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont));
10278 #endif
10085 10279
10086 gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index); 10280 gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index);
10087 10281
10088 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv); 10282 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv);
10089 10283
10162 gdkwin = gdk_window_get_toplevel(gdkwin); 10356 gdkwin = gdk_window_get_toplevel(gdkwin);
10163 10357
10164 for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) { 10358 for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) {
10165 win = l->data; 10359 win = l->data;
10166 10360
10167 if (gdkwin == win->window->window) 10361 if (gdkwin == gtk_widget_get_window(win->window))
10168 return win; 10362 return win;
10169 } 10363 }
10170 10364
10171 return NULL; 10365 return NULL;
10172 } 10366 }
10284 { 10478 {
10285 int x, y; 10479 int x, y;
10286 PurpleConversationType type = purple_conversation_get_type(conv->active_conv); 10480 PurpleConversationType type = purple_conversation_get_type(conv->active_conv);
10287 GList *all; 10481 GList *all;
10288 10482
10289 if (GTK_WIDGET_VISIBLE(w)) 10483 if (gtk_widget_get_visible(w))
10290 gtk_window_get_position(GTK_WINDOW(w), &x, &y); 10484 gtk_window_get_position(GTK_WINDOW(w), &x, &y);
10291 else 10485 else
10292 return FALSE; /* carry on normally */ 10486 return FALSE; /* carry on normally */
10293 10487
10294 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired 10488 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired
10295 * when the window is being maximized */ 10489 * when the window is being maximized */
10296 if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) 10490 if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
10297 return FALSE; 10491 return FALSE;
10298 10492
10299 /* don't save off-screen positioning */ 10493 /* don't save off-screen positioning */
10300 if (x + event->width < 0 || 10494 if (x + event->width < 0 ||
10301 y + event->height < 0 || 10495 y + event->height < 0 ||

mercurial