pidgin/gtkconv.c

branch
cpw.qulogic.gtk3-required
changeset 33128
88ee8f3bfff3
parent 32872
31e6808f3dc4
parent 33127
02a3db370988
child 33132
24afd2b22579
equal deleted inserted replaced
32893:6063be322695 33128:88ee8f3bfff3
196 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type); 196 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type);
197 static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state); 197 static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state);
198 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state); 198 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
199 static void update_typing_icon(PidginConversation *gtkconv); 199 static void update_typing_icon(PidginConversation *gtkconv);
200 static void update_typing_message(PidginConversation *gtkconv, const char *message); 200 static void update_typing_message(PidginConversation *gtkconv, const char *message);
201 static const char *item_factory_translate_func (const char *path, gpointer func_data);
202 gboolean pidgin_conv_has_focus(PurpleConversation *conv); 201 gboolean pidgin_conv_has_focus(PurpleConversation *conv);
203 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background); 202 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
204 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 203 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
205 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, gboolean create); 204 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, gboolean create);
206 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); 205 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
839 GtkSelectionData *sd, guint inf, guint t, gpointer data) 838 GtkSelectionData *sd, guint inf, guint t, gpointer data)
840 { 839 {
841 InviteBuddyInfo *info = (InviteBuddyInfo *)data; 840 InviteBuddyInfo *info = (InviteBuddyInfo *)data;
842 const char *convprotocol; 841 const char *convprotocol;
843 gboolean success = TRUE; 842 gboolean success = TRUE;
843 GdkAtom target = gtk_selection_data_get_target(sd);
844 844
845 convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv)); 845 convprotocol = purple_account_get_protocol_id(purple_conversation_get_account(info->conv));
846 846
847 if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) 847 if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
848 { 848 {
849 PurpleBlistNode *node = NULL; 849 PurpleBlistNode *node = NULL;
850 PurpleBuddy *buddy; 850 PurpleBuddy *buddy;
851 851 const guchar *data = gtk_selection_data_get_data(sd);
852 memcpy(&node, sd->data, sizeof(node)); 852
853 memcpy(&node, data, sizeof(node));
853 854
854 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) 855 if (PURPLE_BLIST_NODE_IS_CONTACT(node))
855 buddy = purple_contact_get_priority_buddy((PurpleContact *)node); 856 buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
856 else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) 857 else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
857 buddy = (PurpleBuddy *)node; 858 buddy = (PurpleBuddy *)node;
866 success = FALSE; 867 success = FALSE;
867 } 868 }
868 else 869 else
869 gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy)); 870 gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy));
870 871
871 gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t); 872 gtk_drag_finish(dc, success,
872 } 873 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
873 else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE)) 874 }
875 else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
874 { 876 {
875 char *protocol = NULL; 877 char *protocol = NULL;
876 char *username = NULL; 878 char *username = NULL;
877 PurpleAccount *account; 879 PurpleAccount *account;
878 880
879 if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, 881 if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
880 &protocol, &username, NULL)) 882 &protocol, &username, NULL))
881 { 883 {
882 if (account == NULL) 884 if (account == NULL)
883 { 885 {
884 purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL, 886 purple_notify_error(PIDGIN_CONVERSATION(info->conv), NULL,
899 } 901 }
900 902
901 g_free(username); 903 g_free(username);
902 g_free(protocol); 904 g_free(protocol);
903 905
904 gtk_drag_finish(dc, success, (dc->action == GDK_ACTION_MOVE), t); 906 gtk_drag_finish(dc, success,
907 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
905 } 908 }
906 } 909 }
907 910
908 static const GtkTargetEntry dnd_targets[] = 911 static const GtkTargetEntry dnd_targets[] =
909 { 912 {
941 944
942 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog), 945 gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog),
943 GTK_RESPONSE_OK); 946 GTK_RESPONSE_OK);
944 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE); 947 gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE);
945 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE); 948 gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE);
949 /* TODO: set no separator using GTK+ 3.0 */
950 #if 0
946 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE); 951 gtk_dialog_set_has_separator(GTK_DIALOG(invite_dialog), FALSE);
952 #endif
947 953
948 info->window = GTK_WIDGET(invite_dialog); 954 info->window = GTK_WIDGET(invite_dialog);
949 955
950 /* Setup the outside spacing. */ 956 /* Setup the outside spacing. */
951 vbox = GTK_DIALOG(invite_dialog)->vbox; 957 vbox = gtk_dialog_get_content_area(GTK_DIALOG(invite_dialog));
952 958
953 gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER); 959 gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER);
954 gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE); 960 gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE);
955 961
956 /* Setup the inner hbox and put the dialog's icon in it. */ 962 /* Setup the inner hbox and put the dialog's icon in it. */
1038 if (info != NULL) 1044 if (info != NULL)
1039 gtk_widget_grab_focus(info->entry); 1045 gtk_widget_grab_focus(info->entry);
1040 } 1046 }
1041 1047
1042 static void 1048 static void
1043 menu_new_conv_cb(gpointer data, guint action, GtkWidget *widget) 1049 menu_new_conv_cb(GtkAction *action, gpointer data)
1044 { 1050 {
1045 pidgin_dialogs_im(); 1051 pidgin_dialogs_im();
1046 } 1052 }
1047 1053
1048 static void 1054 static void
1088 /* 1094 /*
1089 * It would be kinda cool if this gave the option of saving a 1095 * It would be kinda cool if this gave the option of saving a
1090 * plaintext v. HTML file. 1096 * plaintext v. HTML file.
1091 */ 1097 */
1092 static void 1098 static void
1093 menu_save_as_cb(gpointer data, guint action, GtkWidget *widget) 1099 menu_save_as_cb(GtkAction *action, gpointer data)
1094 { 1100 {
1095 PidginWindow *win = data; 1101 PidginWindow *win = data;
1096 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1102 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1097 PurpleAccount *account = purple_conversation_get_account(conv); 1103 PurpleAccount *account = purple_conversation_get_account(conv);
1098 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); 1104 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
1119 1125
1120 g_free(buf); 1126 g_free(buf);
1121 } 1127 }
1122 1128
1123 static void 1129 static void
1124 menu_view_log_cb(gpointer data, guint action, GtkWidget *widget) 1130 menu_view_log_cb(GtkAction *action, gpointer data)
1125 { 1131 {
1126 PidginWindow *win = data; 1132 PidginWindow *win = data;
1127 PurpleConversation *conv; 1133 PurpleConversation *conv;
1128 PurpleLogType type; 1134 PurpleLogType type;
1129 PidginBuddyList *gtkblist; 1135 PidginBuddyList *gtkblist;
1143 return; 1149 return;
1144 1150
1145 gtkblist = pidgin_blist_get_default_gtk_blist(); 1151 gtkblist = pidgin_blist_get_default_gtk_blist();
1146 1152
1147 cursor = gdk_cursor_new(GDK_WATCH); 1153 cursor = gdk_cursor_new(GDK_WATCH);
1148 gdk_window_set_cursor(gtkblist->window->window, cursor); 1154 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), cursor);
1149 gdk_window_set_cursor(win->window->window, cursor); 1155 gdk_window_set_cursor(gtk_widget_get_window(win->window), cursor);
1150 gdk_cursor_unref(cursor); 1156 gdk_cursor_unref(cursor);
1157 #if GTK_CHECK_VERSION(2,4,0) && !GTK_CHECK_VERSION(2,6,0) //FIXME: What?
1151 gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window))); 1158 gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
1159 #endif
1152 1160
1153 name = purple_conversation_get_name(conv); 1161 name = purple_conversation_get_name(conv);
1154 account = purple_conversation_get_account(conv); 1162 account = purple_conversation_get_account(conv);
1155 1163
1156 buddies = purple_find_buddies(account, name); 1164 buddies = purple_find_buddies(account, name);
1159 PurpleBlistNode *node = cur->data; 1167 PurpleBlistNode *node = cur->data;
1160 if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL))) 1168 if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
1161 { 1169 {
1162 pidgin_log_show_contact((PurpleContact *)node->parent); 1170 pidgin_log_show_contact((PurpleContact *)node->parent);
1163 g_slist_free(buddies); 1171 g_slist_free(buddies);
1164 gdk_window_set_cursor(gtkblist->window->window, NULL); 1172 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
1165 gdk_window_set_cursor(win->window->window, NULL); 1173 gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
1166 return; 1174 return;
1167 } 1175 }
1168 } 1176 }
1169 g_slist_free(buddies); 1177 g_slist_free(buddies);
1170 1178
1171 pidgin_log_show(type, name, account); 1179 pidgin_log_show(type, name, account);
1172 1180
1173 gdk_window_set_cursor(gtkblist->window->window, NULL); 1181 gdk_window_set_cursor(gtk_widget_get_window(gtkblist->window), NULL);
1174 gdk_window_set_cursor(win->window->window, NULL); 1182 gdk_window_set_cursor(gtk_widget_get_window(win->window), NULL);
1175 } 1183 }
1176 1184
1177 static void 1185 static void
1178 menu_clear_cb(gpointer data, guint action, GtkWidget *widget) 1186 menu_clear_cb(GtkAction *action, gpointer data)
1179 { 1187 {
1180 PidginWindow *win = data; 1188 PidginWindow *win = data;
1181 PurpleConversation *conv; 1189 PurpleConversation *conv;
1182 1190
1183 conv = pidgin_conv_window_get_active_conversation(win); 1191 conv = pidgin_conv_window_get_active_conversation(win);
1184 purple_conversation_clear_message_history(conv); 1192 purple_conversation_clear_message_history(conv);
1185 } 1193 }
1186 1194
1187 static void 1195 static void
1188 menu_find_cb(gpointer data, guint action, GtkWidget *widget) 1196 menu_find_cb(GtkAction *action, gpointer data)
1189 { 1197 {
1190 PidginWindow *gtkwin = data; 1198 PidginWindow *gtkwin = data;
1191 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin); 1199 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(gtkwin);
1192 gtk_widget_show_all(gtkconv->quickfind.container); 1200 gtk_widget_show_all(gtkconv->quickfind.container);
1193 gtk_widget_grab_focus(gtkconv->quickfind.entry); 1201 gtk_widget_grab_focus(gtkconv->quickfind.entry);
1194 } 1202 }
1195 1203
1196 #ifdef USE_VV 1204 #ifdef USE_VV
1197 static void 1205 static void
1198 menu_initiate_media_call_cb(gpointer data, guint action, GtkWidget *widget) 1206 menu_initiate_media_call_cb(GtkAction *action, gpointer data)
1199 { 1207 {
1200 PidginWindow *win = (PidginWindow *)data; 1208 PidginWindow *win = (PidginWindow *)data;
1201 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1209 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1202 PurpleAccount *account = purple_conversation_get_account(conv); 1210 PurpleAccount *account = purple_conversation_get_account(conv);
1203 1211
1204 purple_prpl_initiate_media(account, 1212 purple_prpl_initiate_media(account,
1205 purple_conversation_get_name(conv), 1213 purple_conversation_get_name(conv),
1206 action == 0 ? PURPLE_MEDIA_AUDIO : 1214 action == win->audio_call ? PURPLE_MEDIA_AUDIO :
1207 action == 1 ? PURPLE_MEDIA_VIDEO : 1215 action == win->video_call ? PURPLE_MEDIA_VIDEO :
1208 action == 2 ? PURPLE_MEDIA_AUDIO | 1216 action == win->audio_video_call ? PURPLE_MEDIA_AUDIO |
1209 PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE); 1217 PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE);
1210 } 1218 }
1211 #endif 1219 #endif
1212 1220
1213 static void 1221 static void
1214 menu_send_file_cb(gpointer data, guint action, GtkWidget *widget) 1222 menu_send_file_cb(GtkAction *action, gpointer data)
1215 { 1223 {
1216 PidginWindow *win = data; 1224 PidginWindow *win = data;
1217 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1225 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1218 1226
1219 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 1227 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
1221 } 1229 }
1222 1230
1223 } 1231 }
1224 1232
1225 static void 1233 static void
1226 menu_get_attention_cb(gpointer data, guint action, GtkWidget *widget) 1234 menu_get_attention_cb(GObject *obj, gpointer data)
1227 { 1235 {
1228 PidginWindow *win = data; 1236 PidginWindow *win = data;
1229 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); 1237 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
1230 1238
1231 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 1239 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
1232 int index; 1240 int index;
1233 if (widget == win->menu.get_attention) 1241 if ((GtkAction *)obj == win->menu.get_attention)
1234 index = 0; 1242 index = 0;
1235 else 1243 else
1236 index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "index")); 1244 index = GPOINTER_TO_INT(g_object_get_data(obj, "index"));
1237 purple_prpl_send_attention(purple_conversation_get_connection(conv), 1245 purple_prpl_send_attention(purple_conversation_get_connection(conv),
1238 purple_conversation_get_name(conv), index); 1246 purple_conversation_get_name(conv), index);
1239 } 1247 }
1240 } 1248 }
1241 1249
1242 static void 1250 static void
1243 menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget) 1251 menu_add_pounce_cb(GtkAction *action, gpointer data)
1244 { 1252 {
1245 PidginWindow *win = data; 1253 PidginWindow *win = data;
1246 PurpleConversation *conv; 1254 PurpleConversation *conv;
1247 1255
1248 conv = pidgin_conv_window_get_active_gtkconv(win)->active_conv; 1256 conv = pidgin_conv_window_get_active_gtkconv(win)->active_conv;
1250 pidgin_pounce_editor_show(purple_conversation_get_account(conv), 1258 pidgin_pounce_editor_show(purple_conversation_get_account(conv),
1251 purple_conversation_get_name(conv), NULL); 1259 purple_conversation_get_name(conv), NULL);
1252 } 1260 }
1253 1261
1254 static void 1262 static void
1255 menu_insert_link_cb(gpointer data, guint action, GtkWidget *widget) 1263 menu_insert_link_cb(GtkAction *action, gpointer data)
1256 { 1264 {
1257 PidginWindow *win = data; 1265 PidginWindow *win = data;
1258 PidginConversation *gtkconv; 1266 PidginConversation *gtkconv;
1259 GtkIMHtmlToolbar *toolbar; 1267 GtkIMHtmlToolbar *toolbar;
1260 1268
1264 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->link), 1272 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->link),
1265 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->link))); 1273 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->link)));
1266 } 1274 }
1267 1275
1268 static void 1276 static void
1269 menu_insert_image_cb(gpointer data, guint action, GtkWidget *widget) 1277 menu_insert_image_cb(GtkAction *action, gpointer data)
1270 { 1278 {
1271 PidginWindow *win = data; 1279 PidginWindow *win = data;
1272 PidginConversation *gtkconv; 1280 PidginConversation *gtkconv;
1273 GtkIMHtmlToolbar *toolbar; 1281 GtkIMHtmlToolbar *toolbar;
1274 1282
1279 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->image))); 1287 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toolbar->image)));
1280 } 1288 }
1281 1289
1282 1290
1283 static void 1291 static void
1284 menu_alias_cb(gpointer data, guint action, GtkWidget *widget) 1292 menu_alias_cb(GtkAction *action, gpointer data)
1285 { 1293 {
1286 PidginWindow *win = data; 1294 PidginWindow *win = data;
1287 PurpleConversation *conv; 1295 PurpleConversation *conv;
1288 PurpleAccount *account; 1296 PurpleAccount *account;
1289 const char *name; 1297 const char *name;
1306 pidgin_dialogs_alias_chat(c); 1314 pidgin_dialogs_alias_chat(c);
1307 } 1315 }
1308 } 1316 }
1309 1317
1310 static void 1318 static void
1311 menu_get_info_cb(gpointer data, guint action, GtkWidget *widget) 1319 menu_get_info_cb(GtkAction *action, gpointer data)
1312 { 1320 {
1313 PidginWindow *win = data; 1321 PidginWindow *win = data;
1314 PurpleConversation *conv; 1322 PurpleConversation *conv;
1315 1323
1316 conv = pidgin_conv_window_get_active_conversation(win); 1324 conv = pidgin_conv_window_get_active_conversation(win);
1317 1325
1318 info_cb(NULL, PIDGIN_CONVERSATION(conv)); 1326 info_cb(NULL, PIDGIN_CONVERSATION(conv));
1319 } 1327 }
1320 1328
1321 static void 1329 static void
1322 menu_invite_cb(gpointer data, guint action, GtkWidget *widget) 1330 menu_invite_cb(GtkAction *action, gpointer data)
1323 { 1331 {
1324 PidginWindow *win = data; 1332 PidginWindow *win = data;
1325 PurpleConversation *conv; 1333 PurpleConversation *conv;
1326 1334
1327 conv = pidgin_conv_window_get_active_conversation(win); 1335 conv = pidgin_conv_window_get_active_conversation(win);
1328 1336
1329 invite_cb(NULL, PIDGIN_CONVERSATION(conv)); 1337 invite_cb(NULL, PIDGIN_CONVERSATION(conv));
1330 } 1338 }
1331 1339
1332 static void 1340 static void
1333 menu_block_cb(gpointer data, guint action, GtkWidget *widget) 1341 menu_block_cb(GtkAction *action, gpointer data)
1334 { 1342 {
1335 PidginWindow *win = data; 1343 PidginWindow *win = data;
1336 PurpleConversation *conv; 1344 PurpleConversation *conv;
1337 1345
1338 conv = pidgin_conv_window_get_active_conversation(win); 1346 conv = pidgin_conv_window_get_active_conversation(win);
1339 1347
1340 block_cb(NULL, PIDGIN_CONVERSATION(conv)); 1348 block_cb(NULL, PIDGIN_CONVERSATION(conv));
1341 } 1349 }
1342 1350
1343 static void 1351 static void
1344 menu_unblock_cb(gpointer data, guint action, GtkWidget *widget) 1352 menu_unblock_cb(GtkAction *action, gpointer data)
1345 { 1353 {
1346 PidginWindow *win = data; 1354 PidginWindow *win = data;
1347 PurpleConversation *conv; 1355 PurpleConversation *conv;
1348 1356
1349 conv = pidgin_conv_window_get_active_conversation(win); 1357 conv = pidgin_conv_window_get_active_conversation(win);
1350 1358
1351 unblock_cb(NULL, PIDGIN_CONVERSATION(conv)); 1359 unblock_cb(NULL, PIDGIN_CONVERSATION(conv));
1352 } 1360 }
1353 1361
1354 static void 1362 static void
1355 menu_add_remove_cb(gpointer data, guint action, GtkWidget *widget) 1363 menu_add_remove_cb(GtkAction *action, gpointer data)
1356 { 1364 {
1357 PidginWindow *win = data; 1365 PidginWindow *win = data;
1358 PurpleConversation *conv; 1366 PurpleConversation *conv;
1359 1367
1360 conv = pidgin_conv_window_get_active_conversation(win); 1368 conv = pidgin_conv_window_get_active_conversation(win);
1395 #endif 1403 #endif
1396 } 1404 }
1397 } 1405 }
1398 1406
1399 static void 1407 static void
1400 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) 1408 menu_close_conv_cb(GtkAction *action, gpointer data)
1401 { 1409 {
1402 PidginWindow *win = data; 1410 PidginWindow *win = data;
1403 1411
1404 close_conv_cb(NULL, PIDGIN_CONVERSATION(pidgin_conv_window_get_active_conversation(win))); 1412 close_conv_cb(NULL, PIDGIN_CONVERSATION(pidgin_conv_window_get_active_conversation(win)));
1405 } 1413 }
1406 1414
1407 static void 1415 static void
1408 menu_logging_cb(gpointer data, guint action, GtkWidget *widget) 1416 menu_logging_cb(GtkAction *action, gpointer data)
1409 { 1417 {
1410 PidginWindow *win = data; 1418 PidginWindow *win = data;
1411 PurpleConversation *conv; 1419 PurpleConversation *conv;
1412 gboolean logging; 1420 gboolean logging;
1413 PurpleBlistNode *node; 1421 PurpleBlistNode *node;
1415 conv = pidgin_conv_window_get_active_conversation(win); 1423 conv = pidgin_conv_window_get_active_conversation(win);
1416 1424
1417 if (conv == NULL) 1425 if (conv == NULL)
1418 return; 1426 return;
1419 1427
1420 logging = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); 1428 logging = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
1421 1429
1422 if (logging == purple_conversation_is_logging(conv)) 1430 if (logging == purple_conversation_is_logging(conv))
1423 return; 1431 return;
1424 1432
1425 node = get_conversation_blist_node(conv); 1433 node = get_conversation_blist_node(conv);
1466 break; 1474 break;
1467 } 1475 }
1468 } 1476 }
1469 1477
1470 static void 1478 static void
1471 menu_toolbar_cb(gpointer data, guint action, GtkWidget *widget) 1479 menu_toolbar_cb(GtkAction *action, gpointer data)
1472 { 1480 {
1473 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar", 1481 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar",
1474 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))); 1482 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
1475 } 1483 }
1476 1484
1477 static void 1485 static void
1478 menu_sounds_cb(gpointer data, guint action, GtkWidget *widget) 1486 menu_sounds_cb(GtkAction *action, gpointer data)
1479 { 1487 {
1480 PidginWindow *win = data; 1488 PidginWindow *win = data;
1481 PurpleConversation *conv; 1489 PurpleConversation *conv;
1482 PidginConversation *gtkconv; 1490 PidginConversation *gtkconv;
1483 PurpleBlistNode *node; 1491 PurpleBlistNode *node;
1488 return; 1496 return;
1489 1497
1490 gtkconv = PIDGIN_CONVERSATION(conv); 1498 gtkconv = PIDGIN_CONVERSATION(conv);
1491 1499
1492 gtkconv->make_sound = 1500 gtkconv->make_sound =
1493 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); 1501 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
1494 node = get_conversation_blist_node(conv); 1502 node = get_conversation_blist_node(conv);
1495 if (node) 1503 if (node)
1496 purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound); 1504 purple_blist_node_set_bool(node, "gtk-mute-sound", !gtkconv->make_sound);
1497 } 1505 }
1498 1506
1499 static void 1507 static void
1500 menu_timestamps_cb(gpointer data, guint action, GtkWidget *widget) 1508 menu_timestamps_cb(GtkAction *action, gpointer data)
1501 { 1509 {
1502 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps", 1510 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps",
1503 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))); 1511 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)));
1504 } 1512 }
1505 1513
1506 static void 1514 static void
1507 chat_do_im(PidginConversation *gtkconv, const char *who) 1515 chat_do_im(PidginConversation *gtkconv, const char *who)
1508 { 1516 {
1966 pidgin_tooltip_destroy(); 1974 pidgin_tooltip_destroy();
1967 1975
1968 /* If CTRL was held down... */ 1976 /* If CTRL was held down... */
1969 if (event->state & GDK_CONTROL_MASK) { 1977 if (event->state & GDK_CONTROL_MASK) {
1970 switch (event->keyval) { 1978 switch (event->keyval) {
1971 case GDK_Page_Down: 1979 case GDK_KEY_Page_Down:
1972 case GDK_KP_Page_Down: 1980 case GDK_KEY_KP_Page_Down:
1973 case ']': 1981 case ']':
1974 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1)) 1982 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv + 1))
1975 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); 1983 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0);
1976 else 1984 else
1977 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1); 1985 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv + 1);
1978 return TRUE; 1986 return TRUE;
1979 break; 1987 break;
1980 1988
1981 case GDK_Page_Up: 1989 case GDK_KEY_Page_Up:
1982 case GDK_KP_Page_Up: 1990 case GDK_KEY_KP_Page_Up:
1983 case '[': 1991 case '[':
1984 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1)) 1992 if (!pidgin_conv_window_get_gtkconv_at_index(win, curconv - 1))
1985 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1); 1993 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), -1);
1986 else 1994 else
1987 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1); 1995 gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), curconv - 1);
1988 return TRUE; 1996 return TRUE;
1989 break; 1997 break;
1990 1998
1991 case GDK_Tab: 1999 case GDK_KEY_Tab:
1992 case GDK_KP_Tab: 2000 case GDK_KEY_KP_Tab:
1993 case GDK_ISO_Left_Tab: 2001 case GDK_KEY_ISO_Left_Tab:
1994 if (event->state & GDK_SHIFT_MASK) { 2002 if (event->state & GDK_SHIFT_MASK) {
1995 move_to_next_unread_tab(gtkconv, FALSE); 2003 move_to_next_unread_tab(gtkconv, FALSE);
1996 } else { 2004 } else {
1997 move_to_next_unread_tab(gtkconv, TRUE); 2005 move_to_next_unread_tab(gtkconv, TRUE);
1998 } 2006 }
1999 2007
2000 return TRUE; 2008 return TRUE;
2001 break; 2009 break;
2002 2010
2003 case GDK_comma: 2011 case GDK_KEY_comma:
2004 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), 2012 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
2005 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), 2013 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
2006 curconv - 1); 2014 curconv - 1);
2007 return TRUE; 2015 return TRUE;
2008 break; 2016 break;
2009 2017
2010 case GDK_period: 2018 case GDK_KEY_period:
2011 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), 2019 gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook),
2012 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv), 2020 gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), curconv),
2013 (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook))); 2021 (curconv + 1) % gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook)));
2014 return TRUE; 2022 return TRUE;
2015 break; 2023 break;
2016 case GDK_F6: 2024 case GDK_KEY_F6:
2017 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) 2025 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
2018 return TRUE; 2026 return TRUE;
2019 break; 2027 break;
2020 } /* End of switch */ 2028 } /* End of switch */
2021 } 2029 }
2035 2043
2036 /* If neither CTRL nor ALT were held down... */ 2044 /* If neither CTRL nor ALT were held down... */
2037 else 2045 else
2038 { 2046 {
2039 switch (event->keyval) { 2047 switch (event->keyval) {
2040 case GDK_F2: 2048 case GDK_KEY_F2:
2041 if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) { 2049 if (gtk_widget_is_focus(GTK_WIDGET(win->notebook))) {
2042 infopane_entry_activate(gtkconv); 2050 infopane_entry_activate(gtkconv);
2043 return TRUE; 2051 return TRUE;
2044 } 2052 }
2045 break; 2053 break;
2046 case GDK_F6: 2054 case GDK_KEY_F6:
2047 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) 2055 if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD))
2048 return TRUE; 2056 return TRUE;
2049 break; 2057 break;
2050 } 2058 }
2051 } 2059 }
2065 return TRUE; 2073 return TRUE;
2066 2074
2067 /* If CTRL was held down... */ 2075 /* If CTRL was held down... */
2068 if (event->state & GDK_CONTROL_MASK) { 2076 if (event->state & GDK_CONTROL_MASK) {
2069 switch (event->keyval) { 2077 switch (event->keyval) {
2070 case GDK_Up: 2078 case GDK_KEY_Up:
2071 if (!gtkconv->send_history) 2079 if (!gtkconv->send_history)
2072 break; 2080 break;
2073 2081
2074 if (gtkconv->entry != entry) 2082 if (gtkconv->entry != entry)
2075 break; 2083 break;
2116 } 2124 }
2117 2125
2118 return TRUE; 2126 return TRUE;
2119 break; 2127 break;
2120 2128
2121 case GDK_Down: 2129 case GDK_KEY_Down:
2122 if (!gtkconv->send_history) 2130 if (!gtkconv->send_history)
2123 break; 2131 break;
2124 2132
2125 if (gtkconv->entry != entry) 2133 if (gtkconv->entry != entry)
2126 break; 2134 break;
2169 } 2177 }
2170 2178
2171 /* If neither CTRL nor ALT were held down... */ 2179 /* If neither CTRL nor ALT were held down... */
2172 else { 2180 else {
2173 switch (event->keyval) { 2181 switch (event->keyval) {
2174 case GDK_Tab: 2182 case GDK_KEY_Tab:
2175 case GDK_KP_Tab: 2183 case GDK_KEY_KP_Tab:
2176 case GDK_ISO_Left_Tab: 2184 case GDK_KEY_ISO_Left_Tab:
2177 if (gtkconv->entry != entry) 2185 if (gtkconv->entry != entry)
2178 break; 2186 break;
2179 { 2187 {
2180 gint plugin_return; 2188 gint plugin_return;
2181 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( 2189 plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
2183 conv, event->state & GDK_SHIFT_MASK)); 2191 conv, event->state & GDK_SHIFT_MASK));
2184 return plugin_return ? TRUE : tab_complete(conv); 2192 return plugin_return ? TRUE : tab_complete(conv);
2185 } 2193 }
2186 break; 2194 break;
2187 2195
2188 case GDK_Page_Up: 2196 case GDK_KEY_Page_Up:
2189 case GDK_KP_Page_Up: 2197 case GDK_KEY_KP_Page_Up:
2190 gtk_webview_page_up(GTK_WEBVIEW(gtkconv->webview)); 2198 gtk_webview_page_up(GTK_WEBVIEW(gtkconv->webview));
2191 return TRUE; 2199 return TRUE;
2192 break; 2200 break;
2193 2201
2194 case GDK_Page_Down: 2202 case GDK_KEY_Page_Down:
2195 case GDK_KP_Page_Down: 2203 case GDK_KEY_KP_Page_Down:
2196 gtk_webview_page_down(GTK_WEBVIEW(gtkconv->webview)); 2204 gtk_webview_page_down(GTK_WEBVIEW(gtkconv->webview));
2197 return TRUE; 2205 return TRUE;
2198 break; 2206 break;
2199 2207
2200 } 2208 }
2234 { 2242 {
2235 PidginConversation *gtkconv = data; 2243 PidginConversation *gtkconv = data;
2236 2244
2237 /* If we have a valid key for the conversation display, then exit */ 2245 /* If we have a valid key for the conversation display, then exit */
2238 if ((event->state & GDK_CONTROL_MASK) || 2246 if ((event->state & GDK_CONTROL_MASK) ||
2239 (event->keyval == GDK_F6) || 2247 (event->keyval == GDK_KEY_F6) ||
2240 (event->keyval == GDK_F10) || 2248 (event->keyval == GDK_KEY_F10) ||
2241 (event->keyval == GDK_Shift_L) || 2249 (event->keyval == GDK_KEY_Shift_L) ||
2242 (event->keyval == GDK_Shift_R) || 2250 (event->keyval == GDK_KEY_Shift_R) ||
2243 (event->keyval == GDK_Control_L) || 2251 (event->keyval == GDK_KEY_Control_L) ||
2244 (event->keyval == GDK_Control_R) || 2252 (event->keyval == GDK_KEY_Control_R) ||
2245 (event->keyval == GDK_Escape) || 2253 (event->keyval == GDK_KEY_Escape) ||
2246 (event->keyval == GDK_Up) || 2254 (event->keyval == GDK_KEY_Up) ||
2247 (event->keyval == GDK_Down) || 2255 (event->keyval == GDK_KEY_Down) ||
2248 (event->keyval == GDK_Left) || 2256 (event->keyval == GDK_KEY_Left) ||
2249 (event->keyval == GDK_Right) || 2257 (event->keyval == GDK_KEY_Right) ||
2250 (event->keyval == GDK_Page_Up) || 2258 (event->keyval == GDK_KEY_Page_Up) ||
2251 (event->keyval == GDK_KP_Page_Up) || 2259 (event->keyval == GDK_KEY_KP_Page_Up) ||
2252 (event->keyval == GDK_Page_Down) || 2260 (event->keyval == GDK_KEY_Page_Down) ||
2253 (event->keyval == GDK_KP_Page_Down) || 2261 (event->keyval == GDK_KEY_KP_Page_Down) ||
2254 (event->keyval == GDK_Home) || 2262 (event->keyval == GDK_KEY_Home) ||
2255 (event->keyval == GDK_End) || 2263 (event->keyval == GDK_KEY_End) ||
2256 (event->keyval == GDK_Tab) || 2264 (event->keyval == GDK_KEY_Tab) ||
2257 (event->keyval == GDK_KP_Tab) || 2265 (event->keyval == GDK_KEY_KP_Tab) ||
2258 (event->keyval == GDK_ISO_Left_Tab)) 2266 (event->keyval == GDK_KEY_ISO_Left_Tab))
2259 { 2267 {
2260 if (event->type == GDK_KEY_PRESS) 2268 if (event->type == GDK_KEY_PRESS)
2261 return conv_keypress_common(gtkconv, event); 2269 return conv_keypress_common(gtkconv, event);
2262 return FALSE; 2270 return FALSE;
2263 } 2271 }
2297 2305
2298 purple_conversation_close_logs(old_conv); 2306 purple_conversation_close_logs(old_conv);
2299 gtkconv->active_conv = conv; 2307 gtkconv->active_conv = conv;
2300 2308
2301 purple_conversation_set_logging(conv, 2309 purple_conversation_set_logging(conv,
2302 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging))); 2310 gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging)));
2303 2311
2304 entry = GTK_IMHTML(gtkconv->entry); 2312 entry = GTK_IMHTML(gtkconv->entry);
2305 protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv)); 2313 protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv));
2306 gtk_imhtml_set_protocol_name(entry, protocol_name); 2314 gtk_imhtml_set_protocol_name(entry, protocol_name);
2307 /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */ 2315 /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */
2486 2494
2487 /* Use the buddy icon, if possible */ 2495 /* Use the buddy icon, if possible */
2488 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 2496 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
2489 PurpleBuddy *b = purple_find_buddy(account, name); 2497 PurpleBuddy *b = purple_find_buddy(account, name);
2490 if (b != NULL) { 2498 if (b != NULL) {
2491 PurplePresence *p; 2499 PurplePresence *p = purple_buddy_get_presence(b);
2492 p = purple_buddy_get_presence(b);
2493 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY)) 2500 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY))
2494 return away_list; 2501 return away_list;
2495 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE)) 2502 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE))
2496 return busy_list; 2503 return busy_list;
2497 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY)) 2504 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY))
2723 2730
2724 return FALSE; 2731 return FALSE;
2725 } 2732 }
2726 2733
2727 static void 2734 static void
2728 start_anim(GtkObject *obj, PidginConversation *gtkconv) 2735 start_anim(GtkWidget *widget, PidginConversation *gtkconv)
2729 { 2736 {
2730 int delay; 2737 int delay;
2731 2738
2732 if (gtkconv->u.im->anim == NULL) 2739 if (gtkconv->u.im->anim == NULL)
2733 return; 2740 return;
2896 2903
2897 g_free(buf); 2904 g_free(buf);
2898 } 2905 }
2899 2906
2900 static void 2907 static void
2901 stop_anim(GtkObject *obj, PidginConversation *gtkconv) 2908 stop_anim(GtkWidget *widget, PidginConversation *gtkconv)
2902 { 2909 {
2903 if (gtkconv->u.im->icon_timer != 0) 2910 if (gtkconv->u.im->icon_timer != 0)
2904 g_source_remove(gtkconv->u.im->icon_timer); 2911 g_source_remove(gtkconv->u.im->icon_timer);
2905 2912
2906 gtkconv->u.im->icon_timer = 0; 2913 gtkconv->u.im->icon_timer = 0;
2918 else 2925 else
2919 stop_anim(NULL, gtkconv); 2926 stop_anim(NULL, gtkconv);
2920 } 2927 }
2921 2928
2922 static gboolean 2929 static gboolean
2923 icon_menu(GtkObject *obj, GdkEventButton *e, PidginConversation *gtkconv) 2930 icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
2924 { 2931 {
2925 static GtkWidget *menu = NULL; 2932 static GtkWidget *menu = NULL;
2926 PurpleConversation *conv; 2933 PurpleConversation *conv;
2927 PurpleBuddy *buddy; 2934 PurpleBuddy *buddy;
2928 2935
3112 { 3119 {
3113 g_return_val_if_fail(gtkconv != NULL, NULL); 3120 g_return_val_if_fail(gtkconv != NULL, NULL);
3114 return gtkconv->win; 3121 return gtkconv->win;
3115 } 3122 }
3116 3123
3124 #if 1
3125
3126 static GtkActionEntry menu_entries[] =
3127 /* TODO: fill out tooltips... */
3128 {
3129 /* Conversation menu */
3130 { "ConversationMenu", NULL, N_("_Conversation"), NULL, NULL, NULL },
3131 { "NewInstantMessage", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, N_("New Instant _Message..."), "<control>M", NULL, G_CALLBACK(menu_new_conv_cb) },
3132 { "Find", GTK_STOCK_FIND, N_("_Find..."), NULL, NULL, G_CALLBACK(menu_find_cb) },
3133 { "ViewLog", NULL, N_("View _Log"), NULL, NULL, G_CALLBACK(menu_view_log_cb) },
3134 { "SaveAs", GTK_STOCK_SAVE_AS, N_("_Save As..."), NULL, NULL, G_CALLBACK(menu_save_as_cb) },
3135 { "ClearScrollback", GTK_STOCK_CLEAR, N_("Clea_r Scrollback"), "<control>L", NULL, G_CALLBACK(menu_clear_cb) },
3136
3137 #ifdef USE_VV
3138 { "MediaMenu", NULL, N_("M_edia"), NULL, NULL, NULL },
3139 { "AudioCall", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL, N_("_Audio Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3140 { "VideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("_Video Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3141 { "AudioVideoCall", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL, N_("Audio/Video _Call"), NULL, NULL, G_CALLBACK(menu_initiate_media_call_cb) },
3142 #endif
3143
3144 { "SendFile", PIDGIN_STOCK_TOOLBAR_SEND_FILE, N_("Se_nd File..."), NULL, NULL, G_CALLBACK(menu_send_file_cb) },
3145 { "GetAttention", PIDGIN_STOCK_TOOLBAR_SEND_ATTENTION, N_("Get _Attention"), NULL, NULL, G_CALLBACK(menu_get_attention_cb) },
3146 { "AddBuddyPounce", NULL, N_("Add Buddy _Pounce..."), NULL, NULL, G_CALLBACK(menu_add_pounce_cb) },
3147 { "GetInfo", PIDGIN_STOCK_TOOLBAR_USER_INFO, N_("_Get Info"), "<control>O", NULL, G_CALLBACK(menu_get_info_cb) },
3148 { "Invite", NULL, N_("In_vite..."), NULL, NULL, G_CALLBACK(menu_invite_cb) },
3149 { "MoreMenu", NULL, N_("M_ore"), NULL, NULL, NULL },
3150 { "Alias", NULL, N_("Al_ias..."), NULL, NULL, G_CALLBACK(menu_alias_cb) },
3151 { "Block", PIDGIN_STOCK_TOOLBAR_BLOCK, N_("_Block..."), NULL, NULL, G_CALLBACK(menu_block_cb) },
3152 { "Unblock", PIDGIN_STOCK_TOOLBAR_UNBLOCK, N_("_Unblock..."), NULL, NULL, G_CALLBACK(menu_unblock_cb) },
3153 { "Add", GTK_STOCK_ADD, N_("_Add..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
3154 { "Remove", GTK_STOCK_REMOVE, N_("_Remove..."), NULL, NULL, G_CALLBACK(menu_add_remove_cb) },
3155 { "InsertLink", PIDGIN_STOCK_TOOLBAR_INSERT_LINK, N_("Insert Lin_k..."), NULL, NULL, G_CALLBACK(menu_insert_link_cb) },
3156 { "InsertImage", PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, N_("Insert Imag_e..."), NULL, NULL, G_CALLBACK(menu_insert_image_cb) },
3157 { "Close", GTK_STOCK_CLOSE, N_("_Close"), NULL, NULL, G_CALLBACK(menu_close_conv_cb) },
3158
3159 /* Options */
3160 { "OptionsMenu", NULL, N_("_Options"), NULL, NULL, NULL },
3161 };
3162
3163 /* Toggle items */
3164 static const GtkToggleActionEntry menu_toggle_entries[] = {
3165 { "EnableLogging", NULL, N_("Enable _Logging"), NULL, NULL, G_CALLBACK(menu_logging_cb), FALSE },
3166 { "EnableSounds", NULL, N_("Enable _Sounds"), NULL, NULL, G_CALLBACK(menu_sounds_cb), FALSE },
3167 { "ShowFormattingToolbars", NULL, N_("Show Formatting _Toolbars"), NULL, NULL, G_CALLBACK(menu_toolbar_cb), FALSE },
3168 { "ShowTimestamps", NULL, N_("Show Ti_mestamps"), NULL, NULL, G_CALLBACK(menu_timestamps_cb), FALSE },
3169 };
3170
3171 static const char *conversation_menu =
3172 "<ui>"
3173 "<menubar name='Conversation'>"
3174 "<menu action='ConversationMenu'>"
3175 "<menuitem action='NewInstantMessage'/>"
3176 "<separator/>"
3177 "<menuitem action='Find'/>"
3178 "<menuitem action='ViewLog'/>"
3179 "<menuitem action='SaveAs'/>"
3180 "<menuitem action='ClearScrollback'/>"
3181 "<separator/>"
3182 #ifdef USE_VV
3183 "<menu action='MediaMenu'>"
3184 "<menuitem action='AudioCall'/>"
3185 "<menuitem action='VideoCall'/>"
3186 "<menuitem action='AudioVideoCall'/>"
3187 "</menu>"
3188 #endif
3189 "<menuitem action='SendFile'/>"
3190 "<menuitem action='GetAttention'/>"
3191 "<menuitem action='AddBuddyPounce'/>"
3192 "<menuitem action='GetInfo'/>"
3193 "<menuitem action='Invite'/>"
3194 "<menu action='MoreMenu'/>"
3195 "<separator/>"
3196 "<menuitem action='Alias'/>"
3197 "<menuitem action='Block'/>"
3198 "<menuitem action='Unblock'/>"
3199 "<menuitem action='Add'/>"
3200 "<menuitem action='Remove'/>"
3201 "<separator/>"
3202 "<menuitem action='InsertLink'/>"
3203 "<menuitem action='InsertImage'/>"
3204 "<separator/>"
3205 "<menuitem action='Close'/>"
3206 "</menu>"
3207 "<menu action='OptionsMenu'>"
3208 "<menuitem action='EnableLogging'/>"
3209 "<menuitem action='EnableSounds'/>"
3210 "<separator/>"
3211 "<menuitem action='ShowFormattingToolbars'/>"
3212 "<menuitem action='ShowTimestamps'/>"
3213 "</menu>"
3214 "</menubar>"
3215 "</ui>";
3216
3217 #else
3218
3117 static GtkItemFactoryEntry menu_items[] = 3219 static GtkItemFactoryEntry menu_items[] =
3118 { 3220 {
3119 /* Conversation menu */ 3221 /* Conversation menu */
3120 { N_("/_Conversation"), NULL, NULL, 0, "<Branch>", NULL }, 3222 { N_("/_Conversation"), NULL, NULL, 0, "<Branch>", NULL },
3121 3223
3188 { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL }, 3290 { N_("/Options/Enable _Sounds"), NULL, menu_sounds_cb, 0, "<CheckItem>", NULL },
3189 { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL }, 3291 { "/Options/sep0", NULL, NULL, 0, "<Separator>", NULL },
3190 { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL }, 3292 { N_("/Options/Show Formatting _Toolbars"), NULL, menu_toolbar_cb, 0, "<CheckItem>", NULL },
3191 { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL }, 3293 { N_("/Options/Show Ti_mestamps"), NULL, menu_timestamps_cb, 0, "<CheckItem>", NULL },
3192 }; 3294 };
3193 3295 #endif
3194 static const int menu_item_count =
3195 sizeof(menu_items) / sizeof(*menu_items);
3196
3197 static const char *
3198 item_factory_translate_func (const char *path, gpointer func_data)
3199 {
3200 return _(path);
3201 }
3202 3296
3203 static void 3297 static void
3204 sound_method_pref_changed_cb(const char *name, PurplePrefType type, 3298 sound_method_pref_changed_cb(const char *name, PurplePrefType type,
3205 gconstpointer value, gpointer data) 3299 gconstpointer value, gpointer data)
3206 { 3300 {
3207 PidginWindow *win = data; 3301 PidginWindow *win = data;
3208 const char *method = value; 3302 const char *method = value;
3209 3303
3210 if (!strcmp(method, "none")) 3304 if (!strcmp(method, "none"))
3211 { 3305 {
3212 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3306 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3213 FALSE); 3307 FALSE);
3214 gtk_widget_set_sensitive(win->menu.sounds, FALSE); 3308 gtk_action_set_sensitive(win->menu.sounds, FALSE);
3215 } 3309 }
3216 else 3310 else
3217 { 3311 {
3218 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3312 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3219 3313
3220 if (gtkconv != NULL) 3314 if (gtkconv != NULL)
3221 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3315 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3222 gtkconv->make_sound); 3316 gtkconv->make_sound);
3223 gtk_widget_set_sensitive(win->menu.sounds, TRUE); 3317 gtk_action_set_sensitive(win->menu.sounds, TRUE);
3224
3225 } 3318 }
3226 } 3319 }
3227 3320
3228 /* Returns TRUE if some items were added to the menu, FALSE otherwise */ 3321 /* Returns TRUE if some items were added to the menu, FALSE otherwise */
3229 static gboolean 3322 static gboolean
3349 == PURPLE_CONV_TYPE_IM) { 3442 == PURPLE_CONV_TYPE_IM) {
3350 PurpleMediaCaps caps = 3443 PurpleMediaCaps caps =
3351 purple_prpl_get_media_caps(account, 3444 purple_prpl_get_media_caps(account,
3352 purple_conversation_get_name(conv)); 3445 purple_conversation_get_name(conv));
3353 3446
3354 gtk_widget_set_sensitive(win->audio_call, 3447 gtk_action_set_sensitive(win->audio_call,
3355 caps & PURPLE_MEDIA_CAPS_AUDIO 3448 caps & PURPLE_MEDIA_CAPS_AUDIO
3356 ? TRUE : FALSE); 3449 ? TRUE : FALSE);
3357 gtk_widget_set_sensitive(win->video_call, 3450 gtk_action_set_sensitive(win->video_call,
3358 caps & PURPLE_MEDIA_CAPS_VIDEO 3451 caps & PURPLE_MEDIA_CAPS_VIDEO
3359 ? TRUE : FALSE); 3452 ? TRUE : FALSE);
3360 gtk_widget_set_sensitive(win->audio_video_call, 3453 gtk_action_set_sensitive(win->audio_video_call,
3361 caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO 3454 caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO
3362 ? TRUE : FALSE); 3455 ? TRUE : FALSE);
3363 } else if (purple_conversation_get_type(conv) 3456 } else if (purple_conversation_get_type(conv)
3364 == PURPLE_CONV_TYPE_CHAT) { 3457 == PURPLE_CONV_TYPE_CHAT) {
3365 /* for now, don't care about chats... */ 3458 /* for now, don't care about chats... */
3366 gtk_widget_set_sensitive(win->audio_call, FALSE); 3459 gtk_action_set_sensitive(win->audio_call, FALSE);
3367 gtk_widget_set_sensitive(win->video_call, FALSE); 3460 gtk_action_set_sensitive(win->video_call, FALSE);
3368 gtk_widget_set_sensitive(win->audio_video_call, FALSE); 3461 gtk_action_set_sensitive(win->audio_video_call, FALSE);
3369 } else { 3462 } else {
3370 gtk_widget_set_sensitive(win->audio_call, FALSE); 3463 gtk_action_set_sensitive(win->audio_call, FALSE);
3371 gtk_widget_set_sensitive(win->video_call, FALSE); 3464 gtk_action_set_sensitive(win->video_call, FALSE);
3372 gtk_widget_set_sensitive(win->audio_video_call, FALSE); 3465 gtk_action_set_sensitive(win->audio_video_call, FALSE);
3373 } 3466 }
3374 #endif 3467 #endif
3375 } 3468 }
3376 3469
3377 static void 3470 static void
3432 regenerate_options_items(PidginWindow *win) 3525 regenerate_options_items(PidginWindow *win)
3433 { 3526 {
3434 GtkWidget *menu; 3527 GtkWidget *menu;
3435 PidginConversation *gtkconv; 3528 PidginConversation *gtkconv;
3436 GList *list; 3529 GList *list;
3437 3530 #if GTK_CHECK_VERSION(2,6,0)
3531 GtkWidget *more_menu;
3532
3533 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3534 more_menu = gtk_ui_manager_get_widget(win->menu.ui,
3535 "/Conversation/ConversationMenu/MoreMenu");
3536 gtk_widget_show(more_menu);
3537 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(more_menu));
3538 #else
3438 gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3539 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3439 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More")); 3540 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More"));
3541 #endif
3440 3542
3441 /* Remove the previous entries */ 3543 /* Remove the previous entries */
3442 for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; ) 3544 for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; )
3443 { 3545 {
3444 GtkWidget *w = list->data; 3546 GtkWidget *w = list->data;
3490 G_CALLBACK(remove_from_list), win); 3592 G_CALLBACK(remove_from_list), win);
3491 gtk_widget_destroy(action_items->data); 3593 gtk_widget_destroy(action_items->data);
3492 action_items = g_list_delete_link(action_items, action_items); 3594 action_items = g_list_delete_link(action_items, action_items);
3493 } 3595 }
3494 3596
3597 #if GTK_CHECK_VERSION(2,6,0)
3598 item = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/OptionsMenu");
3599 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(item));
3600 #else
3495 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options")); 3601 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options"));
3602 #endif
3496 3603
3497 list = purple_conversation_get_extended_menu(conv); 3604 list = purple_conversation_get_extended_menu(conv);
3498 if (list) { 3605 if (list) {
3499 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu))); 3606 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu)));
3500 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); 3607 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win);
3527 static void 3634 static void
3528 focus_out_from_menubar(GtkWidget *wid, PidginWindow *win) 3635 focus_out_from_menubar(GtkWidget *wid, PidginWindow *win)
3529 { 3636 {
3530 /* The menubar has been deactivated. Make sure the 'More' submenu is regenerated next time 3637 /* The menubar has been deactivated. Make sure the 'More' submenu is regenerated next time
3531 * the 'Conversation' menu pops up. */ 3638 * the 'Conversation' menu pops up. */
3532 GtkWidget *menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation")); 3639 GtkWidget *menuitem = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/ConversationMenu");
3533 g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), G_CALLBACK(menubar_activated), win); 3640 g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), G_CALLBACK(menubar_activated), win);
3534 g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar), 3641 g_signal_handlers_disconnect_by_func(G_OBJECT(win->menu.menubar),
3535 G_CALLBACK(focus_out_from_menubar), win); 3642 G_CALLBACK(focus_out_from_menubar), win);
3536 } 3643 }
3537 3644
3538 static GtkWidget * 3645 static GtkWidget *
3539 setup_menubar(PidginWindow *win) 3646 setup_menubar(PidginWindow *win)
3540 { 3647 {
3541 GtkAccelGroup *accel_group; 3648 GtkAccelGroup *accel_group;
3542 const char *method; 3649 const char *method;
3650 GtkActionGroup *action_group;
3651 GError *error;
3543 GtkWidget *menuitem; 3652 GtkWidget *menuitem;
3544 3653
3545 accel_group = gtk_accel_group_new (); 3654 action_group = gtk_action_group_new("ConversationActions");
3655 gtk_action_group_add_actions(action_group,
3656 menu_entries,
3657 G_N_ELEMENTS(menu_entries),
3658 win);
3659 gtk_action_group_add_toggle_actions(action_group,
3660 menu_toggle_entries,
3661 G_N_ELEMENTS(menu_toggle_entries),
3662 win);
3663 #ifdef ENABLE_NLS
3664 gtk_action_group_set_translation_domain(action_group,
3665 PACKAGE);
3666 #endif
3667
3668 win->menu.ui = gtk_ui_manager_new();
3669 gtk_ui_manager_insert_action_group(win->menu.ui, action_group, 0);
3670
3671 accel_group = gtk_ui_manager_get_accel_group(win->menu.ui);
3546 gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group); 3672 gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group);
3547 g_object_unref(accel_group);
3548
3549 win->menu.item_factory =
3550 gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
3551
3552 gtk_item_factory_set_translate_func(win->menu.item_factory,
3553 (GtkTranslateFunc)item_factory_translate_func,
3554 NULL, NULL);
3555
3556 gtk_item_factory_create_items(win->menu.item_factory, menu_item_count,
3557 menu_items, win);
3558 g_signal_connect(G_OBJECT(accel_group), "accel-changed", 3673 g_signal_connect(G_OBJECT(accel_group), "accel-changed",
3559 G_CALLBACK(pidgin_save_accels_cb), NULL); 3674 G_CALLBACK(pidgin_save_accels_cb), NULL);
3560 3675
3561 /* Make sure the 'Conversation -> More' menuitems are regenerated whenever 3676 error = NULL;
3562 * the 'Conversation' menu pops up because the entries can change after the 3677 if (!gtk_ui_manager_add_ui_from_string(win->menu.ui, conversation_menu, -1, &error))
3563 * conversation is created. */ 3678 {
3564 menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation")); 3679 g_message("building menus failed: %s", error->message);
3680 g_error_free(error);
3681 exit(EXIT_FAILURE);
3682 }
3683
3684 win->menu.menubar =
3685 gtk_ui_manager_get_widget(win->menu.ui, "/Conversation");
3686
3687 menuitem = gtk_ui_manager_get_widget(win->menu.ui, "/Conversation/ConversationMenu");
3565 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win); 3688 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win);
3566 3689
3567 win->menu.menubar =
3568 gtk_item_factory_get_widget(win->menu.item_factory, "<main>");
3569
3570 win->menu.view_log = 3690 win->menu.view_log =
3571 gtk_item_factory_get_widget(win->menu.item_factory, 3691 gtk_ui_manager_get_action(win->menu.ui,
3572 N_("/Conversation/View Log")); 3692 "/Conversation/ConversationMenu/ViewLog");
3573 3693
3574 #ifdef USE_VV 3694 #ifdef USE_VV
3575 win->audio_call = 3695 win->audio_call =
3576 gtk_item_factory_get_widget(win->menu.item_factory, 3696 gtk_ui_manager_get_action(win->menu.ui,
3577 N_("/Conversation/Media/Audio Call")); 3697 "/Conversation/ConversationMenu/MediaMenu/AudioCall");
3578 win->video_call = 3698 win->video_call =
3579 gtk_item_factory_get_widget(win->menu.item_factory, 3699 gtk_ui_manager_get_action(win->menu.ui,
3580 N_("/Conversation/Media/Video Call")); 3700 "/Conversation/ConversationMenu/MediaMenu/VideoCall");
3581 win->audio_video_call = 3701 win->audio_video_call =
3582 gtk_item_factory_get_widget(win->menu.item_factory, 3702 gtk_ui_manager_get_action(win->menu.ui,
3583 N_("/Conversation/Media/Audio\\/Video Call")); 3703 "/Conversation/ConversationMenu/MediaMenu/AudioVideoCall");
3584 #endif 3704 #endif
3585 3705
3586 /* --- */ 3706 /* --- */
3587 3707
3588 win->menu.send_file = 3708 win->menu.send_file =
3589 gtk_item_factory_get_widget(win->menu.item_factory, 3709 gtk_ui_manager_get_action(win->menu.ui,
3590 N_("/Conversation/Send File...")); 3710 "/Conversation/ConversationMenu/SendFile");
3591 3711
3592 win->menu.get_attention = 3712 win->menu.get_attention =
3593 gtk_item_factory_get_widget(win->menu.item_factory, 3713 gtk_ui_manager_get_action(win->menu.ui,
3594 N_("/Conversation/Get Attention")); 3714 "/Conversation/ConversationMenu/GetAttention");
3595 3715
3596 win->menu.add_pounce = 3716 win->menu.add_pounce =
3597 gtk_item_factory_get_widget(win->menu.item_factory, 3717 gtk_ui_manager_get_action(win->menu.ui,
3598 N_("/Conversation/Add Buddy Pounce...")); 3718 "/Conversation/ConversationMenu/AddBuddyPounce");
3599 3719
3600 /* --- */ 3720 /* --- */
3601 3721
3602 win->menu.get_info = 3722 win->menu.get_info =
3603 gtk_item_factory_get_widget(win->menu.item_factory, 3723 gtk_ui_manager_get_action(win->menu.ui,
3604 N_("/Conversation/Get Info")); 3724 "/Conversation/ConversationMenu/GetInfo");
3605 3725
3606 win->menu.invite = 3726 win->menu.invite =
3607 gtk_item_factory_get_widget(win->menu.item_factory, 3727 gtk_ui_manager_get_action(win->menu.ui,
3608 N_("/Conversation/Invite...")); 3728 "/Conversation/ConversationMenu/Invite");
3609 3729
3610 /* --- */ 3730 /* --- */
3611 3731
3612 win->menu.alias = 3732 win->menu.alias =
3613 gtk_item_factory_get_widget(win->menu.item_factory, 3733 gtk_ui_manager_get_action(win->menu.ui,
3614 N_("/Conversation/Alias...")); 3734 "/Conversation/ConversationMenu/Alias");
3615 3735
3616 win->menu.block = 3736 win->menu.block =
3617 gtk_item_factory_get_widget(win->menu.item_factory, 3737 gtk_ui_manager_get_action(win->menu.ui,
3618 N_("/Conversation/Block...")); 3738 "/Conversation/ConversationMenu/Block");
3619 3739
3620 win->menu.unblock = 3740 win->menu.unblock =
3621 gtk_item_factory_get_widget(win->menu.item_factory, 3741 gtk_ui_manager_get_action(win->menu.ui,
3622 N_("/Conversation/Unblock...")); 3742 "/Conversation/ConversationMenu/Unblock");
3623 3743
3624 win->menu.add = 3744 win->menu.add =
3625 gtk_item_factory_get_widget(win->menu.item_factory, 3745 gtk_ui_manager_get_action(win->menu.ui,
3626 N_("/Conversation/Add...")); 3746 "/Conversation/ConversationMenu/Add");
3627 3747
3628 win->menu.remove = 3748 win->menu.remove =
3629 gtk_item_factory_get_widget(win->menu.item_factory, 3749 gtk_ui_manager_get_action(win->menu.ui,
3630 N_("/Conversation/Remove...")); 3750 "/Conversation/ConversationMenu/Remove");
3631 3751
3632 /* --- */ 3752 /* --- */
3633 3753
3634 win->menu.insert_link = 3754 win->menu.insert_link =
3635 gtk_item_factory_get_widget(win->menu.item_factory, 3755 gtk_ui_manager_get_action(win->menu.ui,
3636 N_("/Conversation/Insert Link...")); 3756 "/Conversation/ConversationMenu/InsertLink");
3637 3757
3638 win->menu.insert_image = 3758 win->menu.insert_image =
3639 gtk_item_factory_get_widget(win->menu.item_factory, 3759 gtk_ui_manager_get_action(win->menu.ui,
3640 N_("/Conversation/Insert Image...")); 3760 "/Conversation/ConversationMenu/InsertImage");
3641 3761
3642 /* --- */ 3762 /* --- */
3643 3763
3644 win->menu.logging = 3764 win->menu.logging =
3645 gtk_item_factory_get_widget(win->menu.item_factory, 3765 gtk_ui_manager_get_action(win->menu.ui,
3646 N_("/Options/Enable Logging")); 3766 "/Conversation/OptionsMenu/EnableLogging");
3647 win->menu.sounds = 3767 win->menu.sounds =
3648 gtk_item_factory_get_widget(win->menu.item_factory, 3768 gtk_ui_manager_get_action(win->menu.ui,
3649 N_("/Options/Enable Sounds")); 3769 "/Conversation/OptionsMenu/EnableSounds");
3650 method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); 3770 method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
3651 if (method != NULL && !strcmp(method, "none")) 3771 if (method != NULL && !strcmp(method, "none"))
3652 { 3772 {
3653 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 3773 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
3654 FALSE); 3774 FALSE);
3655 gtk_widget_set_sensitive(win->menu.sounds, FALSE); 3775 gtk_action_set_sensitive(win->menu.sounds, FALSE);
3656 } 3776 }
3657 purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method", 3777 purple_prefs_connect_callback(win, PIDGIN_PREFS_ROOT "/sound/method",
3658 sound_method_pref_changed_cb, win); 3778 sound_method_pref_changed_cb, win);
3659 3779
3660 win->menu.show_formatting_toolbar = 3780 win->menu.show_formatting_toolbar =
3661 gtk_item_factory_get_widget(win->menu.item_factory, 3781 gtk_ui_manager_get_action(win->menu.ui,
3662 N_("/Options/Show Formatting Toolbars")); 3782 "/Conversation/OptionsMenu/ShowFormattingToolbars");
3663 win->menu.show_timestamps = 3783 win->menu.show_timestamps =
3664 gtk_item_factory_get_widget(win->menu.item_factory, 3784 gtk_ui_manager_get_action(win->menu.ui,
3665 N_("/Options/Show Timestamps")); 3785 "/Conversation/OptionsMenu/ShowTimestamps");
3666 win->menu.show_icon = NULL; 3786 win->menu.show_icon = NULL;
3667 3787
3668 win->menu.tray = pidgin_menu_tray_new(); 3788 win->menu.tray = pidgin_menu_tray_new();
3669 gtk_menu_shell_append(GTK_MENU_SHELL(win->menu.menubar), 3789 gtk_menu_shell_append(GTK_MENU_SHELL(win->menu.menubar),
3670 win->menu.tray); 3790 win->menu.tray);
3735 case 4: 3855 case 4:
3736 stock_id = PIDGIN_STOCK_ANIMATION_TYPING4; 3856 stock_id = PIDGIN_STOCK_ANIMATION_TYPING4;
3737 break; 3857 break;
3738 } 3858 }
3739 if (gtkwin->menu.typing_icon == NULL) { 3859 if (gtkwin->menu.typing_icon == NULL) {
3740 gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU); 3860 gtkwin->menu.typing_icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_MENU);
3741 pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray), 3861 pidgin_menu_tray_append(PIDGIN_MENU_TRAY(gtkwin->menu.tray),
3742 gtkwin->menu.typing_icon, 3862 gtkwin->menu.typing_icon,
3743 _("User is typing...")); 3863 _("User is typing..."));
3744 } else { 3864 } else {
3745 gtk_image_set_from_stock(GTK_IMAGE(gtkwin->menu.typing_icon), stock_id, GTK_ICON_SIZE_MENU); 3865 gtk_image_set_from_stock(GTK_IMAGE(gtkwin->menu.typing_icon), stock_id, GTK_ICON_SIZE_MENU);
3746 } 3866 }
3747 gtk_widget_show(gtkwin->menu.typing_icon); 3867 gtk_widget_show(gtkwin->menu.typing_icon);
3748 return TRUE; 3868 return TRUE;
3844 return FALSE; 3964 return FALSE;
3845 3965
3846 if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv)))) 3966 if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv))))
3847 return FALSE; 3967 return FALSE;
3848 3968
3849 3969 #if 0 /* TODO */
3850 gtk_widget_show(win->menu.send_to); 3970 gtk_widget_show(win->menu.send_to);
3851 3971
3852 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to)); 3972 menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(win->menu.send_to));
3853 3973
3854 for (child = gtk_container_get_children(GTK_CONTAINER(menu)); 3974 for (child = gtk_container_get_children(GTK_CONTAINER(menu));
3866 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); 3986 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
3867 g_list_free(child); 3987 g_list_free(child);
3868 break; 3988 break;
3869 } 3989 }
3870 } 3990 }
3991 #endif
3871 3992
3872 return FALSE; 3993 return FALSE;
3873 } 3994 }
3874 3995
3875 static gboolean 3996 static gboolean
3975 } 4096 }
3976 4097
3977 static void 4098 static void
3978 generate_send_to_items(PidginWindow *win) 4099 generate_send_to_items(PidginWindow *win)
3979 { 4100 {
4101 #if 0 /* TODO */
3980 GtkWidget *menu; 4102 GtkWidget *menu;
3981 GSList *group = NULL; 4103 GSList *group = NULL;
3982 GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 4104 GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3983 PidginConversation *gtkconv; 4105 PidginConversation *gtkconv;
3984 GSList *l, *buds; 4106 GSList *l, *buds;
4060 gtk_widget_show(win->menu.send_to); 4182 gtk_widget_show(win->menu.send_to);
4061 /* TODO: This should never be insensitive. Possibly hidden or not. */ 4183 /* TODO: This should never be insensitive. Possibly hidden or not. */
4062 if (!group) 4184 if (!group)
4063 gtk_widget_set_sensitive(win->menu.send_to, FALSE); 4185 gtk_widget_set_sensitive(win->menu.send_to, FALSE);
4064 update_send_to_selection(win); 4186 update_send_to_selection(win);
4187 #endif
4065 } 4188 }
4066 4189
4067 static const char * 4190 static const char *
4068 get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvChatBuddyFlags flags) 4191 get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvChatBuddyFlags flags)
4069 { 4192 {
4712 GtkTextIter iter; 4835 GtkTextIter iter;
4713 int lines; 4836 int lines;
4714 GdkRectangle oneline; 4837 GdkRectangle oneline;
4715 int height, diff; 4838 int height, diff;
4716 int pad_top, pad_inside, pad_bottom; 4839 int pad_top, pad_inside, pad_bottom;
4717 int total_height = (gtkconv->webview->allocation.height + gtkconv->entry->allocation.height); 4840 int total_height;
4718 int max_height = total_height / 2; 4841 int max_height;
4719 int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines"); 4842 int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines");
4720 int min_height; 4843 int min_height;
4721 gboolean interior_focus; 4844 gboolean interior_focus;
4722 int focus_width; 4845 int focus_width;
4846 GtkAllocation webview_allocation;
4847 GtkAllocation entry_allocation;
4848 GtkAllocation lower_hbox_allocation;
4849
4850 gtk_widget_get_allocation(gtkconv->webview, &webview_allocation);
4851 gtk_widget_get_allocation(gtkconv->entry, &entry_allocation);
4852 gtk_widget_get_allocation(gtkconv->lower_hbox, &lower_hbox_allocation);
4853 total_height = webview_allocation.height + entry_allocation.height;
4854 max_height = total_height / 2;
4723 4855
4724 pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry)); 4856 pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry));
4725 pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry)); 4857 pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry));
4726 pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry)); 4858 pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry));
4727 4859
4751 "focus-line-width", &focus_width, 4883 "focus-line-width", &focus_width,
4752 NULL); 4884 NULL);
4753 if (!interior_focus) 4885 if (!interior_focus)
4754 height += 2 * focus_width; 4886 height += 2 * focus_width;
4755 4887
4756 diff = height - gtkconv->entry->allocation.height; 4888 diff = height - entry_allocation.height;
4757 if (ABS(diff) < oneline.height / 2) 4889 if (ABS(diff) < oneline.height / 2)
4758 return FALSE; 4890 return FALSE;
4759 4891
4892 purple_debug_info("pidgin", "resizing to %d, %d lines, diff %d\n",
4893 diff + lower_hbox_allocation.height, min_lines, diff);
4894
4760 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, 4895 gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
4761 diff + gtkconv->lower_hbox->allocation.height); 4896 diff + lower_hbox_allocation.height);
4762 4897
4763 return FALSE; 4898 return FALSE;
4764 } 4899 }
4765 4900
4766 static void 4901 static void
4803 gtk_widget_set_size_request(gtkchat->topic_text, -1, BUDDYICON_SIZE_MIN); 4938 gtk_widget_set_size_request(gtkchat->topic_text, -1, BUDDYICON_SIZE_MIN);
4804 4939
4805 if(prpl_info->set_chat_topic == NULL) { 4940 if(prpl_info->set_chat_topic == NULL) {
4806 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE); 4941 gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE);
4807 } else { 4942 } else {
4808 g_signal_connect(GTK_OBJECT(gtkchat->topic_text), "activate", 4943 g_signal_connect(GTK_WIDGET(gtkchat->topic_text), "activate",
4809 G_CALLBACK(topic_callback), gtkconv); 4944 G_CALLBACK(topic_callback), gtkconv);
4810 } 4945 }
4811 4946
4812 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); 4947 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0);
4813 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", 4948 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event",
4974 pidgin_conv_end_quickfind(PidginConversation *gtkconv) 5109 pidgin_conv_end_quickfind(PidginConversation *gtkconv)
4975 { 5110 {
4976 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); 5111 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
4977 5112
4978 webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview)); 5113 webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview));
4979 gtk_widget_hide_all(gtkconv->quickfind.container); 5114 gtk_widget_hide(gtkconv->quickfind.container);
4980 5115
4981 gtk_widget_grab_focus(gtkconv->entry); 5116 gtk_widget_grab_focus(gtkconv->entry);
4982 return TRUE; 5117 return TRUE;
4983 } 5118 }
4984 5119
4985 static gboolean 5120 static gboolean
4986 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv) 5121 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv)
4987 { 5122 {
4988 switch (event->keyval) { 5123 switch (event->keyval) {
4989 case GDK_Return: 5124 case GDK_KEY_Return:
4990 case GDK_KP_Enter: 5125 case GDK_KEY_KP_Enter:
4991 if (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) { 5126 if (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) {
4992 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); 5127 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL);
4993 } else { 5128 } else {
4994 GdkColor col; 5129 GdkColor col;
4995 col.red = 0xffff; 5130 col.red = 0xffff;
4996 col.green = 0xafff; 5131 col.green = 0xafff;
4997 col.blue = 0xafff; 5132 col.blue = 0xafff;
4998 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col); 5133 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, &col);
4999 } 5134 }
5000 break; 5135 break;
5001 case GDK_Escape: 5136 case GDK_KEY_Escape:
5002 pidgin_conv_end_quickfind(gtkconv); 5137 pidgin_conv_end_quickfind(gtkconv);
5003 break; 5138 break;
5004 default: 5139 default:
5005 return FALSE; 5140 return FALSE;
5006 } 5141 }
5015 5150
5016 gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0); 5151 gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0);
5017 5152
5018 close = pidgin_create_small_button(gtk_label_new("×")); 5153 close = pidgin_create_small_button(gtk_label_new("×"));
5019 gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0); 5154 gtk_box_pack_start(GTK_BOX(widget), close, FALSE, FALSE, 0);
5155 #if GTK_CHECK_VERSION(2,12,0)
5156 gtk_widget_set_tooltip_text(close, _("Close Find bar"));
5157 #else
5020 gtk_tooltips_set_tip(gtkconv->tooltips, close, 5158 gtk_tooltips_set_tip(gtkconv->tooltips, close,
5021 _("Close Find bar"), NULL); 5159 _("Close Find bar"), NULL);
5160 #endif
5022 5161
5023 label = gtk_label_new(_("Find:")); 5162 label = gtk_label_new(_("Find:"));
5024 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10); 5163 gtk_box_pack_start(GTK_BOX(widget), label, FALSE, FALSE, 10);
5025 5164
5026 entry = gtk_entry_new(); 5165 entry = gtk_entry_new();
5449 PidginWindow *win = gtkconv->win; 5588 PidginWindow *win = gtkconv->win;
5450 PurpleConversation *c; 5589 PurpleConversation *c;
5451 PurpleAccount *convaccount = purple_conversation_get_account(conv); 5590 PurpleAccount *convaccount = purple_conversation_get_account(conv);
5452 PurpleConnection *gc = purple_account_get_connection(convaccount); 5591 PurpleConnection *gc = purple_account_get_connection(convaccount);
5453 PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL; 5592 PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL;
5454 5593 GdkAtom target = gtk_selection_data_get_target(sd);
5455 if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) 5594 const guchar *data = gtk_selection_data_get_data(sd);
5595
5596 if (target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
5456 { 5597 {
5457 PurpleBlistNode *n = NULL; 5598 PurpleBlistNode *n = NULL;
5458 PurpleBuddy *b; 5599 PurpleBuddy *b;
5459 PidginConversation *gtkconv = NULL; 5600 PidginConversation *gtkconv = NULL;
5460 PurpleAccount *buddyaccount; 5601 PurpleAccount *buddyaccount;
5461 const char *buddyname; 5602 const char *buddyname;
5462 5603
5463 n = *(PurpleBlistNode **)sd->data; 5604 n = *(PurpleBlistNode **) data;
5464 5605
5465 if (PURPLE_BLIST_NODE_IS_CONTACT(n)) 5606 if (PURPLE_BLIST_NODE_IS_CONTACT(n))
5466 b = purple_contact_get_priority_buddy((PurpleContact*)n); 5607 b = purple_contact_get_priority_buddy((PurpleContact*)n);
5467 else if (PURPLE_BLIST_NODE_IS_BUDDY(n)) 5608 else if (PURPLE_BLIST_NODE_IS_BUDDY(n))
5468 b = (PurpleBuddy*)n; 5609 b = (PurpleBuddy*)n;
5506 5647
5507 /* Make this conversation the active conversation */ 5648 /* Make this conversation the active conversation */
5508 pidgin_conv_window_switch_gtkconv(win, gtkconv); 5649 pidgin_conv_window_switch_gtkconv(win, gtkconv);
5509 } 5650 }
5510 5651
5511 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); 5652 gtk_drag_finish(dc, TRUE,
5512 } 5653 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
5513 else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE)) 5654 }
5655 else if (target == gdk_atom_intern("application/x-im-contact", FALSE))
5514 { 5656 {
5515 char *protocol = NULL; 5657 char *protocol = NULL;
5516 char *username = NULL; 5658 char *username = NULL;
5517 PurpleAccount *account; 5659 PurpleAccount *account;
5518 PidginConversation *gtkconv; 5660 PidginConversation *gtkconv;
5519 5661
5520 if (pidgin_parse_x_im_contact((const char *)sd->data, FALSE, &account, 5662 if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
5521 &protocol, &username, NULL)) 5663 &protocol, &username, NULL))
5522 { 5664 {
5523 if (account == NULL) 5665 if (account == NULL)
5524 { 5666 {
5525 purple_notify_error(win, NULL, 5667 purple_notify_error(win, NULL,
5546 } 5688 }
5547 5689
5548 g_free(username); 5690 g_free(username);
5549 g_free(protocol); 5691 g_free(protocol);
5550 5692
5551 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); 5693 gtk_drag_finish(dc, TRUE,
5552 } 5694 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
5553 else if (sd->target == gdk_atom_intern("text/uri-list", FALSE)) { 5695 }
5696 else if (target == gdk_atom_intern("text/uri-list", FALSE)) {
5554 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 5697 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
5555 pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv)); 5698 pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv));
5556 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); 5699 gtk_drag_finish(dc, TRUE,
5700 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
5557 } 5701 }
5558 else 5702 else
5559 gtk_drag_finish(dc, FALSE, FALSE, t); 5703 gtk_drag_finish(dc, FALSE, FALSE, t);
5560 } 5704 }
5561 5705
5689 gtkconv->active_conv = conv; 5833 gtkconv->active_conv = conv;
5690 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); 5834 gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
5691 gtkconv->send_history = g_list_append(NULL, NULL); 5835 gtkconv->send_history = g_list_append(NULL, NULL);
5692 5836
5693 /* Setup some initial variables. */ 5837 /* Setup some initial variables. */
5838 #if !GTK_CHECK_VERSION(2,12,0)
5694 gtkconv->tooltips = gtk_tooltips_new(); 5839 gtkconv->tooltips = gtk_tooltips_new();
5840 #endif
5695 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; 5841 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
5696 gtkconv->unseen_count = 0; 5842 gtkconv->unseen_count = 0;
5697 theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation"); 5843 theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation");
5698 if (!theme) 5844 if (!theme)
5699 theme = purple_theme_manager_find_theme("Default", "conversation"); 5845 theme = purple_theme_manager_find_theme("Default", "conversation");
5888 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 6034 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
5889 purple_signals_disconnect_by_handle(gtkconv->u.chat); 6035 purple_signals_disconnect_by_handle(gtkconv->u.chat);
5890 g_free(gtkconv->u.chat); 6036 g_free(gtkconv->u.chat);
5891 } 6037 }
5892 6038
6039 #if !GTK_CHECK_VERSION(2,12,0)
5893 gtk_object_sink(GTK_OBJECT(gtkconv->tooltips)); 6040 gtk_object_sink(GTK_OBJECT(gtkconv->tooltips));
6041 #endif
5894 6042
5895 gtkconv->send_history = g_list_first(gtkconv->send_history); 6043 gtkconv->send_history = g_list_first(gtkconv->send_history);
5896 g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL); 6044 g_list_foreach(gtkconv->send_history, (GFunc)g_free, NULL);
5897 g_list_free(gtkconv->send_history); 6045 g_list_free(gtkconv->send_history);
5898 6046
5957 if (event->type == GDK_BUTTON_PRESS 6105 if (event->type == GDK_BUTTON_PRESS
5958 || event->type == GDK_2BUTTON_PRESS) { 6106 || event->type == GDK_2BUTTON_PRESS) {
5959 GdkEventButton *btn_event = (GdkEventButton*) event; 6107 GdkEventButton *btn_event = (GdkEventButton*) event;
5960 PurpleConversation *conv = data; 6108 PurpleConversation *conv = data;
5961 char *buddyname; 6109 char *buddyname;
6110 gchar *name;
6111
6112 g_object_get(G_OBJECT(tag), "name", &name, NULL);
5962 6113
5963 /* strlen("BUDDY " or "HILIT ") == 6 */ 6114 /* strlen("BUDDY " or "HILIT ") == 6 */
5964 g_return_val_if_fail((tag->name != NULL) 6115 g_return_val_if_fail((name != NULL) && (strlen(name) > 6), FALSE);
5965 && (strlen(tag->name) > 6), FALSE); 6116
5966 6117 buddyname = name + 6;
5967 buddyname = (tag->name) + 6;
5968 6118
5969 /* emit chat-nick-clicked signal */ 6119 /* emit chat-nick-clicked signal */
5970 if (event->type == GDK_BUTTON_PRESS) { 6120 if (event->type == GDK_BUTTON_PRESS) {
5971 gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1( 6121 gint plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
5972 pidgin_conversations_get_handle(), "chat-nick-clicked", 6122 pidgin_conversations_get_handle(), "chat-nick-clicked",
5973 data, buddyname, btn_event->button)); 6123 data, buddyname, btn_event->button));
5974 if (plugin_return) 6124 if (plugin_return) {
6125 g_free(name);
5975 return TRUE; 6126 return TRUE;
5976 } 6127 }
5977 6128 }
5978 if (btn_event->button == 1 && 6129
5979 event->type == GDK_2BUTTON_PRESS) { 6130 if (btn_event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
5980 chat_do_im(PIDGIN_CONVERSATION(conv), buddyname); 6131 chat_do_im(PIDGIN_CONVERSATION(conv), buddyname);
6132 g_free(name);
6133
5981 return TRUE; 6134 return TRUE;
5982 } else if (btn_event->button == 2 6135 } else if (btn_event->button == 2 && event->type == GDK_2BUTTON_PRESS) {
5983 && event->type == GDK_2BUTTON_PRESS) {
5984 chat_do_info(PIDGIN_CONVERSATION(conv), buddyname); 6136 chat_do_info(PIDGIN_CONVERSATION(conv), buddyname);
6137 g_free(name);
5985 6138
5986 return TRUE; 6139 return TRUE;
5987 } else if (btn_event->button == 3 6140 } else if (btn_event->button == 3 && event->type == GDK_BUTTON_PRESS) {
5988 && event->type == GDK_BUTTON_PRESS) {
5989 GtkTextIter start, end; 6141 GtkTextIter start, end;
5990 6142
5991 /* we shouldn't display the popup 6143 /* we shouldn't display the popup
5992 * if the user has selected something: */ 6144 * if the user has selected something: */
5993 if (!gtk_text_buffer_get_selection_bounds( 6145 if (!gtk_text_buffer_get_selection_bounds(
6002 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, 6154 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
6003 NULL, GTK_WIDGET(imhtml), 6155 NULL, GTK_WIDGET(imhtml),
6004 btn_event->button, 6156 btn_event->button,
6005 btn_event->time); 6157 btn_event->time);
6006 6158
6159 g_free(name);
6160
6007 /* Don't propagate the event any further */ 6161 /* Don't propagate the event any further */
6008 return TRUE; 6162 return TRUE;
6009 } 6163 }
6010 } 6164 }
6165
6166 g_free(name);
6011 } 6167 }
6012 6168
6013 return FALSE; 6169 return FALSE;
6014 } 6170 }
6015 #endif 6171 #endif
7003 */ 7159 */
7004 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 7160 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
7005 /* Show stuff that applies to IMs, hide stuff that applies to chats */ 7161 /* Show stuff that applies to IMs, hide stuff that applies to chats */
7006 7162
7007 /* Deal with menu items */ 7163 /* Deal with menu items */
7008 gtk_widget_show(win->menu.view_log); 7164 gtk_action_set_visible(win->menu.view_log, TRUE);
7009 gtk_widget_show(win->menu.send_file); 7165 gtk_action_set_visible(win->menu.send_file, TRUE);
7010 gtk_widget_show(win->menu.get_attention); 7166 gtk_action_set_visible(win->menu.get_attention, TRUE);
7011 gtk_widget_show(win->menu.add_pounce); 7167 gtk_action_set_visible(win->menu.add_pounce, TRUE);
7012 gtk_widget_show(win->menu.get_info); 7168 gtk_action_set_visible(win->menu.get_info, TRUE);
7013 gtk_widget_hide(win->menu.invite); 7169 gtk_action_set_visible(win->menu.invite, FALSE);
7014 gtk_widget_show(win->menu.alias); 7170 gtk_action_set_visible(win->menu.alias, TRUE);
7015 if (purple_privacy_check(account, purple_conversation_get_name(conv))) { 7171 if (purple_privacy_check(account, purple_conversation_get_name(conv))) {
7016 gtk_widget_hide(win->menu.unblock); 7172 gtk_action_set_visible(win->menu.unblock, FALSE);
7017 gtk_widget_show(win->menu.block); 7173 gtk_action_set_visible(win->menu.block, TRUE);
7018 } else { 7174 } else {
7019 gtk_widget_hide(win->menu.block); 7175 gtk_action_set_visible(win->menu.block, FALSE);
7020 gtk_widget_show(win->menu.unblock); 7176 gtk_action_set_visible(win->menu.unblock, TRUE);
7021 } 7177 }
7022 7178
7023 if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) { 7179 if ((account == NULL) || purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
7024 gtk_widget_show(win->menu.add); 7180 gtk_action_set_visible(win->menu.add, TRUE);
7025 gtk_widget_hide(win->menu.remove); 7181 gtk_action_set_visible(win->menu.remove, FALSE);
7026 } else { 7182 } else {
7027 gtk_widget_show(win->menu.remove); 7183 gtk_action_set_visible(win->menu.remove, TRUE);
7028 gtk_widget_hide(win->menu.add); 7184 gtk_action_set_visible(win->menu.add, FALSE);
7029 } 7185 }
7030 7186
7031 gtk_widget_show(win->menu.insert_link); 7187 gtk_action_set_visible(win->menu.insert_link, TRUE);
7032 gtk_widget_show(win->menu.insert_image); 7188 gtk_action_set_visible(win->menu.insert_image, TRUE);
7033 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 7189 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
7034 /* Show stuff that applies to Chats, hide stuff that applies to IMs */ 7190 /* Show stuff that applies to Chats, hide stuff that applies to IMs */
7035 7191
7036 /* Deal with menu items */ 7192 /* Deal with menu items */
7037 gtk_widget_show(win->menu.view_log); 7193 gtk_action_set_visible(win->menu.view_log, TRUE);
7038 gtk_widget_hide(win->menu.send_file); 7194 gtk_action_set_visible(win->menu.send_file, FALSE);
7039 gtk_widget_hide(win->menu.get_attention); 7195 gtk_action_set_visible(win->menu.get_attention, FALSE);
7040 gtk_widget_hide(win->menu.add_pounce); 7196 gtk_action_set_visible(win->menu.add_pounce, FALSE);
7041 gtk_widget_hide(win->menu.get_info); 7197 gtk_action_set_visible(win->menu.get_info, FALSE);
7042 gtk_widget_show(win->menu.invite); 7198 gtk_action_set_visible(win->menu.invite, TRUE);
7043 gtk_widget_show(win->menu.alias); 7199 gtk_action_set_visible(win->menu.alias, TRUE);
7044 gtk_widget_hide(win->menu.block); 7200 gtk_action_set_visible(win->menu.block, FALSE);
7045 gtk_widget_hide(win->menu.unblock); 7201 gtk_action_set_visible(win->menu.unblock, FALSE);
7046 7202
7047 if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) { 7203 if ((account == NULL) || purple_blist_find_chat(account, purple_conversation_get_name(conv)) == NULL) {
7048 /* If the chat is NOT in the buddy list */ 7204 /* If the chat is NOT in the buddy list */
7049 gtk_widget_show(win->menu.add); 7205 gtk_action_set_visible(win->menu.add, TRUE);
7050 gtk_widget_hide(win->menu.remove); 7206 gtk_action_set_visible(win->menu.remove, FALSE);
7051 } else { 7207 } else {
7052 /* If the chat IS in the buddy list */ 7208 /* If the chat IS in the buddy list */
7053 gtk_widget_hide(win->menu.add); 7209 gtk_action_set_visible(win->menu.add, FALSE);
7054 gtk_widget_show(win->menu.remove); 7210 gtk_action_set_visible(win->menu.remove, TRUE);
7055 } 7211 }
7056 7212
7057 gtk_widget_show(win->menu.insert_link); 7213 gtk_action_set_visible(win->menu.insert_link, TRUE);
7058 gtk_widget_show(win->menu.insert_image); 7214 gtk_action_set_visible(win->menu.insert_image, TRUE);
7059 } 7215 }
7060 7216
7061 /* 7217 /*
7062 * Handle graying stuff out based on whether an account is connected 7218 * Handle graying stuff out based on whether an account is connected
7063 * and what features that account supports. 7219 * and what features that account supports.
7102 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons); 7258 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons);
7103 if (account != NULL) 7259 if (account != NULL)
7104 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account)); 7260 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account));
7105 7261
7106 /* Deal with menu items */ 7262 /* Deal with menu items */
7107 gtk_widget_set_sensitive(win->menu.view_log, TRUE); 7263 gtk_action_set_sensitive(win->menu.view_log, TRUE);
7108 gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); 7264 gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
7109 gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL)); 7265 gtk_action_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL));
7110 gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL)); 7266 gtk_action_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL));
7111 gtk_widget_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML)); 7267 gtk_action_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML));
7112 gtk_widget_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES)); 7268 gtk_action_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES));
7113 7269
7114 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 7270 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
7115 { 7271 {
7116 gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL)); 7272 gtk_action_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL));
7117 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL)); 7273 gtk_action_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
7118 gtk_widget_set_sensitive(win->menu.send_file, 7274 gtk_action_set_sensitive(win->menu.send_file,
7119 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || 7275 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
7120 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); 7276 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv)))));
7121 gtk_widget_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL)); 7277 gtk_action_set_sensitive(win->menu.get_attention, (prpl_info->send_attention != NULL));
7122 gtk_widget_set_sensitive(win->menu.alias, 7278 gtk_action_set_sensitive(win->menu.alias,
7123 (account != NULL) && 7279 (account != NULL) &&
7124 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL)); 7280 (purple_find_buddy(account, purple_conversation_get_name(conv)) != NULL));
7125 } 7281 }
7126 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) 7282 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
7127 { 7283 {
7128 gtk_widget_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL)); 7284 gtk_action_set_sensitive(win->menu.add, (prpl_info->join_chat != NULL));
7129 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL)); 7285 gtk_action_set_sensitive(win->menu.remove, (prpl_info->join_chat != NULL));
7130 gtk_widget_set_sensitive(win->menu.alias, 7286 gtk_action_set_sensitive(win->menu.alias,
7131 (account != NULL) && 7287 (account != NULL) &&
7132 (purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL)); 7288 (purple_blist_find_chat(account, purple_conversation_get_name(conv)) != NULL));
7133 } 7289 }
7134 7290
7135 } else { 7291 } else {
7136 /* Account is offline */ 7292 /* Account is offline */
7137 /* Or it's a chat that we've left. */ 7293 /* Or it's a chat that we've left. */
7138 7294
7139 /* Then deal with menu items */ 7295 /* Then deal with menu items */
7140 gtk_widget_set_sensitive(win->menu.view_log, TRUE); 7296 gtk_action_set_sensitive(win->menu.view_log, TRUE);
7141 gtk_widget_set_sensitive(win->menu.send_file, FALSE); 7297 gtk_action_set_sensitive(win->menu.send_file, FALSE);
7142 gtk_widget_set_sensitive(win->menu.get_attention, FALSE); 7298 gtk_action_set_sensitive(win->menu.get_attention, FALSE);
7143 gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); 7299 gtk_action_set_sensitive(win->menu.add_pounce, TRUE);
7144 gtk_widget_set_sensitive(win->menu.get_info, FALSE); 7300 gtk_action_set_sensitive(win->menu.get_info, FALSE);
7145 gtk_widget_set_sensitive(win->menu.invite, FALSE); 7301 gtk_action_set_sensitive(win->menu.invite, FALSE);
7146 gtk_widget_set_sensitive(win->menu.alias, FALSE); 7302 gtk_action_set_sensitive(win->menu.alias, FALSE);
7147 gtk_widget_set_sensitive(win->menu.add, FALSE); 7303 gtk_action_set_sensitive(win->menu.add, FALSE);
7148 gtk_widget_set_sensitive(win->menu.remove, FALSE); 7304 gtk_action_set_sensitive(win->menu.remove, FALSE);
7149 gtk_widget_set_sensitive(win->menu.insert_link, TRUE); 7305 gtk_action_set_sensitive(win->menu.insert_link, TRUE);
7150 gtk_widget_set_sensitive(win->menu.insert_image, FALSE); 7306 gtk_action_set_sensitive(win->menu.insert_image, FALSE);
7151 } 7307 }
7152 7308
7153 /* 7309 /*
7154 * Update the window's icon 7310 * Update the window's icon
7155 */ 7311 */
7226 if (gtkchat->topic_text != NULL) 7382 if (gtkchat->topic_text != NULL)
7227 { 7383 {
7228 topic = purple_conv_chat_get_topic(chat); 7384 topic = purple_conv_chat_get_topic(chat);
7229 7385
7230 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : ""); 7386 gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), topic ? topic : "");
7387 #if GTK_CHECK_VERSION(2,12,0)
7388 gtk_widget_set_tooltip_text(gtkchat->topic_text,
7389 topic ? topic : "");
7390 #else
7231 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text, 7391 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text,
7232 topic ? topic : "", NULL); 7392 topic ? topic : "", NULL);
7393 #endif
7233 } 7394 }
7234 } 7395 }
7235 7396
7236 #if 0 7397 #if 0
7237 if (fields & PIDGIN_CONV_SMILEY_THEME) 7398 if (fields & PIDGIN_CONV_SMILEY_THEME)
7238 pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview); 7399 pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview);
7239 #endif 7400 #endif
7240 7401
7241 if ((fields & PIDGIN_CONV_COLORIZE_TITLE) || 7402 if ((fields & PIDGIN_CONV_COLORIZE_TITLE) ||
7242 (fields & PIDGIN_CONV_SET_TITLE) || 7403 (fields & PIDGIN_CONV_SET_TITLE) ||
7243 (fields & PIDGIN_CONV_TOPIC)) 7404 (fields & PIDGIN_CONV_TOPIC))
7244 { 7405 {
7245 char *title; 7406 char *title;
7246 PurpleConvIm *im = NULL; 7407 PurpleConvIm *im = NULL;
7247 PurpleAccount *account = purple_conversation_get_account(conv); 7408 PurpleAccount *account = purple_conversation_get_account(conv);
7248 PurpleBuddy *buddy = NULL; 7409 PurpleBuddy *buddy = NULL;
7289 gtk_widget_queue_draw(gtkconv->infopane); 7450 gtk_widget_queue_draw(gtkconv->infopane);
7290 7451
7291 if (title != markup) 7452 if (title != markup)
7292 g_free(markup); 7453 g_free(markup);
7293 7454
7294 if (!GTK_WIDGET_REALIZED(gtkconv->tab_label)) 7455 if (!gtk_widget_get_realized(gtkconv->tab_label))
7295 gtk_widget_realize(gtkconv->tab_label); 7456 gtk_widget_realize(gtkconv->tab_label);
7296 7457
7297 accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont); 7458 accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont);
7298 if (im != NULL && 7459 if (im != NULL &&
7299 purple_conv_im_get_typing_state(im) == PURPLE_TYPING) { 7460 purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
7604 7765
7605 event = gtk_event_box_new(); 7766 event = gtk_event_box_new();
7606 gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event); 7767 gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
7607 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), FALSE); 7768 gtk_event_box_set_visible_window(GTK_EVENT_BOX(event), FALSE);
7608 gtk_widget_add_events(event, 7769 gtk_widget_add_events(event,
7609 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); 7770 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
7610 g_signal_connect(G_OBJECT(event), "button-press-event", 7771 g_signal_connect(G_OBJECT(event), "button-press-event",
7611 G_CALLBACK(icon_menu), gtkconv); 7772 G_CALLBACK(icon_menu), gtkconv);
7612 7773
7613 pidgin_tooltip_setup_for_widget(event, gtkconv, pidgin_conv_create_tooltip, NULL); 7774 pidgin_tooltip_setup_for_widget(event, gtkconv, pidgin_conv_create_tooltip, NULL);
7614 gtk_widget_show(event); 7775 gtk_widget_show(event);
7646 static gboolean 7807 static gboolean
7647 pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y) 7808 pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y)
7648 { 7809 {
7649 gint pane_x, pane_y, x_rel; 7810 gint pane_x, pane_y, x_rel;
7650 PidginConversation *gtkconv; 7811 PidginConversation *gtkconv;
7651 7812 GtkAllocation allocation;
7652 gdk_window_get_origin(win->notebook->window, &pane_x, &pane_y); 7813
7814 gdk_window_get_origin(gtk_widget_get_window(win->notebook),
7815 &pane_x, &pane_y);
7653 x_rel = x - pane_x; 7816 x_rel = x - pane_x;
7654 gtkconv = pidgin_conv_window_get_active_gtkconv(win); 7817 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
7655 return (x_rel > gtkconv->infopane->allocation.x + gtkconv->infopane->allocation.width / 2); 7818 gtk_widget_get_allocation(gtkconv->infopane, &allocation);
7819 return (x_rel > allocation.x + allocation.width / 2);
7656 } 7820 }
7657 7821
7658 int 7822 int
7659 pidgin_conv_get_tab_at_xy(PidginWindow *win, int x, int y, gboolean *to_right) 7823 pidgin_conv_get_tab_at_xy(PidginWindow *win, int x, int y, gboolean *to_right)
7660 { 7824 {
7668 if (to_right) 7832 if (to_right)
7669 *to_right = FALSE; 7833 *to_right = FALSE;
7670 7834
7671 notebook = GTK_NOTEBOOK(win->notebook); 7835 notebook = GTK_NOTEBOOK(win->notebook);
7672 7836
7673 gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y); 7837 gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
7674 x_rel = x - nb_x; 7838 x_rel = x - nb_x;
7675 y_rel = y - nb_y; 7839 y_rel = y - nb_y;
7676 7840
7677 horiz = (gtk_notebook_get_tab_pos(notebook) == GTK_POS_TOP || 7841 horiz = (gtk_notebook_get_tab_pos(notebook) == GTK_POS_TOP ||
7678 gtk_notebook_get_tab_pos(notebook) == GTK_POS_BOTTOM); 7842 gtk_notebook_get_tab_pos(notebook) == GTK_POS_BOTTOM);
7679 7843
7680 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook)); 7844 count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
7681 7845
7682 for (i = 0; i < count; i++) { 7846 for (i = 0; i < count; i++) {
7847 GtkAllocation allocation;
7683 7848
7684 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i); 7849 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
7685 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page); 7850 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
7851 gtk_widget_get_allocation(tab, &allocation);
7686 7852
7687 /* Make sure the tab is not hidden beyond an arrow */ 7853 /* Make sure the tab is not hidden beyond an arrow */
7688 if (!GTK_WIDGET_DRAWABLE(tab) && gtk_notebook_get_show_tabs(notebook)) 7854 if (!gtk_widget_is_drawable(tab) && gtk_notebook_get_show_tabs(notebook))
7689 continue; 7855 continue;
7690 7856
7691 if (horiz) { 7857 if (horiz) {
7692 if (x_rel >= tab->allocation.x - PIDGIN_HIG_BOX_SPACE && 7858 if (x_rel >= allocation.x - PIDGIN_HIG_BOX_SPACE &&
7693 x_rel <= tab->allocation.x + tab->allocation.width + PIDGIN_HIG_BOX_SPACE) { 7859 x_rel <= allocation.x + allocation.width + PIDGIN_HIG_BOX_SPACE) {
7694 page_num = i; 7860 page_num = i;
7695 7861
7696 if (to_right && x_rel >= tab->allocation.x + tab->allocation.width/2) 7862 if (to_right && x_rel >= allocation.x + allocation.width/2)
7697 *to_right = TRUE; 7863 *to_right = TRUE;
7698 7864
7699 break; 7865 break;
7700 } 7866 }
7701 } else { 7867 } else {
7702 if (y_rel >= tab->allocation.y - PIDGIN_HIG_BOX_SPACE && 7868 if (y_rel >= allocation.y - PIDGIN_HIG_BOX_SPACE &&
7703 y_rel <= tab->allocation.y + tab->allocation.height + PIDGIN_HIG_BOX_SPACE) { 7869 y_rel <= allocation.y + allocation.height + PIDGIN_HIG_BOX_SPACE) {
7704 page_num = i; 7870 page_num = i;
7705 7871
7706 if (to_right && y_rel >= tab->allocation.y + tab->allocation.height/2) 7872 if (to_right && y_rel >= allocation.y + allocation.height/2)
7707 *to_right = TRUE; 7873 *to_right = TRUE;
7708 7874
7709 break; 7875 break;
7710 } 7876 }
7711 } 7877 }
7808 continue; 7974 continue;
7809 7975
7810 gtkconv = PIDGIN_CONVERSATION(conv); 7976 gtkconv = PIDGIN_CONVERSATION(conv);
7811 win = gtkconv->win; 7977 win = gtkconv->win;
7812 7978
7813 gtk_check_menu_item_set_active( 7979 gtk_toggle_action_set_active(
7814 GTK_CHECK_MENU_ITEM(win->menu.show_timestamps), 7980 GTK_TOGGLE_ACTION(win->menu.show_timestamps),
7815 (gboolean)GPOINTER_TO_INT(value)); 7981 (gboolean)GPOINTER_TO_INT(value));
7816 7982
7817 /* TODO WEBKIT: Use WebKit version of this. */ 7983 /* TODO WEBKIT: Use WebKit version of this. */
7818 #if 0 7984 #if 0
7819 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), 7985 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
7839 continue; 8005 continue;
7840 8006
7841 gtkconv = PIDGIN_CONVERSATION(conv); 8007 gtkconv = PIDGIN_CONVERSATION(conv);
7842 win = gtkconv->win; 8008 win = gtkconv->win;
7843 8009
7844 gtk_check_menu_item_set_active( 8010 gtk_toggle_action_set_active(
7845 GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar), 8011 GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
7846 (gboolean)GPOINTER_TO_INT(value)); 8012 (gboolean)GPOINTER_TO_INT(value));
7847 8013
7848 if ((gboolean)GPOINTER_TO_INT(value)) 8014 if ((gboolean)GPOINTER_TO_INT(value))
7849 gtk_widget_show(gtkconv->toolbar); 8015 gtk_widget_show(gtkconv->toolbar);
7850 else 8016 else
8465 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons", 8631 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons",
8466 show_buddy_icons_pref_cb, NULL); 8632 show_buddy_icons_pref_cb, NULL);
8467 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons", 8633 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/blist/show_protocol_icons",
8468 show_protocol_icons_pref_cb, NULL); 8634 show_protocol_icons_pref_cb, NULL);
8469 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new", 8635 purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/im/hide_new",
8470 hide_new_pref_cb, NULL); 8636 hide_new_pref_cb, NULL);
8471 8637
8472 8638
8473 8639
8474 /********************************************************************** 8640 /**********************************************************************
8475 * Register signals 8641 * Register signals
8622 8788
8623 hidden_convwin = pidgin_conv_window_new(); 8789 hidden_convwin = pidgin_conv_window_new();
8624 window_list = g_list_remove(window_list, hidden_convwin); 8790 window_list = g_list_remove(window_list, hidden_convwin);
8625 8791
8626 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", 8792 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed",
8627 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); 8793 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
8628 8794
8629 /* Callbacks to update a conversation */ 8795 /* Callbacks to update a conversation */
8630 purple_signal_connect(blist_handle, "blist-node-added", handle, 8796 purple_signal_connect(blist_handle, "blist-node-added", handle,
8631 G_CALLBACK(buddy_update_cb), NULL); 8797 G_CALLBACK(buddy_update_cb), NULL);
8632 purple_signal_connect(blist_handle, "blist-node-removed", handle, 8798 purple_signal_connect(blist_handle, "blist-node-removed", handle,
8808 GTK_RESPONSE_OK); 8974 GTK_RESPONSE_OK);
8809 8975
8810 gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog), 8976 gtk_container_set_border_width(GTK_CONTAINER(warn_close_dialog),
8811 6); 8977 6);
8812 gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE); 8978 gtk_window_set_resizable(GTK_WINDOW(warn_close_dialog), FALSE);
8979
8980 /* TODO: figure out how to set no separator in GTK+ 3.0 */
8981 #if 0
8813 gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog), 8982 gtk_dialog_set_has_separator(GTK_DIALOG(warn_close_dialog),
8814 FALSE); 8983 FALSE);
8984 #endif
8815 8985
8816 /* Setup the outside spacing. */ 8986 /* Setup the outside spacing. */
8817 vbox = GTK_DIALOG(warn_close_dialog)->vbox; 8987 vbox = gtk_dialog_get_content_area(GTK_DIALOG(warn_close_dialog));
8818 8988
8819 gtk_box_set_spacing(GTK_BOX(vbox), 12); 8989 gtk_box_set_spacing(GTK_BOX(vbox), 12);
8820 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); 8990 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
8821 8991
8822 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_WARNING, 8992 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_WARNING,
8966 #ifndef _WIN32 9136 #ifndef _WIN32
8967 /* Currently for win32 GTK+ (as of 2.2.1), gdk_pointer_is_grabbed will 9137 /* Currently for win32 GTK+ (as of 2.2.1), gdk_pointer_is_grabbed will
8968 always be true after a button press. */ 9138 always be true after a button press. */
8969 if (!gdk_pointer_is_grabbed()) 9139 if (!gdk_pointer_is_grabbed())
8970 #endif 9140 #endif
8971 gdk_pointer_grab(gtkwin->notebook->window, FALSE, 9141 gdk_pointer_grab(gtk_widget_get_window(gtkwin->notebook), FALSE,
8972 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, 9142 GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
8973 NULL, cursor, GDK_CURRENT_TIME); 9143 NULL, cursor, GDK_CURRENT_TIME);
8974 } 9144 }
8975 9145
8976 static gboolean 9146 static gboolean
9086 if (e->type != GDK_BUTTON_PRESS) 9256 if (e->type != GDK_BUTTON_PRESS)
9087 return FALSE; 9257 return FALSE;
9088 9258
9089 if (e->button == 1) { 9259 if (e->button == 1) {
9090 int nb_x, nb_y; 9260 int nb_x, nb_y;
9261 GtkAllocation allocation;
9262
9263 gtk_widget_get_allocation(gtkconv->infopane_hbox, &allocation);
9091 9264
9092 if (gtkconv->win->in_drag) 9265 if (gtkconv->win->in_drag)
9093 return TRUE; 9266 return TRUE;
9094 9267
9095 gtkconv->win->in_predrag = TRUE; 9268 gtkconv->win->in_predrag = TRUE;
9096 gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont); 9269 gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont);
9097 9270
9098 gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y); 9271 gdk_window_get_origin(gtk_widget_get_window(gtkconv->infopane_hbox), &nb_x, &nb_y);
9099 9272
9100 gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x; 9273 gtkconv->win->drag_min_x = allocation.x + nb_x;
9101 gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y; 9274 gtkconv->win->drag_min_y = allocation.y + nb_y;
9102 gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x; 9275 gtkconv->win->drag_max_x = allocation.width + gtkconv->win->drag_min_x;
9103 gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y; 9276 gtkconv->win->drag_max_y = allocation.height + gtkconv->win->drag_min_y;
9104 9277
9105 gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event", 9278 gtkconv->win->drag_motion_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event",
9106 G_CALLBACK(notebook_motion_cb), gtkconv->win); 9279 G_CALLBACK(notebook_motion_cb), gtkconv->win);
9107 gtkconv->win->drag_leave_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event", 9280 gtkconv->win->drag_leave_signal = g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event",
9108 G_CALLBACK(notebook_leave_cb), gtkconv->win); 9281 G_CALLBACK(notebook_leave_cb), gtkconv->win);
9111 9284
9112 if (e->button == 3) { 9285 if (e->button == 3) {
9113 /* Right click was pressed. Popup the context menu. */ 9286 /* Right click was pressed. Popup the context menu. */
9114 GtkWidget *menu = gtk_menu_new(), *sub; 9287 GtkWidget *menu = gtk_menu_new(), *sub;
9115 gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE); 9288 gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE);
9289 #if 0 /* TODO */
9116 sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to)); 9290 sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
9117 9291
9118 if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) { 9292 if (sub && GTK_WIDGET_IS_SENSITIVE(gtkconv->win->menu.send_to)) {
9119 GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To")); 9293 GtkWidget *item = gtk_menu_item_new_with_mnemonic(_("S_end To"));
9120 if (populated) 9294 if (populated)
9125 gtk_widget_show_all(sub); 9299 gtk_widget_show_all(sub);
9126 } else if (!populated) { 9300 } else if (!populated) {
9127 gtk_widget_destroy(menu); 9301 gtk_widget_destroy(menu);
9128 return FALSE; 9302 return FALSE;
9129 } 9303 }
9130 9304 #endif
9131 gtk_widget_show_all(menu); 9305 gtk_widget_show_all(menu);
9132 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time); 9306 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time);
9133 return TRUE; 9307 return TRUE;
9134 } 9308 }
9135 return FALSE; 9309 return FALSE;
9140 { 9314 {
9141 gint nb_x, nb_y; 9315 gint nb_x, nb_y;
9142 int tab_clicked; 9316 int tab_clicked;
9143 GtkWidget *page; 9317 GtkWidget *page;
9144 GtkWidget *tab; 9318 GtkWidget *tab;
9319 GtkAllocation allocation;
9145 9320
9146 if (e->button == 2 && e->type == GDK_BUTTON_PRESS) { 9321 if (e->button == 2 && e->type == GDK_BUTTON_PRESS) {
9147 PidginConversation *gtkconv; 9322 PidginConversation *gtkconv;
9148 tab_clicked = pidgin_conv_get_tab_at_xy(win, e->x_root, e->y_root, NULL); 9323 tab_clicked = pidgin_conv_get_tab_at_xy(win, e->x_root, e->y_root, NULL);
9149 9324
9177 9352
9178 /* 9353 /*
9179 * Get the relative position of the press event, with regards to 9354 * Get the relative position of the press event, with regards to
9180 * the position of the notebook. 9355 * the position of the notebook.
9181 */ 9356 */
9182 gdk_window_get_origin(win->notebook->window, &nb_x, &nb_y); 9357 gdk_window_get_origin(gtk_widget_get_window(win->notebook), &nb_x, &nb_y);
9183 9358
9184 /* Reset the min/max x/y */ 9359 /* Reset the min/max x/y */
9185 win->drag_min_x = 0; 9360 win->drag_min_x = 0;
9186 win->drag_min_y = 0; 9361 win->drag_min_y = 0;
9187 win->drag_max_x = 0; 9362 win->drag_max_x = 0;
9189 9364
9190 /* Find out which tab was dragged. */ 9365 /* Find out which tab was dragged. */
9191 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked); 9366 page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(win->notebook), tab_clicked);
9192 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page); 9367 tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(win->notebook), page);
9193 9368
9194 win->drag_min_x = tab->allocation.x + nb_x; 9369 gtk_widget_get_allocation(tab, &allocation);
9195 win->drag_min_y = tab->allocation.y + nb_y; 9370
9196 win->drag_max_x = tab->allocation.width + win->drag_min_x; 9371 win->drag_min_x = allocation.x + nb_x;
9197 win->drag_max_y = tab->allocation.height + win->drag_min_y; 9372 win->drag_min_y = allocation.y + nb_y;
9373 win->drag_max_x = allocation.width + win->drag_min_x;
9374 win->drag_max_y = allocation.height + win->drag_min_y;
9198 9375
9199 /* Make sure the click occurred in the tab. */ 9376 /* Make sure the click occurred in the tab. */
9200 if (e->x_root < win->drag_min_x || 9377 if (e->x_root < win->drag_min_x ||
9201 e->x_root >= win->drag_max_x || 9378 e->x_root >= win->drag_max_x ||
9202 e->y_root < win->drag_min_y || 9379 e->y_root < win->drag_min_y ||
9203 e->y_root >= win->drag_max_y) { 9380 e->y_root >= win->drag_max_y) {
9204 9381
9205 return FALSE; 9382 return FALSE;
9206 } 9383 }
9207 9384
9208 win->in_predrag = TRUE; 9385 win->in_predrag = TRUE;
9209 win->drag_tab = tab_clicked; 9386 win->drag_tab = tab_clicked;
9210 9387
9211 /* Connect the new motion signals. */ 9388 /* Connect the new motion signals. */
9429 9606
9430 if (gtkconv) 9607 if (gtkconv)
9431 close_conv_cb(NULL, gtkconv); 9608 close_conv_cb(NULL, gtkconv);
9432 } 9609 }
9433 9610
9611 /* TODO: I don't know if this doable in GTK+ 3.0 */
9612 #if 0
9434 static gboolean 9613 static gboolean
9435 right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win) 9614 right_click_menu_cb(GtkNotebook *notebook, GdkEventButton *event, PidginWindow *win)
9436 { 9615 {
9437 GtkWidget *item, *menu; 9616 GtkWidget *item;
9438 PidginConversation *gtkconv; 9617 PidginConversation *gtkconv;
9618 GtkWidget *menu = gtk_notebook_get_menu
9439 9619
9440 if (event->type != GDK_BUTTON_PRESS || event->button != 3) 9620 if (event->type != GDK_BUTTON_PRESS || event->button != 3)
9441 return FALSE; 9621 return FALSE;
9442 9622
9443 gtkconv = pidgin_conv_window_get_gtkconv_at_index(win, 9623 gtkconv = pidgin_conv_window_get_gtkconv_at_index(win,
9480 g_signal_connect(G_OBJECT(item), "activate", 9660 g_signal_connect(G_OBJECT(item), "activate",
9481 G_CALLBACK(close_tab_cb), menu); 9661 G_CALLBACK(close_tab_cb), menu);
9482 9662
9483 return FALSE; 9663 return FALSE;
9484 } 9664 }
9665 #endif
9485 9666
9486 static void 9667 static void
9487 remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry) 9668 remove_edit_entry(PidginConversation *gtkconv, GtkWidget *entry)
9488 { 9669 {
9489 g_signal_handlers_disconnect_matched(G_OBJECT(entry), G_SIGNAL_MATCH_DATA, 9670 g_signal_handlers_disconnect_matched(G_OBJECT(entry), G_SIGNAL_MATCH_DATA,
9501 } 9682 }
9502 9683
9503 static gboolean 9684 static gboolean
9504 alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data) 9685 alias_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
9505 { 9686 {
9506 if (event->keyval == GDK_Escape) { 9687 if (event->keyval == GDK_KEY_Escape) {
9507 remove_edit_entry(user_data, widget); 9688 remove_edit_entry(user_data, widget);
9508 return TRUE; 9689 return TRUE;
9509 } 9690 }
9510 return FALSE; 9691 return FALSE;
9511 } 9692 }
9528 9709
9529 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 9710 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
9530 PurpleBuddy *buddy; 9711 PurpleBuddy *buddy;
9531 buddy = purple_find_buddy(account, name); 9712 buddy = purple_find_buddy(account, name);
9532 if (buddy != NULL) { 9713 if (buddy != NULL) {
9533 purple_blist_alias_buddy(buddy, 9714 purple_blist_alias_buddy(buddy, gtk_entry_get_text(entry));
9534 gtk_entry_get_text(entry));
9535 } 9715 }
9536 serv_alias_buddy(buddy); 9716 serv_alias_buddy(buddy);
9537 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 9717 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
9538 gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry)); 9718 gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry));
9539 topic_callback(NULL, gtkconv); 9719 topic_callback(NULL, gtkconv);
9546 { 9726 {
9547 GtkWidget *entry = NULL; 9727 GtkWidget *entry = NULL;
9548 PurpleConversation *conv = gtkconv->active_conv; 9728 PurpleConversation *conv = gtkconv->active_conv;
9549 const char *text = NULL; 9729 const char *text = NULL;
9550 9730
9551 if (!GTK_WIDGET_VISIBLE(gtkconv->infopane)) { 9731 if (!gtk_widget_get_visible(gtkconv->infopane)) {
9552 /* There's already an entry for alias. Let's not create another one. */ 9732 /* There's already an entry for alias. Let's not create another one. */
9553 return FALSE; 9733 return FALSE;
9554 } 9734 }
9555 9735
9556 if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) { 9736 if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) {
9630 gtkconv_set_unseen(gtkconv, PIDGIN_UNSEEN_NONE); 9810 gtkconv_set_unseen(gtkconv, PIDGIN_UNSEEN_NONE);
9631 } 9811 }
9632 9812
9633 /* Update the menubar */ 9813 /* Update the menubar */
9634 9814
9635 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging), 9815 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtkconv->win->menu.logging),
9636 purple_conversation_is_logging(conv)); 9816 purple_conversation_is_logging(conv));
9637 9817
9638 generate_send_to_items(win); 9818 generate_send_to_items(win);
9639 regenerate_options_items(win); 9819 regenerate_options_items(win);
9640 regenerate_plugins_items(win); 9820 regenerate_plugins_items(win);
9641 9821
9642 pidgin_conv_switch_active_conversation(conv); 9822 pidgin_conv_switch_active_conversation(conv);
9643 9823
9644 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"); 9824 sound_method = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method");
9645 if (strcmp(sound_method, "none") != 0) 9825 if (strcmp(sound_method, "none") != 0)
9646 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.sounds), 9826 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.sounds),
9647 gtkconv->make_sound); 9827 gtkconv->make_sound);
9648 9828
9649 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_formatting_toolbar), 9829 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_formatting_toolbar),
9650 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")); 9830 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"));
9651 9831
9652 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(win->menu.show_timestamps), 9832 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(win->menu.show_timestamps),
9653 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps")); 9833 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
9654 9834
9655 /* 9835 /*
9656 * We pause icons when they are not visible. If this icon should 9836 * We pause icons when they are not visible. If this icon should
9657 * be animated then start it back up again. 9837 * be animated then start it back up again.
9658 */ 9838 */
9675 9855
9676 static GList* 9856 static GList*
9677 make_status_icon_list(const char *stock, GtkWidget *w) 9857 make_status_icon_list(const char *stock, GtkWidget *w)
9678 { 9858 {
9679 GList *l = NULL; 9859 GList *l = NULL;
9680 l = g_list_append(l, gtk_widget_render_icon (w, stock, 9860 l = g_list_append(l,
9681 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow")); 9861 gtk_widget_render_icon(w, stock,
9682 l = g_list_append(l, gtk_widget_render_icon (w, stock, 9862 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL), "GtkWindow"));
9683 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow")); 9863 l = g_list_append(l,
9684 l = g_list_append(l, gtk_widget_render_icon (w, stock, 9864 gtk_widget_render_icon(w, stock,
9685 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow")); 9865 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow"));
9686 l = g_list_append(l, gtk_widget_render_icon (w, stock, 9866 l = g_list_append(l,
9687 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow")); 9867 gtk_widget_render_icon(w, stock,
9868 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM), "GtkWindow"));
9869 l = g_list_append(l,
9870 gtk_widget_render_icon(w, stock,
9871 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_LARGE), "GtkWindow"));
9688 return l; 9872 return l;
9689 } 9873 }
9690 9874
9691 static void 9875 static void
9692 create_icon_lists(GtkWidget *w) 9876 create_icon_lists(GtkWidget *w)
9706 } 9890 }
9707 9891
9708 static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) { 9892 static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
9709 int x, y; 9893 int x, y;
9710 9894
9711 if (GTK_WIDGET_VISIBLE(w)) 9895 if (gtk_widget_get_visible(w))
9712 gtk_window_get_position(GTK_WINDOW(w), &x, &y); 9896 gtk_window_get_position(GTK_WINDOW(w), &x, &y);
9713 else 9897 else
9714 return FALSE; /* carry on normally */ 9898 return FALSE; /* carry on normally */
9715 9899
9716 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired 9900 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired
9717 * when the window is being maximized */ 9901 * when the window is being maximized */
9718 if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) 9902 if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
9719 return FALSE; 9903 return FALSE;
9720 9904
9721 /* don't save off-screen positioning */ 9905 /* don't save off-screen positioning */
9722 if (x + event->width < 0 || 9906 if (x + event->width < 0 ||
9723 y + event->height < 0 || 9907 y + event->height < 0 ||
9738 9922
9739 static void 9923 static void
9740 pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y, 9924 pidgin_conv_set_position_size(PidginWindow *win, int conv_x, int conv_y,
9741 int conv_width, int conv_height) 9925 int conv_width, int conv_height)
9742 { 9926 {
9743 /* if the window exists, is hidden, we're saving positions, and the 9927 /* if the window exists, is hidden, we're saving positions, and the
9744 * position is sane... */ 9928 * position is sane... */
9745 if (win && win->window && 9929 if (win && win->window &&
9746 !GTK_WIDGET_VISIBLE(win->window) && conv_width != 0) { 9930 !gtk_widget_get_visible(win->window) && conv_width != 0) {
9747 9931
9748 #ifdef _WIN32 /* only override window manager placement on Windows */ 9932 #ifdef _WIN32 /* only override window manager placement on Windows */
9749 /* ...check position is on screen... */ 9933 /* ...check position is on screen... */
9750 if (conv_x >= gdk_screen_width()) 9934 if (conv_x >= gdk_screen_width())
9751 conv_x = gdk_screen_width() - 100; 9935 conv_x = gdk_screen_width() - 100;
9826 gtk_notebook_set_scrollable(GTK_NOTEBOOK(win->notebook), TRUE); 10010 gtk_notebook_set_scrollable(GTK_NOTEBOOK(win->notebook), TRUE);
9827 gtk_notebook_popup_enable(GTK_NOTEBOOK(win->notebook)); 10011 gtk_notebook_popup_enable(GTK_NOTEBOOK(win->notebook));
9828 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE); 10012 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
9829 gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE); 10013 gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), TRUE);
9830 10014
10015 /* TODO: figure out how to add custom stuff to the right-click menu in
10016 GtkNotebook in GTK+ 3.0 */
10017 #if 0
9831 g_signal_connect(G_OBJECT(win->notebook), "button-press-event", 10018 g_signal_connect(G_OBJECT(win->notebook), "button-press-event",
9832 G_CALLBACK(right_click_menu_cb), win); 10019 G_CALLBACK(right_click_menu_cb), win);
10020 #endif
9833 10021
9834 gtk_widget_show(win->notebook); 10022 gtk_widget_show(win->notebook);
9835 10023
9836 g_signal_connect(G_OBJECT(win->notebook), "switch_page", 10024 g_signal_connect(G_OBJECT(win->notebook), "switch_page",
9837 G_CALLBACK(before_switch_conv_cb), win); 10025 G_CALLBACK(before_switch_conv_cb), win);
9896 } 10084 }
9897 return; 10085 return;
9898 } 10086 }
9899 gtk_widget_destroy(win->window); 10087 gtk_widget_destroy(win->window);
9900 10088
9901 g_object_unref(G_OBJECT(win->menu.item_factory)); 10089 g_object_unref(G_OBJECT(win->menu.ui));
9902 10090
9903 purple_notify_close_with_handle(win); 10091 purple_notify_close_with_handle(win);
9904 purple_signals_disconnect_by_handle(win); 10092 purple_signals_disconnect_by_handle(win);
9905 10093
9906 g_free(win); 10094 g_free(win);
9919 } 10107 }
9920 10108
9921 void 10109 void
9922 pidgin_conv_window_raise(PidginWindow *win) 10110 pidgin_conv_window_raise(PidginWindow *win)
9923 { 10111 {
9924 gdk_window_raise(GDK_WINDOW(win->window->window)); 10112 gdk_window_raise(GDK_WINDOW(gtk_widget_get_window(win->window)));
9925 } 10113 }
9926 10114
9927 void 10115 void
9928 pidgin_conv_window_switch_gtkconv(PidginWindow *win, PidginConversation *gtkconv) 10116 pidgin_conv_window_switch_gtkconv(PidginWindow *win, PidginConversation *gtkconv)
9929 { 10117 {
9974 pidgin_conv_tab_pack(win, ((PidginConversation*)win->gtkconvs->data)); 10162 pidgin_conv_tab_pack(win, ((PidginConversation*)win->gtkconvs->data));
9975 10163
9976 10164
9977 /* Close button. */ 10165 /* Close button. */
9978 gtkconv->close = pidgin_create_small_button(gtk_label_new("×")); 10166 gtkconv->close = pidgin_create_small_button(gtk_label_new("×"));
10167 #if GTK_CHECK_VERSION(2,12,0)
10168 gtk_widget_set_tooltip_text(gtkconv->close, _("Close conversation"));
10169 #else
9979 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close, 10170 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
9980 _("Close conversation"), NULL); 10171 _("Close conversation"), NULL);
10172 #endif
9981 10173
9982 g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv); 10174 g_signal_connect(gtkconv->close, "clicked", G_CALLBACK (close_conv_cb), gtkconv);
9983 10175
9984 /* Status icon. */ 10176 /* Status icon. */
9985 gtkconv->icon = gtk_image_new(); 10177 gtkconv->icon = gtk_image_new();
10090 gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE); 10282 gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE);
10091 gtk_container_add(GTK_CONTAINER(ebox), gtkconv->tabby); 10283 gtk_container_add(GTK_CONTAINER(ebox), gtkconv->tabby);
10092 g_signal_connect(G_OBJECT(ebox), "enter-notify-event", 10284 g_signal_connect(G_OBJECT(ebox), "enter-notify-event",
10093 G_CALLBACK(gtkconv_tab_set_tip), gtkconv); 10285 G_CALLBACK(gtkconv_tab_set_tip), gtkconv);
10094 10286
10095 if (gtkconv->tab_label->parent == NULL) { 10287 if (gtk_widget_get_parent(gtkconv->tab_label) == NULL) {
10096 /* Pack if it's a new widget */ 10288 /* Pack if it's a new widget */
10097 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0); 10289 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), first, FALSE, FALSE, 0);
10098 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE, TRUE, 0); 10290 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), gtkconv->tab_label, TRUE, TRUE, 0);
10099 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), third, FALSE, FALSE, 0); 10291 gtk_box_pack_start(GTK_BOX(gtkconv->tabby), third, FALSE, FALSE, 0);
10100 10292
10111 10303
10112 /* Reset the tabs label to the new version */ 10304 /* Reset the tabs label to the new version */
10113 gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox); 10305 gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox);
10114 } 10306 }
10115 10307
10116 gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, 10308 g_object_set(G_OBJECT(win->notebook), "expand", !tabs_side && !angle, NULL);
10117 !tabs_side && !angle,
10118 TRUE, GTK_PACK_START);
10119 10309
10120 if (pidgin_conv_window_get_gtkconv_count(win) == 1) 10310 if (pidgin_conv_window_get_gtkconv_count(win) == 1)
10121 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), 10311 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
10122 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") && 10312 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") &&
10123 (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") || 10313 (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") ||
10137 { 10327 {
10138 unsigned int index; 10328 unsigned int index;
10139 10329
10140 index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont); 10330 index = gtk_notebook_page_num(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont);
10141 10331
10332 #if GTK_CHECK_VERSION(2,10,0)
10333 g_object_ref_sink(G_OBJECT(gtkconv->tab_cont));
10334 #else
10142 g_object_ref(gtkconv->tab_cont); 10335 g_object_ref(gtkconv->tab_cont);
10143 gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont)); 10336 gtk_object_sink(GTK_OBJECT(gtkconv->tab_cont));
10337 #endif
10144 10338
10145 gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index); 10339 gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index);
10146 10340
10147 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv); 10341 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv);
10148 10342
10221 gdkwin = gdk_window_get_toplevel(gdkwin); 10415 gdkwin = gdk_window_get_toplevel(gdkwin);
10222 10416
10223 for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) { 10417 for (l = pidgin_conv_windows_get_list(); l != NULL; l = l->next) {
10224 win = l->data; 10418 win = l->data;
10225 10419
10226 if (gdkwin == win->window->window) 10420 if (gdkwin == gtk_widget_get_window(win->window))
10227 return win; 10421 return win;
10228 } 10422 }
10229 10423
10230 return NULL; 10424 return NULL;
10231 } 10425 }
10343 { 10537 {
10344 int x, y; 10538 int x, y;
10345 PurpleConversationType type = purple_conversation_get_type(conv->active_conv); 10539 PurpleConversationType type = purple_conversation_get_type(conv->active_conv);
10346 GList *all; 10540 GList *all;
10347 10541
10348 if (GTK_WIDGET_VISIBLE(w)) 10542 if (gtk_widget_get_visible(w))
10349 gtk_window_get_position(GTK_WINDOW(w), &x, &y); 10543 gtk_window_get_position(GTK_WINDOW(w), &x, &y);
10350 else 10544 else
10351 return FALSE; /* carry on normally */ 10545 return FALSE; /* carry on normally */
10352 10546
10353 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired 10547 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired
10354 * when the window is being maximized */ 10548 * when the window is being maximized */
10355 if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED) 10549 if (gdk_window_get_state(gtk_widget_get_window(w)) & GDK_WINDOW_STATE_MAXIMIZED)
10356 return FALSE; 10550 return FALSE;
10357 10551
10358 /* don't save off-screen positioning */ 10552 /* don't save off-screen positioning */
10359 if (x + event->width < 0 || 10553 if (x + event->width < 0 ||
10360 y + event->height < 0 || 10554 y + event->height < 0 ||

mercurial