| 3247 gtkblist->mouseover_contact = NULL; |
3248 gtkblist->mouseover_contact = NULL; |
| 3248 } |
3249 } |
| 3249 return FALSE; |
3250 return FALSE; |
| 3250 } |
3251 } |
| 3251 |
3252 |
| 3252 static char *get_mood_icon_path(const char *mood) |
|
| 3253 { |
|
| 3254 char *path; |
|
| 3255 |
|
| 3256 if (purple_strequal(mood, "busy")) { |
|
| 3257 path = g_build_filename(PURPLE_DATADIR, "pidgin", "icons", |
|
| 3258 "hicolor", "16x16", "status", "user-busy.png", NULL); |
|
| 3259 } else if (purple_strequal(mood, "hiptop")) { |
|
| 3260 path = g_build_filename(PURPLE_DATADIR, "pidgin", "icons", |
|
| 3261 "hicolor", "16x16", "emblems", "emblem-hiptop.png", |
|
| 3262 NULL); |
|
| 3263 } else { |
|
| 3264 char *filename = g_strdup_printf("%s.png", mood); |
|
| 3265 path = g_build_filename(PURPLE_DATADIR, "pixmaps", "pidgin", |
|
| 3266 "emotes", "small", filename, NULL); |
|
| 3267 g_free(filename); |
|
| 3268 } |
|
| 3269 return path; |
|
| 3270 } |
|
| 3271 |
|
| 3272 static void |
|
| 3273 update_status_with_mood(PurpleAccount *account, const gchar *mood, |
|
| 3274 const gchar *text) |
|
| 3275 { |
|
| 3276 if (mood && *mood) { |
|
| 3277 if (text) { |
|
| 3278 purple_account_set_status(account, "mood", TRUE, |
|
| 3279 PURPLE_MOOD_NAME, mood, |
|
| 3280 PURPLE_MOOD_COMMENT, text, |
|
| 3281 NULL); |
|
| 3282 } else { |
|
| 3283 purple_account_set_status(account, "mood", TRUE, |
|
| 3284 PURPLE_MOOD_NAME, mood, |
|
| 3285 NULL); |
|
| 3286 } |
|
| 3287 } else { |
|
| 3288 purple_account_set_status(account, "mood", FALSE, NULL); |
|
| 3289 } |
|
| 3290 } |
|
| 3291 |
|
| 3292 static void |
|
| 3293 edit_mood_cb(PurpleConnection *gc, PurpleRequestFields *fields) |
|
| 3294 { |
|
| 3295 PurpleRequestField *mood_field; |
|
| 3296 GList *l; |
|
| 3297 |
|
| 3298 mood_field = purple_request_fields_get_field(fields, "mood"); |
|
| 3299 l = purple_request_field_list_get_selected(mood_field); |
|
| 3300 |
|
| 3301 if (l) { |
|
| 3302 const char *mood = purple_request_field_list_get_data(mood_field, l->data); |
|
| 3303 |
|
| 3304 if (gc) { |
|
| 3305 const char *text; |
|
| 3306 PurpleAccount *account = purple_connection_get_account(gc); |
|
| 3307 |
|
| 3308 if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOOD_MESSAGES) { |
|
| 3309 PurpleRequestField *text_field; |
|
| 3310 text_field = purple_request_fields_get_field(fields, "text"); |
|
| 3311 text = purple_request_field_string_get_value(text_field); |
|
| 3312 } else { |
|
| 3313 text = NULL; |
|
| 3314 } |
|
| 3315 |
|
| 3316 update_status_with_mood(account, mood, text); |
|
| 3317 } else { |
|
| 3318 GList *accounts = purple_accounts_get_all_active(); |
|
| 3319 |
|
| 3320 for (; accounts ; accounts = g_list_delete_link(accounts, accounts)) { |
|
| 3321 PurpleAccount *account = (PurpleAccount *) accounts->data; |
|
| 3322 PurpleConnection *gc = purple_account_get_connection(account); |
|
| 3323 |
|
| 3324 if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOODS)) { |
|
| 3325 update_status_with_mood(account, mood, NULL); |
|
| 3326 } |
|
| 3327 } |
|
| 3328 } |
|
| 3329 } |
|
| 3330 } |
|
| 3331 |
|
| 3332 static void |
|
| 3333 global_moods_for_each(gpointer key, gpointer value, gpointer user_data) |
|
| 3334 { |
|
| 3335 GList **out_moods = (GList **) user_data; |
|
| 3336 PurpleMood *mood = (PurpleMood *) value; |
|
| 3337 |
|
| 3338 *out_moods = g_list_append(*out_moods, mood); |
|
| 3339 } |
|
| 3340 |
|
| 3341 static PurpleMood * |
|
| 3342 get_global_moods(void) |
|
| 3343 { |
|
| 3344 GHashTable *global_moods = |
|
| 3345 g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); |
|
| 3346 GHashTable *mood_counts = |
|
| 3347 g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); |
|
| 3348 GList *accounts = purple_accounts_get_all_active(); |
|
| 3349 PurpleMood *result = NULL; |
|
| 3350 GList *out_moods = NULL; |
|
| 3351 int i = 0; |
|
| 3352 int num_accounts = 0; |
|
| 3353 |
|
| 3354 for (; accounts ; accounts = g_list_delete_link(accounts, accounts)) { |
|
| 3355 PurpleAccount *account = (PurpleAccount *) accounts->data; |
|
| 3356 if (purple_account_is_connected(account)) { |
|
| 3357 PurpleConnection *gc = purple_account_get_connection(account); |
|
| 3358 |
|
| 3359 if (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOODS) { |
|
| 3360 PurpleProtocol *protocol = purple_connection_get_protocol(gc); |
|
| 3361 PurpleMood *mood = NULL; |
|
| 3362 |
|
| 3363 for (mood = purple_protocol_client_iface_get_moods(protocol, account) ; |
|
| 3364 mood->mood != NULL ; mood++) { |
|
| 3365 int mood_count = |
|
| 3366 GPOINTER_TO_INT(g_hash_table_lookup(mood_counts, mood->mood)); |
|
| 3367 |
|
| 3368 if (!g_hash_table_lookup(global_moods, mood->mood)) { |
|
| 3369 g_hash_table_insert(global_moods, (gpointer)mood->mood, mood); |
|
| 3370 } |
|
| 3371 g_hash_table_insert(mood_counts, (gpointer)mood->mood, |
|
| 3372 GINT_TO_POINTER(mood_count + 1)); |
|
| 3373 } |
|
| 3374 |
|
| 3375 num_accounts++; |
|
| 3376 } |
|
| 3377 } |
|
| 3378 } |
|
| 3379 |
|
| 3380 g_hash_table_foreach(global_moods, global_moods_for_each, &out_moods); |
|
| 3381 result = g_new0(PurpleMood, g_hash_table_size(global_moods) + 1); |
|
| 3382 |
|
| 3383 while (out_moods) { |
|
| 3384 PurpleMood *mood = (PurpleMood *) out_moods->data; |
|
| 3385 int in_num_accounts = |
|
| 3386 GPOINTER_TO_INT(g_hash_table_lookup(mood_counts, mood->mood)); |
|
| 3387 |
|
| 3388 if (in_num_accounts == num_accounts) { |
|
| 3389 /* mood is present in all accounts supporting moods */ |
|
| 3390 result[i].mood = mood->mood; |
|
| 3391 result[i].description = mood->description; |
|
| 3392 i++; |
|
| 3393 } |
|
| 3394 out_moods = g_list_delete_link(out_moods, out_moods); |
|
| 3395 } |
|
| 3396 |
|
| 3397 g_hash_table_destroy(global_moods); |
|
| 3398 g_hash_table_destroy(mood_counts); |
|
| 3399 |
|
| 3400 return result; |
|
| 3401 } |
|
| 3402 |
|
| 3403 /* get current set mood for all mood-supporting accounts, or NULL if not set |
|
| 3404 or not set to the same on all */ |
|
| 3405 static const gchar * |
|
| 3406 get_global_mood_status(void) |
|
| 3407 { |
|
| 3408 GList *accounts = purple_accounts_get_all_active(); |
|
| 3409 const gchar *found_mood = NULL; |
|
| 3410 |
|
| 3411 for (; accounts ; accounts = g_list_delete_link(accounts, accounts)) { |
|
| 3412 PurpleAccount *account = (PurpleAccount *) accounts->data; |
|
| 3413 |
|
| 3414 if (purple_account_is_connected(account) && |
|
| 3415 (purple_connection_get_flags(purple_account_get_connection(account)) & |
|
| 3416 PURPLE_CONNECTION_FLAG_SUPPORT_MOODS)) { |
|
| 3417 PurplePresence *presence = purple_account_get_presence(account); |
|
| 3418 PurpleStatus *status = purple_presence_get_status(presence, "mood"); |
|
| 3419 const gchar *curr_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); |
|
| 3420 |
|
| 3421 if (found_mood != NULL && !purple_strequal(curr_mood, found_mood)) { |
|
| 3422 /* found a different mood */ |
|
| 3423 found_mood = NULL; |
|
| 3424 break; |
|
| 3425 } else { |
|
| 3426 found_mood = curr_mood; |
|
| 3427 } |
|
| 3428 } |
|
| 3429 } |
|
| 3430 |
|
| 3431 return found_mood; |
|
| 3432 } |
|
| 3433 |
|
| 3434 static void |
|
| 3435 set_mood_cb(GtkWidget *widget, PurpleAccount *account) |
|
| 3436 { |
|
| 3437 const char *current_mood; |
|
| 3438 PurpleRequestFields *fields; |
|
| 3439 PurpleRequestFieldGroup *g; |
|
| 3440 PurpleRequestField *f; |
|
| 3441 PurpleConnection *gc = NULL; |
|
| 3442 PurpleProtocol *protocol = NULL; |
|
| 3443 PurpleMood *mood; |
|
| 3444 PurpleMood *global_moods = NULL; |
|
| 3445 |
|
| 3446 if (account) { |
|
| 3447 PurplePresence *presence = purple_account_get_presence(account); |
|
| 3448 PurpleStatus *status = purple_presence_get_status(presence, "mood"); |
|
| 3449 gc = purple_account_get_connection(account); |
|
| 3450 g_return_if_fail(purple_connection_get_protocol(gc) != NULL); |
|
| 3451 protocol = purple_connection_get_protocol(gc); |
|
| 3452 current_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); |
|
| 3453 } else { |
|
| 3454 current_mood = get_global_mood_status(); |
|
| 3455 } |
|
| 3456 |
|
| 3457 fields = purple_request_fields_new(); |
|
| 3458 g = purple_request_field_group_new(NULL); |
|
| 3459 f = purple_request_field_list_new("mood", _("Please select your mood from the list")); |
|
| 3460 |
|
| 3461 purple_request_field_list_add_icon(f, _("None"), NULL, ""); |
|
| 3462 if (current_mood == NULL) |
|
| 3463 purple_request_field_list_add_selected(f, _("None")); |
|
| 3464 |
|
| 3465 /* TODO: rlaager wants this sorted. */ |
|
| 3466 /* TODO: darkrain wants it sorted post-translation */ |
|
| 3467 if (account && PURPLE_PROTOCOL_IMPLEMENTS(protocol, CLIENT, get_moods)) { |
|
| 3468 mood = purple_protocol_client_iface_get_moods(protocol, account); |
|
| 3469 } else { |
|
| 3470 mood = global_moods = get_global_moods(); |
|
| 3471 } |
|
| 3472 for ( ; mood->mood != NULL ; mood++) { |
|
| 3473 char *path; |
|
| 3474 |
|
| 3475 if (mood->description == NULL) { |
|
| 3476 continue; |
|
| 3477 } |
|
| 3478 |
|
| 3479 path = get_mood_icon_path(mood->mood); |
|
| 3480 purple_request_field_list_add_icon(f, _(mood->description), |
|
| 3481 path, (gpointer)mood->mood); |
|
| 3482 g_free(path); |
|
| 3483 |
|
| 3484 if (current_mood && purple_strequal(current_mood, mood->mood)) |
|
| 3485 purple_request_field_list_add_selected(f, _(mood->description)); |
|
| 3486 } |
|
| 3487 purple_request_field_group_add_field(g, f); |
|
| 3488 |
|
| 3489 purple_request_fields_add_group(fields, g); |
|
| 3490 |
|
| 3491 /* if the connection allows setting a mood message */ |
|
| 3492 if (gc && (purple_connection_get_flags(gc) & PURPLE_CONNECTION_FLAG_SUPPORT_MOOD_MESSAGES)) { |
|
| 3493 g = purple_request_field_group_new(NULL); |
|
| 3494 f = purple_request_field_string_new("text", |
|
| 3495 _("Message (optional)"), NULL, FALSE); |
|
| 3496 purple_request_field_group_add_field(g, f); |
|
| 3497 purple_request_fields_add_group(fields, g); |
|
| 3498 } |
|
| 3499 |
|
| 3500 purple_request_fields(gc, _("Edit User Mood"), _("Edit User Mood"), |
|
| 3501 NULL, fields, |
|
| 3502 _("OK"), G_CALLBACK(edit_mood_cb), |
|
| 3503 _("Cancel"), NULL, |
|
| 3504 purple_request_cpar_from_connection(gc), gc); |
|
| 3505 |
|
| 3506 g_free(global_moods); |
|
| 3507 } |
|
| 3508 |
|
| 3509 static void |
|
| 3510 set_mood_show(void) |
|
| 3511 { |
|
| 3512 set_mood_cb(NULL, NULL); |
|
| 3513 } |
|
| 3514 |
|
| 3515 /*************************************************** |
|
| 3516 * Crap * |
|
| 3517 ***************************************************/ |
|
| 3518 static const GtkActionEntry blist_menu_entries[] = { |
|
| 3519 /* Tools */ |
|
| 3520 { "ToolsMenu", NULL, N_("_Tools"), NULL, NULL, NULL }, |
|
| 3521 { "SetMood", NULL, N_("Set _Mood"), "<control>D", NULL, set_mood_show }, |
|
| 3522 }; |
|
| 3523 |
|
| 3524 static const char *blist_menu = |
|
| 3525 "<ui>" |
|
| 3526 "<menubar name='BList'>" |
|
| 3527 "<menu action='ToolsMenu'>" |
|
| 3528 "<menuitem action='SetMood'/>" |
|
| 3529 "</menu>" |
|
| 3530 "</menubar>" |
|
| 3531 "</ui>"; |
|
| 3532 |
|
| 3533 /********************************************************* |
3253 /********************************************************* |
| 3534 * Private Utility functions * |
3254 * Private Utility functions * |
| 3535 *********************************************************/ |
3255 *********************************************************/ |
| 3536 |
3256 |
| 3537 static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full) |
3257 static char *pidgin_get_tooltip_text(PurpleBlistNode *node, gboolean full) |
| 5494 /******************************* Menu bar *************************************/ |
5210 /******************************* Menu bar *************************************/ |
| 5495 actions = pidgin_action_group_new(); |
5211 actions = pidgin_action_group_new(); |
| 5496 gtk_widget_insert_action_group(gtkblist->window, "blist", |
5212 gtk_widget_insert_action_group(gtkblist->window, "blist", |
| 5497 G_ACTION_GROUP(actions)); |
5213 G_ACTION_GROUP(actions)); |
| 5498 |
5214 |
| 5499 action_group = gtk_action_group_new("BListActions"); |
|
| 5500 gtk_action_group_set_translation_domain(action_group, PACKAGE); |
|
| 5501 gtk_action_group_add_actions(action_group, |
|
| 5502 blist_menu_entries, |
|
| 5503 G_N_ELEMENTS(blist_menu_entries), |
|
| 5504 GTK_WINDOW(gtkblist->window)); |
|
| 5505 |
|
| 5506 gtkblist->ui = gtk_ui_manager_new(); |
|
| 5507 gtk_ui_manager_insert_action_group(gtkblist->ui, action_group, 0); |
|
| 5508 |
|
| 5509 accel_group = gtk_ui_manager_get_accel_group(gtkblist->ui); |
|
| 5510 gtk_window_add_accel_group(GTK_WINDOW(gtkblist->window), accel_group); |
|
| 5511 pidgin_load_accels(); |
|
| 5512 g_signal_connect(G_OBJECT(accel_group), "accel-changed", G_CALLBACK(pidgin_save_accels_cb), NULL); |
|
| 5513 |
|
| 5514 error = NULL; |
|
| 5515 if (!gtk_ui_manager_add_ui_from_string(gtkblist->ui, blist_menu, -1, &error)) |
|
| 5516 { |
|
| 5517 g_message("building menus failed: %s", error->message); |
|
| 5518 g_error_free(error); |
|
| 5519 exit(EXIT_FAILURE); |
|
| 5520 } |
|
| 5521 |
|
| 5522 menu = gtk_ui_manager_get_widget(gtkblist->ui, "/BList"); |
|
| 5523 gtk_widget_show(menu); |
|
| 5524 gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), menu, FALSE, FALSE, 0); |
|
| 5525 |
|
| 5526 gtkblist->menu = pidgin_buddy_list_menu_new(); |
5215 gtkblist->menu = pidgin_buddy_list_menu_new(); |
| 5527 gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), gtkblist->menu, FALSE, |
5216 gtk_box_pack_start(GTK_BOX(gtkblist->main_vbox), gtkblist->menu, FALSE, |
| 5528 FALSE, 0); |
5217 FALSE, 0); |
| 5529 |
5218 |
| 5530 gtkblist->menutray = pidgin_buddy_list_menu_get_menu_tray(gtkblist->menu); |
5219 gtkblist->menutray = pidgin_buddy_list_menu_get_menu_tray(PIDGIN_BUDDY_LIST_MENU(gtkblist->menu)); |
| 5531 |
5220 |
| 5532 /****************************** Notebook *************************************/ |
5221 /****************************** Notebook *************************************/ |
| 5533 gtkblist->notebook = gtk_notebook_new(); |
5222 gtkblist->notebook = gtk_notebook_new(); |
| 5534 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gtkblist->notebook), FALSE); |
5223 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gtkblist->notebook), FALSE); |
| 5535 gtk_notebook_set_show_border(GTK_NOTEBOOK(gtkblist->notebook), FALSE); |
5224 gtk_notebook_set_show_border(GTK_NOTEBOOK(gtkblist->notebook), FALSE); |