| 117 PIDGIN_CONV_MENU = 1 << 2, |
117 PIDGIN_CONV_MENU = 1 << 2, |
| 118 PIDGIN_CONV_TAB_ICON = 1 << 3, |
118 PIDGIN_CONV_TAB_ICON = 1 << 3, |
| 119 PIDGIN_CONV_TOPIC = 1 << 4, |
119 PIDGIN_CONV_TOPIC = 1 << 4, |
| 120 PIDGIN_CONV_SMILEY_THEME = 1 << 5, |
120 PIDGIN_CONV_SMILEY_THEME = 1 << 5, |
| 121 PIDGIN_CONV_COLORIZE_TITLE = 1 << 6, |
121 PIDGIN_CONV_COLORIZE_TITLE = 1 << 6, |
| 122 PIDGIN_CONV_E2EE = 1 << 7 |
|
| 123 }PidginConvFields; |
122 }PidginConvFields; |
| 124 |
123 |
| 125 enum { |
124 enum { |
| 126 CONV_ICON_COLUMN, |
125 CONV_ICON_COLUMN, |
| 127 CONV_TEXT_COLUMN, |
126 CONV_TEXT_COLUMN, |
| 160 static GList *away_list = NULL; |
159 static GList *away_list = NULL; |
| 161 static GList *busy_list = NULL; |
160 static GList *busy_list = NULL; |
| 162 static GList *xa_list = NULL; |
161 static GList *xa_list = NULL; |
| 163 static GList *offline_list = NULL; |
162 static GList *offline_list = NULL; |
| 164 static GHashTable *protocol_lists = NULL; |
163 static GHashTable *protocol_lists = NULL; |
| 165 static GHashTable *e2ee_stock = NULL; |
|
| 166 |
164 |
| 167 static gboolean update_send_to_selection(PidginConvWindow *win); |
165 static gboolean update_send_to_selection(PidginConvWindow *win); |
| 168 static void generate_send_to_items(PidginConvWindow *win); |
166 static void generate_send_to_items(PidginConvWindow *win); |
| 169 |
167 |
| 170 /* Prototypes. <-- because Paco-Paco hates this comment. */ |
168 /* Prototypes. <-- because Paco-Paco hates this comment. */ |
| 3346 { |
3344 { |
| 3347 gtk_widget_set_sensitive(GTK_WIDGET(label), FALSE); |
3345 gtk_widget_set_sensitive(GTK_WIDGET(label), FALSE); |
| 3348 return FALSE; |
3346 return FALSE; |
| 3349 } |
3347 } |
| 3350 |
3348 |
| 3351 static GtkWidget * |
|
| 3352 e2ee_state_to_gtkimage(PurpleE2eeState *state) |
|
| 3353 { |
|
| 3354 PurpleImage *img; |
|
| 3355 |
|
| 3356 img = _pidgin_e2ee_stock_icon_get( |
|
| 3357 purple_e2ee_state_get_stock_icon(state)); |
|
| 3358 if (!img) |
|
| 3359 return NULL; |
|
| 3360 |
|
| 3361 return gtk_image_new_from_pixbuf(pidgin_pixbuf_from_image(img)); |
|
| 3362 } |
|
| 3363 |
|
| 3364 static void |
3349 static void |
| 3365 create_sendto_item(GtkWidget *menu, GtkSizeGroup *sg, GSList **group, |
3350 create_sendto_item(GtkWidget *menu, GtkSizeGroup *sg, GSList **group, |
| 3366 PurpleBuddy *buddy, PurpleAccount *account, const char *name, |
3351 PurpleBuddy *buddy, PurpleAccount *account, const char *name) |
| 3367 gboolean e2ee_enabled) |
|
| 3368 { |
3352 { |
| 3369 GtkWidget *box; |
3353 GtkWidget *box; |
| 3370 GtkWidget *label; |
3354 GtkWidget *label; |
| 3371 GtkWidget *image; |
3355 GtkWidget *image; |
| 3372 GtkWidget *e2ee_image = NULL; |
|
| 3373 GtkWidget *menuitem; |
3356 GtkWidget *menuitem; |
| 3374 GdkPixbuf *pixbuf; |
3357 GdkPixbuf *pixbuf; |
| 3375 gchar *text; |
3358 gchar *text; |
| 3376 |
3359 |
| 3377 /* Create a pixmap for the protocol icon. */ |
3360 /* Create a pixmap for the protocol icon. */ |
| 3384 { |
3367 { |
| 3385 image = gtk_image_new_from_pixbuf(pixbuf); |
3368 image = gtk_image_new_from_pixbuf(pixbuf); |
| 3386 g_object_unref(G_OBJECT(pixbuf)); |
3369 g_object_unref(G_OBJECT(pixbuf)); |
| 3387 } |
3370 } |
| 3388 |
3371 |
| 3389 if (e2ee_enabled) { |
|
| 3390 PurpleIMConversation *im; |
|
| 3391 PurpleE2eeState *state = NULL; |
|
| 3392 |
|
| 3393 im = purple_conversations_find_im_with_account( |
|
| 3394 purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); |
|
| 3395 if (im) |
|
| 3396 state = purple_conversation_get_e2ee_state(PURPLE_CONVERSATION(im)); |
|
| 3397 if (state) |
|
| 3398 e2ee_image = e2ee_state_to_gtkimage(state); |
|
| 3399 else |
|
| 3400 e2ee_image = gtk_image_new(); |
|
| 3401 } |
|
| 3402 |
|
| 3403 gtk_size_group_add_widget(sg, image); |
3372 gtk_size_group_add_widget(sg, image); |
| 3404 |
3373 |
| 3405 /* Make our menu item */ |
3374 /* Make our menu item */ |
| 3406 text = g_strdup_printf("%s (%s)", name, purple_account_get_name_for_display(account)); |
3375 text = g_strdup_printf("%s (%s)", name, purple_account_get_name_for_display(account)); |
| 3407 menuitem = gtk_radio_menu_item_new_with_label(*group, text); |
3376 menuitem = gtk_radio_menu_item_new_with_label(*group, text); |
| 3416 gtk_container_remove(GTK_CONTAINER(menuitem), label); |
3385 gtk_container_remove(GTK_CONTAINER(menuitem), label); |
| 3417 |
3386 |
| 3418 gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0); |
3387 gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0); |
| 3419 |
3388 |
| 3420 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 4); |
3389 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 4); |
| 3421 if (e2ee_image) |
|
| 3422 gtk_box_pack_start(GTK_BOX(box), e2ee_image, FALSE, FALSE, 0); |
|
| 3423 |
3390 |
| 3424 if (buddy != NULL && |
3391 if (buddy != NULL && |
| 3425 !purple_presence_is_online(purple_buddy_get_presence(buddy))) |
3392 !purple_presence_is_online(purple_buddy_get_presence(buddy))) |
| 3426 { |
3393 { |
| 3427 gtk_widget_set_sensitive(label, FALSE); |
3394 gtk_widget_set_sensitive(label, FALSE); |
| 3440 |
3407 |
| 3441 gtk_container_add(GTK_CONTAINER(menuitem), box); |
3408 gtk_container_add(GTK_CONTAINER(menuitem), box); |
| 3442 |
3409 |
| 3443 gtk_widget_show(label); |
3410 gtk_widget_show(label); |
| 3444 gtk_widget_show(image); |
3411 gtk_widget_show(image); |
| 3445 if (e2ee_image) |
|
| 3446 gtk_widget_show(e2ee_image); |
|
| 3447 gtk_widget_show(box); |
3412 gtk_widget_show(box); |
| 3448 |
3413 |
| 3449 /* Set our data and callbacks. */ |
3414 /* Set our data and callbacks. */ |
| 3450 g_object_set_data(G_OBJECT(menuitem), "purple_account", account); |
3415 g_object_set_data(G_OBJECT(menuitem), "purple_account", account); |
| 3451 g_object_set_data_full(G_OBJECT(menuitem), "purple_buddy_name", g_strdup(name), g_free); |
3416 g_object_set_data_full(G_OBJECT(menuitem), "purple_buddy_name", g_strdup(name), g_free); |
| 3525 |
3489 |
| 3526 if (!PURPLE_IS_BUDDY(node)) |
3490 if (!PURPLE_IS_BUDDY(node)) |
| 3527 continue; |
3491 continue; |
| 3528 |
3492 |
| 3529 im = purple_conversations_find_im_with_account(purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); |
3493 im = purple_conversations_find_im_with_account(purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); |
| 3530 if (im && purple_conversation_get_e2ee_state(PURPLE_CONVERSATION(im)) != NULL) |
|
| 3531 e2ee_enabled = TRUE; |
|
| 3532 |
3494 |
| 3533 account = purple_buddy_get_account(buddy); |
3495 account = purple_buddy_get_account(buddy); |
| 3534 /* TODO WEBKIT: (I'm not actually sure if this is webkit-related --Mark Doliner) */ |
3496 /* TODO WEBKIT: (I'm not actually sure if this is webkit-related --Mark Doliner) */ |
| 3535 if (purple_account_is_connected(account) /*|| account == purple_conversation_get_account(gtkconv->active_conv)*/) |
3497 if (purple_account_is_connected(account) /*|| account == purple_conversation_get_account(gtkconv->active_conv)*/) |
| 3536 { |
3498 { |
| 3548 * since we did a g_list_prepend() earlier. */ |
3510 * since we did a g_list_prepend() earlier. */ |
| 3549 for (iter = g_list_last(list); iter != NULL; iter = iter->prev) { |
3511 for (iter = g_list_last(list); iter != NULL; iter = iter->prev) { |
| 3550 PurplePresence *pre = iter->data; |
3512 PurplePresence *pre = iter->data; |
| 3551 PurpleBuddy *buddy = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(pre)); |
3513 PurpleBuddy *buddy = purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(pre)); |
| 3552 create_sendto_item(menu, sg, &group, buddy, |
3514 create_sendto_item(menu, sg, &group, buddy, |
| 3553 purple_buddy_get_account(buddy), purple_buddy_get_name(buddy), e2ee_enabled); |
3515 purple_buddy_get_account(buddy), purple_buddy_get_name(buddy)); |
| 3554 } |
3516 } |
| 3555 } |
3517 } |
| 3556 g_list_free(list); |
3518 g_list_free(list); |
| 3557 g_slist_free(buds); |
3519 g_slist_free(buds); |
| 3558 } |
3520 } |
| 3563 gtk_widget_show(win->menu->send_to); |
3525 gtk_widget_show(win->menu->send_to); |
| 3564 /* TODO: This should never be insensitive. Possibly hidden or not. */ |
3526 /* TODO: This should never be insensitive. Possibly hidden or not. */ |
| 3565 if (!group) |
3527 if (!group) |
| 3566 gtk_widget_set_sensitive(win->menu->send_to, FALSE); |
3528 gtk_widget_set_sensitive(win->menu->send_to, FALSE); |
| 3567 update_send_to_selection(win); |
3529 update_send_to_selection(win); |
| 3568 } |
|
| 3569 |
|
| 3570 PurpleImage * |
|
| 3571 _pidgin_e2ee_stock_icon_get(const gchar *stock_name) |
|
| 3572 { |
|
| 3573 gchar filename[100], *path; |
|
| 3574 PurpleImage *image; |
|
| 3575 |
|
| 3576 /* core is quitting */ |
|
| 3577 if (e2ee_stock == NULL) |
|
| 3578 return NULL; |
|
| 3579 |
|
| 3580 if (g_hash_table_lookup_extended(e2ee_stock, stock_name, NULL, (gpointer*)&image)) |
|
| 3581 return image; |
|
| 3582 |
|
| 3583 g_snprintf(filename, sizeof(filename), "e2ee-%s.png", stock_name); |
|
| 3584 path = g_build_filename(PURPLE_DATADIR, "pidgin", "icons", |
|
| 3585 "hicolor", "16x16", "status", filename, NULL); |
|
| 3586 image = purple_image_new_from_file(path, NULL); |
|
| 3587 g_free(path); |
|
| 3588 |
|
| 3589 g_hash_table_insert(e2ee_stock, g_strdup(stock_name), image); |
|
| 3590 return image; |
|
| 3591 } |
|
| 3592 |
|
| 3593 static void |
|
| 3594 generate_e2ee_controls(PidginConvWindow *win) |
|
| 3595 { |
|
| 3596 PidginConversation *gtkconv; |
|
| 3597 PurpleConversation *conv; |
|
| 3598 PurpleE2eeState *state; |
|
| 3599 PurpleE2eeProvider *provider; |
|
| 3600 GtkWidget *menu; |
|
| 3601 GList *menu_actions, *it; |
|
| 3602 GtkWidget *e2ee_image; |
|
| 3603 |
|
| 3604 gtkconv = pidgin_conv_window_get_active_gtkconv(win); |
|
| 3605 g_return_if_fail(gtkconv != NULL); |
|
| 3606 |
|
| 3607 conv = gtkconv->active_conv; |
|
| 3608 g_return_if_fail(conv != NULL); |
|
| 3609 |
|
| 3610 if (win->menu->e2ee != NULL) { |
|
| 3611 gtk_widget_destroy(win->menu->e2ee); |
|
| 3612 win->menu->e2ee = NULL; |
|
| 3613 } |
|
| 3614 |
|
| 3615 provider = purple_e2ee_provider_get_main(); |
|
| 3616 state = purple_conversation_get_e2ee_state(conv); |
|
| 3617 if (state == NULL || provider == NULL) |
|
| 3618 return; |
|
| 3619 if (purple_e2ee_state_get_provider(state) != provider) |
|
| 3620 return; |
|
| 3621 |
|
| 3622 win->menu->e2ee = gtk_image_menu_item_new_with_label( |
|
| 3623 purple_e2ee_provider_get_name(provider)); |
|
| 3624 |
|
| 3625 menu = gtk_menu_new(); |
|
| 3626 gtk_menu_shell_insert(GTK_MENU_SHELL(win->menu->menubar), |
|
| 3627 win->menu->e2ee, 3); |
|
| 3628 gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu->e2ee), menu); |
|
| 3629 |
|
| 3630 e2ee_image = e2ee_state_to_gtkimage(state); |
|
| 3631 if (e2ee_image) { |
|
| 3632 gtk_image_menu_item_set_image( |
|
| 3633 GTK_IMAGE_MENU_ITEM(win->menu->e2ee), e2ee_image); |
|
| 3634 } |
|
| 3635 |
|
| 3636 gtk_widget_set_tooltip_text(win->menu->e2ee, |
|
| 3637 purple_e2ee_state_get_name(state)); |
|
| 3638 |
|
| 3639 menu_actions = purple_e2ee_provider_get_conv_menu_actions(provider, conv); |
|
| 3640 for (it = menu_actions; it; it = g_list_next(it)) { |
|
| 3641 PurpleActionMenu *action = it->data; |
|
| 3642 |
|
| 3643 gtk_widget_show_all( |
|
| 3644 pidgin_append_menu_action(menu, action, conv)); |
|
| 3645 } |
|
| 3646 g_list_free(menu_actions); |
|
| 3647 |
|
| 3648 gtk_widget_show(win->menu->e2ee); |
|
| 3649 gtk_widget_show(menu); |
|
| 3650 } |
3530 } |
| 3651 |
3531 |
| 3652 static const char * |
3532 static const char * |
| 3653 get_chat_user_status_icon(PurpleChatConversation *chat, const char *name, PurpleChatUserFlags flags) |
3533 get_chat_user_status_icon(PurpleChatConversation *chat, const char *name, PurpleChatUserFlags flags) |
| 3654 { |
3534 { |
| 6524 static int handle; |
6397 static int handle; |
| 6525 |
6398 |
| 6526 return &handle; |
6399 return &handle; |
| 6527 } |
6400 } |
| 6528 |
6401 |
| 6529 static void |
|
| 6530 pidgin_conversations_pre_uninit(void); |
|
| 6531 |
|
| 6532 void |
6402 void |
| 6533 pidgin_conversations_init(void) |
6403 pidgin_conversations_init(void) |
| 6534 { |
6404 { |
| 6535 void *handle = pidgin_conversations_get_handle(); |
6405 void *handle = pidgin_conversations_get_handle(); |
| 6536 void *blist_handle = purple_blist_get_handle(); |
6406 void *blist_handle = purple_blist_get_handle(); |
| 6537 |
|
| 6538 e2ee_stock = g_hash_table_new_full(g_str_hash, g_str_equal, |
|
| 6539 g_free, g_object_unref); |
|
| 6540 |
6407 |
| 6541 /* Conversations */ |
6408 /* Conversations */ |
| 6542 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations"); |
6409 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations"); |
| 6543 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE); |
6410 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE); |
| 6544 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE); |
6411 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE); |
| 6748 hidden_convwin = pidgin_conv_window_new(); |
6615 hidden_convwin = pidgin_conv_window_new(); |
| 6749 window_list = g_list_remove(window_list, hidden_convwin); |
6616 window_list = g_list_remove(window_list, hidden_convwin); |
| 6750 |
6617 |
| 6751 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", |
6618 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", |
| 6752 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); |
6619 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); |
| 6753 |
|
| 6754 purple_signal_connect_priority(purple_get_core(), "quitting", handle, |
|
| 6755 PURPLE_CALLBACK(pidgin_conversations_pre_uninit), NULL, PURPLE_SIGNAL_PRIORITY_HIGHEST); |
|
| 6756 |
6620 |
| 6757 /* Callbacks to update a conversation */ |
6621 /* Callbacks to update a conversation */ |
| 6758 purple_signal_connect(blist_handle, "blist-node-added", handle, |
6622 purple_signal_connect(blist_handle, "blist-node-added", handle, |
| 6759 G_CALLBACK(buddy_update_cb), NULL); |
6623 G_CALLBACK(buddy_update_cb), NULL); |
| 6760 purple_signal_connect(blist_handle, "blist-node-removed", handle, |
6624 purple_signal_connect(blist_handle, "blist-node-removed", handle, |
| 6790 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
6654 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
| 6791 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, |
6655 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, |
| 6792 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
6656 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
| 6793 } |
6657 } |
| 6794 |
6658 |
| 6795 static void |
|
| 6796 pidgin_conversations_pre_uninit(void) |
|
| 6797 { |
|
| 6798 g_hash_table_destroy(e2ee_stock); |
|
| 6799 e2ee_stock = NULL; |
|
| 6800 } |
|
| 6801 |
|
| 6802 /* Invalidate the first tab color set */ |
6659 /* Invalidate the first tab color set */ |
| 6803 static gboolean tab_color_fuse = TRUE; |
6660 static gboolean tab_color_fuse = TRUE; |
| 6804 |
6661 |
| 6805 static void |
6662 static void |
| 6806 pidgin_conversations_set_tab_colors(void) |
6663 pidgin_conversations_set_tab_colors(void) |