pidgin/gtkconv.c

changeset 40304
a3d49ff045a8
parent 40212
352d23243db5
child 40315
6746d9b67b3e
equal deleted inserted replaced
40303:0a01f2c891c2 40304:a3d49ff045a8
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);
3507 { 3472 {
3508 /* The user isn't on the buddy list. So we don't create any sendto menu. */ 3473 /* The user isn't on the buddy list. So we don't create any sendto menu. */
3509 } 3474 }
3510 else 3475 else
3511 { 3476 {
3512 gboolean e2ee_enabled = FALSE;
3513 GList *list = NULL, *iter; 3477 GList *list = NULL, *iter;
3514 for (l = buds; l != NULL; l = l->next) 3478 for (l = buds; l != NULL; l = l->next)
3515 { 3479 {
3516 PurpleBlistNode *node; 3480 PurpleBlistNode *node;
3517 3481
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 {
5403 gray_stuff_out(PIDGIN_CONVERSATION(conv)); 5283 gray_stuff_out(PIDGIN_CONVERSATION(conv));
5404 generate_send_to_items(win); 5284 generate_send_to_items(win);
5405 regenerate_plugins_items(win); 5285 regenerate_plugins_items(win);
5406 } 5286 }
5407 5287
5408 if (fields & PIDGIN_CONV_E2EE)
5409 generate_e2ee_controls(win);
5410
5411 if (fields & PIDGIN_CONV_TAB_ICON) 5288 if (fields & PIDGIN_CONV_TAB_ICON)
5412 { 5289 {
5413 update_tab_icon(conv); 5290 update_tab_icon(conv);
5414 generate_send_to_items(win); /* To update the icons in SendTo menu */ 5291 generate_send_to_items(win); /* To update the icons in SendTo menu */
5415 } 5292 }
5597 } 5474 }
5598 else if (type == PURPLE_CONVERSATION_UPDATE_FEATURES) 5475 else if (type == PURPLE_CONVERSATION_UPDATE_FEATURES)
5599 { 5476 {
5600 flags = PIDGIN_CONV_MENU; 5477 flags = PIDGIN_CONV_MENU;
5601 } 5478 }
5602 else if (type == PURPLE_CONVERSATION_UPDATE_E2EE)
5603 {
5604 flags = PIDGIN_CONV_E2EE | PIDGIN_CONV_MENU;
5605 }
5606 5479
5607 pidgin_conv_update_fields(conv, flags); 5480 pidgin_conv_update_fields(conv, flags);
5608 } 5481 }
5609 5482
5610 static void 5483 static void
6337 static void 6210 static void
6338 update_conversation_switched(PurpleConversation *conv) 6211 update_conversation_switched(PurpleConversation *conv)
6339 { 6212 {
6340 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | 6213 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON |
6341 PIDGIN_CONV_SET_TITLE | PIDGIN_CONV_MENU | 6214 PIDGIN_CONV_SET_TITLE | PIDGIN_CONV_MENU |
6342 PIDGIN_CONV_BUDDY_ICON | PIDGIN_CONV_E2EE ); 6215 PIDGIN_CONV_BUDDY_ICON);
6343 } 6216 }
6344 6217
6345 static void 6218 static void
6346 update_buddy_typing(PurpleAccount *account, const char *who) 6219 update_buddy_typing(PurpleAccount *account, const char *who)
6347 { 6220 {
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)
7881 7738
7882 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtkconv->win->menu->logging), 7739 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtkconv->win->menu->logging),
7883 purple_conversation_is_logging(conv)); 7740 purple_conversation_is_logging(conv));
7884 7741
7885 generate_send_to_items(win); 7742 generate_send_to_items(win);
7886 generate_e2ee_controls(win);
7887 regenerate_options_items(win); 7743 regenerate_options_items(win);
7888 regenerate_plugins_items(win); 7744 regenerate_plugins_items(win);
7889 7745
7890 pidgin_conv_switch_active_conversation(conv); 7746 pidgin_conv_switch_active_conversation(conv);
7891 7747

mercurial