| 525 |
525 |
| 526 return vbox; |
526 return vbox; |
| 527 } |
527 } |
| 528 |
528 |
| 529 static gpointer |
529 static gpointer |
| 530 aop_option_menu_get_selected(GtkWidget *optmenu, GtkWidget **p_item) |
530 aop_option_menu_get_selected(GtkWidget *optmenu) |
| 531 { |
531 { |
| 532 GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); |
532 gpointer data = NULL; |
| 533 GtkWidget *item = gtk_menu_get_active(GTK_MENU(menu)); |
533 GtkTreeIter iter; |
| 534 if (p_item) |
534 |
| 535 (*p_item) = item; |
535 g_return_val_if_fail(optmenu != NULL, NULL); |
| 536 return item ? g_object_get_data(G_OBJECT(item), "aop_per_item_data") : NULL; |
536 |
| |
537 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(optmenu), &iter)) |
| |
538 gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu)), &iter, 2, &data, -1); |
| |
539 |
| |
540 return data; |
| 537 } |
541 } |
| 538 |
542 |
| 539 static void |
543 static void |
| 540 aop_menu_cb(GtkWidget *optmenu, GCallback cb) |
544 aop_menu_cb(GtkWidget *optmenu, GCallback cb) |
| 541 { |
545 { |
| 542 GtkWidget *item; |
|
| 543 gpointer per_item_data; |
|
| 544 |
|
| 545 per_item_data = aop_option_menu_get_selected(optmenu, &item); |
|
| 546 |
|
| 547 if (cb != NULL) { |
546 if (cb != NULL) { |
| 548 ((void (*)(GtkWidget *, gpointer, gpointer))cb)(item, per_item_data, g_object_get_data(G_OBJECT(optmenu), "user_data")); |
547 ((void (*)(GtkWidget *, gpointer, gpointer))cb)(NULL, |
| 549 } |
548 aop_option_menu_get_selected(optmenu), |
| 550 } |
549 g_object_get_data(G_OBJECT(optmenu), "user_data")); |
| 551 |
550 } |
| 552 static GtkWidget * |
551 } |
| 553 aop_menu_item_new(GtkSizeGroup *sg, GdkPixbuf *pixbuf, const char *lbl, gpointer per_item_data, const char *data) |
552 |
| 554 { |
553 static void |
| 555 GtkWidget *item; |
554 aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu) |
| 556 GtkWidget *hbox; |
555 { |
| 557 GtkWidget *image; |
556 gtk_combo_box_set_model(GTK_COMBO_BOX(optmenu), new_aop_menu->model); |
| 558 GtkWidget *label; |
557 gtk_combo_box_set_active(GTK_COMBO_BOX(optmenu), new_aop_menu->default_item); |
| 559 |
558 g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", new_aop_menu, (GDestroyNotify)g_free); |
| 560 item = gtk_menu_item_new(); |
|
| 561 gtk_widget_show(item); |
|
| 562 |
|
| 563 hbox = gtk_hbox_new(FALSE, 4); |
|
| 564 gtk_widget_show(hbox); |
|
| 565 |
|
| 566 /* Create the image */ |
|
| 567 if (pixbuf == NULL) |
|
| 568 image = gtk_image_new(); |
|
| 569 else |
|
| 570 image = gtk_image_new_from_pixbuf(pixbuf); |
|
| 571 gtk_widget_show(image); |
|
| 572 |
|
| 573 if (sg) |
|
| 574 gtk_size_group_add_widget(sg, image); |
|
| 575 |
|
| 576 /* Create the label */ |
|
| 577 label = gtk_label_new (lbl); |
|
| 578 gtk_widget_show (label); |
|
| 579 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); |
|
| 580 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); |
|
| 581 |
|
| 582 gtk_container_add(GTK_CONTAINER(item), hbox); |
|
| 583 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); |
|
| 584 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); |
|
| 585 |
|
| 586 g_object_set_data(G_OBJECT (item), data, per_item_data); |
|
| 587 g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data); |
|
| 588 |
|
| 589 pidgin_set_accessible_label(item, label); |
|
| 590 |
|
| 591 return item; |
|
| 592 } |
559 } |
| 593 |
560 |
| 594 static GdkPixbuf * |
561 static GdkPixbuf * |
| 595 pidgin_create_prpl_icon_from_prpl(PurplePlugin *prpl, PidginPrplIconSize size, PurpleAccount *account) |
562 pidgin_create_prpl_icon_from_prpl(PurplePlugin *prpl, PidginPrplIconSize size, PurpleAccount *account) |
| 596 { |
563 { |
| 627 } |
594 } |
| 628 |
595 |
| 629 static GtkWidget * |
596 static GtkWidget * |
| 630 aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data) |
597 aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data) |
| 631 { |
598 { |
| 632 GtkWidget *optmenu; |
599 GtkWidget *optmenu = NULL; |
| 633 |
600 GtkCellRenderer *cr = NULL; |
| 634 optmenu = gtk_option_menu_new(); |
601 |
| |
602 optmenu = gtk_combo_box_new(); |
| 635 gtk_widget_show(optmenu); |
603 gtk_widget_show(optmenu); |
| 636 gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), aop_menu->menu); |
604 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(optmenu), cr = gtk_cell_renderer_pixbuf_new(), FALSE); |
| 637 |
605 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(optmenu), cr, "pixbuf", 0); |
| 638 if (aop_menu->default_item != -1) |
606 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(optmenu), cr = gtk_cell_renderer_text_new(), TRUE); |
| 639 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), aop_menu->default_item); |
607 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(optmenu), cr, "text", 1); |
| 640 |
608 |
| 641 g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", aop_menu, (GDestroyNotify)g_free); |
609 aop_option_menu_replace_menu(optmenu, aop_menu); |
| |
610 if (aop_menu->default_item == -1) |
| |
611 gtk_combo_box_set_active(GTK_COMBO_BOX(optmenu), 0); |
| 642 g_object_set_data(G_OBJECT(optmenu), "user_data", user_data); |
612 g_object_set_data(G_OBJECT(optmenu), "user_data", user_data); |
| 643 |
613 |
| 644 g_signal_connect(G_OBJECT(optmenu), "changed", G_CALLBACK(aop_menu_cb), cb); |
614 g_signal_connect(G_OBJECT(optmenu), "changed", G_CALLBACK(aop_menu_cb), cb); |
| 645 |
615 |
| 646 return optmenu; |
616 return optmenu; |
| 647 } |
|
| 648 |
|
| 649 static void |
|
| 650 aop_option_menu_replace_menu(GtkWidget *optmenu, AopMenu *new_aop_menu) |
|
| 651 { |
|
| 652 if (gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu))) |
|
| 653 gtk_option_menu_remove_menu(GTK_OPTION_MENU(optmenu)); |
|
| 654 |
|
| 655 gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), new_aop_menu->menu); |
|
| 656 |
|
| 657 if (new_aop_menu->default_item != -1) |
|
| 658 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), new_aop_menu->default_item); |
|
| 659 |
|
| 660 g_object_set_data_full(G_OBJECT(optmenu), "aop_menu", new_aop_menu, (GDestroyNotify)g_free); |
|
| 661 } |
617 } |
| 662 |
618 |
| 663 static void |
619 static void |
| 664 aop_option_menu_select_by_data(GtkWidget *optmenu, gpointer data) |
620 aop_option_menu_select_by_data(GtkWidget *optmenu, gpointer data) |
| 665 { |
621 { |
| 666 guint idx; |
622 GtkTreeModel *model; |
| 667 GList *llItr = NULL; |
623 GtkTreeIter iter; |
| 668 |
624 gpointer iter_data; |
| 669 for (idx = 0, llItr = GTK_MENU_SHELL(gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)))->children; |
625 model = gtk_combo_box_get_model(GTK_COMBO_BOX(optmenu)); |
| 670 llItr != NULL; |
626 if (gtk_tree_model_get_iter_first(model, &iter)) { |
| 671 llItr = llItr->next, idx++) { |
627 do { |
| 672 if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) { |
628 gtk_tree_model_get(model, &iter, 2, &iter_data, -1); |
| 673 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx); |
629 if (iter_data == data) { |
| 674 break; |
630 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(optmenu), &iter); |
| 675 } |
631 return; |
| |
632 } |
| |
633 } while (gtk_tree_model_iter_next(model, &iter)); |
| 676 } |
634 } |
| 677 } |
635 } |
| 678 |
636 |
| 679 static AopMenu * |
637 static AopMenu * |
| 680 create_protocols_menu(const char *default_proto_id) |
638 create_protocols_menu(const char *default_proto_id) |
| 681 { |
639 { |
| 682 AopMenu *aop_menu = NULL; |
640 AopMenu *aop_menu = NULL; |
| 683 PurplePluginProtocolInfo *prpl_info; |
641 PurplePluginProtocolInfo *prpl_info; |
| 684 PurplePlugin *plugin; |
642 PurplePlugin *plugin; |
| 685 GdkPixbuf *pixbuf = NULL; |
643 GdkPixbuf *pixbuf = NULL; |
| 686 GtkSizeGroup *sg; |
644 GtkTreeIter iter; |
| |
645 GtkListStore *ls; |
| 687 GList *p; |
646 GList *p; |
| 688 const char *gtalk_name = NULL; |
647 const char *gtalk_name = NULL; |
| 689 int i; |
648 int i; |
| 690 |
649 |
| |
650 ls = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER); |
| |
651 |
| 691 aop_menu = g_malloc0(sizeof(AopMenu)); |
652 aop_menu = g_malloc0(sizeof(AopMenu)); |
| 692 aop_menu->default_item = -1; |
653 aop_menu->default_item = -1; |
| 693 aop_menu->menu = gtk_menu_new(); |
654 aop_menu->model = GTK_TREE_MODEL(ls); |
| 694 gtk_widget_show(aop_menu->menu); |
|
| 695 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
|
| 696 |
655 |
| 697 if (purple_find_prpl("prpl-jabber")) |
656 if (purple_find_prpl("prpl-jabber")) |
| 698 gtalk_name = _("Google Talk"); |
657 gtalk_name = _("Google Talk"); |
| 699 |
658 |
| 700 for (p = purple_plugins_get_protocols(), i = 0; |
659 for (p = purple_plugins_get_protocols(), i = 0; |
| 705 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); |
664 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); |
| 706 |
665 |
| 707 if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) { |
666 if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) { |
| 708 char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", |
667 char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", |
| 709 "16", "google-talk.png", NULL); |
668 "16", "google-talk.png", NULL); |
| 710 GtkWidget *item; |
|
| 711 |
|
| 712 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); |
669 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); |
| 713 g_free(filename); |
670 g_free(filename); |
| 714 |
671 |
| 715 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
672 gtk_list_store_append(ls, &iter); |
| 716 item = aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber", "protocol")); |
673 gtk_list_store_set(ls, &iter, 0, pixbuf, 1, gtalk_name, 2, "prpl-jabber", -1); |
| 717 g_object_set_data(G_OBJECT(item), "fake", GINT_TO_POINTER(1)); |
|
| 718 |
674 |
| 719 if (pixbuf) |
675 if (pixbuf) |
| 720 g_object_unref(pixbuf); |
676 g_object_unref(pixbuf); |
| 721 |
677 |
| 722 gtalk_name = NULL; |
678 gtalk_name = NULL; |
| 723 i++; |
679 i++; |
| 724 } |
680 } |
| 725 |
681 |
| 726 pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL); |
682 pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL); |
| 727 |
683 |
| 728 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
684 gtk_list_store_append(ls, &iter); |
| 729 aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id, "protocol")); |
685 gtk_list_store_set(ls, &iter, 0, pixbuf, 1, plugin->info->name, 2, plugin->info->id, -1); |
| 730 |
686 |
| 731 if (pixbuf) |
687 if (pixbuf) |
| 732 g_object_unref(pixbuf); |
688 g_object_unref(pixbuf); |
| 733 |
689 |
| 734 if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id)) |
690 if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id)) |
| 735 aop_menu->default_item = i; |
691 aop_menu->default_item = i; |
| 736 } |
692 } |
| 737 |
|
| 738 g_object_unref(sg); |
|
| 739 |
|
| 740 return aop_menu; |
693 return aop_menu; |
| 741 } |
694 } |
| 742 |
695 |
| 743 GtkWidget * |
696 GtkWidget * |
| 744 pidgin_protocol_option_menu_new(const char *id, GCallback cb, |
697 pidgin_protocol_option_menu_new(const char *id, GCallback cb, |
| 766 AopMenu *aop_menu = NULL; |
719 AopMenu *aop_menu = NULL; |
| 767 PurpleAccount *account; |
720 PurpleAccount *account; |
| 768 GdkPixbuf *pixbuf = NULL; |
721 GdkPixbuf *pixbuf = NULL; |
| 769 GList *list; |
722 GList *list; |
| 770 GList *p; |
723 GList *p; |
| 771 GtkSizeGroup *sg; |
724 GtkListStore *ls; |
| |
725 GtkTreeIter iter; |
| 772 int i; |
726 int i; |
| 773 char buf[256]; |
727 char buf[256]; |
| 774 |
728 |
| 775 if (show_all) |
729 if (show_all) |
| 776 list = purple_accounts_get_all(); |
730 list = purple_accounts_get_all(); |
| 777 else |
731 else |
| 778 list = purple_connections_get_all(); |
732 list = purple_connections_get_all(); |
| 779 |
733 |
| |
734 ls = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER); |
| |
735 |
| 780 aop_menu = g_malloc0(sizeof(AopMenu)); |
736 aop_menu = g_malloc0(sizeof(AopMenu)); |
| 781 aop_menu->default_item = -1; |
737 aop_menu->default_item = -1; |
| 782 aop_menu->menu = gtk_menu_new(); |
738 aop_menu->model = GTK_TREE_MODEL(ls); |
| 783 gtk_widget_show(aop_menu->menu); |
|
| 784 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
|
| 785 |
739 |
| 786 for (p = list, i = 0; p != NULL; p = p->next, i++) { |
740 for (p = list, i = 0; p != NULL; p = p->next, i++) { |
| 787 PurplePlugin *plugin; |
741 PurplePlugin *plugin; |
| 788 |
742 |
| 789 if (show_all) |
743 if (show_all) |
| 818 g_snprintf(buf, sizeof(buf), "%s (%s)", |
772 g_snprintf(buf, sizeof(buf), "%s (%s)", |
| 819 purple_account_get_username(account), |
773 purple_account_get_username(account), |
| 820 purple_account_get_protocol_name(account)); |
774 purple_account_get_protocol_name(account)); |
| 821 } |
775 } |
| 822 |
776 |
| 823 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
777 gtk_list_store_append(ls, &iter); |
| 824 aop_menu_item_new(sg, pixbuf, buf, account, "account")); |
778 gtk_list_store_set(ls, &iter, 0, pixbuf, 1, buf, 2, account, -1); |
| 825 |
779 |
| 826 if (pixbuf) |
780 if (pixbuf) |
| 827 g_object_unref(pixbuf); |
781 g_object_unref(pixbuf); |
| 828 |
782 |
| 829 if (default_account && account == default_account) |
783 if (default_account && account == default_account) |
| 830 aop_menu->default_item = i; |
784 aop_menu->default_item = i; |
| 831 } |
785 } |
| 832 |
|
| 833 g_object_unref(sg); |
|
| 834 |
|
| 835 return aop_menu; |
786 return aop_menu; |
| 836 } |
787 } |
| 837 |
788 |
| 838 static void |
789 static void |
| 839 regenerate_account_menu(GtkWidget *optmenu) |
790 regenerate_account_menu(GtkWidget *optmenu) |
| 840 { |
791 { |
| 841 gboolean show_all; |
792 gboolean show_all; |
| 842 PurpleAccount *account; |
793 PurpleAccount *account; |
| 843 PurpleFilterAccountFunc filter_func; |
794 PurpleFilterAccountFunc filter_func; |
| 844 |
795 |
| 845 account = (PurpleAccount *)aop_option_menu_get_selected(optmenu, NULL); |
796 account = (PurpleAccount *)aop_option_menu_get_selected(optmenu); |
| 846 show_all = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(optmenu), "show_all")); |
797 show_all = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(optmenu), "show_all")); |
| 847 filter_func = g_object_get_data(G_OBJECT(optmenu), "filter_func"); |
798 filter_func = g_object_get_data(G_OBJECT(optmenu), "filter_func"); |
| 848 |
799 |
| 849 aop_option_menu_replace_menu(optmenu, create_account_menu(account, filter_func, show_all)); |
800 aop_option_menu_replace_menu(optmenu, create_account_menu(account, filter_func, show_all)); |
| 850 } |
801 } |