Mercurial > pidgin
comparison src/gtkpounce.c @ 12136:370f9d7868f9
[gaim-migrate @ 14436]
SF Patch #1356575 from Kevin Stange (SimGuy)
"This patch moves buddy pounces out of the menu and into
a new dialog, as suggested by Sean. I'm not ready to
say this is finished, but it's a solid starting point
and it does work.
I changed the namespacing a little from gaim_gtkpounce
to gaim_gtk_pounce to be consistent with the rest of Gaim.
I wanted to try to get more information into the pounce
manager, but I wasn't sure how to display it. I
thought perhaps a column containing a row of icons
representing which events are being watched (so the
user can see which of several pounces for the same
buddy are which), however, while I know how to do this,
there aren't icons in Gaim suitable for representing
all the events. Like "returned from away" and
"idle/unidle", as far as I can see. I'm not sure what
else could be shown to make the manager dialog more
"informative."
The dialog updates automatically to show pounces only
for connected accounts and updates when a pounce is
added, changed, or removed in some other way than the
dialog.
I'd like to get feedback on it if anyone has anything
they think I should change or fix, I'll do that and
update this patch. Otherwise, feel free to commit. :)"
As ridingpigs commented in the tracker, this is "far better than the current menu thing."
I made a few small changes to this. I believe most of them were related to adding hooks to disable things if there were no accounts connected. I also sorte
d the Tools menu a bit and updated the docklet to match.
I wish the plugin action code could sort the items it added.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Fri, 18 Nov 2005 16:37:51 +0000 |
parents | 969fd533bd5d |
children | 44104dfce57b |
comparison
equal
deleted
inserted
replaced
12135:e09bf5bc81d8 | 12136:370f9d7868f9 |
---|---|
37 #include "util.h" | 37 #include "util.h" |
38 | 38 |
39 #include "gtkblist.h" | 39 #include "gtkblist.h" |
40 #include "gtkdialogs.h" | 40 #include "gtkdialogs.h" |
41 #include "gtkpounce.h" | 41 #include "gtkpounce.h" |
42 #include "gtkstock.h" | |
42 #include "gtkutils.h" | 43 #include "gtkutils.h" |
44 | |
45 /** | |
46 * These are used for the GtkTreeView when you're scrolling through | |
47 * all your saved pounces. | |
48 */ | |
49 enum | |
50 { | |
51 /* Hidden column containing the GaimPounce */ | |
52 POUNCES_MANAGER_COLUMN_POUNCE, | |
53 POUNCES_MANAGER_COLUMN_ICON, | |
54 POUNCES_MANAGER_COLUMN_TARGET, | |
55 POUNCES_MANAGER_COLUMN_ACCOUNT, | |
56 POUNCES_MANAGER_COLUMN_PERSISTENCE, | |
57 POUNCES_MANAGER_NUM_COLUMNS | |
58 }; | |
43 | 59 |
44 typedef struct | 60 typedef struct |
45 { | 61 { |
46 /* Pounce data */ | 62 /* Pounce data */ |
47 GaimPounce *pounce; | 63 GaimPounce *pounce; |
82 /* Buttons */ | 98 /* Buttons */ |
83 GtkWidget *save_button; | 99 GtkWidget *save_button; |
84 | 100 |
85 } GaimGtkPounceDialog; | 101 } GaimGtkPounceDialog; |
86 | 102 |
103 typedef struct | |
104 { | |
105 GtkWidget *window; | |
106 GtkListStore *model; | |
107 GtkWidget *treeview; | |
108 GtkWidget *modify_button; | |
109 GtkWidget *delete_button; | |
110 } PouncesManager; | |
111 | |
112 static PouncesManager *pounces_manager = NULL; | |
113 | |
87 /************************************************************************** | 114 /************************************************************************** |
88 * Callbacks | 115 * Callbacks |
89 **************************************************************************/ | 116 **************************************************************************/ |
90 static gint | 117 static gint |
91 delete_win_cb(GtkWidget *w, GdkEventAny *e, GaimGtkPounceDialog *dialog) | 118 delete_win_cb(GtkWidget *w, GdkEventAny *e, GaimGtkPounceDialog *dialog) |
143 else | 170 else |
144 gaim_sound_play_event(GAIM_SOUND_POUNCE_DEFAULT, NULL); | 171 gaim_sound_play_event(GAIM_SOUND_POUNCE_DEFAULT, NULL); |
145 } | 172 } |
146 | 173 |
147 static void | 174 static void |
175 add_pounce_to_treeview(GtkListStore *model, GaimPounce *pounce) | |
176 { | |
177 GtkTreeIter iter; | |
178 GaimAccount *account; | |
179 GaimPounceEvent events; | |
180 gboolean persists; | |
181 const char *pouncer; | |
182 const char *pouncee; | |
183 GdkPixbuf *pixbuf, *scale = NULL; | |
184 | |
185 account = gaim_pounce_get_pouncer(pounce); | |
186 | |
187 if (gaim_account_is_disconnected(account)) | |
188 return; | |
189 | |
190 events = gaim_pounce_get_events(pounce); | |
191 | |
192 pixbuf = gaim_gtk_create_prpl_icon(account); | |
193 | |
194 if (pixbuf != NULL) | |
195 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, | |
196 GDK_INTERP_BILINEAR); | |
197 | |
198 pouncer = gaim_account_get_username(account); | |
199 pouncee = gaim_pounce_get_pouncee(pounce); | |
200 persists = gaim_pounce_get_save(pounce); | |
201 | |
202 gtk_list_store_append(model, &iter); | |
203 gtk_list_store_set(model, &iter, | |
204 POUNCES_MANAGER_COLUMN_POUNCE, pounce, | |
205 POUNCES_MANAGER_COLUMN_ICON, scale, | |
206 POUNCES_MANAGER_COLUMN_TARGET, pouncee, | |
207 POUNCES_MANAGER_COLUMN_ACCOUNT, pouncer, | |
208 POUNCES_MANAGER_COLUMN_PERSISTENCE, persists, | |
209 -1); | |
210 } | |
211 | |
212 static void | |
213 populate_pounces_list(PouncesManager *dialog) | |
214 { | |
215 const GList *pounces; | |
216 | |
217 gtk_list_store_clear(dialog->model); | |
218 | |
219 for (pounces = gaim_pounces_get_all(); pounces != NULL; | |
220 pounces = g_list_next(pounces)) | |
221 { | |
222 add_pounce_to_treeview(dialog->model, pounces->data); | |
223 } | |
224 } | |
225 | |
226 static void | |
227 update_pounces(void) | |
228 { | |
229 /* Rebuild the pounces list if the pounces manager is open */ | |
230 if (pounces_manager != NULL) | |
231 { | |
232 populate_pounces_list(pounces_manager); | |
233 } | |
234 } | |
235 | |
236 static void | |
237 signed_on_off_cb(GaimConnection *gc, gpointer user_data) | |
238 { | |
239 update_pounces(); | |
240 } | |
241 | |
242 static void | |
148 save_pounce_cb(GtkWidget *w, GaimGtkPounceDialog *dialog) | 243 save_pounce_cb(GtkWidget *w, GaimGtkPounceDialog *dialog) |
149 { | 244 { |
150 const char *name; | 245 const char *name; |
151 const char *message, *command, *sound; | 246 const char *message, *command, *sound; |
152 GaimBuddyList *blist; | |
153 GaimGtkBuddyList *gtkblist; | |
154 GaimPounceEvent events = GAIM_POUNCE_NONE; | 247 GaimPounceEvent events = GAIM_POUNCE_NONE; |
155 | 248 |
156 name = gtk_entry_get_text(GTK_ENTRY(dialog->buddy_entry)); | 249 name = gtk_entry_get_text(GTK_ENTRY(dialog->buddy_entry)); |
157 | 250 |
158 if (*name == '\0') | 251 if (*name == '\0') |
239 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->play_sound))); | 332 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->play_sound))); |
240 | 333 |
241 gaim_pounce_set_save(dialog->pounce, | 334 gaim_pounce_set_save(dialog->pounce, |
242 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->save_pounce))); | 335 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->save_pounce))); |
243 | 336 |
337 update_pounces(); | |
338 | |
244 delete_win_cb(NULL, NULL, dialog); | 339 delete_win_cb(NULL, NULL, dialog); |
245 | |
246 /* Rebuild the pounce menu */ | |
247 blist = gaim_get_blist(); | |
248 | |
249 if (GAIM_IS_GTK_BLIST(blist)) | |
250 { | |
251 gtkblist = GAIM_GTK_BLIST(blist); | |
252 | |
253 gaim_gtkpounce_menu_build(gtkblist->bpmenu); | |
254 } | |
255 } | 340 } |
256 | 341 |
257 static void | 342 static void |
258 pounce_choose_cb(GtkWidget *item, GaimAccount *account, | 343 pounce_choose_cb(GtkWidget *item, GaimAccount *account, |
259 GaimGtkPounceDialog *dialog) | 344 GaimGtkPounceDialog *dialog) |
336 {"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, 0}, | 421 {"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, 0}, |
337 {"application/x-im-contact", 0, 1} | 422 {"application/x-im-contact", 0, 1} |
338 }; | 423 }; |
339 | 424 |
340 void | 425 void |
341 gaim_gtkpounce_dialog_show(GaimAccount *account, const char *name, | 426 gaim_gtk_pounce_editor_show(GaimAccount *account, const char *name, |
342 GaimPounce *cur_pounce) | 427 GaimPounce *cur_pounce) |
343 { | 428 { |
344 GaimGtkPounceDialog *dialog; | 429 GaimGtkPounceDialog *dialog; |
345 GtkWidget *window; | 430 GtkWidget *window; |
346 GtkWidget *label; | 431 GtkWidget *label; |
347 GtkWidget *bbox; | 432 GtkWidget *bbox; |
795 | 880 |
796 gtk_widget_show_all(vbox2); | 881 gtk_widget_show_all(vbox2); |
797 gtk_widget_show(window); | 882 gtk_widget_show(window); |
798 } | 883 } |
799 | 884 |
800 static void | 885 static gboolean |
801 new_pounce_cb(GtkWidget *w, GaimBuddy *b) | 886 pounces_manager_configure_cb(GtkWidget *widget, GdkEventConfigure *event, PouncesManager *dialog) |
802 { | 887 { |
803 if (b == NULL) | 888 if (GTK_WIDGET_VISIBLE(widget)) { |
804 gaim_gtkpounce_dialog_show(NULL, NULL, NULL); | 889 gaim_prefs_set_int("/gaim/gtk/pounces/dialog/width", event->width); |
805 else | 890 gaim_prefs_set_int("/gaim/gtk/pounces/dialog/height", event->height); |
806 gaim_gtkpounce_dialog_show(b->account, b->name, NULL); | 891 } |
807 } | 892 |
808 | 893 return FALSE; |
809 static void | 894 } |
810 delete_pounce_cb(GtkWidget *w, GaimPounce *pounce) | 895 |
811 { | 896 static gboolean |
897 pounces_manager_find_pounce(GtkTreeIter *iter, GaimPounce *pounce) | |
898 { | |
899 GtkTreeModel *model = GTK_TREE_MODEL(pounces_manager->model); | |
900 GaimPounce *p; | |
901 | |
902 if (!gtk_tree_model_get_iter_first(model, iter)) | |
903 return FALSE; | |
904 | |
905 gtk_tree_model_get(model, iter, POUNCES_MANAGER_COLUMN_POUNCE, &p, -1); | |
906 if (pounce == p) | |
907 return TRUE; | |
908 | |
909 while (gtk_tree_model_iter_next(model, iter)) | |
910 { | |
911 gtk_tree_model_get(model, iter, POUNCES_MANAGER_COLUMN_POUNCE, &p, -1); | |
912 if (pounce == p) | |
913 return TRUE; | |
914 } | |
915 | |
916 return FALSE; | |
917 } | |
918 | |
919 static gboolean | |
920 pounces_manager_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | |
921 { | |
922 PouncesManager *dialog = user_data; | |
923 | |
924 dialog->window = NULL; | |
925 gaim_gtk_pounces_manager_hide(); | |
926 | |
927 return FALSE; | |
928 } | |
929 | |
930 #if !GTK_CHECK_VERSION(2,2,0) | |
931 static void | |
932 count_selected_helper(GtkTreeModel *model, GtkTreePath *path, | |
933 GtkTreeIter *iter, gpointer user_data) | |
934 { | |
935 (*(gint *)user_data)++; | |
936 } | |
937 #endif | |
938 | |
939 static void | |
940 pounces_manager_connection_cb(GaimConnection *gc, GtkWidget *add_button) | |
941 { | |
942 gtk_widget_set_sensitive(add_button, (gaim_connections_get_all() != NULL)); | |
943 } | |
944 | |
945 static void | |
946 pounces_manager_add_cb(GtkButton *button, gpointer user_data) | |
947 { | |
948 gaim_gtk_pounce_editor_show(NULL, NULL, NULL); | |
949 } | |
950 | |
951 static void | |
952 pounces_manager_modify_foreach(GtkTreeModel *model, GtkTreePath *path, | |
953 GtkTreeIter *iter, gpointer user_data) | |
954 { | |
955 GaimPounce *pounce; | |
956 | |
957 gtk_tree_model_get(model, iter, POUNCES_MANAGER_COLUMN_POUNCE, &pounce, -1); | |
958 gaim_gtk_pounce_editor_show(NULL, NULL, pounce); | |
959 } | |
960 | |
961 static void | |
962 pounces_manager_modify_cb(GtkButton *button, gpointer user_data) | |
963 { | |
964 PouncesManager *dialog = user_data; | |
965 GtkTreeSelection *selection; | |
966 | |
967 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
968 | |
969 gtk_tree_selection_selected_foreach(selection, pounces_manager_modify_foreach, user_data); | |
970 } | |
971 | |
972 static void | |
973 pounces_manager_delete_confirm_cb(GaimPounce *pounce) | |
974 { | |
975 GtkTreeIter iter; | |
976 | |
977 if (pounces_manager_find_pounce(&iter, pounce)) | |
978 gtk_list_store_remove(pounces_manager->model, &iter); | |
979 | |
812 gaim_pounce_destroy(pounce); | 980 gaim_pounce_destroy(pounce); |
813 } | 981 } |
814 | 982 |
815 static void | 983 static void |
816 edit_pounce_cb(GtkWidget *w, GaimPounce *pounce) | 984 pounces_manager_delete_foreach(GtkTreeModel *model, GtkTreePath *path, |
817 { | 985 GtkTreeIter *iter, gpointer user_data) |
818 gaim_gtkpounce_dialog_show(NULL, NULL, pounce); | 986 { |
987 GaimPounce *pounce; | |
988 GaimAccount *account; | |
989 const char *pouncer, *pouncee; | |
990 char *buf; | |
991 | |
992 gtk_tree_model_get(model, iter, POUNCES_MANAGER_COLUMN_POUNCE, &pounce, -1); | |
993 account = gaim_pounce_get_pouncer(pounce); | |
994 pouncer = gaim_account_get_username(account); | |
995 pouncee = gaim_pounce_get_pouncee(pounce); | |
996 | |
997 buf = g_strdup_printf(_("Are you sure you want to delete the pounce on %s for %s?"), pouncee, pouncer); | |
998 gaim_request_action(NULL, NULL, buf, NULL, 0, pounce, 2, | |
999 _("Delete"), pounces_manager_delete_confirm_cb, | |
1000 _("Cancel"), g_free); | |
1001 g_free(buf); | |
1002 } | |
1003 | |
1004 static void | |
1005 pounces_manager_delete_cb(GtkButton *button, gpointer user_data) | |
1006 { | |
1007 PouncesManager *dialog = user_data; | |
1008 GtkTreeSelection *selection; | |
1009 | |
1010 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
1011 | |
1012 gtk_tree_selection_selected_foreach(selection, pounces_manager_delete_foreach, user_data); | |
1013 } | |
1014 | |
1015 static void | |
1016 pounces_manager_close_cb(GtkButton *button, gpointer user_data) | |
1017 { | |
1018 gaim_gtk_pounces_manager_hide(); | |
1019 } | |
1020 | |
1021 static void | |
1022 pounce_selected_cb(GtkTreeSelection *sel, gpointer user_data) | |
1023 { | |
1024 PouncesManager *dialog = user_data; | |
1025 int num_selected = 0; | |
1026 | |
1027 #if GTK_CHECK_VERSION(2,2,0) | |
1028 num_selected = gtk_tree_selection_count_selected_rows(sel); | |
1029 #else | |
1030 gtk_tree_selection_selected_foreach(sel, count_selected_helper, &num_selected); | |
1031 #endif | |
1032 | |
1033 gtk_widget_set_sensitive(dialog->modify_button, (num_selected > 0)); | |
1034 gtk_widget_set_sensitive(dialog->delete_button, (num_selected > 0)); | |
1035 } | |
1036 | |
1037 static void | |
1038 pounces_manager_persists_cb(GtkCellRendererToggle *renderer, gchar *path_str, | |
1039 gpointer user_data) | |
1040 { | |
1041 PouncesManager *dialog = user_data; | |
1042 GaimPounce *pounce; | |
1043 gboolean persists; | |
1044 GtkTreeModel *model = GTK_TREE_MODEL(dialog->model); | |
1045 GtkTreeIter iter; | |
1046 | |
1047 gtk_tree_model_get_iter_from_string(model, &iter, path_str); | |
1048 gtk_tree_model_get(model, &iter, | |
1049 POUNCES_MANAGER_COLUMN_POUNCE, &pounce, | |
1050 POUNCES_MANAGER_COLUMN_PERSISTENCE, &persists, | |
1051 -1); | |
1052 | |
1053 gaim_pounce_set_save(pounce, !persists); | |
1054 | |
1055 update_pounces(); | |
819 } | 1056 } |
820 | 1057 |
821 static gboolean | 1058 static gboolean |
822 fill_menu(GtkWidget *menu, GCallback cb) | 1059 search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data) |
823 { | 1060 { |
824 GtkWidget *image; | 1061 gboolean result; |
825 GtkWidget *item; | 1062 char *haystack; |
826 GdkPixbuf *pixbuf, *scale; | 1063 |
827 GaimPounce *pounce; | 1064 gtk_tree_model_get(model, iter, column, &haystack, -1); |
828 GaimBuddy *buddy; | 1065 |
829 const char *buddyname; | 1066 result = (gaim_strcasestr(haystack, key) == NULL); |
830 gboolean has_items = FALSE; | 1067 |
831 GList *bp; | 1068 g_free(haystack); |
832 | 1069 |
833 for (bp = gaim_pounces_get_all(); bp != NULL; bp = bp->next) | 1070 return result; |
834 { | 1071 } |
835 pounce = (GaimPounce *)bp->data; | 1072 |
836 | 1073 static GtkWidget * |
837 /* Check if account is online, if not skip it */ | 1074 create_pounces_list(PouncesManager *dialog) |
838 if (!gaim_account_is_connected(gaim_pounce_get_pouncer(pounce))) | 1075 { |
839 continue; | 1076 GtkWidget *sw; |
840 | 1077 GtkWidget *treeview; |
841 buddy = gaim_find_buddy(gaim_pounce_get_pouncer(pounce), gaim_pounce_get_pouncee(pounce)); | 1078 GtkTreeSelection *sel; |
842 | 1079 GtkTreeViewColumn *column; |
843 if (buddy != NULL) | 1080 GtkCellRenderer *renderer; |
844 buddyname = gaim_buddy_get_contact_alias(buddy); | 1081 |
845 else | 1082 /* Create the scrolled window */ |
846 buddyname = gaim_pounce_get_pouncee(pounce); | 1083 sw = gtk_scrolled_window_new(0, 0); |
847 | 1084 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), |
848 has_items = TRUE; | 1085 GTK_POLICY_AUTOMATIC, |
849 | 1086 GTK_POLICY_ALWAYS); |
850 /* Build the menu item */ | 1087 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), |
851 item = gtk_image_menu_item_new_with_label(buddyname); | 1088 GTK_SHADOW_IN); |
852 | 1089 gtk_widget_show(sw); |
853 /* Create a pixmap for the protocol icon. */ | 1090 |
854 pixbuf = gaim_gtk_create_prpl_icon(gaim_pounce_get_pouncer(pounce)); | 1091 /* Create the list model */ |
855 if (pixbuf != NULL) | 1092 dialog->model = gtk_list_store_new(POUNCES_MANAGER_NUM_COLUMNS, |
856 { | 1093 G_TYPE_POINTER, |
857 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, | 1094 GDK_TYPE_PIXBUF, |
858 GDK_INTERP_BILINEAR); | 1095 G_TYPE_STRING, |
859 | 1096 G_TYPE_STRING, |
860 /* Now convert it to GtkImage */ | 1097 G_TYPE_BOOLEAN |
861 image = gtk_image_new_from_pixbuf(scale); | 1098 ); |
862 g_object_unref(G_OBJECT(scale)); | 1099 |
863 g_object_unref(G_OBJECT(pixbuf)); | 1100 /* Create the treeview */ |
864 gtk_widget_show(image); | 1101 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); |
865 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); | 1102 dialog->treeview = treeview; |
866 } | 1103 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); |
867 | 1104 |
868 /* Put the item in the menu */ | 1105 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); |
869 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | 1106 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); |
870 gtk_widget_show(item); | 1107 g_signal_connect(G_OBJECT(sel), "changed", |
871 | 1108 G_CALLBACK(pounce_selected_cb), dialog); |
872 /* Set our callbacks. */ | 1109 |
873 g_signal_connect(G_OBJECT(item), "activate", cb, pounce); | 1110 gtk_container_add(GTK_CONTAINER(sw), treeview); |
874 } | 1111 gtk_widget_show(treeview); |
875 | 1112 |
876 return has_items; | 1113 /* Pouncee Column */ |
1114 column = gtk_tree_view_column_new(); | |
1115 gtk_tree_view_column_set_title(column, _("Pounce Target")); | |
1116 gtk_tree_view_column_set_resizable(column, TRUE); | |
1117 gtk_tree_view_column_set_min_width(column, 200); | |
1118 gtk_tree_view_column_set_sort_column_id(column, | |
1119 POUNCES_MANAGER_COLUMN_TARGET); | |
1120 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
1121 | |
1122 /* Icon */ | |
1123 renderer = gtk_cell_renderer_pixbuf_new(); | |
1124 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
1125 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", | |
1126 POUNCES_MANAGER_COLUMN_ICON); | |
1127 | |
1128 /* Pouncee */ | |
1129 renderer = gtk_cell_renderer_text_new(); | |
1130 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1131 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
1132 POUNCES_MANAGER_COLUMN_TARGET); | |
1133 | |
1134 | |
1135 /* Account Column */ | |
1136 column = gtk_tree_view_column_new(); | |
1137 gtk_tree_view_column_set_title(column, _("Account")); | |
1138 gtk_tree_view_column_set_resizable(column, TRUE); | |
1139 gtk_tree_view_column_set_min_width(column, 200); | |
1140 gtk_tree_view_column_set_sort_column_id(column, | |
1141 POUNCES_MANAGER_COLUMN_ACCOUNT); | |
1142 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
1143 renderer = gtk_cell_renderer_text_new(); | |
1144 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1145 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
1146 POUNCES_MANAGER_COLUMN_ACCOUNT); | |
1147 | |
1148 /* Persistence Column */ | |
1149 renderer = gtk_cell_renderer_toggle_new(); | |
1150 column = gtk_tree_view_column_new_with_attributes(_("Persists"), renderer, | |
1151 "active", POUNCES_MANAGER_COLUMN_PERSISTENCE, NULL); | |
1152 gtk_tree_view_column_set_sort_column_id(column, | |
1153 POUNCES_MANAGER_COLUMN_PERSISTENCE); | |
1154 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
1155 g_signal_connect(G_OBJECT(renderer), "toggled", | |
1156 G_CALLBACK(pounces_manager_persists_cb), dialog); | |
1157 | |
1158 /* Enable CTRL+F searching */ | |
1159 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), POUNCES_MANAGER_COLUMN_TARGET); | |
1160 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview), search_func, NULL, NULL); | |
1161 | |
1162 /* Sort the pouncee column by default */ | |
1163 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dialog->model), | |
1164 POUNCES_MANAGER_COLUMN_TARGET, | |
1165 GTK_SORT_ASCENDING); | |
1166 | |
1167 /* Populate list */ | |
1168 populate_pounces_list(dialog); | |
1169 | |
1170 return sw; | |
877 } | 1171 } |
878 | 1172 |
879 void | 1173 void |
880 gaim_gtkpounce_menu_build(GtkWidget *menu) | 1174 gaim_gtk_pounces_manager_show(void) |
881 { | 1175 { |
882 GtkWidget *remmenu; | 1176 PouncesManager *dialog; |
883 GtkWidget *item; | 1177 GtkWidget *bbox; |
884 GList *children, *l; | 1178 GtkWidget *button; |
885 gboolean has_items; | 1179 GtkWidget *list; |
886 | 1180 GtkWidget *vbox; |
887 g_return_if_fail(menu != NULL); | 1181 GtkWidget *win; |
888 | 1182 int width, height; |
889 if ((children = gtk_container_get_children(GTK_CONTAINER(menu))) != NULL) | 1183 |
890 { | 1184 if (pounces_manager != NULL) { |
891 for (l = children; l != NULL; l = l->next) | 1185 gtk_window_present(GTK_WINDOW(pounces_manager->window)); |
892 gtk_widget_destroy(GTK_WIDGET(l->data)); | 1186 return; |
893 | 1187 } |
894 g_list_free(children); | 1188 |
895 } | 1189 pounces_manager = dialog = g_new0(PouncesManager, 1); |
896 | 1190 |
897 /* "New Buddy Pounce" */ | 1191 width = gaim_prefs_get_int("/gaim/gtk/pounces/dialog/width"); |
898 item = gtk_menu_item_new_with_label(_("New Buddy Pounce")); | 1192 height = gaim_prefs_get_int("/gaim/gtk/pounces/dialog/height"); |
899 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | 1193 |
900 gtk_widget_set_sensitive(item, (gaim_connections_get_all() != NULL)); | 1194 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
901 gtk_widget_show(item); | 1195 gtk_window_set_default_size(GTK_WINDOW(win), width, height); |
902 g_signal_connect(G_OBJECT(item), "activate", | 1196 gtk_window_set_role(GTK_WINDOW(win), "pounces"); |
903 G_CALLBACK(new_pounce_cb), NULL); | 1197 gtk_window_set_title(GTK_WINDOW(win), _("Buddy Pounces")); |
904 | 1198 gtk_container_set_border_width(GTK_CONTAINER(win), GAIM_HIG_BORDER); |
905 /* "Remove Buddy Pounce" */ | 1199 |
906 item = gtk_menu_item_new_with_label(_("Remove Buddy Pounce")); | 1200 g_signal_connect(G_OBJECT(win), "delete_event", |
907 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | 1201 G_CALLBACK(pounces_manager_destroy_cb), dialog); |
908 | 1202 g_signal_connect(G_OBJECT(win), "configure_event", |
909 /* "Remove Buddy Pounce" menu */ | 1203 G_CALLBACK(pounces_manager_configure_cb), dialog); |
910 remmenu = gtk_menu_new(); | 1204 |
911 | 1205 /* Setup the vbox */ |
912 has_items = fill_menu(remmenu, G_CALLBACK(delete_pounce_cb)); | 1206 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); |
913 | 1207 gtk_container_add(GTK_CONTAINER(win), vbox); |
914 if (!has_items) | 1208 gtk_widget_show(vbox); |
915 gtk_widget_set_sensitive(item, FALSE); | 1209 |
916 | 1210 /* List of saved buddy pounces */ |
917 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), remmenu); | 1211 list = create_pounces_list(dialog); |
918 gtk_widget_show(remmenu); | 1212 gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0); |
919 gtk_widget_show(item); | 1213 |
920 | 1214 /* Button box. */ |
921 /* Separator */ | 1215 bbox = gtk_hbutton_box_new(); |
922 if (has_items) | 1216 gtk_box_set_spacing(GTK_BOX(bbox), GAIM_HIG_BOX_SPACE); |
923 { | 1217 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); |
924 item = gtk_separator_menu_item_new(); | 1218 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); |
925 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | 1219 gtk_widget_show(bbox); |
926 gtk_widget_show(item); | 1220 |
927 } | 1221 /* Add button */ |
928 fill_menu(menu, G_CALLBACK(edit_pounce_cb)); | 1222 button = gtk_button_new_from_stock(GTK_STOCK_ADD); |
1223 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1224 gtk_widget_set_sensitive(button, (gaim_connections_get_all() != NULL)); | |
1225 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | |
1226 pounces_manager, GAIM_CALLBACK(pounces_manager_connection_cb), button); | |
1227 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | |
1228 pounces_manager, GAIM_CALLBACK(pounces_manager_connection_cb), button); | |
1229 gtk_widget_show(button); | |
1230 | |
1231 g_signal_connect(G_OBJECT(button), "clicked", | |
1232 G_CALLBACK(pounces_manager_add_cb), dialog); | |
1233 | |
1234 /* Modify button */ | |
1235 button = gtk_button_new_from_stock(GAIM_STOCK_MODIFY); | |
1236 dialog->modify_button = button; | |
1237 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1238 gtk_widget_set_sensitive(button, FALSE); | |
1239 gtk_widget_show(button); | |
1240 | |
1241 g_signal_connect(G_OBJECT(button), "clicked", | |
1242 G_CALLBACK(pounces_manager_modify_cb), dialog); | |
1243 | |
1244 /* Delete button */ | |
1245 button = gtk_button_new_from_stock(GTK_STOCK_DELETE); | |
1246 dialog->delete_button = button; | |
1247 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1248 gtk_widget_set_sensitive(button, FALSE); | |
1249 gtk_widget_show(button); | |
1250 | |
1251 g_signal_connect(G_OBJECT(button), "clicked", | |
1252 G_CALLBACK(pounces_manager_delete_cb), dialog); | |
1253 | |
1254 /* Close button */ | |
1255 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
1256 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1257 gtk_widget_show(button); | |
1258 | |
1259 g_signal_connect(G_OBJECT(button), "clicked", | |
1260 G_CALLBACK(pounces_manager_close_cb), dialog); | |
1261 | |
1262 gtk_widget_show(win); | |
1263 } | |
1264 | |
1265 void | |
1266 gaim_gtk_pounces_manager_hide(void) | |
1267 { | |
1268 if (pounces_manager == NULL) | |
1269 return; | |
1270 | |
1271 if (pounces_manager->window != NULL) | |
1272 gtk_widget_destroy(pounces_manager->window); | |
1273 | |
1274 gaim_signals_disconnect_by_handle(pounces_manager); | |
1275 | |
1276 g_free(pounces_manager); | |
1277 pounces_manager = NULL; | |
929 } | 1278 } |
930 | 1279 |
931 static void | 1280 static void |
932 pounce_cb(GaimPounce *pounce, GaimPounceEvent events, void *data) | 1281 pounce_cb(GaimPounce *pounce, GaimPounceEvent events, void *data) |
933 { | 1282 { |
1111 } | 1460 } |
1112 | 1461 |
1113 static void | 1462 static void |
1114 free_pounce(GaimPounce *pounce) | 1463 free_pounce(GaimPounce *pounce) |
1115 { | 1464 { |
1116 GaimBuddyList *blist; | 1465 update_pounces(); |
1117 GaimGtkBuddyList *gtkblist; | |
1118 | |
1119 /* Rebuild the pounce menu */ | |
1120 blist = gaim_get_blist(); | |
1121 | |
1122 if (GAIM_IS_GTK_BLIST(blist)) | |
1123 { | |
1124 gtkblist = GAIM_GTK_BLIST(blist); | |
1125 | |
1126 gaim_gtkpounce_menu_build(gtkblist->bpmenu); | |
1127 } | |
1128 } | 1466 } |
1129 | 1467 |
1130 static void | 1468 static void |
1131 new_pounce(GaimPounce *pounce) | 1469 new_pounce(GaimPounce *pounce) |
1132 { | 1470 { |
1133 gaim_pounce_action_register(pounce, "open-window"); | 1471 gaim_pounce_action_register(pounce, "open-window"); |
1134 gaim_pounce_action_register(pounce, "popup-notify"); | 1472 gaim_pounce_action_register(pounce, "popup-notify"); |
1135 gaim_pounce_action_register(pounce, "send-message"); | 1473 gaim_pounce_action_register(pounce, "send-message"); |
1136 gaim_pounce_action_register(pounce, "execute-command"); | 1474 gaim_pounce_action_register(pounce, "execute-command"); |
1137 gaim_pounce_action_register(pounce, "play-sound"); | 1475 gaim_pounce_action_register(pounce, "play-sound"); |
1476 | |
1477 update_pounces(); | |
1478 } | |
1479 | |
1480 void * | |
1481 gaim_gtk_pounces_get_handle() { | |
1482 static int handle; | |
1483 | |
1484 return &handle; | |
1138 } | 1485 } |
1139 | 1486 |
1140 void | 1487 void |
1141 gaim_gtk_pounces_init(void) | 1488 gaim_gtk_pounces_init(void) |
1142 { | 1489 { |
1153 TRUE); | 1500 TRUE); |
1154 gaim_prefs_add_bool("/gaim/gtk/pounces/default_actions/execute-command", | 1501 gaim_prefs_add_bool("/gaim/gtk/pounces/default_actions/execute-command", |
1155 FALSE); | 1502 FALSE); |
1156 gaim_prefs_add_bool("/gaim/gtk/pounces/default_actions/play-sound", | 1503 gaim_prefs_add_bool("/gaim/gtk/pounces/default_actions/play-sound", |
1157 FALSE); | 1504 FALSE); |
1158 } | 1505 gaim_prefs_add_none("/gaim/gtk/pounces/dialog"); |
1506 gaim_prefs_add_int("/gaim/gtk/pounces/dialog/width", 550); | |
1507 gaim_prefs_add_int("/gaim/gtk/pounces/dialog/height", 250); | |
1508 | |
1509 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | |
1510 gaim_gtk_pounces_get_handle(), | |
1511 GAIM_CALLBACK(signed_on_off_cb), NULL); | |
1512 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | |
1513 gaim_gtk_pounces_get_handle(), | |
1514 GAIM_CALLBACK(signed_on_off_cb), NULL); | |
1515 } |