pidgin/gtkutils.c

changeset 17861
8c4f798347ea
parent 17497
6cbc2e55e878
parent 17858
14d53a1be2ee
child 17868
c3c0831ff968
equal deleted inserted replaced
17502:173cc15a3abc 17861:8c4f798347ea
243 gtk_widget_hide(to_toggle); 243 gtk_widget_hide(to_toggle);
244 else 244 else
245 gtk_widget_show(to_toggle); 245 gtk_widget_show(to_toggle);
246 } 246 }
247 247
248 void pidgin_separator(GtkWidget *menu) 248 GtkWidget *pidgin_separator(GtkWidget *menu)
249 { 249 {
250 GtkWidget *menuitem; 250 GtkWidget *menuitem;
251 251
252 menuitem = gtk_separator_menu_item_new(); 252 menuitem = gtk_separator_menu_item_new();
253 gtk_widget_show(menuitem); 253 gtk_widget_show(menuitem);
254 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 254 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
255 return menuitem;
255 } 256 }
256 257
257 GtkWidget *pidgin_new_item(GtkWidget *menu, const char *str) 258 GtkWidget *pidgin_new_item(GtkWidget *menu, const char *str)
258 { 259 {
259 GtkWidget *menuitem; 260 GtkWidget *menuitem;
460 ((void (*)(GtkWidget *, gpointer, gpointer))cb)(item, per_item_data, g_object_get_data(G_OBJECT(optmenu), "user_data")); 461 ((void (*)(GtkWidget *, gpointer, gpointer))cb)(item, per_item_data, g_object_get_data(G_OBJECT(optmenu), "user_data"));
461 } 462 }
462 } 463 }
463 464
464 static GtkWidget * 465 static GtkWidget *
465 aop_menu_item_new(GtkSizeGroup *sg, GdkPixbuf *pixbuf, const char *lbl, gpointer per_item_data) 466 aop_menu_item_new(GtkSizeGroup *sg, GdkPixbuf *pixbuf, const char *lbl, gpointer per_item_data, const char *data)
466 { 467 {
467 GtkWidget *item; 468 GtkWidget *item;
468 GtkWidget *hbox; 469 GtkWidget *hbox;
469 GtkWidget *image; 470 GtkWidget *image;
470 GtkWidget *label; 471 GtkWidget *label;
493 494
494 gtk_container_add(GTK_CONTAINER(item), hbox); 495 gtk_container_add(GTK_CONTAINER(item), hbox);
495 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); 496 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
496 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); 497 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
497 498
499 g_object_set_data(G_OBJECT (item), data, per_item_data);
498 g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data); 500 g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data);
499 501
500 pidgin_set_accessible_label(item, label); 502 pidgin_set_accessible_label(item, label);
501 503
502 return item; 504 return item;
505 }
506
507 static GdkPixbuf *
508 pidgin_create_prpl_icon_from_prpl(PurplePlugin *prpl, PidginPrplIconSize size, PurpleAccount *account)
509 {
510 PurplePluginProtocolInfo *prpl_info;
511 const char *protoname = NULL;
512 char buf[MAXPATHLEN];
513 char *filename = NULL;
514 GdkPixbuf *pixbuf;
515
516 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
517 if (prpl_info->list_icon == NULL)
518 return NULL;
519
520 protoname = prpl_info->list_icon(account, NULL);
521 if (protoname == NULL)
522 return NULL;
523
524 /*
525 * Status icons will be themeable too, and then it will look up
526 * protoname from the theme
527 */
528 g_snprintf(buf, sizeof(buf), "%s.png", protoname);
529
530 filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
531 size == PIDGIN_PRPL_ICON_SMALL ? "16" :
532 size == PIDGIN_PRPL_ICON_MEDIUM ? "22" : "48",
533 buf, NULL);
534 pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
535 g_free(filename);
536
537 return pixbuf;
503 } 538 }
504 539
505 static GtkWidget * 540 static GtkWidget *
506 aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data) 541 aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data)
507 { 542 {
548 if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) { 583 if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) {
549 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx); 584 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx);
550 break; 585 break;
551 } 586 }
552 } 587 }
553 }
554
555 static GdkPixbuf *
556 get_prpl_pixbuf(PurplePluginProtocolInfo *prpl_info)
557 {
558 const char *proto_name;
559 GdkPixbuf *pixbuf = NULL;
560 char *filename;
561 char buf[256];
562
563 proto_name = prpl_info->list_icon(NULL, NULL);
564 g_return_val_if_fail(proto_name != NULL, NULL);
565
566 g_snprintf(buf, sizeof(buf), "%s.png", proto_name);
567 filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "16", buf, NULL);
568 pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
569 g_free(filename);
570
571 return pixbuf;
572 } 588 }
573 589
574 static AopMenu * 590 static AopMenu *
575 create_protocols_menu(const char *default_proto_id) 591 create_protocols_menu(const char *default_proto_id)
576 { 592 {
600 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); 616 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
601 617
602 if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) { 618 if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) {
603 char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", 619 char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
604 "16", "google-talk.png", NULL); 620 "16", "google-talk.png", NULL);
621 GtkWidget *item;
622
605 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); 623 pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
606 g_free(filename); 624 g_free(filename);
607 625
608 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), 626 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
609 aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber")); 627 item = aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber", "protocol"));
628 g_object_set_data(G_OBJECT(item), "fake", GINT_TO_POINTER(1));
610 629
611 if (pixbuf) 630 if (pixbuf)
612 g_object_unref(pixbuf); 631 g_object_unref(pixbuf);
613 632
614 gtalk_name = NULL; 633 gtalk_name = NULL;
615 } 634 }
616 635
617 pixbuf = get_prpl_pixbuf(prpl_info); 636 pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL);
618 637
619 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), 638 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
620 aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id)); 639 aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id, "protocol"));
621 640
622 if (pixbuf) 641 if (pixbuf)
623 g_object_unref(pixbuf); 642 g_object_unref(pixbuf);
624 643
625 if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id)) 644 if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id))
667 aop_menu->menu = gtk_menu_new(); 686 aop_menu->menu = gtk_menu_new();
668 gtk_widget_show(aop_menu->menu); 687 gtk_widget_show(aop_menu->menu);
669 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 688 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
670 689
671 for (p = list, i = 0; p != NULL; p = p->next, i++) { 690 for (p = list, i = 0; p != NULL; p = p->next, i++) {
672 PurplePluginProtocolInfo *prpl_info = NULL;
673 PurplePlugin *plugin; 691 PurplePlugin *plugin;
674 692
675 if (show_all) 693 if (show_all)
676 account = (PurpleAccount *)p->data; 694 account = (PurpleAccount *)p->data;
677 else { 695 else {
685 continue; 703 continue;
686 } 704 }
687 705
688 plugin = purple_find_prpl(purple_account_get_protocol_id(account)); 706 plugin = purple_find_prpl(purple_account_get_protocol_id(account));
689 707
690 if (plugin) 708 pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
691 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); 709
692 710 if (pixbuf) {
693 /* Load the image. */ 711 if (purple_account_is_disconnected(account) && show_all &&
694 if (prpl_info) { 712 purple_connections_get_all())
695 pixbuf = get_prpl_pixbuf(prpl_info); 713 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
696
697 if (pixbuf) {
698 if (purple_account_is_disconnected(account) && show_all &&
699 purple_connections_get_all())
700 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
701 }
702 } 714 }
703 715
704 if (purple_account_get_alias(account)) { 716 if (purple_account_get_alias(account)) {
705 g_snprintf(buf, sizeof(buf), "%s (%s) (%s)", 717 g_snprintf(buf, sizeof(buf), "%s (%s) (%s)",
706 purple_account_get_username(account), 718 purple_account_get_username(account),
711 purple_account_get_username(account), 723 purple_account_get_username(account),
712 purple_account_get_protocol_name(account)); 724 purple_account_get_protocol_name(account));
713 } 725 }
714 726
715 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), 727 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu),
716 aop_menu_item_new(sg, pixbuf, buf, account)); 728 aop_menu_item_new(sg, pixbuf, buf, account, "account"));
717 729
718 if (pixbuf) 730 if (pixbuf)
719 g_object_unref(pixbuf); 731 g_object_unref(pixbuf);
720 732
721 if (default_account && account == default_account) 733 if (default_account && account == default_account)
878 890
879 filename = g_build_filename(purple_user_dir(), G_DIR_SEPARATOR_S, 891 filename = g_build_filename(purple_user_dir(), G_DIR_SEPARATOR_S,
880 "accels", NULL); 892 "accels", NULL);
881 gtk_accel_map_load(filename); 893 gtk_accel_map_load(filename);
882 g_free(filename); 894 g_free(filename);
895 }
896
897 void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name)
898 {
899 PurpleNotifyUserInfo *info = purple_notify_user_info_new();
900 purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving..."));
901 purple_notify_userinfo(conn, name, info, NULL, NULL);
902 purple_notify_user_info_destroy(info);
903 serv_get_info(conn, name);
883 } 904 }
884 905
885 gboolean 906 gboolean
886 pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts, 907 pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts,
887 PurpleAccount **ret_account, char **ret_protocol, 908 PurpleAccount **ret_account, char **ret_protocol,
1580 1601
1581 GdkPixbuf * 1602 GdkPixbuf *
1582 pidgin_create_prpl_icon(PurpleAccount *account, PidginPrplIconSize size) 1603 pidgin_create_prpl_icon(PurpleAccount *account, PidginPrplIconSize size)
1583 { 1604 {
1584 PurplePlugin *prpl; 1605 PurplePlugin *prpl;
1585 PurplePluginProtocolInfo *prpl_info;
1586 const char *protoname = NULL;
1587 char buf[256]; /* TODO: We should use a define for max file length */
1588 char *filename = NULL;
1589 GdkPixbuf *pixbuf;
1590 1606
1591 g_return_val_if_fail(account != NULL, NULL); 1607 g_return_val_if_fail(account != NULL, NULL);
1592 1608
1593 prpl = purple_find_prpl(purple_account_get_protocol_id(account)); 1609 prpl = purple_find_prpl(purple_account_get_protocol_id(account));
1594 if (prpl == NULL) 1610 if (prpl == NULL)
1595 return NULL; 1611 return NULL;
1596 1612 return pidgin_create_prpl_icon_from_prpl(prpl, size, account);
1597 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
1598 if (prpl_info->list_icon == NULL)
1599 return NULL;
1600
1601 protoname = prpl_info->list_icon(account, NULL);
1602 if (protoname == NULL)
1603 return NULL;
1604
1605 /*
1606 * Status icons will be themeable too, and then it will look up
1607 * protoname from the theme
1608 */
1609 g_snprintf(buf, sizeof(buf), "%s.png", protoname);
1610
1611 filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
1612 size == PIDGIN_PRPL_ICON_SMALL ? "16" :
1613 size == PIDGIN_PRPL_ICON_MEDIUM ? "22" : "48",
1614 buf, NULL);
1615 pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
1616 g_free(filename);
1617
1618 return pixbuf;
1619 } 1613 }
1620 1614
1621 static void 1615 static void
1622 menu_action_cb(GtkMenuItem *item, gpointer object) 1616 menu_action_cb(GtkMenuItem *item, gpointer object)
1623 { 1617 {
1629 1623
1630 if (callback) 1624 if (callback)
1631 callback(object, data); 1625 callback(object, data);
1632 } 1626 }
1633 1627
1634 void 1628 GtkWidget *
1635 pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act, 1629 pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act,
1636 gpointer object) 1630 gpointer object)
1637 { 1631 {
1632 GtkWidget *menuitem;
1633
1638 if (act == NULL) { 1634 if (act == NULL) {
1639 pidgin_separator(menu); 1635 return pidgin_separator(menu);
1636 }
1637
1638 if (act->children == NULL) {
1639 menuitem = gtk_menu_item_new_with_mnemonic(act->label);
1640
1641 if (act->callback != NULL) {
1642 g_object_set_data(G_OBJECT(menuitem),
1643 "purplecallback",
1644 act->callback);
1645 g_object_set_data(G_OBJECT(menuitem),
1646 "purplecallbackdata",
1647 act->data);
1648 g_signal_connect(G_OBJECT(menuitem), "activate",
1649 G_CALLBACK(menu_action_cb),
1650 object);
1651 } else {
1652 gtk_widget_set_sensitive(menuitem, FALSE);
1653 }
1654
1655 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1640 } else { 1656 } else {
1641 GtkWidget *menuitem; 1657 GList *l = NULL;
1642 1658 GtkWidget *submenu = NULL;
1643 if (act->children == NULL) { 1659 GtkAccelGroup *group;
1644 menuitem = gtk_menu_item_new_with_mnemonic(act->label); 1660
1645 1661 menuitem = gtk_menu_item_new_with_mnemonic(act->label);
1646 if (act->callback != NULL) { 1662 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1647 g_object_set_data(G_OBJECT(menuitem), 1663
1648 "purplecallback", 1664 submenu = gtk_menu_new();
1649 act->callback); 1665 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
1650 g_object_set_data(G_OBJECT(menuitem), 1666
1651 "purplecallbackdata", 1667 group = gtk_menu_get_accel_group(GTK_MENU(menu));
1652 act->data); 1668 if (group) {
1653 g_signal_connect(G_OBJECT(menuitem), "activate", 1669 char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label);
1654 G_CALLBACK(menu_action_cb), 1670 gtk_menu_set_accel_path(GTK_MENU(submenu), path);
1655 object); 1671 g_free(path);
1656 } else { 1672 gtk_menu_set_accel_group(GTK_MENU(submenu), group);
1657 gtk_widget_set_sensitive(menuitem, FALSE); 1673 }
1658 } 1674
1659 1675 for (l = act->children; l; l = l->next) {
1660 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 1676 PurpleMenuAction *act = (PurpleMenuAction *)l->data;
1661 } else { 1677
1662 GList *l = NULL; 1678 pidgin_append_menu_action(submenu, act, object);
1663 GtkWidget *submenu = NULL; 1679 }
1664 GtkAccelGroup *group; 1680 g_list_free(act->children);
1665 1681 act->children = NULL;
1666 menuitem = gtk_menu_item_new_with_mnemonic(act->label); 1682 }
1667 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 1683 purple_menu_action_free(act);
1668 1684 return menuitem;
1669 submenu = gtk_menu_new();
1670 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
1671
1672 group = gtk_menu_get_accel_group(GTK_MENU(menu));
1673 if (group) {
1674 char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label);
1675 gtk_menu_set_accel_path(GTK_MENU(submenu), path);
1676 g_free(path);
1677 gtk_menu_set_accel_group(GTK_MENU(submenu), group);
1678 }
1679
1680 for (l = act->children; l; l = l->next) {
1681 PurpleMenuAction *act = (PurpleMenuAction *)l->data;
1682
1683 pidgin_append_menu_action(submenu, act, object);
1684 }
1685 g_list_free(act->children);
1686 act->children = NULL;
1687 }
1688 purple_menu_action_free(act);
1689 }
1690 } 1685 }
1691 1686
1692 #if GTK_CHECK_VERSION(2,3,0) 1687 #if GTK_CHECK_VERSION(2,3,0)
1693 # define NEW_STYLE_COMPLETION 1688 # define NEW_STYLE_COMPLETION
1694 #endif 1689 #endif

mercurial