comparison pidgin/gtkblist.c @ 29869:f44718de8b06

merged with im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 22 Feb 2010 16:05:25 +0900
parents e3031e5785a3 185677f47825
children 0fe3f0bc0695
comparison
equal deleted inserted replaced
29445:d74e3cd6cbb5 29869:f44718de8b06
140 140
141 static GList *pidgin_blist_sort_methods = NULL; 141 static GList *pidgin_blist_sort_methods = NULL;
142 static struct pidgin_blist_sort_method *current_sort_method = NULL; 142 static struct pidgin_blist_sort_method *current_sort_method = NULL;
143 static void sort_method_none(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); 143 static void sort_method_none(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
144 144
145 /* The functions we use for sorting aren't available in gtk 2.0.x, and
146 * segfault in 2.2.0. 2.2.1 is known to work, so I'll require that */
147 #if GTK_CHECK_VERSION(2,2,1)
148 static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); 145 static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
149 static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); 146 static void sort_method_status(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
150 static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter); 147 static void sort_method_log_activity(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter);
151 #endif
152 static PidginBuddyList *gtkblist = NULL; 148 static PidginBuddyList *gtkblist = NULL;
153 149
154 static GList *groups_tree(void); 150 static GList *groups_tree(void);
155 static gboolean pidgin_blist_refresh_timer(PurpleBuddyList *list); 151 static gboolean pidgin_blist_refresh_timer(PurpleBuddyList *list);
156 static void pidgin_blist_update_buddy(PurpleBuddyList *list, PurpleBlistNode *node, gboolean status_change); 152 static void pidgin_blist_update_buddy(PurpleBuddyList *list, PurpleBlistNode *node, gboolean status_change);
204 return FALSE; 200 return FALSE;
205 } 201 }
206 202
207 static gboolean gtk_blist_window_state_cb(GtkWidget *w, GdkEventWindowState *event, gpointer data) 203 static gboolean gtk_blist_window_state_cb(GtkWidget *w, GdkEventWindowState *event, gpointer data)
208 { 204 {
209 #if GTK_CHECK_VERSION(2,2,0)
210 if(event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) { 205 if(event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) {
211 if(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) 206 if(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN)
212 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", FALSE); 207 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", FALSE);
213 else { 208 else {
214 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", TRUE); 209 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", TRUE);
226 /* Refresh gtkblist if un-iconifying */ 221 /* Refresh gtkblist if un-iconifying */
227 if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED){ 222 if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED){
228 if (!(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)) 223 if (!(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED))
229 pidgin_blist_refresh_timer(purple_get_blist()); 224 pidgin_blist_refresh_timer(purple_get_blist());
230 } 225 }
231 #else
232 /* At least gtk+ 2.0.6 does not properly set the change_mask when unsetting a
233 * GdkWindowState flag. To work around, the window state will be explicitly
234 * queried on these older versions of gtk+. See pidgin ticket #739.
235 */
236 GdkWindowState new_window_state = gdk_window_get_state(G_OBJECT(gtkblist->window->window));
237
238 if(new_window_state & GDK_WINDOW_STATE_WITHDRAWN) {
239 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", FALSE);
240 } else {
241 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", TRUE);
242 pidgin_blist_refresh_timer(purple_get_blist());
243 }
244
245 if(new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
246 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_maximized", TRUE);
247 else
248 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_maximized", FALSE);
249
250 if (!(new_window_state & GDK_WINDOW_STATE_ICONIFIED))
251 pidgin_blist_refresh_timer(purple_get_blist());
252 #endif
253 226
254 return FALSE; 227 return FALSE;
255 } 228 }
256 229
257 static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) 230 static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data)
437 static void gtk_blist_menu_join_cb(GtkWidget *w, PurpleChat *chat) 410 static void gtk_blist_menu_join_cb(GtkWidget *w, PurpleChat *chat)
438 { 411 {
439 gtk_blist_join_chat(chat); 412 gtk_blist_join_chat(chat);
440 } 413 }
441 414
442 #if GTK_CHECK_VERSION(2,6,0)
443 static void gtk_blist_renderer_editing_cancelled_cb(GtkCellRenderer *renderer, PurpleBuddyList *list) 415 static void gtk_blist_renderer_editing_cancelled_cb(GtkCellRenderer *renderer, PurpleBuddyList *list)
444 { 416 {
445 editing_blist = FALSE; 417 editing_blist = FALSE;
446 g_object_set(G_OBJECT(renderer), "editable", FALSE, NULL); 418 g_object_set(G_OBJECT(renderer), "editable", FALSE, NULL);
447 pidgin_blist_refresh(list); 419 pidgin_blist_refresh(list);
486 GtkEntry *entry = GTK_ENTRY (editable); 458 GtkEntry *entry = GTK_ENTRY (editable);
487 gtk_entry_set_text(entry, text); 459 gtk_entry_set_text(entry, text);
488 } 460 }
489 editing_blist = TRUE; 461 editing_blist = TRUE;
490 } 462 }
491 #endif
492 463
493 static void 464 static void
494 gtk_blist_do_personize(GList *merges) 465 gtk_blist_do_personize(GList *merges)
495 { 466 {
496 PurpleBlistNode *contact = NULL; 467 PurpleBlistNode *contact = NULL;
766 737
767 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); 738 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
768 g_object_set(G_OBJECT(gtkblist->text_rend), "editable", TRUE, NULL); 739 g_object_set(G_OBJECT(gtkblist->text_rend), "editable", TRUE, NULL);
769 gtk_tree_view_set_enable_search (GTK_TREE_VIEW(gtkblist->treeview), FALSE); 740 gtk_tree_view_set_enable_search (GTK_TREE_VIEW(gtkblist->treeview), FALSE);
770 gtk_widget_grab_focus(gtkblist->treeview); 741 gtk_widget_grab_focus(gtkblist->treeview);
771 #if GTK_CHECK_VERSION(2,2,0)
772 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(gtkblist->treeview), path, 742 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(gtkblist->treeview), path,
773 gtkblist->text_column, gtkblist->text_rend, TRUE); 743 gtkblist->text_column, gtkblist->text_rend, TRUE);
774 #else
775 gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtkblist->treeview), path, gtkblist->text_column, TRUE);
776 #endif
777 gtk_tree_path_free(path); 744 gtk_tree_path_free(path);
778 } 745 }
779 746
780 static void gtk_blist_menu_bp_cb(GtkWidget *w, PurpleBuddy *b) 747 static void gtk_blist_menu_bp_cb(GtkWidget *w, PurpleBuddy *b)
781 { 748 {
1244 1211
1245 g_free(title); 1212 g_free(title);
1246 1213
1247 purple_blist_node_set_bool(node, "collapsed", TRUE); 1214 purple_blist_node_set_bool(node, "collapsed", TRUE);
1248 1215
1249 for(cnode = node->child; cnode; cnode = cnode->next) { 1216 for(cnode = purple_blist_node_get_first_child(node); cnode; cnode = purple_blist_node_get_sibling_next(cnode)) {
1250 if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) { 1217 if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
1251 gtknode = cnode->ui_data; 1218 gtknode = purple_blist_node_get_ui_data(cnode);
1252 if (!gtknode->contact_expanded) 1219 if (!gtknode->contact_expanded)
1253 continue; 1220 continue;
1254 gtknode->contact_expanded = FALSE; 1221 gtknode->contact_expanded = FALSE;
1255 pidgin_blist_update_contact(NULL, cnode); 1222 pidgin_blist_update_contact(NULL, cnode);
1256 } 1223 }
1278 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) 1245 if(PURPLE_BLIST_NODE_IS_CONTACT(node))
1279 buddy = purple_contact_get_priority_buddy((PurpleContact*)node); 1246 buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
1280 else 1247 else
1281 buddy = (PurpleBuddy*)node; 1248 buddy = (PurpleBuddy*)node;
1282 1249
1283 pidgin_dialogs_im_with_user(buddy->account, buddy->name); 1250 pidgin_dialogs_im_with_user(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy));
1284 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { 1251 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
1285 gtk_blist_join_chat((PurpleChat *)node); 1252 gtk_blist_join_chat((PurpleChat *)node);
1286 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { 1253 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
1287 /* if (gtk_tree_view_row_expanded(tv, path)) 1254 /* if (gtk_tree_view_row_expanded(tv, path))
1288 gtk_tree_view_collapse_row(tv, path); 1255 gtk_tree_view_collapse_row(tv, path);
1298 PurpleBlistNode *node; 1265 PurpleBlistNode *node;
1299 1266
1300 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ 1267 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){
1301 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); 1268 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
1302 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) 1269 if (PURPLE_BLIST_NODE_IS_BUDDY(node))
1303 purple_blist_request_add_chat(NULL, (PurpleGroup*)node->parent->parent, NULL, NULL); 1270 purple_blist_request_add_chat(NULL, purple_buddy_get_group(PURPLE_BUDDY(node)), NULL, NULL);
1304 if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_CHAT(node)) 1271 if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_CHAT(node))
1305 purple_blist_request_add_chat(NULL, (PurpleGroup*)node->parent, NULL, NULL); 1272 purple_blist_request_add_chat(NULL, purple_contact_get_group(PURPLE_CONTACT(node)), NULL, NULL);
1306 else if (PURPLE_BLIST_NODE_IS_GROUP(node)) 1273 else if (PURPLE_BLIST_NODE_IS_GROUP(node))
1307 purple_blist_request_add_chat(NULL, (PurpleGroup*)node, NULL, NULL); 1274 purple_blist_request_add_chat(NULL, (PurpleGroup*)node, NULL, NULL);
1308 } 1275 }
1309 else { 1276 else {
1310 purple_blist_request_add_chat(NULL, NULL, NULL, NULL); 1277 purple_blist_request_add_chat(NULL, NULL, NULL, NULL);
1318 PurpleBlistNode *node; 1285 PurpleBlistNode *node;
1319 1286
1320 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ 1287 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){
1321 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); 1288 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
1322 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { 1289 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
1323 purple_blist_request_add_buddy(NULL, NULL, ((PurpleGroup*)node->parent->parent)->name, 1290 PurpleGroup *group = purple_buddy_get_group(PURPLE_BUDDY(node));
1324 NULL); 1291 purple_blist_request_add_buddy(NULL, NULL, purple_group_get_name(group), NULL);
1325 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node) 1292 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_CHAT(node)) {
1326 || PURPLE_BLIST_NODE_IS_CHAT(node)) { 1293 PurpleGroup *group = purple_contact_get_group(PURPLE_CONTACT(node));
1327 purple_blist_request_add_buddy(NULL, NULL, ((PurpleGroup*)node->parent)->name, NULL); 1294 purple_blist_request_add_buddy(NULL, NULL, purple_group_get_name(group), NULL);
1328 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { 1295 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
1329 purple_blist_request_add_buddy(NULL, NULL, ((PurpleGroup*)node)->name, NULL); 1296 purple_blist_request_add_buddy(NULL, NULL, purple_group_get_name(PURPLE_GROUP(node)), NULL);
1330 } 1297 }
1331 } 1298 }
1332 else { 1299 else {
1333 purple_blist_request_add_buddy(NULL, NULL, NULL, NULL); 1300 purple_blist_request_add_buddy(NULL, NULL, NULL, NULL);
1334 } 1301 }
1376 GtkTreePath *path; 1343 GtkTreePath *path;
1377 1344
1378 if(!PURPLE_BLIST_NODE_IS_CONTACT(node)) 1345 if(!PURPLE_BLIST_NODE_IS_CONTACT(node))
1379 return; 1346 return;
1380 1347
1381 gtknode = (struct _pidgin_blist_node *)node->ui_data; 1348 gtknode = purple_blist_node_get_ui_data(node);
1382 1349
1383 gtknode->contact_expanded = TRUE; 1350 gtknode->contact_expanded = TRUE;
1384 1351
1385 for(bnode = node->child; bnode; bnode = bnode->next) { 1352 for(bnode = purple_blist_node_get_first_child(node); bnode; bnode = purple_blist_node_get_sibling_next(bnode)) {
1386 pidgin_blist_update(NULL, bnode); 1353 pidgin_blist_update(NULL, bnode);
1387 } 1354 }
1388 1355
1389 /* This ensures that the bottom buddy is visible, i.e. not scrolled off the alignment */ 1356 /* This ensures that the bottom buddy is visible, i.e. not scrolled off the alignment */
1390 if (get_iter_from_node(node, &parent)) { 1357 if (get_iter_from_node(node, &parent)) {
1395 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); 1362 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
1396 1363
1397 /* Let the treeview draw so it knows where to scroll */ 1364 /* Let the treeview draw so it knows where to scroll */
1398 ex->treeview = GTK_TREE_VIEW(gtkblist->treeview); 1365 ex->treeview = GTK_TREE_VIEW(gtkblist->treeview);
1399 ex->path = path; 1366 ex->path = path;
1400 ex->node = node->child; 1367 ex->node = purple_blist_node_get_first_child(node);
1401 g_idle_add(scroll_to_expanded_cell, ex); 1368 g_idle_add(scroll_to_expanded_cell, ex);
1402 } 1369 }
1403 } 1370 }
1404 1371
1405 static void 1372 static void
1409 struct _pidgin_blist_node *gtknode; 1376 struct _pidgin_blist_node *gtknode;
1410 1377
1411 if(!PURPLE_BLIST_NODE_IS_CONTACT(node)) 1378 if(!PURPLE_BLIST_NODE_IS_CONTACT(node))
1412 return; 1379 return;
1413 1380
1414 gtknode = (struct _pidgin_blist_node *)node->ui_data; 1381 gtknode = purple_blist_node_get_ui_data(node);
1415 1382
1416 gtknode->contact_expanded = FALSE; 1383 gtknode->contact_expanded = FALSE;
1417 1384
1418 for(bnode = node->child; bnode; bnode = bnode->next) { 1385 for(bnode = purple_blist_node_get_first_child(node); bnode; bnode = purple_blist_node_get_sibling_next(bnode)) {
1419 pidgin_blist_update(NULL, bnode); 1386 pidgin_blist_update(NULL, bnode);
1420 } 1387 }
1421 } 1388 }
1422 1389
1423 static void 1390 static void
1504 gtk_widget_show(menuitem); 1471 gtk_widget_show(menuitem);
1505 1472
1506 submenu = gtk_menu_new(); 1473 submenu = gtk_menu_new();
1507 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); 1474 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
1508 1475
1509 for (group = purple_blist_get_root(); group; group = group->next) { 1476 for (group = purple_blist_get_root(); group; group = purple_blist_node_get_sibling_next(group)) {
1510 if (group->type != PURPLE_BLIST_GROUP_NODE) 1477 if (!PURPLE_BLIST_NODE_IS_GROUP(group))
1511 continue; 1478 continue;
1512 if (group == node->parent) 1479 if (group == purple_blist_node_get_parent(node))
1513 continue; 1480 continue;
1514 menuitem = pidgin_new_item_from_stock(submenu, purple_group_get_name((PurpleGroup *)group), NULL, 1481 menuitem = pidgin_new_item_from_stock(submenu, purple_group_get_name((PurpleGroup *)group), NULL,
1515 G_CALLBACK(gtk_blist_menu_move_to_cb), node, 0, 0, NULL); 1482 G_CALLBACK(gtk_blist_menu_move_to_cb), node, 0, 0, NULL);
1516 g_object_set_data(G_OBJECT(menuitem), "groupnode", group); 1483 g_object_set_data(G_OBJECT(menuitem), "groupnode", group);
1517 } 1484 }
1518 gtk_widget_show_all(submenu); 1485 gtk_widget_show_all(submenu);
1519 } 1486 }
1520 1487
1521 void 1488 void
1522 pidgin_blist_make_buddy_menu(GtkWidget *menu, PurpleBuddy *buddy, gboolean sub) { 1489 pidgin_blist_make_buddy_menu(GtkWidget *menu, PurpleBuddy *buddy, gboolean sub) {
1490 PurpleAccount *account = NULL;
1491 PurpleConnection *pc = NULL;
1523 PurplePluginProtocolInfo *prpl_info; 1492 PurplePluginProtocolInfo *prpl_info;
1524 PurpleContact *contact; 1493 PurpleContact *contact;
1525 PurpleBlistNode *node; 1494 PurpleBlistNode *node;
1526 gboolean contact_expanded = FALSE; 1495 gboolean contact_expanded = FALSE;
1527 1496
1528 g_return_if_fail(menu); 1497 g_return_if_fail(menu);
1529 g_return_if_fail(buddy); 1498 g_return_if_fail(buddy);
1530 1499
1531 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(buddy->account->gc->prpl); 1500 account = purple_buddy_get_account(buddy);
1532 1501 pc = purple_account_get_connection(account);
1533 node = (PurpleBlistNode*)buddy; 1502 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(pc));
1503
1504 node = PURPLE_BLIST_NODE(buddy);
1534 1505
1535 contact = purple_buddy_get_contact(buddy); 1506 contact = purple_buddy_get_contact(buddy);
1536 if (contact) { 1507 if (contact) {
1537 contact_expanded = ((struct _pidgin_blist_node *)(((PurpleBlistNode*)contact)->ui_data))->contact_expanded; 1508 PidginBlistNode *node = purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(contact));
1509 contact_expanded = node->contact_expanded;
1538 } 1510 }
1539 1511
1540 if (prpl_info && prpl_info->get_info) { 1512 if (prpl_info && prpl_info->get_info) {
1541 pidgin_new_item_from_stock(menu, _("Get _Info"), PIDGIN_STOCK_TOOLBAR_USER_INFO, 1513 pidgin_new_item_from_stock(menu, _("Get _Info"), PIDGIN_STOCK_TOOLBAR_USER_INFO,
1542 G_CALLBACK(gtk_blist_menu_info_cb), buddy, 0, 0, NULL); 1514 G_CALLBACK(gtk_blist_menu_info_cb), buddy, 0, 0, NULL);
3068 NULL, gtkblist->tipwindow, "tooltip", 3040 NULL, gtkblist->tipwindow, "tooltip",
3069 max_width - (td->avatar_width+ TOOLTIP_BORDER)-1, 3041 max_width - (td->avatar_width+ TOOLTIP_BORDER)-1,
3070 current_height-1,td->avatar_width+2, td->avatar_height+2); 3042 current_height-1,td->avatar_width+2, td->avatar_height+2);
3071 } 3043 }
3072 3044
3073 #if GTK_CHECK_VERSION(2,2,0)
3074 if (td->status_icon) { 3045 if (td->status_icon) {
3075 if (dir == GTK_TEXT_DIR_RTL) 3046 if (dir == GTK_TEXT_DIR_RTL)
3076 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, 3047 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon,
3077 0, 0, max_width - TOOLTIP_BORDER - status_size, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); 3048 0, 0, max_width - TOOLTIP_BORDER - status_size, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
3078 else 3049 else
3095 0, 0, 3066 0, 0,
3096 prpl_col, 3067 prpl_col,
3097 current_height + ((td->name_height / 2) - (PRPL_SIZE / 2)), 3068 current_height + ((td->name_height / 2) - (PRPL_SIZE / 2)),
3098 -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); 3069 -1 , -1, GDK_RGB_DITHER_NONE, 0, 0);
3099 3070
3100 #else
3101 if (td->status_icon) {
3102 gdk_pixbuf_render_to_drawable(td->status_icon, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 12, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
3103 }
3104 if(td->avatar)
3105 gdk_pixbuf_render_to_drawable(td->avatar,
3106 GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0,
3107 max_width - (td->avatar_width + TOOLTIP_BORDER),
3108 current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
3109 #endif
3110 if (td->name_layout) { 3071 if (td->name_layout) {
3111 if (dir == GTK_TEXT_DIR_RTL) { 3072 if (dir == GTK_TEXT_DIR_RTL) {
3112 gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE, 3073 gtk_paint_layout(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE,
3113 NULL, gtkblist->tipwindow, "tooltip", 3074 NULL, gtkblist->tipwindow, "tooltip",
3114 max_width -(TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000), 3075 max_width -(TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
3484 { N_("/Tools/Mute _Sounds"), NULL, pidgin_blist_mute_sounds_cb, 0, "<CheckItem>", NULL }, 3445 { N_("/Tools/Mute _Sounds"), NULL, pidgin_blist_mute_sounds_cb, 0, "<CheckItem>", NULL },
3485 3446
3486 /* Help */ 3447 /* Help */
3487 { N_("/_Help"), NULL, NULL, 0, "<Branch>", NULL }, 3448 { N_("/_Help"), NULL, NULL, 0, "<Branch>", NULL },
3488 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP }, 3449 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP },
3450 { "/Help/sep1", NULL, NULL, 0, "<Separator>", NULL },
3451 { N_("/Help/_Build Information"), NULL, pidgin_dialogs_buildinfo, 0, "<Item>", NULL },
3489 { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, "<Item>", NULL }, 3452 { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, "<Item>", NULL },
3490 #if GTK_CHECK_VERSION(2,6,0) 3453 { N_("/Help/De_veloper Information"), NULL, pidgin_dialogs_developers, 0, "<Item>", NULL },
3454 { N_("/Help/_Translator Information"), NULL, pidgin_dialogs_translators, 0, "<Item>", NULL },
3455 { "/Help/sep2", NULL, NULL, 0, "<Separator>", NULL },
3491 { N_("/Help/_About"), NULL, pidgin_dialogs_about, 4, "<StockItem>", GTK_STOCK_ABOUT }, 3456 { N_("/Help/_About"), NULL, pidgin_dialogs_about, 4, "<StockItem>", GTK_STOCK_ABOUT },
3492 #else
3493 { N_("/Help/_About"), NULL, pidgin_dialogs_about, 4, "<Item>", NULL },
3494 #endif
3495 }; 3457 };
3496 3458
3497 /********************************************************* 3459 /*********************************************************
3498 * Private Utility functions * 3460 * Private Utility functions *
3499 *********************************************************/ 3461 *********************************************************/
3709 } 3671 }
3710 } 3672 }
3711 3673
3712 3674
3713 /* Offline? */ 3675 /* Offline? */
3714 /* FIXME: Why is this status special-cased by the core? -- rlaager */ 3676 /* FIXME: Why is this status special-cased by the core? --rlaager
3677 * FIXME: Alternatively, why not have the core do all of them? --rlaager */
3715 if (!PURPLE_BUDDY_IS_ONLINE(b)) { 3678 if (!PURPLE_BUDDY_IS_ONLINE(b)) {
3716 purple_notify_user_info_add_pair(user_info, _("Status"), _("Offline")); 3679 purple_notify_user_info_add_pair(user_info, _("Status"), _("Offline"));
3717 } 3680 }
3718 3681
3719 if (purple_account_is_connected(b->account) && 3682 if (purple_account_is_connected(b->account) &&
3804 } 3767 }
3805 3768
3806 return pb; 3769 return pb;
3807 } 3770 }
3808 3771
3772 static char *get_mood_icon_path(const char *mood)
3773 {
3774 char *path;
3775
3776 if (!strcmp(mood, "busy")) {
3777 path = g_build_filename(DATADIR, "pixmaps", "pidgin",
3778 "status", "16", "busy.png", NULL);
3779 } else if (!strcmp(mood, "hiptop")) {
3780 path = g_build_filename(DATADIR, "pixmaps", "pidgin",
3781 "emblems", "16", "hiptop.png", NULL);
3782 } else {
3783 char *filename = g_strdup_printf("%s.png", mood);
3784 path = g_build_filename(DATADIR, "pixmaps", "pidgin",
3785 "emotes", "small", filename, NULL);
3786 g_free(filename);
3787 }
3788 return path;
3789 }
3809 3790
3810 GdkPixbuf * 3791 GdkPixbuf *
3811 pidgin_blist_get_emblem(PurpleBlistNode *node) 3792 pidgin_blist_get_emblem(PurpleBlistNode *node)
3812 { 3793 {
3813 PurpleBuddy *buddy = NULL; 3794 PurpleBuddy *buddy = NULL;
3815 struct _pidgin_blist_node *gtkbuddynode = NULL; 3796 struct _pidgin_blist_node *gtkbuddynode = NULL;
3816 PurplePlugin *prpl; 3797 PurplePlugin *prpl;
3817 PurplePluginProtocolInfo *prpl_info; 3798 PurplePluginProtocolInfo *prpl_info;
3818 const char *name = NULL; 3799 const char *name = NULL;
3819 char *filename, *path; 3800 char *filename, *path;
3820 PurplePresence *p; 3801 PurplePresence *p = NULL;
3821 PurpleStatus *tune; 3802 PurpleStatus *tune;
3822 3803
3823 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { 3804 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
3824 if(!gtknode->contact_expanded) { 3805 if(!gtknode->contact_expanded) {
3825 buddy = purple_contact_get_priority_buddy((PurpleContact*)node); 3806 buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
3828 } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { 3809 } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
3829 buddy = (PurpleBuddy*)node; 3810 buddy = (PurpleBuddy*)node;
3830 gtkbuddynode = node->ui_data; 3811 gtkbuddynode = node->ui_data;
3831 p = purple_buddy_get_presence(buddy); 3812 p = purple_buddy_get_presence(buddy);
3832 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) { 3813 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
3833 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", 3814 /* This emblem comes from the small emoticon set now,
3834 "16", "mobile.png", NULL); 3815 * to reduce duplication. */
3816 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes",
3817 "small", "mobile.png", NULL);
3835 return _pidgin_blist_get_cached_emblem(path); 3818 return _pidgin_blist_get_cached_emblem(path);
3836 } 3819 }
3837 3820
3838 if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded) { 3821 if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded) {
3839 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) 3822 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"))
3840 return pidgin_create_prpl_icon(((PurpleBuddy*)node)->account, PIDGIN_PRPL_ICON_SMALL); 3823 return NULL;
3824 return pidgin_create_prpl_icon(((PurpleBuddy*)node)->account, PIDGIN_PRPL_ICON_SMALL);
3841 } 3825 }
3842 } else { 3826 } else {
3843 return NULL; 3827 return NULL;
3844 } 3828 }
3845 3829
3848 if (!purple_privacy_check(buddy->account, purple_buddy_get_name(buddy))) { 3832 if (!purple_privacy_check(buddy->account, purple_buddy_get_name(buddy))) {
3849 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL); 3833 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "blocked.png", NULL);
3850 return _pidgin_blist_get_cached_emblem(path); 3834 return _pidgin_blist_get_cached_emblem(path);
3851 } 3835 }
3852 3836
3853 p = purple_buddy_get_presence(buddy); 3837 /* If we came through the contact code flow above, we didn't need
3838 * to get the presence until now. */
3839 if (p == NULL)
3840 p = purple_buddy_get_presence(buddy);
3841
3854 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) { 3842 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
3855 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "mobile.png", NULL); 3843 /* This emblem comes from the small emoticon set now, to reduce duplication. */
3844 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", "small", "mobile.png", NULL);
3856 return _pidgin_blist_get_cached_emblem(path); 3845 return _pidgin_blist_get_cached_emblem(path);
3857 } 3846 }
3858 3847
3859 tune = purple_presence_get_status(p, "tune"); 3848 tune = purple_presence_get_status(p, "tune");
3860 if (tune && purple_status_is_active(tune)) { 3849 if (tune && purple_status_is_active(tune)) {
3869 if (purple_status_get_attr_string(tune, "office") != NULL) { 3858 if (purple_status_get_attr_string(tune, "office") != NULL) {
3870 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "office.png", NULL); 3859 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "office.png", NULL);
3871 return _pidgin_blist_get_cached_emblem(path); 3860 return _pidgin_blist_get_cached_emblem(path);
3872 } 3861 }
3873 /* Regular old "tune" is the only one in all protocols. */ 3862 /* Regular old "tune" is the only one in all protocols. */
3874 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "music.png", NULL); 3863 /* This emblem comes from the small emoticon set now, to reduce duplication. */
3864 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", "small", "music.png", NULL);
3875 return _pidgin_blist_get_cached_emblem(path); 3865 return _pidgin_blist_get_cached_emblem(path);
3876 } 3866 }
3877 3867
3878 prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account)); 3868 prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
3879 if (!prpl) 3869 if (!prpl)
3881 3871
3882 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); 3872 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
3883 if (prpl_info && prpl_info->list_emblem) 3873 if (prpl_info && prpl_info->list_emblem)
3884 name = prpl_info->list_emblem(buddy); 3874 name = prpl_info->list_emblem(buddy);
3885 3875
3886 if (name == NULL) 3876 if (name == NULL) {
3887 return NULL; 3877 PurpleStatus *status;
3888 3878
3889 filename = g_strdup_printf("%s.png", name); 3879 if (!purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOOD))
3890 3880 return NULL;
3891 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL); 3881
3892 g_free(filename); 3882 status = purple_presence_get_status(p, "mood");
3883 name = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
3884
3885 if (!(name && *name))
3886 return NULL;
3887
3888 path = get_mood_icon_path(name);
3889 } else {
3890 filename = g_strdup_printf("%s.png", name);
3891 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", filename, NULL);
3892 g_free(filename);
3893 }
3893 3894
3894 /* _pidgin_blist_get_cached_emblem() assumes ownership of path */ 3895 /* _pidgin_blist_get_cached_emblem() assumes ownership of path */
3895 return _pidgin_blist_get_cached_emblem(path); 3896 return _pidgin_blist_get_cached_emblem(path);
3896 } 3897 }
3897 3898
4079 char *new = g_strndup(tmp, 4080 char *new = g_strndup(tmp,
4080 g_utf8_pointer_to_offset(tmp, end)); 4081 g_utf8_pointer_to_offset(tmp, end));
4081 g_free(tmp); 4082 g_free(tmp);
4082 tmp = new; 4083 tmp = new;
4083 } 4084 }
4084 /* add ... to messages that are too long, GTK 2.6+ does it automatically */
4085 #if !GTK_CHECK_VERSION(2,6,0)
4086 if(tmp) {
4087 char buf[32];
4088 char *c = tmp;
4089 int length = 0, vis=0;
4090 gboolean inside = FALSE;
4091 g_strdelimit(tmp, "\n", ' ');
4092 purple_str_strip_char(tmp, '\r');
4093
4094 while(*c && vis < 20) {
4095 if(*c == '&')
4096 inside = TRUE;
4097 else if(*c == ';')
4098 inside = FALSE;
4099 if(!inside)
4100 vis++;
4101 c = g_utf8_next_char(c); /* this is fun */
4102 }
4103
4104 length = c - tmp;
4105
4106 if(vis == 20)
4107 g_snprintf(buf, sizeof(buf), "%%.%ds...", length);
4108 else
4109 g_snprintf(buf, sizeof(buf), "%%s ");
4110
4111 statustext = g_strdup_printf(buf, tmp);
4112
4113 g_free(tmp);
4114 }
4115 #else
4116 if(tmp) { 4085 if(tmp) {
4117 g_strdelimit(tmp, "\n", ' '); 4086 g_strdelimit(tmp, "\n", ' ');
4118 purple_str_strip_char(tmp, '\r'); 4087 purple_str_strip_char(tmp, '\r');
4119 } 4088 }
4120 statustext = tmp; 4089 statustext = tmp;
4121 #endif
4122 } 4090 }
4123 4091
4124 if(!purple_presence_is_online(presence) && !statustext) 4092 if(!purple_presence_is_online(presence) && !statustext)
4125 statustext = g_strdup(_("Offline")); 4093 statustext = g_strdup(_("Offline"));
4126 4094
4675 void pidgin_blist_setup_sort_methods() 4643 void pidgin_blist_setup_sort_methods()
4676 { 4644 {
4677 const char *id; 4645 const char *id;
4678 4646
4679 pidgin_blist_sort_method_reg("none", _("Manually"), sort_method_none); 4647 pidgin_blist_sort_method_reg("none", _("Manually"), sort_method_none);
4680 #if GTK_CHECK_VERSION(2,2,1)
4681 pidgin_blist_sort_method_reg("alphabetical", _("Alphabetically"), sort_method_alphabetical); 4648 pidgin_blist_sort_method_reg("alphabetical", _("Alphabetically"), sort_method_alphabetical);
4682 pidgin_blist_sort_method_reg("status", _("By status"), sort_method_status); 4649 pidgin_blist_sort_method_reg("status", _("By status"), sort_method_status);
4683 pidgin_blist_sort_method_reg("log_size", _("By recent log activity"), sort_method_log_activity); 4650 pidgin_blist_sort_method_reg("log_size", _("By recent log activity"), sort_method_log_activity);
4684 #endif
4685 4651
4686 id = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type"); 4652 id = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/sort_type");
4687 if (id == NULL) { 4653 if (id == NULL) {
4688 purple_debug_warning("gtkblist", "Sort method was NULL, resetting to alphabetical\n"); 4654 purple_debug_warning("gtkblist", "Sort method was NULL, resetting to alphabetical\n");
4689 id = "alphabetical"; 4655 id = "alphabetical";
4703 { 4669 {
4704 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); 4670 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
4705 } 4671 }
4706 4672
4707 redo_buddy_list(purple_get_blist(), FALSE, FALSE); 4673 redo_buddy_list(purple_get_blist(), FALSE, FALSE);
4708 #if GTK_CHECK_VERSION(2,6,0)
4709 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); 4674 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview));
4710 #endif
4711 4675
4712 if (node) 4676 if (node)
4713 { 4677 {
4714 struct _pidgin_blist_node *gtknode; 4678 struct _pidgin_blist_node *gtknode;
4715 GtkTreePath *path; 4679 GtkTreePath *path;
4741 4705
4742 priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); 4706 priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist);
4743 4707
4744 /* this is far too ugly thanks to me not wanting to fix #3989 properly right now */ 4708 /* this is far too ugly thanks to me not wanting to fix #3989 properly right now */
4745 if (priv->error_scrollbook != NULL) { 4709 if (priv->error_scrollbook != NULL) {
4746 #if GTK_CHECK_VERSION(2,2,0)
4747 errors = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->error_scrollbook->notebook)); 4710 errors = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->error_scrollbook->notebook));
4748 #else
4749 errors = g_list_length(GTK_NOTEBOOK(priv->error_scrollbook->notebook)->children);
4750 #endif
4751 } 4711 }
4752 if ((list = purple_accounts_get_all_active()) != NULL || errors) { 4712 if ((list = purple_accounts_get_all_active()) != NULL || errors) {
4753 gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 1); 4713 gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 1);
4754 g_list_free(list); 4714 g_list_free(list);
4755 } else 4715 } else
4822 headline_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, PidginBuddyList *gtkblist) 4782 headline_box_enter_cb(GtkWidget *widget, GdkEventCrossing *event, PidginBuddyList *gtkblist)
4823 { 4783 {
4824 gdk_window_set_cursor(widget->window, gtkblist->hand_cursor); 4784 gdk_window_set_cursor(widget->window, gtkblist->hand_cursor);
4825 4785
4826 if (gtkblist->headline_close) { 4786 if (gtkblist->headline_close) {
4827 #if GTK_CHECK_VERSION(2,2,0)
4828 gdk_draw_pixbuf(widget->window, NULL, gtkblist->headline_close, 4787 gdk_draw_pixbuf(widget->window, NULL, gtkblist->headline_close,
4829 #else
4830 gdk_pixbuf_render_to_drawable(gtkblist->headline_close,
4831 GDK_DRAWABLE(widget->window), NULL,
4832 #endif
4833 0, 0, 4788 0, 0,
4834 widget->allocation.width - 2 - HEADLINE_CLOSE_SIZE, 2, 4789 widget->allocation.width - 2 - HEADLINE_CLOSE_SIZE, 2,
4835 HEADLINE_CLOSE_SIZE, HEADLINE_CLOSE_SIZE, 4790 HEADLINE_CLOSE_SIZE, HEADLINE_CLOSE_SIZE,
4836 GDK_RGB_DITHER_NONE, 0, 0); 4791 GDK_RGB_DITHER_NONE, 0, 0);
4837 #if 0
4838 /* The presence of one opening paren in each branch of
4839 * GTK_CHECK_VERSION confuses vim's bracket matching for the
4840 * rest of the file.
4841 */
4842 )
4843 #endif
4844 gtk_paint_focus(widget->style, widget->window, GTK_STATE_PRELIGHT, 4792 gtk_paint_focus(widget->style, widget->window, GTK_STATE_PRELIGHT,
4845 NULL, widget, NULL, 4793 NULL, widget, NULL,
4846 widget->allocation.width - HEADLINE_CLOSE_SIZE - 3, 1, 4794 widget->allocation.width - HEADLINE_CLOSE_SIZE - 3, 1,
4847 HEADLINE_CLOSE_SIZE + 2, HEADLINE_CLOSE_SIZE + 2); 4795 HEADLINE_CLOSE_SIZE + 2, HEADLINE_CLOSE_SIZE + 2);
4848 } 4796 }
5197 label = gtk_label_new(NULL); 5145 label = gtk_label_new(NULL);
5198 markup = g_strdup_printf("<span size=\"smaller\">%s</span>", username); 5146 markup = g_strdup_printf("<span size=\"smaller\">%s</span>", username);
5199 gtk_label_set_markup(GTK_LABEL(label), markup); 5147 gtk_label_set_markup(GTK_LABEL(label), markup);
5200 g_free(markup); 5148 g_free(markup);
5201 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 5149 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
5202 #if GTK_CHECK_VERSION(2,6,0)
5203 g_object_set(G_OBJECT(label), "ellipsize", PANGO_ELLIPSIZE_END, NULL); 5150 g_object_set(G_OBJECT(label), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
5204 #endif
5205 #if GTK_CHECK_VERSION(2,12,0) 5151 #if GTK_CHECK_VERSION(2,12,0)
5206 { /* avoid unused variable warnings on pre-2.12 Gtk */ 5152 { /* avoid unused variable warnings on pre-2.12 Gtk */
5207 char *description = 5153 char *description =
5208 purple_account_get_current_error(account)->description; 5154 purple_account_get_current_error(account)->description;
5209 if (description != NULL && *description != '\0') 5155 if (description != NULL && *description != '\0')
5402 5348
5403 if (gtkblist->changing_style) 5349 if (gtkblist->changing_style)
5404 return; 5350 return;
5405 5351
5406 tooltips = gtk_tooltips_new (); 5352 tooltips = gtk_tooltips_new ();
5407 #if GLIB_CHECK_VERSION(2,10,0)
5408 g_object_ref_sink (tooltips); 5353 g_object_ref_sink (tooltips);
5409 #else
5410 g_object_ref(tooltips);
5411 gtk_object_sink(GTK_OBJECT(tooltips));
5412 #endif
5413 5354
5414 gtk_tooltips_force_window (tooltips); 5355 gtk_tooltips_force_window (tooltips);
5415 #if GTK_CHECK_VERSION(2, 12, 0) 5356 #if GTK_CHECK_VERSION(2, 12, 0)
5416 gtk_widget_set_name (tooltips->tip_window, "gtk-tooltips"); 5357 gtk_widget_set_name (tooltips->tip_window, "gtk-tooltips");
5417 #endif 5358 #endif
5515 rend = pidgin_cell_renderer_expander_new(); 5456 rend = pidgin_cell_renderer_expander_new();
5516 gtk_tree_view_column_pack_start(column, rend, FALSE); 5457 gtk_tree_view_column_pack_start(column, rend, FALSE);
5517 gtk_tree_view_column_set_attributes(column, rend, 5458 gtk_tree_view_column_set_attributes(column, rend,
5518 "visible", GROUP_EXPANDER_VISIBLE_COLUMN, 5459 "visible", GROUP_EXPANDER_VISIBLE_COLUMN,
5519 "expander-visible", GROUP_EXPANDER_COLUMN, 5460 "expander-visible", GROUP_EXPANDER_COLUMN,
5520 #if GTK_CHECK_VERSION(2,6,0)
5521 "sensitive", GROUP_EXPANDER_COLUMN, 5461 "sensitive", GROUP_EXPANDER_COLUMN,
5522 "cell-background-gdk", BGCOLOR_COLUMN, 5462 "cell-background-gdk", BGCOLOR_COLUMN,
5523 #endif
5524 NULL); 5463 NULL);
5525 5464
5526 /* contact */ 5465 /* contact */
5527 rend = pidgin_cell_renderer_expander_new(); 5466 rend = pidgin_cell_renderer_expander_new();
5528 gtk_tree_view_column_pack_start(column, rend, FALSE); 5467 gtk_tree_view_column_pack_start(column, rend, FALSE);
5529 gtk_tree_view_column_set_attributes(column, rend, 5468 gtk_tree_view_column_set_attributes(column, rend,
5530 "visible", CONTACT_EXPANDER_VISIBLE_COLUMN, 5469 "visible", CONTACT_EXPANDER_VISIBLE_COLUMN,
5531 "expander-visible", CONTACT_EXPANDER_COLUMN, 5470 "expander-visible", CONTACT_EXPANDER_COLUMN,
5532 #if GTK_CHECK_VERSION(2,6,0)
5533 "sensitive", CONTACT_EXPANDER_COLUMN, 5471 "sensitive", CONTACT_EXPANDER_COLUMN,
5534 "cell-background-gdk", BGCOLOR_COLUMN, 5472 "cell-background-gdk", BGCOLOR_COLUMN,
5535 #endif
5536 NULL); 5473 NULL);
5537 5474
5538 for (i = 0; i < 5; i++) { 5475 for (i = 0; i < 5; i++) {
5539 5476
5540 if (status_icon == i) { 5477 if (status_icon == i) {
5542 rend = gtk_cell_renderer_pixbuf_new(); 5479 rend = gtk_cell_renderer_pixbuf_new();
5543 gtk_tree_view_column_pack_start(column, rend, FALSE); 5480 gtk_tree_view_column_pack_start(column, rend, FALSE);
5544 gtk_tree_view_column_set_attributes(column, rend, 5481 gtk_tree_view_column_set_attributes(column, rend,
5545 "pixbuf", STATUS_ICON_COLUMN, 5482 "pixbuf", STATUS_ICON_COLUMN,
5546 "visible", STATUS_ICON_VISIBLE_COLUMN, 5483 "visible", STATUS_ICON_VISIBLE_COLUMN,
5547 #if GTK_CHECK_VERSION(2,6,0)
5548 "cell-background-gdk", BGCOLOR_COLUMN, 5484 "cell-background-gdk", BGCOLOR_COLUMN,
5549 #endif
5550 NULL); 5485 NULL);
5551 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); 5486 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL);
5552 5487
5553 } else if (text == i) { 5488 } else if (text == i) {
5554 /* name */ 5489 /* name */
5555 gtkblist->text_rend = rend = gtk_cell_renderer_text_new(); 5490 gtkblist->text_rend = rend = gtk_cell_renderer_text_new();
5556 gtk_tree_view_column_pack_start(column, rend, TRUE); 5491 gtk_tree_view_column_pack_start(column, rend, TRUE);
5557 gtk_tree_view_column_set_attributes(column, rend, 5492 gtk_tree_view_column_set_attributes(column, rend,
5558 #if GTK_CHECK_VERSION(2,6,0)
5559 "cell-background-gdk", BGCOLOR_COLUMN, 5493 "cell-background-gdk", BGCOLOR_COLUMN,
5560 #endif
5561 "markup", NAME_COLUMN, 5494 "markup", NAME_COLUMN,
5562 NULL); 5495 NULL);
5563 #if GTK_CHECK_VERSION(2,6,0)
5564 g_signal_connect(G_OBJECT(rend), "editing-started", G_CALLBACK(gtk_blist_renderer_editing_started_cb), NULL); 5496 g_signal_connect(G_OBJECT(rend), "editing-started", G_CALLBACK(gtk_blist_renderer_editing_started_cb), NULL);
5565 g_signal_connect(G_OBJECT(rend), "editing-canceled", G_CALLBACK(gtk_blist_renderer_editing_cancelled_cb), list); 5497 g_signal_connect(G_OBJECT(rend), "editing-canceled", G_CALLBACK(gtk_blist_renderer_editing_cancelled_cb), list);
5566 #endif
5567 g_signal_connect(G_OBJECT(rend), "edited", G_CALLBACK(gtk_blist_renderer_edited_cb), list); 5498 g_signal_connect(G_OBJECT(rend), "edited", G_CALLBACK(gtk_blist_renderer_edited_cb), list);
5568 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); 5499 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL);
5569 #if GTK_CHECK_VERSION(2,6,0)
5570 g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); 5500 g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
5571 #endif
5572 5501
5573 /* idle */ 5502 /* idle */
5574 rend = gtk_cell_renderer_text_new(); 5503 rend = gtk_cell_renderer_text_new();
5575 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); 5504 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL);
5576 gtk_tree_view_column_pack_start(column, rend, FALSE); 5505 gtk_tree_view_column_pack_start(column, rend, FALSE);
5577 gtk_tree_view_column_set_attributes(column, rend, 5506 gtk_tree_view_column_set_attributes(column, rend,
5578 "markup", IDLE_COLUMN, 5507 "markup", IDLE_COLUMN,
5579 "visible", IDLE_VISIBLE_COLUMN, 5508 "visible", IDLE_VISIBLE_COLUMN,
5580 #if GTK_CHECK_VERSION(2,6,0)
5581 "cell-background-gdk", BGCOLOR_COLUMN, 5509 "cell-background-gdk", BGCOLOR_COLUMN,
5582 #endif
5583 NULL); 5510 NULL);
5584 } else if (emblem == i) { 5511 } else if (emblem == i) {
5585 /* emblem */ 5512 /* emblem */
5586 rend = gtk_cell_renderer_pixbuf_new(); 5513 rend = gtk_cell_renderer_pixbuf_new();
5587 g_object_set(rend, "xalign", 1.0, "yalign", 0.5, "ypad", 0, "xpad", 3, NULL); 5514 g_object_set(rend, "xalign", 1.0, "yalign", 0.5, "ypad", 0, "xpad", 3, NULL);
5588 gtk_tree_view_column_pack_start(column, rend, FALSE); 5515 gtk_tree_view_column_pack_start(column, rend, FALSE);
5589 gtk_tree_view_column_set_attributes(column, rend, "pixbuf", EMBLEM_COLUMN, 5516 gtk_tree_view_column_set_attributes(column, rend, "pixbuf", EMBLEM_COLUMN,
5590 #if GTK_CHECK_VERSION(2,6,0)
5591 "cell-background-gdk", BGCOLOR_COLUMN, 5517 "cell-background-gdk", BGCOLOR_COLUMN,
5592 #endif
5593 "visible", EMBLEM_VISIBLE_COLUMN, NULL); 5518 "visible", EMBLEM_VISIBLE_COLUMN, NULL);
5594 5519
5595 } else if (protocol_icon == i) { 5520 } else if (protocol_icon == i) {
5596 /* protocol icon */ 5521 /* protocol icon */
5597 rend = gtk_cell_renderer_pixbuf_new(); 5522 rend = gtk_cell_renderer_pixbuf_new();
5598 gtk_tree_view_column_pack_start(column, rend, FALSE); 5523 gtk_tree_view_column_pack_start(column, rend, FALSE);
5599 gtk_tree_view_column_set_attributes(column, rend, 5524 gtk_tree_view_column_set_attributes(column, rend,
5600 "pixbuf", PROTOCOL_ICON_COLUMN, 5525 "pixbuf", PROTOCOL_ICON_COLUMN,
5601 "visible", PROTOCOL_ICON_VISIBLE_COLUMN, 5526 "visible", PROTOCOL_ICON_VISIBLE_COLUMN,
5602 #if GTK_CHECK_VERSION(2,6,0)
5603 "cell-background-gdk", BGCOLOR_COLUMN, 5527 "cell-background-gdk", BGCOLOR_COLUMN,
5604 #endif
5605 NULL); 5528 NULL);
5606 g_object_set(rend, "xalign", 0.0, "xpad", 3, "ypad", 0, NULL); 5529 g_object_set(rend, "xalign", 0.0, "xpad", 3, "ypad", 0, NULL);
5607 5530
5608 } else if (buddy_icon == i) { 5531 } else if (buddy_icon == i) {
5609 /* buddy icon */ 5532 /* buddy icon */
5610 rend = gtk_cell_renderer_pixbuf_new(); 5533 rend = gtk_cell_renderer_pixbuf_new();
5611 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); 5534 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL);
5612 gtk_tree_view_column_pack_start(column, rend, FALSE); 5535 gtk_tree_view_column_pack_start(column, rend, FALSE);
5613 gtk_tree_view_column_set_attributes(column, rend, "pixbuf", BUDDY_ICON_COLUMN, 5536 gtk_tree_view_column_set_attributes(column, rend, "pixbuf", BUDDY_ICON_COLUMN,
5614 #if GTK_CHECK_VERSION(2,6,0)
5615 "cell-background-gdk", BGCOLOR_COLUMN, 5537 "cell-background-gdk", BGCOLOR_COLUMN,
5616 #endif
5617 "visible", BUDDY_ICON_VISIBLE_COLUMN, 5538 "visible", BUDDY_ICON_VISIBLE_COLUMN,
5618 NULL); 5539 NULL);
5619 } 5540 }
5620 5541
5621 }/* end for loop */ 5542 }/* end for loop */
6798 break; 6719 break;
6799 case PURPLE_BLIST_OTHER_NODE: 6720 case PURPLE_BLIST_OTHER_NODE:
6800 return; 6721 return;
6801 } 6722 }
6802 6723
6803 #if !GTK_CHECK_VERSION(2,6,0)
6804 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview));
6805 #endif
6806 } 6724 }
6807 6725
6808 static void pidgin_blist_destroy(PurpleBuddyList *list) 6726 static void pidgin_blist_destroy(PurpleBuddyList *list)
6809 { 6727 {
6810 PidginBuddyListPrivate *priv; 6728 PidginBuddyListPrivate *priv;
7599 gtk_tree_store_insert_after(gtkblist->treemodel, iter, 7517 gtk_tree_store_insert_after(gtkblist->treemodel, iter,
7600 node->parent ? &parent_iter : NULL, 7518 node->parent ? &parent_iter : NULL,
7601 sibling ? &sibling_iter : NULL); 7519 sibling ? &sibling_iter : NULL);
7602 } 7520 }
7603 7521
7604 #if GTK_CHECK_VERSION(2,2,1)
7605
7606 static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter) 7522 static void sort_method_alphabetical(PurpleBlistNode *node, PurpleBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur, GtkTreeIter *iter)
7607 { 7523 {
7608 GtkTreeIter more_z; 7524 GtkTreeIter more_z;
7609 7525
7610 const char *my_name; 7526 const char *my_name;
7844 gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter); 7760 gtk_tree_store_append(gtkblist->treemodel, iter, &groupiter);
7845 return; 7761 return;
7846 } 7762 }
7847 } 7763 }
7848 7764
7849 #endif
7850
7851 static void 7765 static void
7852 plugin_act(GtkObject *obj, PurplePluginAction *pam) 7766 plugin_act(GtkObject *obj, PurplePluginAction *pam)
7853 { 7767 {
7854 if (pam && pam->callback) 7768 if (pam && pam->callback)
7855 pam->callback(pam); 7769 pam->callback(pam);
7912 disable_account_cb(GtkCheckMenuItem *widget, gpointer data) 7826 disable_account_cb(GtkCheckMenuItem *widget, gpointer data)
7913 { 7827 {
7914 PurpleAccount *account = data; 7828 PurpleAccount *account = data;
7915 7829
7916 purple_account_set_enabled(account, PIDGIN_UI, FALSE); 7830 purple_account_set_enabled(account, PIDGIN_UI, FALSE);
7831 }
7832
7833 static void
7834 edit_mood_cb(PurpleConnection *gc, PurpleRequestFields *fields)
7835 {
7836 PurpleRequestField *f;
7837 GList *l;
7838
7839 f = purple_request_fields_get_field(fields, "mood");
7840 l = purple_request_field_list_get_selected(f);
7841
7842 if (l) {
7843 const char *mood = purple_request_field_list_get_data(f, l->data);
7844 PurpleAccount *account = purple_connection_get_account(gc);
7845
7846 if (mood != NULL) {
7847 purple_account_set_status(account, "mood", TRUE,
7848 PURPLE_MOOD_NAME, mood,
7849 NULL);
7850 } else {
7851 purple_account_set_status(account, "mood", FALSE, NULL);
7852 }
7853 }
7854 }
7855
7856 static void
7857 set_mood_cb(GtkWidget *widget, PurpleAccount *account)
7858 {
7859 PurplePresence *presence = purple_account_get_presence(account);
7860 PurpleStatus *status = purple_presence_get_status(presence, "mood");
7861 const char *current_mood;
7862 PurpleRequestFields *fields;
7863 PurpleRequestFieldGroup *g;
7864 PurpleRequestField *f;
7865 char* na_fn;
7866 PurpleConnection *gc = purple_account_get_connection(account);
7867 PurplePluginProtocolInfo *prpl_info;
7868 PurpleMood *mood;
7869
7870 g_return_if_fail(gc->prpl != NULL);
7871 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
7872
7873 current_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
7874
7875 fields = purple_request_fields_new();
7876 g = purple_request_field_group_new(NULL);
7877 f = purple_request_field_list_new("mood", _("Please select your mood from the list"));
7878
7879 na_fn = g_build_filename("pixmaps", "pidgin", "emblems", "16", "not-authorized.png", NULL);
7880
7881 purple_request_field_list_add_icon(f, _("None"), na_fn, NULL);
7882 if (current_mood == NULL)
7883 purple_request_field_list_add_selected(f, _("None"));
7884
7885 g_free(na_fn);
7886
7887 /* TODO: rlaager wants this sorted. */
7888 for (mood = prpl_info->get_moods(account);
7889 mood->mood != NULL ; mood++) {
7890 char *path;
7891
7892 if (mood->mood == NULL || mood->description == NULL)
7893 continue;
7894
7895 path = get_mood_icon_path(mood->mood);
7896 purple_request_field_list_add_icon(f, _(mood->description),
7897 path, (gpointer)mood->mood);
7898 g_free(path);
7899
7900 if (current_mood && !strcmp(current_mood, mood->mood))
7901 purple_request_field_list_add_selected(f, _(mood->description));
7902 }
7903 purple_request_field_group_add_field(g, f);
7904
7905 purple_request_fields_add_group(fields, g);
7906
7907 purple_request_fields(gc, _("Edit User Mood"), _("Edit User Mood"),
7908 NULL, fields,
7909 _("OK"), G_CALLBACK(edit_mood_cb),
7910 _("Cancel"), NULL,
7911 purple_connection_get_account(gc),
7912 NULL, NULL, gc);
7917 } 7913 }
7918 7914
7919 void 7915 void
7920 pidgin_blist_update_accounts_menu(void) 7916 pidgin_blist_update_accounts_menu(void)
7921 { 7917 {
7993 GtkWidget *image = NULL; 7989 GtkWidget *image = NULL;
7994 PurpleConnection *gc = NULL; 7990 PurpleConnection *gc = NULL;
7995 PurpleAccount *account = NULL; 7991 PurpleAccount *account = NULL;
7996 GdkPixbuf *pixbuf = NULL; 7992 GdkPixbuf *pixbuf = NULL;
7997 PurplePlugin *plugin = NULL; 7993 PurplePlugin *plugin = NULL;
7994 PurplePluginProtocolInfo *prpl_info;
7998 7995
7999 account = accounts->data; 7996 account = accounts->data;
8000 7997
8001 if (!purple_account_get_enabled(account, PIDGIN_UI)) 7998 if (!purple_account_get_enabled(account, PIDGIN_UI))
8002 continue; 7999 continue;
8032 8029
8033 pidgin_separator(submenu); 8030 pidgin_separator(submenu);
8034 8031
8035 gc = purple_account_get_connection(account); 8032 gc = purple_account_get_connection(account);
8036 plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL; 8033 plugin = gc && PURPLE_CONNECTION_IS_CONNECTED(gc) ? gc->prpl : NULL;
8037 if (plugin && PURPLE_PLUGIN_HAS_ACTIONS(plugin)) { 8034 prpl_info = plugin ? PURPLE_PLUGIN_PROTOCOL_INFO(plugin) : NULL;
8038 build_plugin_actions(submenu, plugin, gc); 8035
8036 if (prpl_info &&
8037 (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods) ||
8038 PURPLE_PLUGIN_HAS_ACTIONS(plugin))) {
8039 if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_moods)) {
8040 GList *types;
8041 for (types = purple_account_get_status_types(account);
8042 types != NULL ; types = types->next) {
8043 PurpleStatusType *type = types->data;
8044
8045 if (strcmp(purple_status_type_get_id(type), "mood") != 0)
8046 continue;
8047
8048 menuitem = gtk_menu_item_new_with_mnemonic(_("Set _Mood..."));
8049 g_signal_connect(G_OBJECT(menuitem), "activate",
8050 G_CALLBACK(set_mood_cb), account);
8051 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
8052
8053 /* Be safe. It shouldn't match more than once anyway */
8054 break;
8055 }
8056 }
8057 if (PURPLE_PLUGIN_HAS_ACTIONS(plugin)) {
8058 build_plugin_actions(submenu, plugin, gc);
8059 }
8039 } else { 8060 } else {
8040 menuitem = gtk_menu_item_new_with_label(_("No actions available")); 8061 menuitem = gtk_menu_item_new_with_label(_("No actions available"));
8041 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); 8062 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
8042 gtk_widget_set_sensitive(menuitem, FALSE); 8063 gtk_widget_set_sensitive(menuitem, FALSE);
8043 } 8064 }