| 92 }; |
92 }; |
| 93 |
93 |
| 94 void |
94 void |
| 95 pidgin_setup_imhtml(GtkWidget *imhtml) |
95 pidgin_setup_imhtml(GtkWidget *imhtml) |
| 96 { |
96 { |
| |
97 PangoFontDescription *desc = NULL; |
| 97 g_return_if_fail(imhtml != NULL); |
98 g_return_if_fail(imhtml != NULL); |
| 98 g_return_if_fail(GTK_IS_IMHTML(imhtml)); |
99 g_return_if_fail(GTK_IS_IMHTML(imhtml)); |
| 99 |
100 |
| 100 g_signal_connect(G_OBJECT(imhtml), "url_clicked", |
101 g_signal_connect(G_OBJECT(imhtml), "url_clicked", |
| 101 G_CALLBACK(url_clicked_cb), NULL); |
102 G_CALLBACK(url_clicked_cb), NULL); |
| 102 |
103 |
| 103 pidgin_themes_smiley_themeize(imhtml); |
104 pidgin_themes_smiley_themeize(imhtml); |
| 104 |
105 |
| 105 gtk_imhtml_set_funcs(GTK_IMHTML(imhtml), >kimhtml_cbs); |
106 gtk_imhtml_set_funcs(GTK_IMHTML(imhtml), >kimhtml_cbs); |
| 106 |
107 |
| 107 /* Use the GNOME "document" font, if applicable */ |
108 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font")) { |
| 108 if (purple_running_gnome()) { |
109 const char *font = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/custom_font"); |
| |
110 desc = pango_font_description_from_string(font); |
| |
111 } else if (purple_running_gnome()) { |
| |
112 /* Use the GNOME "document" font, if applicable */ |
| 109 char *path, *font; |
113 char *path, *font; |
| 110 PangoFontDescription *desc = NULL; |
|
| 111 |
114 |
| 112 if ((path = g_find_program_in_path("gconftool-2"))) { |
115 if ((path = g_find_program_in_path("gconftool-2"))) { |
| 113 g_free(path); |
116 g_free(path); |
| 114 if (!g_spawn_command_line_sync( |
117 if (!g_spawn_command_line_sync( |
| 115 "gconftool-2 -g /desktop/gnome/interface/document_font_name", |
118 "gconftool-2 -g /desktop/gnome/interface/document_font_name", |
| 116 &font, NULL, NULL, NULL)) |
119 &font, NULL, NULL, NULL)) |
| 117 return; |
120 return; |
| 118 } |
121 } |
| 119 desc = pango_font_description_from_string(font); |
122 desc = pango_font_description_from_string(font); |
| 120 g_free(font); |
123 g_free(font); |
| 121 |
124 } |
| 122 if (desc) { |
125 |
| 123 gtk_widget_modify_font(imhtml, desc); |
126 if (desc) { |
| 124 pango_font_description_free(desc); |
127 gtk_widget_modify_font(imhtml, desc); |
| 125 } |
128 pango_font_description_free(desc); |
| 126 } |
129 } |
| |
130 } |
| |
131 |
| |
132 GtkWidget * |
| |
133 pidgin_create_window(const char *title, guint border_width, const char *role, gboolean resizable) |
| |
134 { |
| |
135 GtkWindow *wnd = NULL; |
| |
136 |
| |
137 wnd = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); |
| |
138 if (title) |
| |
139 gtk_window_set_title(wnd, title); |
| |
140 gtk_container_set_border_width(GTK_CONTAINER(wnd), border_width); |
| |
141 if (role) |
| |
142 gtk_window_set_role(wnd, role); |
| |
143 gtk_window_set_resizable(wnd, resizable); |
| |
144 |
| |
145 return GTK_WIDGET(wnd); |
| 127 } |
146 } |
| 128 |
147 |
| 129 GtkWidget * |
148 GtkWidget * |
| 130 pidgin_create_imhtml(gboolean editable, GtkWidget **imhtml_ret, GtkWidget **toolbar_ret, GtkWidget **sw_ret) |
149 pidgin_create_imhtml(gboolean editable, GtkWidget **imhtml_ret, GtkWidget **toolbar_ret, GtkWidget **sw_ret) |
| 131 { |
150 { |
| 155 gtk_widget_show(sep); |
174 gtk_widget_show(sep); |
| 156 } |
175 } |
| 157 |
176 |
| 158 sw = gtk_scrolled_window_new(NULL, NULL); |
177 sw = gtk_scrolled_window_new(NULL, NULL); |
| 159 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), |
178 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), |
| 160 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); |
179 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); |
| 161 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); |
180 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); |
| 162 gtk_widget_show(sw); |
181 gtk_widget_show(sw); |
| 163 |
182 |
| 164 imhtml = gtk_imhtml_new(NULL, NULL); |
183 imhtml = gtk_imhtml_new(NULL, NULL); |
| 165 gtk_imhtml_set_editable(GTK_IMHTML(imhtml), editable); |
184 gtk_imhtml_set_editable(GTK_IMHTML(imhtml), editable); |
| 490 |
510 |
| 491 gtk_container_add(GTK_CONTAINER(item), hbox); |
511 gtk_container_add(GTK_CONTAINER(item), hbox); |
| 492 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); |
512 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); |
| 493 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); |
513 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); |
| 494 |
514 |
| |
515 g_object_set_data(G_OBJECT (item), data, per_item_data); |
| 495 g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data); |
516 g_object_set_data(G_OBJECT (item), "aop_per_item_data", per_item_data); |
| 496 |
517 |
| 497 pidgin_set_accessible_label(item, label); |
518 pidgin_set_accessible_label(item, label); |
| 498 |
519 |
| 499 return item; |
520 return item; |
| |
521 } |
| |
522 |
| |
523 static GdkPixbuf * |
| |
524 pidgin_create_prpl_icon_from_prpl(PurplePlugin *prpl, PidginPrplIconSize size, PurpleAccount *account) |
| |
525 { |
| |
526 PurplePluginProtocolInfo *prpl_info; |
| |
527 const char *protoname = NULL; |
| |
528 char *tmp; |
| |
529 char *filename = NULL; |
| |
530 GdkPixbuf *pixbuf; |
| |
531 |
| |
532 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); |
| |
533 if (prpl_info->list_icon == NULL) |
| |
534 return NULL; |
| |
535 |
| |
536 protoname = prpl_info->list_icon(account, NULL); |
| |
537 if (protoname == NULL) |
| |
538 return NULL; |
| |
539 |
| |
540 /* |
| |
541 * Status icons will be themeable too, and then it will look up |
| |
542 * protoname from the theme |
| |
543 */ |
| |
544 tmp = g_strconcat(protoname, ".png", NULL); |
| |
545 |
| |
546 filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", |
| |
547 size == PIDGIN_PRPL_ICON_SMALL ? "16" : |
| |
548 size == PIDGIN_PRPL_ICON_MEDIUM ? "22" : "48", |
| |
549 tmp, NULL); |
| |
550 g_free(tmp); |
| |
551 |
| |
552 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); |
| |
553 g_free(filename); |
| |
554 |
| |
555 return pixbuf; |
| 500 } |
556 } |
| 501 |
557 |
| 502 static GtkWidget * |
558 static GtkWidget * |
| 503 aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data) |
559 aop_option_menu_new(AopMenu *aop_menu, GCallback cb, gpointer user_data) |
| 504 { |
560 { |
| 545 if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) { |
601 if (data == g_object_get_data(G_OBJECT(llItr->data), "aop_per_item_data")) { |
| 546 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx); |
602 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), idx); |
| 547 break; |
603 break; |
| 548 } |
604 } |
| 549 } |
605 } |
| 550 } |
|
| 551 |
|
| 552 static GdkPixbuf * |
|
| 553 get_prpl_pixbuf(PurplePluginProtocolInfo *prpl_info) |
|
| 554 { |
|
| 555 const char *proto_name; |
|
| 556 GdkPixbuf *pixbuf = NULL; |
|
| 557 char *filename; |
|
| 558 char buf[256]; |
|
| 559 |
|
| 560 proto_name = prpl_info->list_icon(NULL, NULL); |
|
| 561 g_return_val_if_fail(proto_name != NULL, NULL); |
|
| 562 |
|
| 563 g_snprintf(buf, sizeof(buf), "%s.png", proto_name); |
|
| 564 filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "16", buf, NULL); |
|
| 565 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); |
|
| 566 g_free(filename); |
|
| 567 |
|
| 568 return pixbuf; |
|
| 569 } |
606 } |
| 570 |
607 |
| 571 static AopMenu * |
608 static AopMenu * |
| 572 create_protocols_menu(const char *default_proto_id) |
609 create_protocols_menu(const char *default_proto_id) |
| 573 { |
610 { |
| 597 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); |
634 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); |
| 598 |
635 |
| 599 if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) { |
636 if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) { |
| 600 char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", |
637 char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", |
| 601 "16", "google-talk.png", NULL); |
638 "16", "google-talk.png", NULL); |
| |
639 GtkWidget *item; |
| |
640 |
| 602 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); |
641 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); |
| 603 g_free(filename); |
642 g_free(filename); |
| 604 |
643 |
| 605 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
644 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
| 606 aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber")); |
645 item = aop_menu_item_new(sg, pixbuf, gtalk_name, "prpl-jabber", "protocol")); |
| |
646 g_object_set_data(G_OBJECT(item), "fake", GINT_TO_POINTER(1)); |
| 607 |
647 |
| 608 if (pixbuf) |
648 if (pixbuf) |
| 609 g_object_unref(pixbuf); |
649 g_object_unref(pixbuf); |
| 610 |
650 |
| 611 gtalk_name = NULL; |
651 gtalk_name = NULL; |
| 612 } |
652 i++; |
| 613 |
653 } |
| 614 pixbuf = get_prpl_pixbuf(prpl_info); |
654 |
| |
655 pixbuf = pidgin_create_prpl_icon_from_prpl(plugin, PIDGIN_PRPL_ICON_SMALL, NULL); |
| 615 |
656 |
| 616 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
657 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
| 617 aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id)); |
658 aop_menu_item_new(sg, pixbuf, plugin->info->name, plugin->info->id, "protocol")); |
| 618 |
659 |
| 619 if (pixbuf) |
660 if (pixbuf) |
| 620 g_object_unref(pixbuf); |
661 g_object_unref(pixbuf); |
| 621 |
662 |
| 622 if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id)) |
663 if (default_proto_id != NULL && !strcmp(plugin->info->id, default_proto_id)) |
| 682 continue; |
722 continue; |
| 683 } |
723 } |
| 684 |
724 |
| 685 plugin = purple_find_prpl(purple_account_get_protocol_id(account)); |
725 plugin = purple_find_prpl(purple_account_get_protocol_id(account)); |
| 686 |
726 |
| 687 if (plugin) |
727 pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); |
| 688 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin); |
728 |
| 689 |
729 if (pixbuf) { |
| 690 /* Load the image. */ |
730 if (purple_account_is_disconnected(account) && show_all && |
| 691 if (prpl_info) { |
731 purple_connections_get_all()) |
| 692 pixbuf = get_prpl_pixbuf(prpl_info); |
732 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); |
| 693 |
|
| 694 if (pixbuf) { |
|
| 695 if (purple_account_is_disconnected(account) && show_all && |
|
| 696 purple_connections_get_all()) |
|
| 697 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); |
|
| 698 } |
|
| 699 } |
733 } |
| 700 |
734 |
| 701 if (purple_account_get_alias(account)) { |
735 if (purple_account_get_alias(account)) { |
| 702 g_snprintf(buf, sizeof(buf), "%s (%s) (%s)", |
736 g_snprintf(buf, sizeof(buf), "%s (%s) (%s)", |
| 703 purple_account_get_username(account), |
737 purple_account_get_username(account), |
| 708 purple_account_get_username(account), |
742 purple_account_get_username(account), |
| 709 purple_account_get_protocol_name(account)); |
743 purple_account_get_protocol_name(account)); |
| 710 } |
744 } |
| 711 |
745 |
| 712 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
746 gtk_menu_shell_append(GTK_MENU_SHELL(aop_menu->menu), |
| 713 aop_menu_item_new(sg, pixbuf, buf, account)); |
747 aop_menu_item_new(sg, pixbuf, buf, account, "account")); |
| 714 |
748 |
| 715 if (pixbuf) |
749 if (pixbuf) |
| 716 g_object_unref(pixbuf); |
750 g_object_unref(pixbuf); |
| 717 |
751 |
| 718 if (default_account && account == default_account) |
752 if (default_account && account == default_account) |
| 877 "accels", NULL); |
911 "accels", NULL); |
| 878 gtk_accel_map_load(filename); |
912 gtk_accel_map_load(filename); |
| 879 g_free(filename); |
913 g_free(filename); |
| 880 } |
914 } |
| 881 |
915 |
| |
916 static void |
| |
917 show_retrieveing_info(PurpleConnection *conn, const char *name) |
| |
918 { |
| |
919 PurpleNotifyUserInfo *info = purple_notify_user_info_new(); |
| |
920 purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving...")); |
| |
921 purple_notify_userinfo(conn, name, info, NULL, NULL); |
| |
922 purple_notify_user_info_destroy(info); |
| |
923 } |
| |
924 |
| |
925 void pidgin_retrieve_user_info(PurpleConnection *conn, const char *name) |
| |
926 { |
| |
927 show_retrieveing_info(conn, name); |
| |
928 serv_get_info(conn, name); |
| |
929 } |
| |
930 |
| |
931 void pidgin_retrieve_user_info_in_chat(PurpleConnection *conn, const char *name, int chat) |
| |
932 { |
| |
933 char *who = NULL; |
| |
934 PurplePluginProtocolInfo *prpl_info = NULL; |
| |
935 |
| |
936 if (chat < 0) { |
| |
937 pidgin_retrieve_user_info(conn, name); |
| |
938 return; |
| |
939 } |
| |
940 |
| |
941 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(conn->prpl); |
| |
942 if (prpl_info == NULL || prpl_info->get_cb_info == NULL) { |
| |
943 pidgin_retrieve_user_info(conn, name); |
| |
944 return; |
| |
945 } |
| |
946 |
| |
947 if (prpl_info->get_cb_real_name) |
| |
948 who = prpl_info->get_cb_real_name(conn, chat, name); |
| |
949 show_retrieveing_info(conn, who ? who : name); |
| |
950 prpl_info->get_cb_info(conn, chat, name); |
| |
951 g_free(who); |
| |
952 } |
| |
953 |
| 882 gboolean |
954 gboolean |
| 883 pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts, |
955 pidgin_parse_x_im_contact(const char *msg, gboolean all_accounts, |
| 884 PurpleAccount **ret_account, char **ret_protocol, |
956 PurpleAccount **ret_account, char **ret_protocol, |
| 885 char **ret_username, char **ret_alias) |
957 char **ret_username, char **ret_alias) |
| 886 { |
958 { |
| 1073 const gchar *existing_name; |
1145 const gchar *existing_name; |
| 1074 |
1146 |
| 1075 acc = gtk_widget_get_accessible (w); |
1147 acc = gtk_widget_get_accessible (w); |
| 1076 label = gtk_widget_get_accessible (l); |
1148 label = gtk_widget_get_accessible (l); |
| 1077 |
1149 |
| |
1150 /* Make sure mnemonics work */ |
| |
1151 gtk_label_set_mnemonic_widget(GTK_LABEL(l), w); |
| |
1152 |
| 1078 /* If this object has no name, set it's name with the label text */ |
1153 /* If this object has no name, set it's name with the label text */ |
| 1079 existing_name = atk_object_get_name (acc); |
1154 existing_name = atk_object_get_name (acc); |
| 1080 if (!existing_name) { |
1155 if (!existing_name) { |
| 1081 label_text = gtk_label_get_text (GTK_LABEL(l)); |
1156 label_text = gtk_label_get_text (GTK_LABEL(l)); |
| 1082 if (label_text) |
1157 if (label_text) |
| 1096 relation = atk_relation_new (rel_obj, 1, ATK_RELATION_LABEL_FOR); |
1171 relation = atk_relation_new (rel_obj, 1, ATK_RELATION_LABEL_FOR); |
| 1097 atk_relation_set_add (set, relation); |
1172 atk_relation_set_add (set, relation); |
| 1098 g_object_unref (relation); |
1173 g_object_unref (relation); |
| 1099 } |
1174 } |
| 1100 |
1175 |
| 1101 #if GTK_CHECK_VERSION(2,2,0) |
1176 void |
| 1102 static void |
1177 pidgin_menu_position_func_helper(GtkMenu *menu, |
| 1103 pidgin_menu_position_func(GtkMenu *menu, |
|
| 1104 gint *x, |
1178 gint *x, |
| 1105 gint *y, |
1179 gint *y, |
| 1106 gboolean *push_in, |
1180 gboolean *push_in, |
| 1107 gpointer data) |
1181 gpointer data) |
| 1108 { |
1182 { |
| |
1183 #if GTK_CHECK_VERSION(2,2,0) |
| 1109 GtkWidget *widget; |
1184 GtkWidget *widget; |
| 1110 GtkRequisition requisition; |
1185 GtkRequisition requisition; |
| 1111 GdkScreen *screen; |
1186 GdkScreen *screen; |
| 1112 GdkRectangle monitor; |
1187 GdkRectangle monitor; |
| 1113 gint monitor_num; |
1188 gint monitor_num; |
| 1268 gtk_tree_view_get_cursor (tv, &path, &col); |
1343 gtk_tree_view_get_cursor (tv, &path, &col); |
| 1269 gtk_tree_view_get_cell_area (tv, path, col, &rect); |
1344 gtk_tree_view_get_cell_area (tv, path, col, &rect); |
| 1270 |
1345 |
| 1271 *x += rect.x+rect.width; |
1346 *x += rect.x+rect.width; |
| 1272 *y += rect.y+rect.height+ythickness; |
1347 *y += rect.y+rect.height+ythickness; |
| 1273 #if GTK_CHECK_VERSION(2,2,0) |
1348 pidgin_menu_position_func_helper(menu, x, y, push_in, data); |
| 1274 pidgin_menu_position_func (menu, x, y, push_in, data); |
|
| 1275 #endif |
|
| 1276 } |
1349 } |
| 1277 |
1350 |
| 1278 enum { |
1351 enum { |
| 1279 DND_FILE_TRANSFER, |
1352 DND_FILE_TRANSFER, |
| 1280 DND_IM_IMAGE, |
1353 DND_IM_IMAGE, |
| 1452 account, who, NULL, |
1525 account, who, NULL, |
| 1453 data, (GCallback)dnd_set_icon_ok_cb, (GCallback)dnd_set_icon_cancel_cb); |
1526 data, (GCallback)dnd_set_icon_ok_cb, (GCallback)dnd_set_icon_cancel_cb); |
| 1454 else |
1527 else |
| 1455 purple_request_choice(NULL, NULL, |
1528 purple_request_choice(NULL, NULL, |
| 1456 _("You have dragged an image"), |
1529 _("You have dragged an image"), |
| 1457 (ft ? _("You can send this image as a file transfer or " |
1530 (ft ? _("You can send this image as a file transfer, or use it as the buddy icon for this user.") : |
| 1458 "embed it into this message, or use it as the buddy icon for this user.") : |
|
| 1459 _("You can insert this image into this message, or use it as the buddy icon for this user")), |
1531 _("You can insert this image into this message, or use it as the buddy icon for this user")), |
| 1460 (ft ? DND_FILE_TRANSFER : DND_IM_IMAGE), |
1532 (ft ? DND_FILE_TRANSFER : DND_IM_IMAGE), |
| 1461 "OK", (GCallback)dnd_image_ok_callback, |
1533 "OK", (GCallback)dnd_image_ok_callback, |
| 1462 "Cancel", (GCallback)dnd_image_cancel_callback, |
1534 "Cancel", (GCallback)dnd_image_cancel_callback, |
| 1463 account, who, NULL, |
1535 account, who, NULL, |
| 1578 |
1650 |
| 1579 GdkPixbuf * |
1651 GdkPixbuf * |
| 1580 pidgin_create_prpl_icon(PurpleAccount *account, PidginPrplIconSize size) |
1652 pidgin_create_prpl_icon(PurpleAccount *account, PidginPrplIconSize size) |
| 1581 { |
1653 { |
| 1582 PurplePlugin *prpl; |
1654 PurplePlugin *prpl; |
| 1583 PurplePluginProtocolInfo *prpl_info; |
|
| 1584 const char *protoname = NULL; |
|
| 1585 char buf[256]; /* TODO: We should use a define for max file length */ |
|
| 1586 char *filename = NULL; |
|
| 1587 GdkPixbuf *pixbuf; |
|
| 1588 |
1655 |
| 1589 g_return_val_if_fail(account != NULL, NULL); |
1656 g_return_val_if_fail(account != NULL, NULL); |
| 1590 |
1657 |
| 1591 prpl = purple_find_prpl(purple_account_get_protocol_id(account)); |
1658 prpl = purple_find_prpl(purple_account_get_protocol_id(account)); |
| 1592 if (prpl == NULL) |
1659 if (prpl == NULL) |
| 1593 return NULL; |
1660 return NULL; |
| 1594 |
1661 return pidgin_create_prpl_icon_from_prpl(prpl, size, account); |
| 1595 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); |
|
| 1596 if (prpl_info->list_icon == NULL) |
|
| 1597 return NULL; |
|
| 1598 |
|
| 1599 protoname = prpl_info->list_icon(account, NULL); |
|
| 1600 if (protoname == NULL) |
|
| 1601 return NULL; |
|
| 1602 |
|
| 1603 /* |
|
| 1604 * Status icons will be themeable too, and then it will look up |
|
| 1605 * protoname from the theme |
|
| 1606 */ |
|
| 1607 g_snprintf(buf, sizeof(buf), "%s.png", protoname); |
|
| 1608 |
|
| 1609 filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", |
|
| 1610 size == PIDGIN_PRPL_ICON_SMALL ? "16" : |
|
| 1611 size == PIDGIN_PRPL_ICON_MEDIUM ? "22" : "48", |
|
| 1612 buf, NULL); |
|
| 1613 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); |
|
| 1614 g_free(filename); |
|
| 1615 |
|
| 1616 return pixbuf; |
|
| 1617 } |
1662 } |
| 1618 |
1663 |
| 1619 static void |
1664 static void |
| 1620 menu_action_cb(GtkMenuItem *item, gpointer object) |
1665 menu_action_cb(GtkMenuItem *item, gpointer object) |
| 1621 { |
1666 { |
| 1627 |
1672 |
| 1628 if (callback) |
1673 if (callback) |
| 1629 callback(object, data); |
1674 callback(object, data); |
| 1630 } |
1675 } |
| 1631 |
1676 |
| 1632 void |
1677 GtkWidget * |
| 1633 pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act, |
1678 pidgin_append_menu_action(GtkWidget *menu, PurpleMenuAction *act, |
| 1634 gpointer object) |
1679 gpointer object) |
| 1635 { |
1680 { |
| |
1681 GtkWidget *menuitem; |
| |
1682 |
| 1636 if (act == NULL) { |
1683 if (act == NULL) { |
| 1637 pidgin_separator(menu); |
1684 return pidgin_separator(menu); |
| |
1685 } |
| |
1686 |
| |
1687 if (act->children == NULL) { |
| |
1688 menuitem = gtk_menu_item_new_with_mnemonic(act->label); |
| |
1689 |
| |
1690 if (act->callback != NULL) { |
| |
1691 g_object_set_data(G_OBJECT(menuitem), |
| |
1692 "purplecallback", |
| |
1693 act->callback); |
| |
1694 g_object_set_data(G_OBJECT(menuitem), |
| |
1695 "purplecallbackdata", |
| |
1696 act->data); |
| |
1697 g_signal_connect(G_OBJECT(menuitem), "activate", |
| |
1698 G_CALLBACK(menu_action_cb), |
| |
1699 object); |
| |
1700 } else { |
| |
1701 gtk_widget_set_sensitive(menuitem, FALSE); |
| |
1702 } |
| |
1703 |
| |
1704 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
| 1638 } else { |
1705 } else { |
| 1639 GtkWidget *menuitem; |
1706 GList *l = NULL; |
| 1640 |
1707 GtkWidget *submenu = NULL; |
| 1641 if (act->children == NULL) { |
1708 GtkAccelGroup *group; |
| 1642 menuitem = gtk_menu_item_new_with_mnemonic(act->label); |
1709 |
| 1643 |
1710 menuitem = gtk_menu_item_new_with_mnemonic(act->label); |
| 1644 if (act->callback != NULL) { |
1711 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
| 1645 g_object_set_data(G_OBJECT(menuitem), |
1712 |
| 1646 "purplecallback", |
1713 submenu = gtk_menu_new(); |
| 1647 act->callback); |
1714 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); |
| 1648 g_object_set_data(G_OBJECT(menuitem), |
1715 |
| 1649 "purplecallbackdata", |
1716 group = gtk_menu_get_accel_group(GTK_MENU(menu)); |
| 1650 act->data); |
1717 if (group) { |
| 1651 g_signal_connect(G_OBJECT(menuitem), "activate", |
1718 char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label); |
| 1652 G_CALLBACK(menu_action_cb), |
1719 gtk_menu_set_accel_path(GTK_MENU(submenu), path); |
| 1653 object); |
1720 g_free(path); |
| 1654 } else { |
1721 gtk_menu_set_accel_group(GTK_MENU(submenu), group); |
| 1655 gtk_widget_set_sensitive(menuitem, FALSE); |
1722 } |
| 1656 } |
1723 |
| 1657 |
1724 for (l = act->children; l; l = l->next) { |
| 1658 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
1725 PurpleMenuAction *act = (PurpleMenuAction *)l->data; |
| 1659 } else { |
1726 |
| 1660 GList *l = NULL; |
1727 pidgin_append_menu_action(submenu, act, object); |
| 1661 GtkWidget *submenu = NULL; |
1728 } |
| 1662 GtkAccelGroup *group; |
1729 g_list_free(act->children); |
| 1663 |
1730 act->children = NULL; |
| 1664 menuitem = gtk_menu_item_new_with_mnemonic(act->label); |
1731 } |
| 1665 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
1732 purple_menu_action_free(act); |
| 1666 |
1733 return menuitem; |
| 1667 submenu = gtk_menu_new(); |
|
| 1668 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); |
|
| 1669 |
|
| 1670 group = gtk_menu_get_accel_group(GTK_MENU(menu)); |
|
| 1671 if (group) { |
|
| 1672 char *path = g_strdup_printf("%s/%s", GTK_MENU_ITEM(menuitem)->accel_path, act->label); |
|
| 1673 gtk_menu_set_accel_path(GTK_MENU(submenu), path); |
|
| 1674 g_free(path); |
|
| 1675 gtk_menu_set_accel_group(GTK_MENU(submenu), group); |
|
| 1676 } |
|
| 1677 |
|
| 1678 for (l = act->children; l; l = l->next) { |
|
| 1679 PurpleMenuAction *act = (PurpleMenuAction *)l->data; |
|
| 1680 |
|
| 1681 pidgin_append_menu_action(submenu, act, object); |
|
| 1682 } |
|
| 1683 g_list_free(act->children); |
|
| 1684 act->children = NULL; |
|
| 1685 } |
|
| 1686 purple_menu_action_free(act); |
|
| 1687 } |
|
| 1688 } |
1734 } |
| 1689 |
1735 |
| 1690 #if GTK_CHECK_VERSION(2,3,0) |
1736 #if GTK_CHECK_VERSION(2,3,0) |
| 1691 # define NEW_STYLE_COMPLETION |
1737 # define NEW_STYLE_COMPLETION |
| 1692 #endif |
1738 #endif |
| 2114 purple_signal_connect(purple_accounts_get_handle(), "account-added", entry, |
2161 purple_signal_connect(purple_accounts_get_handle(), "account-added", entry, |
| 2115 PURPLE_CALLBACK(repopulate_autocomplete), cb_data); |
2162 PURPLE_CALLBACK(repopulate_autocomplete), cb_data); |
| 2116 purple_signal_connect(purple_accounts_get_handle(), "account-removed", entry, |
2163 purple_signal_connect(purple_accounts_get_handle(), "account-removed", entry, |
| 2117 PURPLE_CALLBACK(repopulate_autocomplete), cb_data); |
2164 PURPLE_CALLBACK(repopulate_autocomplete), cb_data); |
| 2118 |
2165 |
| 2119 g_signal_connect(G_OBJECT(entry), "destroy", G_CALLBACK(screenname_autocomplete_destroyed_cb), NULL); |
2166 g_signal_connect(G_OBJECT(entry), "destroy", G_CALLBACK(screenname_autocomplete_destroyed_cb), data); |
| 2120 } |
2167 } |
| 2121 |
2168 |
| 2122 void pidgin_set_cursor(GtkWidget *widget, GdkCursorType cursor_type) |
2169 void pidgin_set_cursor(GtkWidget *widget, GdkCursorType cursor_type) |
| 2123 { |
2170 { |
| 2124 GdkCursor *cursor; |
2171 GdkCursor *cursor; |
| 3029 rowstride = gdk_pixbuf_get_rowstride (pixbuf); |
3076 rowstride = gdk_pixbuf_get_rowstride (pixbuf); |
| 3030 pixels = gdk_pixbuf_get_pixels (pixbuf); |
3077 pixels = gdk_pixbuf_get_pixels (pixbuf); |
| 3031 |
3078 |
| 3032 row = pixels; |
3079 row = pixels; |
| 3033 for (i = 3; i < rowstride; i+=4) { |
3080 for (i = 3; i < rowstride; i+=4) { |
| 3034 if (row[i] != 0xff) |
3081 if (row[i] < 0xfe) |
| 3035 return FALSE; |
3082 return FALSE; |
| 3036 } |
3083 } |
| 3037 |
3084 |
| 3038 for (i = 1; i < height - 1; i++) { |
3085 for (i = 1; i < height - 1; i++) { |
| 3039 row = pixels + (i*rowstride); |
3086 row = pixels + (i*rowstride); |
| 3040 if (row[3] != 0xff || row[rowstride-1] != 0xff) { |
3087 if (row[3] < 0xfe || row[rowstride-1] < 0xfe) { |
| 3041 return FALSE; |
3088 return FALSE; |
| 3042 } |
3089 } |
| 3043 } |
3090 } |
| 3044 |
3091 |
| 3045 row = pixels + ((height-1) * rowstride); |
3092 row = pixels + ((height-1) * rowstride); |
| 3046 for (i = 3; i < rowstride; i+=4) { |
3093 for (i = 3; i < rowstride; i+=4) { |
| 3047 if (row[i] != 0xff) |
3094 if (row[i] < 0xfe) |
| 3048 return FALSE; |
3095 return FALSE; |
| 3049 } |
3096 } |
| 3050 |
3097 |
| 3051 return TRUE; |
3098 return TRUE; |
| |
3099 } |
| |
3100 |
| |
3101 void pidgin_gdk_pixbuf_make_round(GdkPixbuf *pixbuf) { |
| |
3102 int width, height, rowstride; |
| |
3103 guchar *pixels; |
| |
3104 if (!gdk_pixbuf_get_has_alpha(pixbuf)) |
| |
3105 return; |
| |
3106 width = gdk_pixbuf_get_width(pixbuf); |
| |
3107 height = gdk_pixbuf_get_height(pixbuf); |
| |
3108 rowstride = gdk_pixbuf_get_rowstride(pixbuf); |
| |
3109 pixels = gdk_pixbuf_get_pixels(pixbuf); |
| |
3110 |
| |
3111 if (width < 6 || height < 6) |
| |
3112 return; |
| |
3113 /* Top left */ |
| |
3114 pixels[3] = 0; |
| |
3115 pixels[7] = 0x80; |
| |
3116 pixels[11] = 0xC0; |
| |
3117 pixels[rowstride + 3] = 0x80; |
| |
3118 pixels[rowstride * 2 + 3] = 0xC0; |
| |
3119 |
| |
3120 /* Top right */ |
| |
3121 pixels[width * 4 - 1] = 0; |
| |
3122 pixels[width * 4 - 5] = 0x80; |
| |
3123 pixels[width * 4 - 9] = 0xC0; |
| |
3124 pixels[rowstride + (width * 4) - 1] = 0x80; |
| |
3125 pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0; |
| |
3126 |
| |
3127 /* Bottom left */ |
| |
3128 pixels[(height - 1) * rowstride + 3] = 0; |
| |
3129 pixels[(height - 1) * rowstride + 7] = 0x80; |
| |
3130 pixels[(height - 1) * rowstride + 11] = 0xC0; |
| |
3131 pixels[(height - 2) * rowstride + 3] = 0x80; |
| |
3132 pixels[(height - 3) * rowstride + 3] = 0xC0; |
| |
3133 |
| |
3134 /* Bottom right */ |
| |
3135 pixels[height * rowstride - 1] = 0; |
| |
3136 pixels[(height - 1) * rowstride - 1] = 0x80; |
| |
3137 pixels[(height - 2) * rowstride - 1] = 0xC0; |
| |
3138 pixels[height * rowstride - 5] = 0x80; |
| |
3139 pixels[height * rowstride - 9] = 0xC0; |
| |
3140 } |
| |
3141 |
| |
3142 const char *pidgin_get_dim_grey_string(GtkWidget *widget) { |
| |
3143 static char dim_grey_string[8] = ""; |
| |
3144 GtkStyle *style; |
| |
3145 |
| |
3146 if (!widget) |
| |
3147 return "dim grey"; |
| |
3148 |
| |
3149 style = gtk_widget_get_style(widget); |
| |
3150 if (!style) |
| |
3151 return "dim grey"; |
| |
3152 |
| |
3153 snprintf(dim_grey_string, sizeof(dim_grey_string), "#%02x%02x%02x", |
| |
3154 style->text_aa[GTK_STATE_NORMAL].red >> 8, |
| |
3155 style->text_aa[GTK_STATE_NORMAL].green >> 8, |
| |
3156 style->text_aa[GTK_STATE_NORMAL].blue >> 8); |
| |
3157 return dim_grey_string; |
| 3052 } |
3158 } |
| 3053 |
3159 |
| 3054 #if !GTK_CHECK_VERSION(2,2,0) |
3160 #if !GTK_CHECK_VERSION(2,2,0) |
| 3055 GtkTreePath * |
3161 GtkTreePath * |
| 3056 gtk_tree_path_new_from_indices (gint first_index, ...) |
3162 gtk_tree_path_new_from_indices (gint first_index, ...) |