Mercurial > pidgin.yaz
annotate src/gtkblist.c @ 12233:02833a0ae716
[gaim-migrate @ 14535]
SF Patch #1367116 from Michael Carlson
"In profiling gaim, I noticed that on simply starting
CVS gaim, xmlnode_insert_child is using up by far the
most CPU time. After some testing, I realized the
reason why: xmlnode_insert_child is called some 18,000
times on startup, and it is inserting the child at the
end of the list each time, simply by traversing through
the entire linked list. Sometimes this list can have as
many as 800 elements.
This patch adds a variable to the _xmlnode struct,
lastchild, which simply keeps track of the last node in
the list of children. This is then used by
xmlnode_insert_child to insert at the end of the list,
instead of traversing through the whole list each time.
The two relevant functions in xmlnode.c that need to be
updated to keep track of this function appropriately
have been updated.
Running 3 times with and without the change, the
results from oprofile say it all. Here are the measured
number of clock cycles / % of total clock cycles /
function used to simply start and close gaim before the
change:
204 60.7143 xmlnode_insert_child
210 61.4035 xmlnode_insert_child
230 61.8280 xmlnode_insert_child
And after (note that one time no clock cycles were
caught at all)
3 2.5862 xmlnode_insert_child
3 2.5641 xmlnode_insert_child
This affects other areas of the program than just
starting up, but this seems to be the most noticeable
place."
Speed is good. As I was verifying this patch, I added some g_return_val_if_fail() checks.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Sun, 27 Nov 2005 03:42:39 +0000 |
parents | 375f1f3817a8 |
children | 36d3b1eaf20e |
rev | line source |
---|---|
5228 | 1 /* |
10297
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10288
diff
changeset
|
2 * @file gtkblist.c GTK+ BuddyList API |
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10288
diff
changeset
|
3 * @ingroup gtkui |
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10288
diff
changeset
|
4 * |
5228 | 5 * gaim |
6 * | |
8046 | 7 * Gaim is the legal property of its developers, whose names are too numerous |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
5228 | 10 * |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 * | |
25 */ | |
9791 | 26 #include "internal.h" |
27 #include "gtkgaim.h" | |
7620 | 28 |
29 #include "account.h" | |
9015 | 30 #include "connection.h" |
7620 | 31 #include "core.h" |
32 #include "debug.h" | |
33 #include "notify.h" | |
34 #include "prpl.h" | |
35 #include "prefs.h" | |
8986 | 36 #include "plugin.h" |
7620 | 37 #include "request.h" |
38 #include "signals.h" | |
10297
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10288
diff
changeset
|
39 #include "gtkstock.h" |
7620 | 40 #include "util.h" |
41 | |
42 #include "gtkaccount.h" | |
43 #include "gtkblist.h" | |
44 #include "gtkconv.h" | |
45 #include "gtkdebug.h" | |
9709 | 46 #include "gtkdialogs.h" |
7620 | 47 #include "gtkft.h" |
48 #include "gtklog.h" | |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
49 #include "gtkmenutray.h" |
7620 | 50 #include "gtkpounce.h" |
11740 | 51 #include "gtkplugin.h" |
7620 | 52 #include "gtkprefs.h" |
53 #include "gtkprivacy.h" | |
8113 | 54 #include "gtkroomlist.h" |
10643 | 55 #include "gtkstatusbox.h" |
7620 | 56 #include "gtkutils.h" |
57 | |
5228 | 58 #include <gdk/gdkkeysyms.h> |
59 #include <gtk/gtk.h> | |
7620 | 60 #include <gdk/gdk.h> |
61 | |
62 typedef struct | |
63 { | |
64 GaimAccount *account; | |
65 | |
66 GtkWidget *window; | |
67 GtkWidget *combo; | |
68 GtkWidget *entry; | |
69 GtkWidget *entry_for_alias; | |
70 GtkWidget *account_box; | |
71 | |
72 } GaimGtkAddBuddyData; | |
73 | |
74 typedef struct | |
75 { | |
9811 | 76 GaimAccount *account; |
9812 | 77 gchar *default_chat_name; |
9811 | 78 |
79 GtkWidget *window; | |
7620 | 80 GtkWidget *account_menu; |
81 GtkWidget *alias_entry; | |
82 GtkWidget *group_combo; | |
83 GtkWidget *entries_box; | |
84 GtkSizeGroup *sg; | |
85 | |
86 GList *entries; | |
87 | |
88 } GaimGtkAddChatData; | |
89 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
90 typedef struct |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
91 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
92 GaimAccount *account; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
93 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
94 GtkWidget *window; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
95 GtkWidget *account_menu; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
96 GtkWidget *entries_box; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
97 GtkSizeGroup *sg; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
98 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
99 GList *entries; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
100 } GaimGtkJoinChatData; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
101 |
7620 | 102 |
9949 | 103 static GtkWidget *protomenu = NULL; |
5228 | 104 |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
105 static guint visibility_manager_count = 0; |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
106 static gboolean gtk_blist_obscured = FALSE; |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
107 |
11796 | 108 static GList *gaim_gtk_blist_sort_methods = NULL; |
5422 | 109 static struct gaim_gtk_blist_sort_method *current_sort_method = NULL; |
7620 | 110 static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); |
111 | |
112 /* The functions we use for sorting aren't available in gtk 2.0.x, and | |
113 * segfault in 2.2.0. 2.2.1 is known to work, so I'll require that */ | |
114 #if GTK_CHECK_VERSION(2,2,1) | |
115 static GtkTreeIter sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
116 static GtkTreeIter sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
117 static GtkTreeIter sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
118 #endif | |
119 static GaimGtkBuddyList *gtkblist = NULL; | |
5228 | 120 |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
121 static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node); |
5228 | 122 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); |
7620 | 123 static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node); |
5234 | 124 static char *gaim_get_tooltip_text(GaimBlistNode *node); |
5228 | 125 static char *item_factory_translate_func (const char *path, gpointer func_data); |
5273 | 126 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter); |
7620 | 127 static void redo_buddy_list(GaimBuddyList *list, gboolean remove); |
128 static void gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node); | |
129 | |
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
130 static void gaim_gtk_blist_tooltip_destroy(); |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
131 |
5256 | 132 struct _gaim_gtk_blist_node { |
133 GtkTreeRowReference *row; | |
7620 | 134 gboolean contact_expanded; |
11910 | 135 gboolean recent_signonoff; |
136 gint recent_signonoff_timer; | |
5256 | 137 }; |
138 | |
10968
e0d5038fbb7e
[gaim-migrate @ 12789]
Christopher O'Brien <siege@pidgin.im>
parents:
10924
diff
changeset
|
139 |
10118 | 140 static char dim_grey_string[8] = ""; |
10144 | 141 static char *dim_grey() |
10118 | 142 { |
143 if (!gtkblist) | |
144 return "dim grey"; | |
145 if (!dim_grey_string[0]) { | |
146 GtkStyle *style = gtk_widget_get_style(gtkblist->treeview); | |
147 snprintf(dim_grey_string, sizeof(dim_grey_string), "#%02x%02x%02x", | |
148 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
149 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
150 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | |
151 } | |
152 return dim_grey_string; | |
153 } | |
10144 | 154 |
5228 | 155 /*************************************************** |
156 * Callbacks * | |
157 ***************************************************/ | |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
158 static gboolean gtk_blist_visibility_cb(GtkWidget *w, GdkEventVisibility *event, gpointer data) |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
159 { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
160 if (event->state == GDK_VISIBILITY_FULLY_OBSCURED) |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
161 gtk_blist_obscured = TRUE; |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
162 else |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
163 gtk_blist_obscured = FALSE; |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
164 |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
165 /* continue to handle event normally */ |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
166 return FALSE; |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
167 } |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
168 |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
169 static gboolean gtk_blist_window_state_cb(GtkWidget *w, GdkEventWindowState *event, gpointer data) |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
170 { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
171 if(event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
172 if(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
173 gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", FALSE); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
174 else |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
175 gaim_prefs_set_bool("/gaim/gtk/blist/list_visible", TRUE); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
176 } |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
177 |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
178 return FALSE; |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
179 } |
5228 | 180 |
181 static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) | |
182 { | |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
183 if(visibility_manager_count) |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
184 gaim_blist_set_visible(FALSE); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
185 else |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
186 gaim_core_quit(); |
5228 | 187 |
188 /* we handle everything, event should not propogate further */ | |
189 return TRUE; | |
190 } | |
191 | |
192 static gboolean gtk_blist_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) | |
193 { | |
194 /* unfortunately GdkEventConfigure ignores the window gravity, but * | |
195 * the only way we have of setting the position doesn't. we have to * | |
7620 | 196 * call get_position because it does pay attention to the gravity. * |
197 * this is inefficient and I agree it sucks, but it's more likely * | |
198 * to work correctly. - Robot101 */ | |
5228 | 199 gint x, y; |
200 | |
201 /* check for visibility because when we aren't visible, this will * | |
202 * give us bogus (0,0) coordinates. - xOr */ | |
7620 | 203 if (GTK_WIDGET_VISIBLE(w)) |
5228 | 204 gtk_window_get_position(GTK_WINDOW(w), &x, &y); |
7620 | 205 else |
206 return FALSE; /* carry on normally */ | |
207 | |
208 /* don't save if nothing changed */ | |
209 if (x == gaim_prefs_get_int("/gaim/gtk/blist/x") && | |
210 y == gaim_prefs_get_int("/gaim/gtk/blist/y") && | |
211 event->width == gaim_prefs_get_int("/gaim/gtk/blist/width") && | |
212 event->height == gaim_prefs_get_int("/gaim/gtk/blist/height")) { | |
213 | |
214 return FALSE; /* carry on normally */ | |
5228 | 215 } |
216 | |
7620 | 217 /* don't save off-screen positioning */ |
218 if (x + event->width < 0 || | |
9811 | 219 y + event->height < 0 || |
220 x > gdk_screen_width() || | |
221 y > gdk_screen_height()) { | |
7620 | 222 |
223 return FALSE; /* carry on normally */ | |
224 } | |
225 | |
226 /* store the position */ | |
227 gaim_prefs_set_int("/gaim/gtk/blist/x", x); | |
228 gaim_prefs_set_int("/gaim/gtk/blist/y", y); | |
229 gaim_prefs_set_int("/gaim/gtk/blist/width", event->width); | |
230 gaim_prefs_set_int("/gaim/gtk/blist/height", event->height); | |
231 | |
5228 | 232 /* continue to handle event normally */ |
233 return FALSE; | |
234 } | |
235 | |
7620 | 236 static void gtk_blist_menu_info_cb(GtkWidget *w, GaimBuddy *b) |
5228 | 237 { |
238 serv_get_info(b->account->gc, b->name); | |
239 } | |
240 | |
7620 | 241 static void gtk_blist_menu_im_cb(GtkWidget *w, GaimBuddy *b) |
5228 | 242 { |
9728 | 243 gaim_gtkdialogs_im_with_user(b->account, b->name); |
5228 | 244 } |
245 | |
9466 | 246 static void gtk_blist_menu_send_file_cb(GtkWidget *w, GaimBuddy *b) |
247 { | |
248 serv_send_file(b->account->gc, b->name, NULL); | |
249 } | |
250 | |
12024 | 251 static void gtk_blist_menu_voice_chat_cb(GtkWidget *w, GaimBuddy *b) |
252 { | |
253 serv_voice_chat(b->account->gc, b->name); | |
254 } | |
255 | |
7620 | 256 static void gtk_blist_menu_autojoin_cb(GtkWidget *w, GaimChat *chat) |
257 { | |
7693 | 258 gaim_blist_node_set_bool((GaimBlistNode*)chat, "gtk-autojoin", |
259 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))); | |
7620 | 260 } |
261 | |
262 static void gtk_blist_menu_join_cb(GtkWidget *w, GaimChat *chat) | |
5228 | 263 { |
5234 | 264 serv_join_chat(chat->account->gc, chat->components); |
265 } | |
266 | |
11016 | 267 static void gtk_blist_renderer_edited_cb(GtkCellRendererText *text_rend, char *arg1, |
268 char *arg2, gpointer nada) | |
269 { | |
270 GtkTreeIter iter; | |
271 GtkTreePath *path; | |
272 GValue val = {0,}; | |
273 GaimBlistNode *node; | |
274 | |
275 path = gtk_tree_path_new_from_string (arg1); | |
276 gtk_tree_model_get_iter (GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
277 gtk_tree_path_free (path); | |
278 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
279 node = g_value_get_pointer(&val); | |
280 gtk_tree_view_set_enable_search (GTK_TREE_VIEW(gtkblist->treeview), TRUE); | |
281 g_object_set(G_OBJECT(gtkblist->text_rend), "editable", FALSE, NULL); | |
282 switch (node->type){ | |
283 case GAIM_BLIST_CONTACT_NODE: | |
284 gaim_blist_alias_buddy(gaim_contact_get_priority_buddy((GaimContact*)node), arg2); | |
285 break; | |
286 case GAIM_BLIST_BUDDY_NODE: | |
287 gaim_blist_alias_buddy((GaimBuddy*)node, arg2); | |
288 break; | |
289 case GAIM_BLIST_GROUP_NODE: | |
290 gaim_blist_rename_group((GaimGroup*)node, arg2); | |
291 break; | |
292 case GAIM_BLIST_CHAT_NODE: | |
293 gaim_blist_alias_chat((GaimChat*)node, arg2); | |
294 break; | |
295 default: | |
296 break; | |
297 } | |
298 } | |
299 | |
5234 | 300 static void gtk_blist_menu_alias_cb(GtkWidget *w, GaimBlistNode *node) |
301 { | |
11016 | 302 GtkTreeIter iter; |
303 GtkTreePath *path; | |
11258 | 304 const char *text = NULL; |
11494 | 305 |
11258 | 306 if (!(get_iter_from_node(node, &iter))) { |
11016 | 307 /* This is either a bug, or the buddy is in a collapsed contact */ |
308 node = node->parent; | |
309 if (!get_iter_from_node(node, &iter)) | |
310 /* Now it's definitely a bug */ | |
311 return; | |
312 } | |
11258 | 313 |
314 switch (node->type) { | |
315 case GAIM_BLIST_BUDDY_NODE: | |
316 text = gaim_buddy_get_alias((GaimBuddy *)node); | |
317 break; | |
318 case GAIM_BLIST_CONTACT_NODE: | |
319 text = gaim_buddy_get_alias(gaim_contact_get_priority_buddy((GaimContact *)node)); | |
320 break; | |
321 case GAIM_BLIST_GROUP_NODE: | |
322 text = ((GaimGroup *)node)->name; | |
323 break; | |
324 case GAIM_BLIST_CHAT_NODE: | |
325 text = gaim_chat_get_name((GaimChat *)node); | |
326 break; | |
327 default: | |
328 g_return_if_reached(); | |
329 } | |
330 | |
331 gtk_tree_store_set(gtkblist->treemodel, &iter, NAME_COLUMN, text, -1); | |
332 | |
11016 | 333 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); |
334 g_object_set(G_OBJECT(gtkblist->text_rend), "editable", TRUE, NULL); | |
335 gtk_tree_view_set_enable_search (GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
336 gtk_widget_grab_focus(gtkblist->treeview); | |
337 gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtkblist->treeview), path, gtkblist->text_column, TRUE); | |
338 gtk_tree_path_free(path); | |
5228 | 339 } |
340 | |
7620 | 341 static void gtk_blist_menu_bp_cb(GtkWidget *w, GaimBuddy *b) |
5228 | 342 { |
12136
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
343 gaim_gtk_pounce_editor_show(b->account, b->name, NULL); |
5228 | 344 } |
345 | |
9917 | 346 static void gtk_blist_menu_showlog_cb(GtkWidget *w, GaimBlistNode *node) |
5228 | 347 { |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
348 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); |
9917 | 349 GaimLogType type; |
350 GaimAccount *account; | |
351 char *name = NULL; | |
10663 | 352 |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
353 gdk_window_set_cursor(gtkblist->window->window, cursor); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
354 gdk_cursor_unref(cursor); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
355 while (gtk_events_pending()) |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
356 gtk_main_iteration(); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
357 |
9917 | 358 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
359 GaimBuddy *b = (GaimBuddy*) node; | |
360 type = GAIM_LOG_IM; | |
361 name = g_strdup(b->name); | |
362 account = b->account; | |
363 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { | |
364 GaimChat *c = (GaimChat*) node; | |
365 GaimPluginProtocolInfo *prpl_info = NULL; | |
366 type = GAIM_LOG_CHAT; | |
367 account = c->account; | |
368 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gaim_find_prpl(gaim_account_get_protocol_id(account))); | |
369 if (prpl_info && prpl_info->get_chat_name) { | |
370 name = prpl_info->get_chat_name(c->components); | |
371 } | |
10663 | 372 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { |
373 gaim_gtk_log_show_contact((GaimContact *)node); | |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
374 gdk_window_set_cursor(gtkblist->window->window, NULL); |
10663 | 375 return; |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
376 } else { |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
377 gdk_window_set_cursor(gtkblist->window->window, NULL); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
378 |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
379 /* This callback should not have been registered for a node |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
380 * that doesn't match the type of one of the blocks above. */ |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
381 g_return_if_reached(); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
382 } |
9917 | 383 |
384 if (name && account) { | |
385 gaim_gtk_log_show(type, name, account); | |
386 g_free(name); | |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
387 |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
388 gdk_window_set_cursor(gtkblist->window->window, NULL); |
9917 | 389 } |
7620 | 390 } |
391 | |
5228 | 392 static void gtk_blist_show_systemlog_cb() |
393 { | |
8573 | 394 gaim_gtk_syslog_show(); |
5228 | 395 } |
396 | |
397 static void gtk_blist_show_onlinehelp_cb() | |
398 { | |
10240
95ca0db2d01d
[gaim-migrate @ 11377]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
10229
diff
changeset
|
399 gaim_notify_uri(NULL, GAIM_WEBSITE "documentation.php"); |
5228 | 400 } |
401 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
402 static void |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
403 do_join_chat(GaimGtkJoinChatData *data) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
404 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
405 if (data) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
406 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
407 GHashTable *components = |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
408 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
409 GList *tmp; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
410 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
411 for (tmp = data->entries; tmp != NULL; tmp = tmp->next) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
412 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
413 if (g_object_get_data(tmp->data, "is_spin")) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
414 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
415 g_hash_table_replace(components, |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
416 g_strdup(g_object_get_data(tmp->data, "identifier")), |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
417 g_strdup_printf("%d", |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
418 gtk_spin_button_get_value_as_int(tmp->data))); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
419 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
420 else |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
421 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
422 g_hash_table_replace(components, |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
423 g_strdup(g_object_get_data(tmp->data, "identifier")), |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
424 g_strdup(gtk_entry_get_text(tmp->data))); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
425 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
426 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
427 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
428 serv_join_chat(gaim_account_get_connection(data->account), components); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
429 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
430 g_hash_table_destroy(components); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
431 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
432 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
433 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
434 static void |
8940 | 435 do_joinchat(GtkWidget *dialog, int id, GaimGtkJoinChatData *info) |
436 { | |
437 switch(id) | |
438 { | |
439 case GTK_RESPONSE_OK: | |
440 do_join_chat(info); | |
441 | |
442 break; | |
443 } | |
444 | |
445 gtk_widget_destroy(GTK_WIDGET(dialog)); | |
446 g_list_free(info->entries); | |
447 g_free(info); | |
448 } | |
449 | |
10475 | 450 /* |
451 * Check the values of all the text entry boxes. If any required input | |
452 * strings are empty then don't allow the user to click on "OK." | |
453 */ | |
454 static void | |
455 joinchat_set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data) | |
456 { | |
457 GaimGtkJoinChatData *data; | |
458 GList *tmp; | |
459 const char *text; | |
460 gboolean required; | |
461 gboolean sensitive = TRUE; | |
462 | |
463 data = user_data; | |
464 | |
465 for (tmp = data->entries; tmp != NULL; tmp = tmp->next) | |
466 { | |
467 if (!g_object_get_data(tmp->data, "is_spin")) | |
468 { | |
469 required = GPOINTER_TO_INT(g_object_get_data(tmp->data, "required")); | |
470 text = gtk_entry_get_text(tmp->data); | |
471 if (required && (*text == '\0')) | |
472 sensitive = FALSE; | |
473 } | |
474 } | |
475 | |
476 gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_OK, sensitive); | |
477 } | |
478 | |
8940 | 479 static void |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
480 rebuild_joinchat_entries(GaimGtkJoinChatData *data) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
481 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
482 GaimConnection *gc; |
9959 | 483 GList *list = NULL, *tmp = NULL; |
9770 | 484 GHashTable *defaults = NULL; |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
485 struct proto_chat_entry *pce; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
486 gboolean focus = TRUE; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
487 |
10127 | 488 g_return_if_fail(data->account != NULL); |
489 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
490 gc = gaim_account_get_connection(data->account); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
491 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
492 while (GTK_BOX(data->entries_box)->children) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
493 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
494 gtk_container_remove(GTK_CONTAINER(data->entries_box), |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
495 ((GtkBoxChild *)GTK_BOX(data->entries_box)->children->data)->widget); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
496 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
497 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
498 if (data->entries != NULL) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
499 g_list_free(data->entries); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
500 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
501 data->entries = NULL; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
502 |
9987 | 503 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) |
9959 | 504 list = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
505 |
9770 | 506 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) |
507 defaults = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, NULL); | |
508 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
509 for (tmp = list; tmp; tmp = tmp->next) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
510 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
511 GtkWidget *label; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
512 GtkWidget *rowbox; |
10475 | 513 GtkWidget *input; |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
514 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
515 pce = tmp->data; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
516 |
11243 | 517 rowbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
518 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
519 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
520 label = gtk_label_new_with_mnemonic(pce->label); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
521 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
522 gtk_size_group_add_widget(data->sg, label); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
523 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
524 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
525 if (pce->is_int) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
526 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
527 GtkObject *adjust; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
528 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
529 1, 10, 10); |
10475 | 530 input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); |
531 gtk_widget_set_size_request(input, 50, -1); | |
532 gtk_box_pack_end(GTK_BOX(rowbox), input, FALSE, FALSE, 0); | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
533 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
534 else |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
535 { |
9770 | 536 char *value; |
10475 | 537 input = gtk_entry_new(); |
538 gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE); | |
9770 | 539 value = g_hash_table_lookup(defaults, pce->identifier); |
540 if (value != NULL) | |
10475 | 541 gtk_entry_set_text(GTK_ENTRY(input), value); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
542 if (pce->secret) |
11986 | 543 { |
10475 | 544 gtk_entry_set_visibility(GTK_ENTRY(input), FALSE); |
11986 | 545 gtk_entry_set_invisible_char(GTK_ENTRY(input), GAIM_INVISIBLE_CHAR); |
546 } | |
10475 | 547 gtk_box_pack_end(GTK_BOX(rowbox), input, TRUE, TRUE, 0); |
548 g_signal_connect(G_OBJECT(input), "changed", | |
549 G_CALLBACK(joinchat_set_sensitive_if_input_cb), data); | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
550 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
551 |
10475 | 552 /* Do the following for any type of input widget */ |
553 if (focus) | |
554 { | |
555 gtk_widget_grab_focus(input); | |
556 focus = FALSE; | |
557 } | |
558 gtk_label_set_mnemonic_widget(GTK_LABEL(label), input); | |
559 gaim_set_accessible_label(input, label); | |
560 g_object_set_data(G_OBJECT(input), "identifier", pce->identifier); | |
561 g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int)); | |
562 g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required)); | |
563 data->entries = g_list_append(data->entries, input); | |
564 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
565 g_free(pce); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
566 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
567 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
568 g_list_free(list); |
10475 | 569 g_hash_table_destroy(defaults); |
570 | |
571 /* Set whether the "OK" button should be clickable initially */ | |
572 joinchat_set_sensitive_if_input_cb(NULL, data); | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
573 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
574 gtk_widget_show_all(data->entries_box); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
575 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
576 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
577 static void |
8940 | 578 joinchat_select_account_cb(GObject *w, GaimAccount *account, |
10475 | 579 GaimGtkJoinChatData *data) |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
580 { |
9460 | 581 if (strcmp(gaim_account_get_protocol_id(data->account), |
10475 | 582 gaim_account_get_protocol_id(account)) == 0) |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
583 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
584 data->account = account; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
585 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
586 else |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
587 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
588 data->account = account; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
589 rebuild_joinchat_entries(data); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
590 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
591 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
592 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
593 static gboolean |
9987 | 594 chat_account_filter_func(GaimAccount *account) |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
595 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
596 GaimConnection *gc = gaim_account_get_connection(account); |
8940 | 597 GaimPluginProtocolInfo *prpl_info = NULL; |
598 | |
599 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
600 | |
601 return (prpl_info->chat_info != NULL); | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
602 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
603 |
8940 | 604 gboolean |
605 gaim_gtk_blist_joinchat_is_showable() | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
606 { |
8940 | 607 GList *c; |
608 GaimConnection *gc; | |
609 | |
610 for (c = gaim_connections_get_all(); c != NULL; c = c->next) { | |
611 gc = c->data; | |
612 | |
9987 | 613 if (chat_account_filter_func(gaim_connection_get_account(gc))) |
8940 | 614 return TRUE; |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
615 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
616 |
8940 | 617 return FALSE; |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
618 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
619 |
8305
57bdd25752c1
[gaim-migrate @ 9029]
Christian Hammond <chipx86@chipx86.com>
parents:
8303
diff
changeset
|
620 void |
8940 | 621 gaim_gtk_blist_joinchat_show(void) |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
622 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
623 GtkWidget *hbox, *vbox; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
624 GtkWidget *rowbox; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
625 GtkWidget *label; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
626 GaimGtkBuddyList *gtkblist; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
627 GtkWidget *img = NULL; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
628 GaimGtkJoinChatData *data = NULL; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
629 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
630 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
631 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
632 GTK_ICON_SIZE_DIALOG); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
633 data = g_new0(GaimGtkJoinChatData, 1); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
634 |
8975 | 635 data->window = gtk_dialog_new_with_buttons(_("Join a Chat"), |
636 NULL, GTK_DIALOG_NO_SEPARATOR, | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
637 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
8308 | 638 GAIM_STOCK_CHAT, GTK_RESPONSE_OK, NULL); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
639 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); |
11243 | 640 gtk_container_set_border_width(GTK_CONTAINER(data->window), GAIM_HIG_BOX_SPACE); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
641 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); |
11243 | 642 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BORDER); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
643 gtk_container_set_border_width( |
11243 | 644 GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BOX_SPACE); |
8975 | 645 gtk_window_set_role(GTK_WINDOW(data->window), "join_chat"); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
646 |
11243 | 647 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
648 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
649 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
650 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
651 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
652 vbox = gtk_vbox_new(FALSE, 5); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
653 gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
654 gtk_container_add(GTK_CONTAINER(hbox), vbox); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
655 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
656 label = gtk_label_new(_("Please enter the appropriate information " |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
657 "about the chat you would like to join.\n")); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
658 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
659 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
660 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
661 |
11243 | 662 rowbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
663 gtk_box_pack_start(GTK_BOX(vbox), rowbox, TRUE, TRUE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
664 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
665 data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
666 |
8940 | 667 label = gtk_label_new_with_mnemonic(_("_Account:")); |
668 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
669 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
670 gtk_size_group_add_widget(data->sg, label); | |
671 | |
672 data->account_menu = gaim_gtk_account_option_menu_new(NULL, FALSE, | |
673 G_CALLBACK(joinchat_select_account_cb), | |
9987 | 674 chat_account_filter_func, data); |
8940 | 675 gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0); |
676 gtk_label_set_mnemonic_widget(GTK_LABEL(label), | |
677 GTK_WIDGET(data->account_menu)); | |
678 gaim_set_accessible_label (data->account_menu, label); | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
679 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
680 data->entries_box = gtk_vbox_new(FALSE, 5); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
681 gtk_container_add(GTK_CONTAINER(vbox), data->entries_box); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
682 gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
683 |
8940 | 684 data->account = gaim_gtk_account_option_menu_get_selected(data->account_menu); |
685 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
686 rebuild_joinchat_entries(data); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
687 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
688 g_signal_connect(G_OBJECT(data->window), "response", |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
689 G_CALLBACK(do_joinchat), data); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
690 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
691 g_object_unref(data->sg); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
692 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
693 gtk_widget_show_all(data->window); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
694 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
695 |
5228 | 696 static void gtk_blist_row_expanded_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { |
697 GaimBlistNode *node; | |
698 GValue val = {0,}; | |
699 | |
700 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val); | |
701 | |
702 node = g_value_get_pointer(&val); | |
703 | |
704 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
7693 | 705 gaim_blist_node_set_bool(node, "collapsed", FALSE); |
5228 | 706 } |
707 } | |
708 | |
709 static void gtk_blist_row_collapsed_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { | |
710 GaimBlistNode *node; | |
711 GValue val = {0,}; | |
712 | |
713 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val); | |
714 | |
715 node = g_value_get_pointer(&val); | |
716 | |
717 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
7693 | 718 gaim_blist_node_set_bool(node, "collapsed", TRUE); |
7620 | 719 } else if(GAIM_BLIST_NODE_IS_CONTACT(node)) { |
720 gaim_gtk_blist_collapse_contact_cb(NULL, node); | |
5228 | 721 } |
722 } | |
723 | |
724 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) { | |
725 GaimBlistNode *node; | |
726 GtkTreeIter iter; | |
727 GValue val = { 0, }; | |
728 | |
729 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
730 | |
731 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
732 node = g_value_get_pointer(&val); | |
733 | |
7620 | 734 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) { |
735 GaimBuddy *buddy; | |
736 | |
737 if(GAIM_BLIST_NODE_IS_CONTACT(node)) | |
738 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
739 else | |
740 buddy = (GaimBuddy*)node; | |
741 | |
9728 | 742 gaim_gtkdialogs_im_with_user(buddy->account, buddy->name); |
5234 | 743 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
7620 | 744 serv_join_chat(((GaimChat *)node)->account->gc, ((GaimChat *)node)->components); |
5228 | 745 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
746 if (gtk_tree_view_row_expanded(tv, path)) | |
747 gtk_tree_view_collapse_row(tv, path); | |
748 else | |
749 gtk_tree_view_expand_row(tv,path,FALSE); | |
750 } | |
751 } | |
752 | |
5234 | 753 static void gaim_gtk_blist_add_chat_cb() |
754 { | |
755 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
756 GtkTreeIter iter; | |
757 GaimBlistNode *node; | |
758 | |
759 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ | |
760 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
7620 | 761 if (GAIM_BLIST_NODE_IS_BUDDY(node)) |
9754 | 762 gaim_blist_request_add_chat(NULL, (GaimGroup*)node->parent->parent, NULL, NULL); |
7620 | 763 if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node)) |
9754 | 764 gaim_blist_request_add_chat(NULL, (GaimGroup*)node->parent, NULL, NULL); |
5234 | 765 else if (GAIM_BLIST_NODE_IS_GROUP(node)) |
9754 | 766 gaim_blist_request_add_chat(NULL, (GaimGroup*)node, NULL, NULL); |
5234 | 767 } |
768 else { | |
9754 | 769 gaim_blist_request_add_chat(NULL, NULL, NULL, NULL); |
5234 | 770 } |
771 } | |
772 | |
5228 | 773 static void gaim_gtk_blist_add_buddy_cb() |
774 { | |
775 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
776 GtkTreeIter iter; | |
777 GaimBlistNode *node; | |
778 | |
779 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ | |
780 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
7620 | 781 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
782 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node->parent->parent)->name, | |
783 NULL); | |
784 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) | |
785 || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
786 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node->parent)->name, NULL); | |
787 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
788 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node)->name, NULL); | |
789 } | |
5228 | 790 } |
791 else { | |
7620 | 792 gaim_blist_request_add_buddy(NULL, NULL, NULL, NULL); |
793 } | |
794 } | |
795 | |
796 static void | |
797 gaim_gtk_blist_remove_cb (GtkWidget *w, GaimBlistNode *node) | |
798 { | |
799 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
9730 | 800 gaim_gtkdialogs_remove_buddy((GaimBuddy*)node); |
7620 | 801 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
9730 | 802 gaim_gtkdialogs_remove_chat((GaimChat*)node); |
7620 | 803 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
9730 | 804 gaim_gtkdialogs_remove_group((GaimGroup*)node); |
7620 | 805 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { |
9730 | 806 gaim_gtkdialogs_remove_contact((GaimContact*)node); |
5228 | 807 } |
808 } | |
809 | |
810 static void | |
7620 | 811 gaim_gtk_blist_expand_contact_cb(GtkWidget *w, GaimBlistNode *node) |
5228 | 812 { |
7620 | 813 struct _gaim_gtk_blist_node *gtknode; |
9632 | 814 GtkTreeIter iter, parent; |
7620 | 815 GaimBlistNode *bnode; |
10325 | 816 GtkTreePath *path; |
7620 | 817 |
818 if(!GAIM_BLIST_NODE_IS_CONTACT(node)) | |
819 return; | |
820 | |
821 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
822 | |
823 gtknode->contact_expanded = TRUE; | |
824 | |
825 for(bnode = node->child; bnode; bnode = bnode->next) { | |
826 gaim_gtk_blist_update(NULL, bnode); | |
827 } | |
10353 | 828 |
9632 | 829 /* This ensures that the bottom buddy is visible, i.e. not scrolled off the alignment */ |
830 get_iter_from_node(node, &parent); | |
10353 | 831 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter, &parent, |
9811 | 832 gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &parent) -1); |
9632 | 833 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); |
834 /* Let the treeview draw so it knows where to scroll */ | |
835 while (gtk_events_pending()) | |
836 gtk_main_iteration(); | |
10353 | 837 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(gtkblist->treeview), path, NULL, FALSE, 0, 0); |
838 | |
9632 | 839 |
7620 | 840 gaim_gtk_blist_update(NULL, node); |
9632 | 841 gtk_tree_path_free(path); |
7620 | 842 } |
843 | |
844 static void | |
845 gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node) | |
846 { | |
847 GaimBlistNode *bnode; | |
848 struct _gaim_gtk_blist_node *gtknode; | |
849 | |
850 if(!GAIM_BLIST_NODE_IS_CONTACT(node)) | |
851 return; | |
852 | |
853 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
854 | |
855 gtknode->contact_expanded = FALSE; | |
856 | |
857 for(bnode = node->child; bnode; bnode = bnode->next) { | |
858 gaim_gtk_blist_update(NULL, bnode); | |
5228 | 859 } |
860 } | |
861 | |
9030 | 862 |
863 static void | |
864 blist_node_menu_cb(GtkMenuItem *item, GaimBlistNode *node) | |
865 { | |
11638 | 866 void (*callback)(GaimBlistNode *, gpointer); |
867 gpointer data; | |
868 callback = g_object_get_data(G_OBJECT(item), "gaimcallback"); | |
869 data = g_object_get_data(G_OBJECT(item), "gaimcallbackdata"); | |
870 if (callback) | |
871 callback(node, data); | |
9030 | 872 } |
873 | |
874 | |
875 static void | |
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
876 append_blist_node_action(GtkWidget *menu, GaimBlistNodeAction *act, |
9030 | 877 GaimBlistNode *node, gboolean *dup_separator) |
5228 | 878 { |
9030 | 879 if(act == NULL) { |
880 if(! *dup_separator) { | |
881 gaim_separator(menu); | |
882 *dup_separator = TRUE; | |
883 } | |
884 } else { | |
885 GtkWidget *menuitem; | |
886 | |
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
887 if (act->children == NULL) { |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
888 *dup_separator = FALSE; |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
889 |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
890 menuitem = gtk_menu_item_new_with_mnemonic(act->label); |
11038
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
891 if (act->callback != NULL) { |
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
892 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", |
11638 | 893 act->callback); |
894 g_object_set_data(G_OBJECT(menuitem), "gaimcallbackdata", | |
895 act->data); | |
11038
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
896 g_signal_connect(G_OBJECT(menuitem), "activate", |
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
897 G_CALLBACK(blist_node_menu_cb), node); |
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
898 } else { |
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
899 gtk_widget_set_sensitive(menuitem, FALSE); |
aedd557f46dd
[gaim-migrate @ 12935]
Richard Laager <rlaager@wiktel.com>
parents:
11033
diff
changeset
|
900 } |
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
901 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
902 } else { |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
903 GtkWidget *submenu = NULL; |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
904 GList *l = NULL; |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
905 |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
906 menuitem = gtk_menu_item_new_with_mnemonic(act->label); |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
907 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
908 |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
909 submenu = gtk_menu_new(); |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
910 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
911 |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
912 for (l = act->children; l; l = l->next) { |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
913 GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
914 |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
915 append_blist_node_action(submenu, act, node, dup_separator); |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
916 } |
11638 | 917 g_list_free(act->children); |
918 act->children = NULL; | |
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
919 } |
11638 | 920 g_free(act); |
9030 | 921 } |
5228 | 922 } |
923 | |
9030 | 924 |
9051 | 925 void |
10662
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
926 gaim_gtk_append_blist_node_proto_menu(GtkWidget *menu, GaimConnection *gc, |
54ac161a876e
[gaim-migrate @ 12199]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10643
diff
changeset
|
927 GaimBlistNode *node) |
9030 | 928 { |
929 GList *l, *ll; | |
930 gboolean dup_separator = FALSE; | |
931 GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
932 | |
933 if(!prpl_info || !prpl_info->blist_node_menu) | |
934 return; | |
935 | |
936 for(l = ll = prpl_info->blist_node_menu(node); l; l = l->next) { | |
937 GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; | |
938 append_blist_node_action(menu, act, node, &dup_separator); | |
939 } | |
940 g_list_free(ll); | |
941 } | |
942 | |
943 | |
9051 | 944 void |
945 gaim_gtk_append_blist_node_extended_menu (GtkWidget *menu, GaimBlistNode *node) | |
9030 | 946 { |
947 GList *l, *ll; | |
948 gboolean dup_separator = FALSE; | |
949 | |
950 for(l = ll = gaim_blist_node_get_extended_menu(node); l; l = l->next) { | |
951 GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; | |
952 append_blist_node_action(menu, act, node, &dup_separator); | |
953 } | |
954 g_list_free(ll); | |
955 } | |
956 | |
957 | |
9774 | 958 void |
10484 | 959 gaim_gtk_blist_make_buddy_menu(GtkWidget *menu, GaimBuddy *buddy, gboolean sub) { |
9774 | 960 GaimPluginProtocolInfo *prpl_info; |
10663 | 961 GaimContact *contact; |
962 gboolean contact_expanded = FALSE; | |
9774 | 963 |
964 g_return_if_fail(menu); | |
965 g_return_if_fail(buddy); | |
966 | |
967 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(buddy->account->gc->prpl); | |
968 | |
10663 | 969 contact = gaim_buddy_get_contact(buddy); |
970 if (contact) { | |
971 contact_expanded = ((struct _gaim_gtk_blist_node *)(((GaimBlistNode*)contact)->ui_data))->contact_expanded; | |
972 } | |
973 | |
7620 | 974 if (prpl_info && prpl_info->get_info) { |
8137 | 975 gaim_new_item_from_stock(menu, _("Get _Info"), GAIM_STOCK_INFO, |
9774 | 976 G_CALLBACK(gtk_blist_menu_info_cb), buddy, 0, 0, NULL); |
7620 | 977 } |
8137 | 978 gaim_new_item_from_stock(menu, _("I_M"), GAIM_STOCK_IM, |
9774 | 979 G_CALLBACK(gtk_blist_menu_im_cb), buddy, 0, 0, NULL); |
9466 | 980 if (prpl_info && prpl_info->send_file) { |
9774 | 981 if (!prpl_info->can_receive_file || |
982 prpl_info->can_receive_file(buddy->account->gc, buddy->name)) | |
983 { | |
984 gaim_new_item_from_stock(menu, _("_Send File"), | |
985 GAIM_STOCK_FILE_TRANSFER, | |
986 G_CALLBACK(gtk_blist_menu_send_file_cb), | |
987 buddy, 0, 0, NULL); | |
9466 | 988 } |
989 } | |
12024 | 990 |
991 if (prpl_info && prpl_info->media_prpl_ops && prpl_info->media_prpl_ops->call) { | |
992 gaim_new_item_from_stock(menu, _("Start _Voice Chat"), | |
993 GAIM_STOCK_VOICE_CHAT, | |
994 G_CALLBACK(gtk_blist_menu_voice_chat_cb), | |
995 buddy, 0, 0, NULL); | |
996 } | |
997 | |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
998 gaim_new_item_from_stock(menu, _("Add Buddy _Pounce"), GAIM_STOCK_POUNCE, |
9774 | 999 G_CALLBACK(gtk_blist_menu_bp_cb), buddy, 0, 0, NULL); |
10663 | 1000 |
1001 if(((GaimBlistNode*)buddy)->parent->child->next && !sub && !contact_expanded) { | |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
1002 gaim_new_item_from_stock(menu, _("View _Log"), GAIM_STOCK_LOG, |
10663 | 1003 G_CALLBACK(gtk_blist_menu_showlog_cb), |
1004 contact, 0, 0, NULL); | |
1005 } else if (!sub) { | |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
1006 gaim_new_item_from_stock(menu, _("View _Log"), GAIM_STOCK_LOG, |
10663 | 1007 G_CALLBACK(gtk_blist_menu_showlog_cb), buddy, 0, 0, NULL); |
1008 } | |
9774 | 1009 |
1010 gaim_gtk_append_blist_node_proto_menu(menu, buddy->account->gc, | |
1011 (GaimBlistNode *)buddy); | |
1012 gaim_gtk_append_blist_node_extended_menu(menu, (GaimBlistNode *)buddy); | |
7620 | 1013 |
1014 gaim_separator(menu); | |
9030 | 1015 |
10663 | 1016 if(((GaimBlistNode*)buddy)->parent->child->next && !sub && !contact_expanded) { |
9925 | 1017 gaim_new_item_from_stock(menu, _("_Alias Buddy..."), GAIM_STOCK_ALIAS, |
1018 G_CALLBACK(gtk_blist_menu_alias_cb), buddy, 0, 0, NULL); | |
1019 gaim_new_item_from_stock(menu, _("_Remove Buddy"), GTK_STOCK_REMOVE, | |
1020 G_CALLBACK(gaim_gtk_blist_remove_cb), buddy, 0, 0, NULL); | |
1021 gaim_new_item_from_stock(menu, _("Alias Contact..."), GAIM_STOCK_ALIAS, | |
1022 G_CALLBACK(gtk_blist_menu_alias_cb), | |
10663 | 1023 contact, 0, 0, NULL); |
9925 | 1024 gaim_new_item_from_stock(menu, _("Remove Contact"), GTK_STOCK_REMOVE, |
1025 G_CALLBACK(gaim_gtk_blist_remove_cb), | |
10663 | 1026 contact, 0, 0, NULL); |
9925 | 1027 } else { |
1028 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, | |
1029 G_CALLBACK(gtk_blist_menu_alias_cb), buddy, 0, 0, NULL); | |
1030 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, | |
1031 G_CALLBACK(gaim_gtk_blist_remove_cb), buddy, | |
1032 0, 0, NULL); | |
1033 } | |
7620 | 1034 } |
1035 | |
9774 | 1036 static gboolean |
1037 gtk_blist_key_press_cb(GtkWidget *tv, GdkEventKey *event, gpointer data) { | |
7620 | 1038 GaimBlistNode *node; |
1039 GValue val = { 0, }; | |
1040 GtkTreeIter iter; | |
1041 GtkTreeSelection *sel; | |
1042 | |
1043 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
1044 if(!gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
1045 return FALSE; | |
1046 | |
1047 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
1048 NODE_COLUMN, &val); | |
1049 node = g_value_get_pointer(&val); | |
1050 | |
1051 if(event->state & GDK_CONTROL_MASK && | |
1052 (event->keyval == 'o' || event->keyval == 'O')) { | |
1053 GaimBuddy *buddy; | |
1054 | |
1055 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
1056 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
1057 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1058 buddy = (GaimBuddy*)node; | |
1059 } else { | |
1060 return FALSE; | |
1061 } | |
1062 if(buddy) | |
1063 serv_get_info(buddy->account->gc, buddy->name); | |
1064 } | |
1065 | |
1066 return FALSE; | |
1067 } | |
1068 | |
9013 | 1069 |
8143 | 1070 static GtkWidget * |
8952 | 1071 create_group_menu (GaimBlistNode *node, GaimGroup *g) |
8143 | 1072 { |
1073 GtkWidget *menu; | |
11988 | 1074 GtkWidget *item; |
8143 | 1075 |
1076 menu = gtk_menu_new(); | |
1077 gaim_new_item_from_stock(menu, _("Add a _Buddy"), GTK_STOCK_ADD, | |
1078 G_CALLBACK(gaim_gtk_blist_add_buddy_cb), node, 0, 0, NULL); | |
11988 | 1079 item = gaim_new_item_from_stock(menu, _("Add a C_hat"), GTK_STOCK_ADD, |
8143 | 1080 G_CALLBACK(gaim_gtk_blist_add_chat_cb), node, 0, 0, NULL); |
11988 | 1081 gtk_widget_set_sensitive(item, gaim_gtk_blist_joinchat_is_showable()); |
8143 | 1082 gaim_new_item_from_stock(menu, _("_Delete Group"), GTK_STOCK_REMOVE, |
1083 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
1084 gaim_new_item_from_stock(menu, _("_Rename"), NULL, | |
11016 | 1085 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
8952 | 1086 |
9051 | 1087 gaim_gtk_append_blist_node_extended_menu(menu, node); |
8952 | 1088 |
8143 | 1089 return menu; |
1090 } | |
1091 | |
8586 | 1092 |
8143 | 1093 static GtkWidget * |
9774 | 1094 create_chat_menu(GaimBlistNode *node, GaimChat *c) { |
8143 | 1095 GtkWidget *menu; |
9030 | 1096 gboolean autojoin; |
8143 | 1097 |
1098 menu = gtk_menu_new(); | |
9030 | 1099 autojoin = (gaim_blist_node_get_bool(node, "gtk-autojoin") || |
1100 (gaim_blist_node_get_string(node, "gtk-autojoin") != NULL)); | |
1101 | |
8143 | 1102 gaim_new_item_from_stock(menu, _("_Join"), GAIM_STOCK_CHAT, |
9030 | 1103 G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL); |
8143 | 1104 gaim_new_check_item(menu, _("Auto-Join"), |
9030 | 1105 G_CALLBACK(gtk_blist_menu_autojoin_cb), node, autojoin); |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
1106 gaim_new_item_from_stock(menu, _("View _Log"), GAIM_STOCK_LOG, |
9917 | 1107 G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL); |
9030 | 1108 |
9051 | 1109 gaim_gtk_append_blist_node_proto_menu(menu, c->account->gc, node); |
1110 gaim_gtk_append_blist_node_extended_menu(menu, node); | |
8586 | 1111 |
1112 gaim_separator(menu); | |
9030 | 1113 |
8302
462ead6fc1a0
[gaim-migrate @ 9026]
Christian Hammond <chipx86@chipx86.com>
parents:
8259
diff
changeset
|
1114 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, |
8143 | 1115 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
1116 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, | |
1117 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
8586 | 1118 |
8143 | 1119 return menu; |
1120 } | |
1121 | |
1122 static GtkWidget * | |
1123 create_contact_menu (GaimBlistNode *node) | |
1124 { | |
1125 GtkWidget *menu; | |
1126 | |
1127 menu = gtk_menu_new(); | |
10663 | 1128 |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
1129 gaim_new_item_from_stock(menu, _("View _Log"), GAIM_STOCK_LOG, |
10663 | 1130 G_CALLBACK(gtk_blist_menu_showlog_cb), |
1131 node, 0, 0, NULL); | |
1132 | |
1133 gaim_separator(menu); | |
1134 | |
8302
462ead6fc1a0
[gaim-migrate @ 9026]
Christian Hammond <chipx86@chipx86.com>
parents:
8259
diff
changeset
|
1135 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, |
8143 | 1136 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
10663 | 1137 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, |
1138 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
1139 | |
1140 gaim_separator(menu); | |
1141 | |
8143 | 1142 gaim_new_item_from_stock(menu, _("_Collapse"), GTK_STOCK_ZOOM_OUT, |
1143 G_CALLBACK(gaim_gtk_blist_collapse_contact_cb), | |
1144 node, 0, 0, NULL); | |
9051 | 1145 |
1146 gaim_gtk_append_blist_node_extended_menu(menu, node); | |
1147 | |
8143 | 1148 return menu; |
1149 } | |
1150 | |
1151 static GtkWidget * | |
9774 | 1152 create_buddy_menu(GaimBlistNode *node, GaimBuddy *b) { |
8143 | 1153 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; |
1154 GtkWidget *menu; | |
1155 GtkWidget *menuitem; | |
1156 gboolean show_offline = gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies"); | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1157 |
8143 | 1158 menu = gtk_menu_new(); |
10484 | 1159 gaim_gtk_blist_make_buddy_menu(menu, b, FALSE); |
8143 | 1160 |
1161 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
1162 gaim_separator(menu); | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1163 |
8143 | 1164 if(gtknode->contact_expanded) { |
1165 gaim_new_item_from_stock(menu, _("_Collapse"), | |
1166 GTK_STOCK_ZOOM_OUT, | |
1167 G_CALLBACK(gaim_gtk_blist_collapse_contact_cb), | |
1168 node, 0, 0, NULL); | |
1169 } else { | |
1170 gaim_new_item_from_stock(menu, _("_Expand"), | |
1171 GTK_STOCK_ZOOM_IN, | |
1172 G_CALLBACK(gaim_gtk_blist_expand_contact_cb), node, | |
1173 0, 0, NULL); | |
1174 } | |
1175 if(node->child->next) { | |
1176 GaimBlistNode *bnode; | |
1177 | |
1178 for(bnode = node->child; bnode; bnode = bnode->next) { | |
1179 GaimBuddy *buddy = (GaimBuddy*)bnode; | |
9340 | 1180 GdkPixbuf *buf; |
8143 | 1181 GtkWidget *submenu; |
1182 GtkWidget *image; | |
1183 | |
1184 if(buddy == b) | |
1185 continue; | |
1186 if(!buddy->account->gc) | |
1187 continue; | |
1188 if(!show_offline && !GAIM_BUDDY_IS_ONLINE(buddy)) | |
1189 continue; | |
1190 | |
1191 menuitem = gtk_image_menu_item_new_with_label(buddy->name); | |
9340 | 1192 buf = gaim_gtk_blist_get_status_icon(bnode, |
1193 GAIM_STATUS_ICON_SMALL); | |
1194 image = gtk_image_new_from_pixbuf(buf); | |
1195 g_object_unref(G_OBJECT(buf)); | |
8143 | 1196 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), |
9811 | 1197 image); |
8143 | 1198 gtk_widget_show(image); |
1199 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
1200 gtk_widget_show(menuitem); | |
1201 | |
1202 submenu = gtk_menu_new(); | |
1203 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
1204 gtk_widget_show(submenu); | |
1205 | |
10484 | 1206 gaim_gtk_blist_make_buddy_menu(submenu, buddy, TRUE); |
8143 | 1207 } |
1208 } | |
1209 } | |
1210 return menu; | |
1211 } | |
1212 | |
1213 static gboolean | |
1214 gaim_gtk_blist_show_context_menu(GaimBlistNode *node, | |
1215 GtkMenuPositionFunc func, | |
1216 GtkWidget *tv, | |
1217 guint button, | |
1218 guint32 time) | |
1219 { | |
1220 struct _gaim_gtk_blist_node *gtknode; | |
1221 GtkWidget *menu = NULL; | |
1222 gboolean handled = FALSE; | |
1223 | |
1224 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
1225 | |
1226 /* Create a menu based on the thing we right-clicked on */ | |
1227 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
8952 | 1228 GaimGroup *g = (GaimGroup *)node; |
9774 | 1229 |
8952 | 1230 menu = create_group_menu(node, g); |
8143 | 1231 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
8586 | 1232 GaimChat *c = (GaimChat *)node; |
9774 | 1233 |
1234 menu = create_chat_menu(node, c); | |
8143 | 1235 } else if ((GAIM_BLIST_NODE_IS_CONTACT(node)) && (gtknode->contact_expanded)) { |
1236 menu = create_contact_menu(node); | |
1237 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1238 GaimBuddy *b; | |
1239 | |
1240 if (GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1241 b = gaim_contact_get_priority_buddy((GaimContact*)node); | |
1242 else | |
1243 b = (GaimBuddy *)node; | |
1244 | |
9774 | 1245 menu = create_buddy_menu(node, b); |
8143 | 1246 } |
1247 | |
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1248 #ifdef _WIN32 |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1249 /* Unhook the tooltip-timeout since we don't want a tooltip |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1250 * to appear and obscure the context menu we are about to show |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1251 This is a workaround for GTK+ bug 107320. */ |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1252 if (gtkblist->timeout) { |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1253 g_source_remove(gtkblist->timeout); |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1254 gtkblist->timeout = 0; |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1255 } |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1256 #endif |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1257 |
8143 | 1258 /* Now display the menu */ |
1259 if (menu != NULL) { | |
1260 gtk_widget_show_all(menu); | |
1261 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, func, tv, button, time); | |
1262 handled = TRUE; | |
1263 } | |
1264 | |
1265 return handled; | |
1266 } | |
1267 | |
1268 static gboolean gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_data) | |
5228 | 1269 { |
1270 GtkTreePath *path; | |
1271 GaimBlistNode *node; | |
1272 GValue val = { 0, }; | |
1273 GtkTreeIter iter; | |
1274 GtkTreeSelection *sel; | |
1275 GaimPlugin *prpl = NULL; | |
1276 GaimPluginProtocolInfo *prpl_info = NULL; | |
7620 | 1277 struct _gaim_gtk_blist_node *gtknode; |
1278 gboolean handled = FALSE; | |
5228 | 1279 |
1280 /* Here we figure out which node was clicked */ | |
1281 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL)) | |
1282 return FALSE; | |
1283 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
8143 | 1284 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); |
5228 | 1285 node = g_value_get_pointer(&val); |
7620 | 1286 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; |
1287 | |
8143 | 1288 /* Right click draws a context menu */ |
1289 if ((event->button == 3) && (event->type == GDK_BUTTON_PRESS)) { | |
1290 handled = gaim_gtk_blist_show_context_menu(node, NULL, tv, 3, event->time); | |
1291 | |
1292 /* CTRL+middle click expands or collapse a contact */ | |
1293 } else if ((event->button == 2) && (event->type == GDK_BUTTON_PRESS) && | |
1294 (event->state & GDK_CONTROL_MASK) && (GAIM_BLIST_NODE_IS_CONTACT(node))) { | |
1295 if (gtknode->contact_expanded) | |
7620 | 1296 gaim_gtk_blist_collapse_contact_cb(NULL, node); |
1297 else | |
1298 gaim_gtk_blist_expand_contact_cb(NULL, node); | |
1299 handled = TRUE; | |
8143 | 1300 |
1301 /* Double middle click gets info */ | |
1302 } else if ((event->button == 2) && (event->type == GDK_2BUTTON_PRESS) && | |
1303 ((GAIM_BLIST_NODE_IS_CONTACT(node)) || (GAIM_BLIST_NODE_IS_BUDDY(node)))) { | |
7620 | 1304 GaimBuddy *b; |
1305 if(GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1306 b = gaim_contact_get_priority_buddy((GaimContact*)node); | |
1307 else | |
1308 b = (GaimBuddy *)node; | |
1309 | |
7956 | 1310 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
5228 | 1311 if (prpl != NULL) |
1312 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
1313 | |
8143 | 1314 if (prpl && prpl_info->get_info) |
1315 serv_get_info(b->account->gc, b->name); | |
1316 handled = TRUE; | |
5228 | 1317 } |
1318 | |
8143 | 1319 #if (1) |
1320 /* | |
10814
364a2ef907ae
[gaim-migrate @ 12468]
Luke Schierer <lschiere@pidgin.im>
parents:
10780
diff
changeset
|
1321 * This code only exists because GTK+ doesn't work. If we return |
8143 | 1322 * FALSE here, as would be normal the event propoagates down and |
1323 * somehow gets interpreted as the start of a drag event. | |
1324 * | |
1325 * Um, isn't it _normal_ to return TRUE here? Since the event | |
1326 * was handled? --Mark | |
1327 */ | |
7620 | 1328 if(handled) { |
1329 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
1330 gtk_tree_selection_select_path(sel, path); | |
1331 gtk_tree_path_free(path); | |
1332 return TRUE; | |
1333 } | |
5228 | 1334 #endif |
7753 | 1335 gtk_tree_path_free(path); |
8143 | 1336 |
7620 | 1337 return FALSE; |
5228 | 1338 } |
1339 | |
8143 | 1340 static gboolean |
1341 gaim_gtk_blist_popup_menu_cb(GtkWidget *tv, void *user_data) | |
1342 { | |
1343 GaimBlistNode *node; | |
1344 GValue val = { 0, }; | |
1345 GtkTreeIter iter; | |
1346 GtkTreeSelection *sel; | |
1347 gboolean handled = FALSE; | |
1348 | |
1349 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
1350 if (!gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
1351 return FALSE; | |
1352 | |
1353 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), | |
1354 &iter, NODE_COLUMN, &val); | |
1355 node = g_value_get_pointer(&val); | |
1356 | |
1357 /* Shift+F10 draws a context menu */ | |
1358 handled = gaim_gtk_blist_show_context_menu(node, gaim_gtk_treeview_popup_menu_position_func, tv, 0, GDK_CURRENT_TIME); | |
1359 | |
1360 return handled; | |
1361 } | |
1362 | |
11796 | 1363 static void gaim_gtk_blist_buddy_details_cb(gpointer data, guint action, GtkWidget *item) |
1364 { | |
1365 gaim_prefs_set_bool("/gaim/gtk/blist/show_buddy_icons", | |
1366 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item))); | |
1367 } | |
1368 | |
5228 | 1369 static void gaim_gtk_blist_show_empty_groups_cb(gpointer data, guint action, GtkWidget *item) |
1370 { | |
7620 | 1371 gaim_prefs_set_bool("/gaim/gtk/blist/show_empty_groups", |
1372 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item))); | |
5228 | 1373 } |
1374 | |
1375 static void gaim_gtk_blist_edit_mode_cb(gpointer callback_data, guint callback_action, | |
1376 GtkWidget *checkitem) { | |
1377 if(gtkblist->window->window) { | |
1378 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); | |
1379 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
1380 while (gtk_events_pending()) | |
1381 gtk_main_iteration(); | |
1382 gdk_cursor_unref(cursor); | |
1383 } | |
1384 | |
7620 | 1385 gaim_prefs_set_bool("/gaim/gtk/blist/show_offline_buddies", |
1386 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem))); | |
5228 | 1387 |
1388 if(gtkblist->window->window) { | |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
12226
diff
changeset
|
1389 gdk_window_set_cursor(gtkblist->window->window, NULL); |
5228 | 1390 } |
1391 } | |
1392 | |
10074 | 1393 static void gaim_gtk_blist_mute_sounds_cb(gpointer data, guint action, GtkWidget *item) |
1394 { | |
1395 gaim_prefs_set_bool("/gaim/gtk/sound/mute", GTK_CHECK_MENU_ITEM(item)->active); | |
1396 } | |
1397 | |
1398 static void gaim_gtk_blist_mute_pref_cb(const char *name, GaimPrefType type, gpointer value, gpointer data) | |
1399 { | |
1400 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(gtkblist->ift, | |
1401 N_("/Tools/Mute Sounds"))), (gboolean)GPOINTER_TO_INT(value)); | |
1402 } | |
1403 | |
1404 static void gaim_gtk_blist_sound_method_pref_cb(const char *name, GaimPrefType type, gpointer value, gpointer data) | |
1405 { | |
1406 gboolean sensitive = TRUE; | |
1407 | |
1408 if(!strcmp(value, "none")) | |
1409 sensitive = FALSE; | |
1410 | |
1411 gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), sensitive); | |
1412 } | |
1413 | |
8089 | 1414 static void |
1415 add_buddies_from_vcard(const char *prpl_id, GaimGroup *group, GList *list, | |
1416 const char *alias) | |
1417 { | |
1418 GList *l; | |
1419 GaimAccount *account = NULL; | |
1420 GaimConnection *gc; | |
1421 | |
1422 if (list == NULL) | |
1423 return; | |
1424 | |
1425 for (l = gaim_connections_get_all(); l != NULL; l = l->next) | |
1426 { | |
1427 gc = (GaimConnection *)l->data; | |
1428 account = gaim_connection_get_account(gc); | |
1429 | |
1430 if (!strcmp(gaim_account_get_protocol_id(account), prpl_id)) | |
1431 break; | |
1432 | |
1433 account = NULL; | |
1434 } | |
1435 | |
1436 if (account != NULL) | |
1437 { | |
1438 for (l = list; l != NULL; l = l->next) | |
1439 { | |
1440 gaim_blist_request_add_buddy(account, l->data, | |
1441 (group ? group->name : NULL), | |
1442 alias); | |
1443 } | |
1444 } | |
1445 | |
1446 g_list_foreach(list, (GFunc)g_free, NULL); | |
1447 g_list_free(list); | |
1448 } | |
1449 | |
1450 static gboolean | |
1451 parse_vcard(const char *vcard, GaimGroup *group) | |
1452 { | |
1453 char *temp_vcard; | |
1454 char *s, *c; | |
1455 char *alias = NULL; | |
1456 GList *aims = NULL; | |
1457 GList *icqs = NULL; | |
1458 GList *yahoos = NULL; | |
1459 GList *msns = NULL; | |
1460 GList *jabbers = NULL; | |
1461 | |
1462 s = temp_vcard = g_strdup(vcard); | |
1463 | |
1464 while (*s != '\0' && strncmp(s, "END:vCard", strlen("END:vCard"))) | |
1465 { | |
1466 char *field, *value; | |
1467 | |
1468 field = s; | |
1469 | |
1470 /* Grab the field */ | |
1471 while (*s != '\r' && *s != '\n' && *s != '\0' && *s != ':') | |
1472 s++; | |
1473 | |
1474 if (*s == '\r') s++; | |
1475 if (*s == '\n') | |
1476 { | |
1477 s++; | |
1478 continue; | |
1479 } | |
1480 | |
1481 if (*s != '\0') *s++ = '\0'; | |
1482 | |
1483 if ((c = strchr(field, ';')) != NULL) | |
1484 *c = '\0'; | |
1485 | |
1486 /* Proceed to the end of the line */ | |
1487 value = s; | |
1488 | |
1489 while (*s != '\r' && *s != '\n' && *s != '\0') | |
1490 s++; | |
1491 | |
1492 if (*s == '\r') *s++ = '\0'; | |
1493 if (*s == '\n') *s++ = '\0'; | |
1494 | |
1495 /* We only want to worry about a few fields here. */ | |
1496 if (!strcmp(field, "FN")) | |
1497 alias = g_strdup(value); | |
1498 else if (!strcmp(field, "X-AIM") || !strcmp(field, "X-ICQ") || | |
1499 !strcmp(field, "X-YAHOO") || !strcmp(field, "X-MSN") || | |
1500 !strcmp(field, "X-JABBER")) | |
1501 { | |
1502 char **values = g_strsplit(value, ":", 0); | |
1503 char **im; | |
1504 | |
1505 for (im = values; *im != NULL; im++) | |
1506 { | |
1507 if (!strcmp(field, "X-AIM")) | |
1508 aims = g_list_append(aims, g_strdup(*im)); | |
1509 else if (!strcmp(field, "X-ICQ")) | |
1510 icqs = g_list_append(icqs, g_strdup(*im)); | |
1511 else if (!strcmp(field, "X-YAHOO")) | |
1512 yahoos = g_list_append(yahoos, g_strdup(*im)); | |
1513 else if (!strcmp(field, "X-MSN")) | |
1514 msns = g_list_append(msns, g_strdup(*im)); | |
1515 else if (!strcmp(field, "X-JABBER")) | |
1516 jabbers = g_list_append(jabbers, g_strdup(*im)); | |
1517 } | |
1518 | |
1519 g_strfreev(values); | |
1520 } | |
1521 } | |
1522 | |
1523 g_free(temp_vcard); | |
1524 | |
1525 if (aims == NULL && icqs == NULL && yahoos == NULL && | |
1526 msns == NULL && jabbers == NULL) | |
1527 { | |
1528 if (alias != NULL) | |
1529 g_free(alias); | |
1530 | |
1531 return FALSE; | |
1532 } | |
1533 | |
1534 add_buddies_from_vcard("prpl-oscar", group, aims, alias); | |
1535 add_buddies_from_vcard("prpl-oscar", group, icqs, alias); | |
1536 add_buddies_from_vcard("prpl-yahoo", group, yahoos, alias); | |
1537 add_buddies_from_vcard("prpl-msn", group, msns, alias); | |
1538 add_buddies_from_vcard("prpl-jabber", group, jabbers, alias); | |
1539 | |
1540 if (alias != NULL) | |
1541 g_free(alias); | |
1542 | |
1543 return TRUE; | |
1544 } | |
1545 | |
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1546 #ifdef _WIN32 |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1547 static void gaim_gtk_blist_drag_begin(GtkWidget *widget, |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1548 GdkDragContext *drag_context, gpointer user_data) |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1549 { |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1550 gaim_gtk_blist_tooltip_destroy(); |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1551 |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1552 |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1553 /* Unhook the tooltip-timeout since we don't want a tooltip |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1554 * to appear and obscure the dragging operation. |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1555 * This is a workaround for GTK+ bug 107320. */ |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1556 if (gtkblist->timeout) { |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1557 g_source_remove(gtkblist->timeout); |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1558 gtkblist->timeout = 0; |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1559 } |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1560 } |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1561 #endif |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1562 |
9811 | 1563 static void gaim_gtk_blist_drag_data_get_cb(GtkWidget *widget, |
1564 GdkDragContext *dc, | |
1565 GtkSelectionData *data, | |
1566 guint info, | |
1567 guint time, | |
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1568 gpointer null) |
5228 | 1569 { |
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
1570 |
8089 | 1571 if (data->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE)) |
1572 { | |
5228 | 1573 GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); |
1574 GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref); | |
1575 GtkTreeIter iter; | |
1576 GaimBlistNode *node = NULL; | |
1577 GValue val = {0}; | |
5273 | 1578 if(!sourcerow) |
1579 return; | |
5228 | 1580 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, sourcerow); |
1581 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
1582 node = g_value_get_pointer(&val); | |
1583 gtk_selection_data_set (data, | |
1584 gdk_atom_intern ("GAIM_BLIST_NODE", FALSE), | |
1585 8, /* bits */ | |
1586 (void*)&node, | |
1587 sizeof (node)); | |
5273 | 1588 |
5228 | 1589 gtk_tree_path_free(sourcerow); |
1590 } | |
8089 | 1591 else if (data->target == gdk_atom_intern("application/x-im-contact", FALSE)) |
1592 { | |
7706 | 1593 GtkTreeRowReference *ref; |
1594 GtkTreePath *sourcerow; | |
1595 GtkTreeIter iter; | |
1596 GaimBlistNode *node = NULL; | |
1597 GaimBuddy *buddy; | |
1598 GaimConnection *gc; | |
1599 GValue val = {0}; | |
1600 GString *str; | |
1601 const char *protocol; | |
1602 char *mime_str; | |
1603 | |
1604 ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); | |
1605 sourcerow = gtk_tree_row_reference_get_path(ref); | |
1606 | |
1607 if (!sourcerow) | |
1608 return; | |
1609 | |
1610 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
1611 sourcerow); | |
1612 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
1613 NODE_COLUMN, &val); | |
1614 | |
1615 node = g_value_get_pointer(&val); | |
1616 | |
1617 if (GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1618 { | |
1619 buddy = gaim_contact_get_priority_buddy((GaimContact *)node); | |
1620 } | |
1621 else if (!GAIM_BLIST_NODE_IS_BUDDY(node)) | |
1622 { | |
1623 gtk_tree_path_free(sourcerow); | |
1624 return; | |
1625 } | |
1626 else | |
1627 { | |
1628 buddy = (GaimBuddy *)node; | |
1629 } | |
1630 | |
1631 gc = gaim_account_get_connection(buddy->account); | |
1632 | |
1633 if (gc == NULL) | |
1634 { | |
1635 gtk_tree_path_free(sourcerow); | |
1636 return; | |
1637 } | |
1638 | |
1639 protocol = | |
1640 GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->list_icon(buddy->account, | |
1641 buddy); | |
1642 | |
1643 str = g_string_new(NULL); | |
1644 g_string_printf(str, | |
1645 "MIME-Version: 1.0\r\n" | |
1646 "Content-Type: application/x-im-contact\r\n" | |
1647 "X-IM-Protocol: %s\r\n" | |
1648 "X-IM-Username: %s\r\n", | |
1649 protocol, | |
1650 buddy->name); | |
1651 | |
1652 if (buddy->alias != NULL) | |
1653 { | |
1654 g_string_append_printf(str, | |
1655 "X-IM-Alias: %s\r\n", | |
1656 buddy->alias); | |
1657 } | |
1658 | |
1659 str = g_string_append(str, "\r\n"); | |
1660 | |
1661 mime_str = g_string_free(str, FALSE); | |
1662 | |
1663 gtk_selection_data_set(data, | |
1664 gdk_atom_intern("application/x-im-contact", FALSE), | |
1665 8, /* bits */ | |
11137 | 1666 (const guchar *)mime_str, |
7706 | 1667 strlen(mime_str) + 1); |
1668 | |
1669 g_free(mime_str); | |
1670 gtk_tree_path_free(sourcerow); | |
1671 } | |
5228 | 1672 } |
1673 | |
1674 static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | |
1675 GtkSelectionData *sd, guint info, guint t) | |
7620 | 1676 { |
5228 | 1677 if (sd->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE) && sd->data) { |
1678 GaimBlistNode *n = NULL; | |
1679 GtkTreePath *path = NULL; | |
1680 GtkTreeViewDropPosition position; | |
1681 memcpy(&n, sd->data, sizeof(n)); | |
1682 if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) { | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1683 /* if we're here, I think it means the drop is ok */ |
7642 | 1684 GtkTreeIter iter; |
5228 | 1685 GaimBlistNode *node; |
1686 GValue val = {0}; | |
7620 | 1687 struct _gaim_gtk_blist_node *gtknode; |
1688 | |
1689 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
1690 &iter, path); | |
1691 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
1692 &iter, NODE_COLUMN, &val); | |
5228 | 1693 node = g_value_get_pointer(&val); |
7620 | 1694 gtknode = node->ui_data; |
1695 | |
1696 if (GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
1697 GaimContact *c = (GaimContact*)n; | |
1698 if (GAIM_BLIST_NODE_IS_CONTACT(node) && gtknode->contact_expanded) { | |
1699 gaim_blist_merge_contact(c, node); | |
1700 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) || | |
5234 | 1701 GAIM_BLIST_NODE_IS_CHAT(node)) { |
5228 | 1702 switch(position) { |
1703 case GTK_TREE_VIEW_DROP_AFTER: | |
1704 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
7620 | 1705 gaim_blist_add_contact(c, (GaimGroup*)node->parent, |
1706 node); | |
1707 break; | |
1708 case GTK_TREE_VIEW_DROP_BEFORE: | |
1709 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1710 gaim_blist_add_contact(c, (GaimGroup*)node->parent, | |
1711 node->prev); | |
1712 break; | |
1713 } | |
1714 } else if(GAIM_BLIST_NODE_IS_GROUP(node)) { | |
1715 gaim_blist_add_contact(c, (GaimGroup*)node, NULL); | |
1716 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1717 gaim_blist_merge_contact(c, node); | |
1718 } | |
1719 } else if (GAIM_BLIST_NODE_IS_BUDDY(n)) { | |
1720 GaimBuddy *b = (GaimBuddy*)n; | |
1721 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1722 switch(position) { | |
1723 case GTK_TREE_VIEW_DROP_AFTER: | |
1724 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1725 gaim_blist_add_buddy(b, (GaimContact*)node->parent, | |
1726 (GaimGroup*)node->parent->parent, node); | |
5228 | 1727 break; |
1728 case GTK_TREE_VIEW_DROP_BEFORE: | |
1729 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
7620 | 1730 gaim_blist_add_buddy(b, (GaimContact*)node->parent, |
1731 (GaimGroup*)node->parent->parent, | |
1732 node->prev); | |
5228 | 1733 break; |
1734 } | |
7620 | 1735 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { |
1736 gaim_blist_add_buddy(b, NULL, (GaimGroup*)node->parent, | |
1737 NULL); | |
5228 | 1738 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
7620 | 1739 gaim_blist_add_buddy(b, NULL, (GaimGroup*)node, NULL); |
1740 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
1741 if(gtknode->contact_expanded) { | |
1742 switch(position) { | |
1743 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1744 case GTK_TREE_VIEW_DROP_AFTER: | |
1745 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1746 gaim_blist_add_buddy(b, (GaimContact*)node, | |
1747 (GaimGroup*)node->parent, NULL); | |
1748 break; | |
1749 case GTK_TREE_VIEW_DROP_BEFORE: | |
1750 gaim_blist_add_buddy(b, NULL, | |
1751 (GaimGroup*)node->parent, node->prev); | |
1752 break; | |
1753 } | |
1754 } else { | |
1755 switch(position) { | |
1756 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1757 case GTK_TREE_VIEW_DROP_AFTER: | |
1758 gaim_blist_add_buddy(b, NULL, | |
1759 (GaimGroup*)node->parent, NULL); | |
1760 break; | |
1761 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1762 case GTK_TREE_VIEW_DROP_BEFORE: | |
1763 gaim_blist_add_buddy(b, NULL, | |
1764 (GaimGroup*)node->parent, node->prev); | |
1765 break; | |
1766 } | |
1767 } | |
5228 | 1768 } |
5234 | 1769 } else if (GAIM_BLIST_NODE_IS_CHAT(n)) { |
7620 | 1770 GaimChat *chat = (GaimChat *)n; |
1771 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1772 switch(position) { | |
1773 case GTK_TREE_VIEW_DROP_AFTER: | |
1774 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1775 gaim_blist_add_chat(chat, | |
1776 (GaimGroup*)node->parent->parent, node); | |
1777 break; | |
1778 case GTK_TREE_VIEW_DROP_BEFORE: | |
1779 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1780 gaim_blist_add_chat(chat, | |
1781 (GaimGroup*)node->parent->parent, | |
1782 node->prev); | |
1783 break; | |
1784 } | |
1785 } else if(GAIM_BLIST_NODE_IS_CONTACT(node) || | |
5234 | 1786 GAIM_BLIST_NODE_IS_CHAT(node)) { |
1787 switch(position) { | |
1788 case GTK_TREE_VIEW_DROP_AFTER: | |
1789 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
7620 | 1790 gaim_blist_add_chat(chat, (GaimGroup*)node->parent, node); |
5234 | 1791 break; |
1792 case GTK_TREE_VIEW_DROP_BEFORE: | |
1793 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
7620 | 1794 gaim_blist_add_chat(chat, (GaimGroup*)node->parent, node->prev); |
5234 | 1795 break; |
1796 } | |
1797 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
7620 | 1798 gaim_blist_add_chat(chat, (GaimGroup*)node, NULL); |
5234 | 1799 } |
5228 | 1800 } else if (GAIM_BLIST_NODE_IS_GROUP(n)) { |
7620 | 1801 GaimGroup *g = (GaimGroup*)n; |
5228 | 1802 if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
1803 switch (position) { | |
1804 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1805 case GTK_TREE_VIEW_DROP_AFTER: | |
1806 gaim_blist_add_group(g, node); | |
1807 break; | |
1808 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1809 case GTK_TREE_VIEW_DROP_BEFORE: | |
1810 gaim_blist_add_group(g, node->prev); | |
1811 break; | |
1812 } | |
7620 | 1813 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
1814 gaim_blist_add_group(g, node->parent->parent); | |
1815 } else if(GAIM_BLIST_NODE_IS_CONTACT(node) || | |
5234 | 1816 GAIM_BLIST_NODE_IS_CHAT(node)) { |
5228 | 1817 gaim_blist_add_group(g, node->parent); |
1818 } | |
1819 } | |
1820 | |
1821 gtk_tree_path_free(path); | |
7620 | 1822 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); |
5228 | 1823 } |
1824 } | |
7706 | 1825 else if (sd->target == gdk_atom_intern("application/x-im-contact", |
1826 FALSE) && sd->data) | |
1827 { | |
1828 GaimGroup *group = NULL; | |
1829 GtkTreePath *path = NULL; | |
1830 GtkTreeViewDropPosition position; | |
7712
2823111061ba
[gaim-migrate @ 8357]
Christian Hammond <chipx86@chipx86.com>
parents:
7706
diff
changeset
|
1831 GaimAccount *account; |
7706 | 1832 char *protocol = NULL; |
1833 char *username = NULL; | |
1834 char *alias = NULL; | |
1835 | |
1836 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
1837 x, y, &path, &position)) | |
1838 { | |
1839 GtkTreeIter iter; | |
1840 GaimBlistNode *node; | |
1841 GValue val = {0}; | |
1842 | |
1843 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
1844 &iter, path); | |
1845 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
1846 &iter, NODE_COLUMN, &val); | |
1847 node = g_value_get_pointer(&val); | |
1848 | |
1849 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
1850 { | |
1851 group = (GaimGroup *)node->parent->parent; | |
1852 } | |
1853 else if (GAIM_BLIST_NODE_IS_CHAT(node) || | |
1854 GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1855 { | |
1856 group = (GaimGroup *)node->parent; | |
1857 } | |
1858 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
1859 { | |
1860 group = (GaimGroup *)node; | |
1861 } | |
1862 } | |
1863 | |
11137 | 1864 if (gaim_gtk_parse_x_im_contact((const char *)sd->data, FALSE, &account, |
7712
2823111061ba
[gaim-migrate @ 8357]
Christian Hammond <chipx86@chipx86.com>
parents:
7706
diff
changeset
|
1865 &protocol, &username, &alias)) |
7706 | 1866 { |
1867 if (account == NULL) | |
1868 { | |
1869 gaim_notify_error(NULL, NULL, | |
1870 _("You are not currently signed on with an account that " | |
1871 "can add that buddy."), NULL); | |
1872 } | |
1873 else | |
1874 { | |
1875 gaim_blist_request_add_buddy(account, username, | |
1876 (group ? group->name : NULL), | |
1877 alias); | |
1878 } | |
1879 } | |
1880 | |
1881 if (username != NULL) g_free(username); | |
1882 if (protocol != NULL) g_free(protocol); | |
1883 if (alias != NULL) g_free(alias); | |
1884 | |
1885 if (path != NULL) | |
1886 gtk_tree_path_free(path); | |
1887 | |
1888 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); | |
1889 } | |
8089 | 1890 else if (sd->target == gdk_atom_intern("text/x-vcard", FALSE) && sd->data) |
1891 { | |
1892 gboolean result; | |
1893 GaimGroup *group = NULL; | |
1894 GtkTreePath *path = NULL; | |
1895 GtkTreeViewDropPosition position; | |
1896 | |
1897 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
1898 x, y, &path, &position)) | |
1899 { | |
1900 GtkTreeIter iter; | |
1901 GaimBlistNode *node; | |
1902 GValue val = {0}; | |
1903 | |
1904 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
1905 &iter, path); | |
1906 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
1907 &iter, NODE_COLUMN, &val); | |
1908 node = g_value_get_pointer(&val); | |
1909 | |
1910 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
1911 { | |
1912 group = (GaimGroup *)node->parent->parent; | |
1913 } | |
1914 else if (GAIM_BLIST_NODE_IS_CHAT(node) || | |
1915 GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1916 { | |
1917 group = (GaimGroup *)node->parent; | |
1918 } | |
1919 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
1920 { | |
1921 group = (GaimGroup *)node; | |
1922 } | |
1923 } | |
1924 | |
11137 | 1925 result = parse_vcard((const gchar *)sd->data, group); |
8089 | 1926 |
1927 gtk_drag_finish(dc, result, (dc->action == GDK_ACTION_MOVE), t); | |
9525 | 1928 } else if (sd->target == gdk_atom_intern("text/uri-list", FALSE) && sd->data) { |
9495 | 1929 GtkTreePath *path = NULL; |
1930 GtkTreeViewDropPosition position; | |
1931 | |
1932 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
9811 | 1933 x, y, &path, &position)) |
9495 | 1934 { |
1935 GtkTreeIter iter; | |
1936 GaimBlistNode *node; | |
1937 GValue val = {0}; | |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
1938 |
9495 | 1939 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), |
1940 &iter, path); | |
1941 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
1942 &iter, NODE_COLUMN, &val); | |
1943 node = g_value_get_pointer(&val); | |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
1944 |
9495 | 1945 if (GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CONTACT(node)) { |
1946 GaimBuddy *b = GAIM_BLIST_NODE_IS_BUDDY(node) ? (GaimBuddy*)node : gaim_contact_get_priority_buddy((GaimContact*)node); | |
10229 | 1947 gaim_dnd_file_manage(sd, b->account, b->name); |
1948 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); | |
1949 } else { | |
1950 gtk_drag_finish(dc, FALSE, FALSE, t); | |
9495 | 1951 } |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
1952 } |
8089 | 1953 } |
5228 | 1954 } |
1955 | |
10482 | 1956 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(GaimBlistNode *node, |
1957 gboolean scaled, gboolean greyed) | |
1958 { | |
10483 | 1959 GdkPixbuf *buf, *ret = NULL; |
10482 | 1960 GdkPixbufLoader *loader; |
1961 GaimBuddyIcon *icon; | |
11137 | 1962 const guchar *data; |
1963 gsize len; | |
10482 | 1964 GaimBuddy *buddy = (GaimBuddy *)node; |
1965 | |
1966 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
1967 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
1968 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1969 buddy = (GaimBuddy*)node; | |
1970 } else { | |
1971 return NULL; | |
1972 } | |
1973 | |
1974 #if 0 | |
1975 if (!gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) | |
1976 return NULL; | |
1977 #endif | |
1978 | |
1979 if (!(icon = gaim_buddy_get_icon(buddy))) | |
1980 if (!(icon = gaim_buddy_icons_find(buddy->account, buddy->name))) /* Not sure I like this...*/ | |
1981 return NULL; | |
1982 | |
1983 loader = gdk_pixbuf_loader_new(); | |
1984 data = gaim_buddy_icon_get_data(icon, &len); | |
1985 gdk_pixbuf_loader_write(loader, data, len, NULL); | |
1986 buf = gdk_pixbuf_loader_get_pixbuf(loader); | |
1987 if (buf) | |
1988 g_object_ref(G_OBJECT(buf)); | |
1989 gdk_pixbuf_loader_close(loader, NULL); | |
1990 g_object_unref(G_OBJECT(loader)); | |
1991 | |
1992 if (buf) { | |
10544 | 1993 GaimAccount *account = gaim_buddy_get_account(buddy); |
1994 GaimPluginProtocolInfo *prpl_info = NULL; | |
1995 int orig_width, orig_height; | |
1996 int scale_width, scale_height; | |
1997 | |
1998 if(account && account->gc) | |
1999 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(account->gc->prpl); | |
2000 | |
10482 | 2001 if (greyed) { |
2002 GaimPresence *presence = gaim_buddy_get_presence(buddy); | |
2003 if (!GAIM_BUDDY_IS_ONLINE(buddy)) | |
2004 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE); | |
2005 if (gaim_presence_is_idle(presence)) | |
2006 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE); | |
2007 } | |
2008 | |
10544 | 2009 /* i'd use the gaim_gtk_buddy_icon_get_scale_size() thing, |
2010 * but it won't tell me the original size, which I need for scaling | |
2011 * purposes */ | |
2012 scale_width = orig_width = gdk_pixbuf_get_width(buf); | |
2013 scale_height = orig_height = gdk_pixbuf_get_height(buf); | |
2014 | |
2015 gaim_buddy_icon_get_scale_size(prpl_info ? &prpl_info->icon_spec : NULL, &scale_width, &scale_height); | |
2016 | |
10482 | 2017 if (scaled) { |
10544 | 2018 if(scale_height > scale_width) { |
2019 scale_width = 30.0 * (double)scale_width / (double)scale_height; | |
2020 scale_height = 30; | |
2021 } else { | |
2022 scale_height = 30.0 * (double)scale_height / (double)scale_width; | |
2023 scale_width = 30; | |
2024 } | |
2025 | |
2026 ret = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 30, 30); | |
2027 gdk_pixbuf_fill(ret, 0x00000000); | |
2028 gdk_pixbuf_scale(buf, ret, (30-scale_width)/2, (30-scale_height)/2, scale_width, scale_height, (30-scale_width)/2, (30-scale_height)/2, (double)scale_width/(double)orig_width, (double)scale_height/(double)orig_height, GDK_INTERP_BILINEAR); | |
10483 | 2029 } else { |
2030 ret = gdk_pixbuf_scale_simple(buf,scale_width,scale_height, GDK_INTERP_BILINEAR); | |
2031 } | |
10544 | 2032 g_object_unref(G_OBJECT(buf)); |
10482 | 2033 } |
2034 | |
10483 | 2035 return ret; |
10482 | 2036 } |
2037 | |
11890 | 2038 struct tooltip_data { |
2039 PangoLayout *layout; | |
2040 GdkPixbuf *status_icon; | |
2041 GdkPixbuf *avatar; | |
11892 | 2042 int avatar_width; |
2043 int width; | |
2044 int height; | |
11890 | 2045 }; |
2046 | |
2047 static struct tooltip_data * create_tip_for_node(GaimBlistNode *node) | |
2048 { | |
2049 struct tooltip_data *td = g_new0(struct tooltip_data, 1); | |
2050 char *tooltip_text = gaim_get_tooltip_text(node); | |
2051 | |
2052 td->status_icon = gaim_gtk_blist_get_status_icon(node, GAIM_STATUS_ICON_LARGE); | |
2053 td->avatar = gaim_gtk_blist_get_buddy_icon(node, FALSE, FALSE); | |
2054 | |
2055 td->layout = gtk_widget_create_pango_layout(gtkblist->tipwindow, NULL); | |
2056 pango_layout_set_markup(td->layout, tooltip_text, strlen(tooltip_text)); | |
2057 pango_layout_set_wrap(td->layout, PANGO_WRAP_WORD); | |
2058 pango_layout_set_width(td->layout, 300000); | |
11983 | 2059 |
11892 | 2060 pango_layout_get_size (td->layout, &td->width, &td->height); |
2061 td->width = PANGO_PIXELS(td->width) + 38 + 8; | |
2062 td->height = MAX(PANGO_PIXELS(td->height) + 8, 38); | |
2063 | |
2064 if(td->avatar) { | |
2065 td->avatar_width = gdk_pixbuf_get_width(td->avatar); | |
2066 td->width += td->avatar_width + 8; | |
2067 td->height = MAX(td->height, gdk_pixbuf_get_height(td->avatar) + 8); | |
2068 } | |
11890 | 2069 |
2070 return td; | |
2071 } | |
2072 | |
5234 | 2073 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, GaimBlistNode *node) |
5228 | 2074 { |
2075 GtkStyle *style; | |
11892 | 2076 int current_height, max_width; |
11890 | 2077 GList *l; |
2078 | |
2079 if(gtkblist->tooltipdata == NULL) | |
7620 | 2080 return; |
2081 | |
11890 | 2082 style = gtkblist->tipwindow->style; |
2083 gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, | |
2084 NULL, gtkblist->tipwindow, "tooltip", 0, 0, -1, -1); | |
2085 | |
11892 | 2086 max_width = 0; |
2087 for(l = gtkblist->tooltipdata; l; l = l->next) | |
2088 { | |
2089 struct tooltip_data *td = l->data; | |
2090 max_width = MAX(max_width, td->width); | |
2091 } | |
2092 | |
11890 | 2093 current_height = 0; |
2094 for(l = gtkblist->tooltipdata; l; l = l->next) | |
10482 | 2095 { |
11890 | 2096 struct tooltip_data *td = l->data; |
5228 | 2097 |
2098 #if GTK_CHECK_VERSION(2,2,0) | |
11890 | 2099 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, |
2100 0, 0, 4, current_height + 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); | |
2101 if(td->avatar) | |
2102 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, | |
11892 | 2103 td->avatar, 0, 0, max_width - (td->avatar_width + 4), current_height + 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); |
5228 | 2104 #else |
11890 | 2105 gdk_pixbuf_render_to_drawable(td->status_icon, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 4, current_height + 4, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); |
2106 if(td->avatar) | |
2107 gdk_pixbuf_render_to_drawable(td->avatar, | |
11983 | 2108 GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, |
11892 | 2109 max_width - (td->avatar_width + 4), |
11890 | 2110 current_height + 4, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); |
5228 | 2111 #endif |
2112 | |
11890 | 2113 gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, FALSE, |
2114 NULL, gtkblist->tipwindow, "tooltip", 38 + 4, current_height + 4, td->layout); | |
2115 | |
11895 | 2116 current_height += td->height; |
2117 | |
11894 | 2118 if(l->next) |
11895 | 2119 gtk_paint_hline(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, NULL, NULL, NULL, 4, max_width - 4, current_height-2); |
11890 | 2120 } |
5228 | 2121 } |
2122 | |
8254 | 2123 static void gaim_gtk_blist_tooltip_destroy() |
2124 { | |
11890 | 2125 while(gtkblist->tooltipdata) { |
2126 struct tooltip_data *td = gtkblist->tooltipdata->data; | |
2127 | |
2128 if(td->avatar) | |
2129 g_object_unref(td->avatar); | |
2130 if(td->status_icon) | |
2131 g_object_unref(td->status_icon); | |
2132 g_object_unref(td->layout); | |
2133 g_free(td); | |
2134 gtkblist->tooltipdata = g_list_delete_link(gtkblist->tooltipdata, gtkblist->tooltipdata); | |
2135 } | |
11636 | 2136 |
8254 | 2137 if (gtkblist->tipwindow == NULL) |
2138 return; | |
2139 | |
2140 gtk_widget_destroy(gtkblist->tipwindow); | |
2141 gtkblist->tipwindow = NULL; | |
2142 } | |
2143 | |
10354 | 2144 static gboolean gaim_gtk_blist_expand_timeout(GtkWidget *tv) |
2145 { | |
2146 GtkTreePath *path; | |
2147 GtkTreeIter iter; | |
2148 GaimBlistNode *node; | |
2149 GValue val = {0}; | |
2150 struct _gaim_gtk_blist_node *gtknode; | |
2151 | |
2152 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->tip_rect.x, gtkblist->tip_rect.y, &path, NULL, NULL, NULL)) | |
2153 return FALSE; | |
2154 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
2155 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
2156 node = g_value_get_pointer(&val); | |
2157 | |
10504 | 2158 if(!GAIM_BLIST_NODE_IS_CONTACT(node)) { |
2159 gtk_tree_path_free(path); | |
10354 | 2160 return FALSE; |
10504 | 2161 } |
10354 | 2162 |
2163 gtknode = node->ui_data; | |
2164 | |
2165 if (!gtknode->contact_expanded) { | |
2166 GtkTreeIter i; | |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
2167 |
10354 | 2168 gaim_gtk_blist_expand_contact_cb(NULL, node); |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
2169 |
10354 | 2170 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->contact_rect); |
2171 gdk_drawable_get_size(GDK_DRAWABLE(tv->window), &(gtkblist->contact_rect.width), NULL); | |
2172 gtkblist->mouseover_contact = node; | |
2173 gtk_tree_path_down (path); | |
2174 while (gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &i, path)) { | |
2175 GdkRectangle rect; | |
2176 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, &rect); | |
2177 gtkblist->contact_rect.height += rect.height; | |
2178 gtk_tree_path_next(path); | |
2179 } | |
2180 } | |
2181 gtk_tree_path_free(path); | |
2182 return FALSE; | |
2183 } | |
2184 | |
11890 | 2185 static gboolean buddy_is_displayable(GaimBuddy *buddy) |
2186 { | |
11910 | 2187 struct _gaim_gtk_blist_node *gtknode; |
2188 | |
2189 if(!buddy) | |
2190 return FALSE; | |
2191 | |
2192 gtknode = ((GaimBlistNode*)buddy)->ui_data; | |
2193 | |
2194 return (gaim_account_is_connected(buddy->account) && | |
11890 | 2195 (gaim_presence_is_online(buddy->presence) || |
11910 | 2196 (gtknode && gtknode->recent_signonoff) || |
2197 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies") || | |
2198 gaim_blist_node_get_bool((GaimBlistNode*)buddy, "show_offline"))); | |
11890 | 2199 } |
2200 | |
5228 | 2201 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv) |
2202 { | |
2203 GtkTreePath *path; | |
2204 GtkTreeIter iter; | |
2205 GaimBlistNode *node; | |
2206 GValue val = {0}; | |
9869 | 2207 int scr_w, scr_h, w, h, x, y; |
2208 #if GTK_CHECK_VERSION(2,2,0) | |
2209 int mon_num; | |
2210 GdkScreen *screen = NULL; | |
2211 #endif | |
7636 | 2212 gboolean tooltip_top = FALSE; |
2213 struct _gaim_gtk_blist_node *gtknode; | |
9773 | 2214 GdkRectangle mon_size; |
5228 | 2215 |
11636 | 2216 /* |
2217 * Attempt to free the previous tooltip. I have a feeling | |
2218 * this is never needed... but just in case. | |
2219 */ | |
2220 gaim_gtk_blist_tooltip_destroy(); | |
2221 | |
7636 | 2222 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->tip_rect.x, gtkblist->tip_rect.y, &path, NULL, NULL, NULL)) |
5228 | 2223 return FALSE; |
2224 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
2225 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
2226 node = g_value_get_pointer(&val); | |
7620 | 2227 |
10504 | 2228 gtk_tree_path_free(path); |
2229 | |
11890 | 2230 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP); |
2231 | |
2232 if(GAIM_BLIST_NODE_IS_CHAT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
2233 struct tooltip_data *td = create_tip_for_node(node); | |
2234 gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td); | |
11892 | 2235 w = td->width; |
2236 h = td->height; | |
11890 | 2237 } else if(GAIM_BLIST_NODE_IS_CONTACT(node)) { |
2238 GaimBlistNode *child; | |
11988 | 2239 GaimBuddy *b = gaim_contact_get_priority_buddy((GaimContact *)node); |
11890 | 2240 w = h = 0; |
2241 for(child = node->child; child; child = child->next) | |
2242 { | |
2243 if(GAIM_BLIST_NODE_IS_BUDDY(child) && buddy_is_displayable((GaimBuddy*)child)) { | |
2244 struct tooltip_data *td = create_tip_for_node(child); | |
11988 | 2245 if (b == (GaimBuddy *)child) { |
2246 gtkblist->tooltipdata = g_list_prepend(gtkblist->tooltipdata, td); | |
2247 } else { | |
2248 gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td); | |
2249 } | |
11892 | 2250 w = MAX(w, td->width); |
2251 h += td->height; | |
11890 | 2252 } |
2253 } | |
2254 } else { | |
2255 gtk_widget_destroy(gtkblist->tipwindow); | |
11892 | 2256 gtkblist->tipwindow = NULL; |
5234 | 2257 return FALSE; |
11890 | 2258 } |
2259 | |
2260 if (gtkblist->tooltipdata == NULL) { | |
2261 gtk_widget_destroy(gtkblist->tipwindow); | |
11892 | 2262 gtkblist->tipwindow = NULL; |
11890 | 2263 return FALSE; |
2264 } | |
5228 | 2265 |
7636 | 2266 gtknode = node->ui_data; |
2267 | |
5234 | 2268 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); |
2269 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); | |
2270 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); | |
2271 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", | |
11890 | 2272 G_CALLBACK(gaim_gtk_blist_paint_tip), NULL); |
5234 | 2273 gtk_widget_ensure_style (gtkblist->tipwindow); |
7837 | 2274 |
9773 | 2275 |
9869 | 2276 #if GTK_CHECK_VERSION(2,2,0) |
9773 | 2277 gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, NULL); |
2278 mon_num = gdk_screen_get_monitor_at_point(screen, x, y); | |
2279 gdk_screen_get_monitor_geometry(screen, mon_num, &mon_size); | |
2280 | |
2281 scr_w = mon_size.width + mon_size.x; | |
2282 scr_h = mon_size.height + mon_size.y; | |
9869 | 2283 #else |
2284 scr_w = gdk_screen_width(); | |
2285 scr_h = gdk_screen_height(); | |
2286 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
2287 mon_size.x = 0; | |
2288 mon_size.y = 0; | |
2289 #endif | |
9773 | 2290 |
9869 | 2291 #if GTK_CHECK_VERSION(2,2,0) |
10046 | 2292 if (w > mon_size.width) |
9773 | 2293 w = mon_size.width - 10; |
2294 | |
10046 | 2295 if (h > mon_size.height) |
9773 | 2296 h = mon_size.height - 10; |
9869 | 2297 #endif |
9773 | 2298 |
5234 | 2299 if (GTK_WIDGET_NO_WINDOW(gtkblist->window)) |
2300 y+=gtkblist->window->allocation.y; | |
2301 | |
2302 x -= ((w >> 1) + 4); | |
5228 | 2303 |
7636 | 2304 if ((y + h + 4) > scr_h || tooltip_top) |
7620 | 2305 y = y - h - 5; |
5234 | 2306 else |
2307 y = y + 6; | |
7620 | 2308 |
9773 | 2309 if (y < mon_size.y) |
2310 y = mon_size.y; | |
2311 | |
2312 if (y != mon_size.y) { | |
7719 | 2313 if ((x + w) > scr_w) |
2314 x -= (x + w + 5) - scr_w; | |
9773 | 2315 else if (x < mon_size.x) |
2316 x = mon_size.x; | |
7719 | 2317 } else { |
2318 x -= (w / 2 + 10); | |
9773 | 2319 if (x < mon_size.x) |
2320 x = mon_size.x; | |
7719 | 2321 } |
2322 | |
5234 | 2323 gtk_widget_set_size_request(gtkblist->tipwindow, w, h); |
2324 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y); | |
2325 gtk_widget_show(gtkblist->tipwindow); | |
5228 | 2326 |
2327 return FALSE; | |
2328 } | |
2329 | |
10354 | 2330 static gboolean gaim_gtk_blist_drag_motion_cb(GtkWidget *tv, GdkDragContext *drag_context, |
2331 gint x, gint y, guint time, gpointer user_data) | |
2332 { | |
2333 GtkTreePath *path; | |
2334 int delay; | |
2335 | |
2336 delay = 500; | |
2337 | |
2338 if (gtkblist->drag_timeout) { | |
2339 if ((y > gtkblist->tip_rect.y) && ((y - gtkblist->tip_rect.height) < gtkblist->tip_rect.y)) | |
2340 return FALSE; | |
2341 /* We've left the cell. Remove the timeout and create a new one below */ | |
2342 g_source_remove(gtkblist->drag_timeout); | |
2343 } | |
2344 | |
2345 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), x, y, &path, NULL, NULL, NULL); | |
2346 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->tip_rect); | |
2347 | |
2348 if (path) | |
2349 gtk_tree_path_free(path); | |
2350 gtkblist->drag_timeout = g_timeout_add(delay, (GSourceFunc)gaim_gtk_blist_expand_timeout, tv); | |
2351 | |
2352 if (gtkblist->mouseover_contact) { | |
2353 if ((y < gtkblist->contact_rect.y) || ((y - gtkblist->contact_rect.height) > gtkblist->contact_rect.y)) { | |
2354 gaim_gtk_blist_collapse_contact_cb(NULL, gtkblist->mouseover_contact); | |
2355 gtkblist->mouseover_contact = NULL; | |
2356 } | |
2357 } | |
2358 | |
2359 return FALSE; | |
2360 } | |
2361 | |
5228 | 2362 static gboolean gaim_gtk_blist_motion_cb (GtkWidget *tv, GdkEventMotion *event, gpointer null) |
2363 { | |
2364 GtkTreePath *path; | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2365 int delay; |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2366 |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2367 delay = gaim_prefs_get_int("/gaim/gtk/blist/tooltip_delay"); |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2368 |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2369 if (delay == 0) |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2370 return FALSE; |
8083 | 2371 |
5228 | 2372 if (gtkblist->timeout) { |
7636 | 2373 if ((event->y > gtkblist->tip_rect.y) && ((event->y - gtkblist->tip_rect.height) < gtkblist->tip_rect.y)) |
5228 | 2374 return FALSE; |
2375 /* We've left the cell. Remove the timeout and create a new one below */ | |
8254 | 2376 gaim_gtk_blist_tooltip_destroy(); |
5228 | 2377 g_source_remove(gtkblist->timeout); |
2378 } | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2379 |
5228 | 2380 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL); |
7636 | 2381 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->tip_rect); |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2382 |
5228 | 2383 if (path) |
2384 gtk_tree_path_free(path); | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2385 gtkblist->timeout = g_timeout_add(delay, (GSourceFunc)gaim_gtk_blist_tooltip_timeout, tv); |
7636 | 2386 |
2387 if (gtkblist->mouseover_contact) { | |
2388 if ((event->y < gtkblist->contact_rect.y) || ((event->y - gtkblist->contact_rect.height) > gtkblist->contact_rect.y)) { | |
2389 gaim_gtk_blist_collapse_contact_cb(NULL, gtkblist->mouseover_contact); | |
2390 gtkblist->mouseover_contact = NULL; | |
2391 } | |
2392 } | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2393 |
5228 | 2394 return FALSE; |
2395 } | |
2396 | |
2397 static void gaim_gtk_blist_leave_cb (GtkWidget *w, GdkEventCrossing *e, gpointer n) | |
2398 { | |
8083 | 2399 |
5228 | 2400 if (gtkblist->timeout) { |
2401 g_source_remove(gtkblist->timeout); | |
2402 gtkblist->timeout = 0; | |
2403 } | |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10357
diff
changeset
|
2404 |
10354 | 2405 if (gtkblist->drag_timeout) { |
2406 g_source_remove(gtkblist->drag_timeout); | |
2407 gtkblist->drag_timeout = 0; | |
2408 } | |
2409 | |
8254 | 2410 gaim_gtk_blist_tooltip_destroy(); |
7720 | 2411 |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2412 if (gtkblist->mouseover_contact && |
9811 | 2413 !((e->x > gtkblist->contact_rect.x) && (e->x < (gtkblist->contact_rect.x + gtkblist->contact_rect.width)) && |
2414 (e->y > gtkblist->contact_rect.y) && (e->y < (gtkblist->contact_rect.y + gtkblist->contact_rect.height)))) { | |
2415 gaim_gtk_blist_collapse_contact_cb(NULL, gtkblist->mouseover_contact); | |
7636 | 2416 gtkblist->mouseover_contact = NULL; |
2417 } | |
5228 | 2418 } |
2419 | |
2420 static void | |
2421 toggle_debug(void) | |
2422 { | |
7620 | 2423 gaim_prefs_set_bool("/gaim/gtk/debug/enabled", |
2424 !gaim_prefs_get_bool("/gaim/gtk/debug/enabled")); | |
5228 | 2425 } |
2426 | |
2427 | |
2428 /*************************************************** | |
2429 * Crap * | |
2430 ***************************************************/ | |
2431 static GtkItemFactoryEntry blist_menu[] = | |
2432 { | |
2433 /* Buddies menu */ | |
2434 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, | |
9714 | 2435 { N_("/Buddies/New Instant _Message..."), "<CTL>M", gaim_gtkdialogs_im, 0, "<StockItem>", GAIM_STOCK_IM }, |
8940 | 2436 { N_("/Buddies/Join a _Chat..."), "<CTL>C", gaim_gtk_blist_joinchat_show, 0, "<StockItem>", GAIM_STOCK_CHAT }, |
9714 | 2437 { N_("/Buddies/Get User _Info..."), "<CTL>I", gaim_gtkdialogs_info, 0, "<StockItem>", GAIM_STOCK_INFO }, |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
2438 { N_("/Buddies/View User _Log..."), "<CTL>L", gaim_gtkdialogs_log, 0, "<StockItem>", GAIM_STOCK_LOG }, |
5228 | 2439 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" }, |
11025 | 2440 { N_("/Buddies/Show _Offline Buddies"), NULL, gaim_gtk_blist_edit_mode_cb, 1, "<CheckItem>"}, |
2441 { N_("/Buddies/Show _Empty Groups"), NULL, gaim_gtk_blist_show_empty_groups_cb, 1, "<CheckItem>"}, | |
11796 | 2442 { N_("/Buddies/Show Buddy _Details"), NULL, gaim_gtk_blist_buddy_details_cb, 1, "<CheckItem>"}, |
11798
01c3eec6ea3c
[gaim-migrate @ 14089]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11797
diff
changeset
|
2443 { N_("/Buddies/Sort Buddies"), NULL, NULL, 0, "<Branch>" }, |
11796 | 2444 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" }, |
7853 | 2445 { N_("/Buddies/_Add Buddy..."), "<CTL>B", gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD }, |
2446 { N_("/Buddies/Add C_hat..."), NULL, gaim_gtk_blist_add_chat_cb, 0, "<StockItem>", GTK_STOCK_ADD }, | |
2447 { N_("/Buddies/Add _Group..."), NULL, gaim_blist_request_add_group, 0, "<StockItem>", GTK_STOCK_ADD }, | |
11796 | 2448 { "/Buddies/sep3", NULL, NULL, 0, "<Separator>" }, |
7620 | 2449 { N_("/Buddies/_Quit"), "<CTL>Q", gaim_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT }, |
5228 | 2450 |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2451 /* Tools */ |
5228 | 2452 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
2453 { N_("/Tools/Account Ac_tions"), NULL, NULL, 0, "<StockItem>", GAIM_STOCK_ACTION }, |
5228 | 2454 { "/Tools/sep1", NULL, NULL, 0, "<Separator>" }, |
7620 | 2455 { N_("/Tools/A_ccounts"), "<CTL>A", gaim_gtk_accounts_window_show, 0, "<StockItem>", GAIM_STOCK_ACCOUNTS }, |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
2456 { N_("/Tools/Buddy _Pounces"), NULL, gaim_gtk_pounces_manager_show, 0, "<StockItem>", GAIM_STOCK_POUNCE }, |
12163
f6f08fd1841a
[gaim-migrate @ 14464]
Richard Laager <rlaager@wiktel.com>
parents:
12136
diff
changeset
|
2457 { N_("/Tools/Plu_gins"), "<CTL>U", gaim_gtk_plugin_dialog_show, 0, "<StockItem>", GAIM_STOCK_PLUGIN }, |
12136
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
2458 { N_("/Tools/Pr_eferences"), "<CTL>P", gaim_gtk_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES }, |
10694 | 2459 { N_("/Tools/Pr_ivacy"), NULL, gaim_gtk_privacy_dialog_show, 0, "<StockItem>", GTK_STOCK_DIALOG_ERROR }, |
12136
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
2460 { "/Tools/sep2", NULL, NULL, 0, "<Separator>" }, |
10019
8cc6f0bfa215
[gaim-migrate @ 10943]
Luke Schierer <lschiere@pidgin.im>
parents:
10018
diff
changeset
|
2461 { N_("/Tools/_File Transfers"), "<CTL>T", gaim_show_xfer_dialog, 0, "<StockItem>", GAIM_STOCK_FILE_TRANSFER }, |
10694 | 2462 { N_("/Tools/R_oom List"), NULL, gaim_gtk_roomlist_dialog_show, 0, "<StockItem>", GTK_STOCK_INDEX }, |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
2463 { N_("/Tools/View System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, "<StockItem>", GAIM_STOCK_LOG }, |
12136
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
2464 { "/Tools/sep3", NULL, NULL, 0, "<Separator>" }, |
10074 | 2465 { N_("/Tools/Mute _Sounds"), "<CTL>S", gaim_gtk_blist_mute_sounds_cb, 0, "<CheckItem>"}, |
5228 | 2466 |
2467 /* Help */ | |
2468 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, | |
2469 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP }, | |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
2470 { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, "<StockItem>", GAIM_STOCK_DEBUG }, |
9753 | 2471 { N_("/Help/_About"), NULL, gaim_gtkdialogs_about, 0, "<StockItem>", GAIM_STOCK_ABOUT }, |
5228 | 2472 }; |
2473 | |
2474 /********************************************************* | |
2475 * Private Utility functions * | |
2476 *********************************************************/ | |
2477 | |
5234 | 2478 static char *gaim_get_tooltip_text(GaimBlistNode *node) |
5228 | 2479 { |
10475 | 2480 GString *str = g_string_new(""); |
5237 | 2481 GaimPlugin *prpl; |
2482 GaimPluginProtocolInfo *prpl_info = NULL; | |
10475 | 2483 char *tmp; |
2484 | |
2485 if (GAIM_BLIST_NODE_IS_CHAT(node)) | |
2486 { | |
2487 GaimChat *chat; | |
2488 GList *cur; | |
5274 | 2489 struct proto_chat_entry *pce; |
10475 | 2490 char *name, *value; |
2491 | |
2492 chat = (GaimChat *)node; | |
7956 | 2493 prpl = gaim_find_prpl(gaim_account_get_protocol_id(chat->account)); |
5274 | 2494 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
2495 | |
10475 | 2496 tmp = g_markup_escape_text(gaim_chat_get_name(chat), -1); |
2497 g_string_append_printf(str, "<span size='larger' weight='bold'>%s</span>", tmp); | |
2498 g_free(tmp); | |
2499 | |
2500 if (g_list_length(gaim_connections_get_all()) > 1) | |
2501 { | |
2502 tmp = g_markup_escape_text(chat->account->username, -1); | |
2503 g_string_append_printf(str, _("\n<b>Account:</b> %s"), tmp); | |
2504 g_free(tmp); | |
2505 } | |
2506 | |
9959 | 2507 if (prpl_info->chat_info != NULL) |
10475 | 2508 cur = prpl_info->chat_info(chat->account->gc); |
2509 else | |
2510 cur = NULL; | |
2511 | |
2512 while (cur != NULL) | |
2513 { | |
2514 pce = cur->data; | |
2515 | |
2516 if (!pce->secret && (!pce->required && | |
2517 g_hash_table_lookup(chat->components, pce->identifier) == NULL)) | |
2518 { | |
2519 tmp = gaim_text_strip_mnemonic(pce->label); | |
2520 name = g_markup_escape_text(tmp, -1); | |
2521 g_free(tmp); | |
2522 value = g_markup_escape_text(g_hash_table_lookup( | |
2523 chat->components, pce->identifier), -1); | |
10924
7a82d86ab44a
[gaim-migrate @ 12695]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10918
diff
changeset
|
2524 g_string_append_printf(str, "\n<b>%s</b> %s", |
7a82d86ab44a
[gaim-migrate @ 12695]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10918
diff
changeset
|
2525 name ? name : "", |
7a82d86ab44a
[gaim-migrate @ 12695]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10918
diff
changeset
|
2526 value ? value : ""); |
10475 | 2527 g_free(name); |
8020 | 2528 g_free(value); |
2529 } | |
10475 | 2530 |
5274 | 2531 g_free(pce); |
10475 | 2532 cur = g_list_remove(cur, pce); |
5274 | 2533 } |
10475 | 2534 } |
2535 else if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) | |
2536 { | |
2537 GaimContact *c; | |
7620 | 2538 GaimBuddy *b; |
9944 | 2539 GaimPresence *presence; |
10475 | 2540 char *tmp; |
9944 | 2541 gboolean idle; |
10567 | 2542 time_t idle_secs, signon; |
10475 | 2543 |
2544 if (GAIM_BLIST_NODE_IS_CONTACT(node)) | |
2545 { | |
2546 c = (GaimContact *)node; | |
2547 b = gaim_contact_get_priority_buddy(c); | |
2548 } | |
2549 else | |
2550 { | |
7620 | 2551 b = (GaimBuddy *)node; |
10475 | 2552 c = gaim_buddy_get_contact(b); |
7620 | 2553 } |
2554 | |
7956 | 2555 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
5234 | 2556 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
2557 | |
10475 | 2558 presence = gaim_buddy_get_presence(b); |
2559 | |
2560 /* Buddy Name */ | |
2561 tmp = g_markup_escape_text(gaim_buddy_get_name(b), -1); | |
2562 g_string_append_printf(str, "<span size='larger' weight='bold'>%s</span>", tmp); | |
2563 g_free(tmp); | |
2564 | |
2565 /* Account */ | |
2566 if (g_list_length(gaim_connections_get_all()) > 1) | |
2567 { | |
2568 tmp = g_markup_escape_text(gaim_account_get_username( | |
2569 gaim_buddy_get_account(b)), -1); | |
2570 g_string_append_printf(str, _("\n<b>Account:</b> %s"), tmp); | |
2571 g_free(tmp); | |
2572 } | |
2573 | |
2574 /* Contact Alias */ | |
2575 if (GAIM_BLIST_NODE_IS_CONTACT(node) && | |
10499 | 2576 (c->alias != NULL)) |
10475 | 2577 { |
10499 | 2578 tmp = g_markup_escape_text(c->alias, -1); |
10475 | 2579 g_string_append_printf(str, _("\n<b>Contact Alias:</b> %s"), tmp); |
2580 g_free(tmp); | |
2581 } | |
2582 | |
2583 /* Alias */ | |
2584 if ((b->alias != NULL) && (b->alias[0] != '\0')) | |
2585 { | |
2586 tmp = g_markup_escape_text(b->alias, -1); | |
2587 g_string_append_printf(str, _("\n<b>Alias:</b> %s"), tmp); | |
2588 g_free(tmp); | |
2589 } | |
2590 | |
2591 /* Nickname/Server Alias */ | |
2592 if (b->server_alias != NULL) | |
2593 { | |
2594 tmp = g_markup_escape_text(b->server_alias, -1); | |
2595 g_string_append_printf(str, _("\n<b>Nickname:</b> %s"), tmp); | |
2596 g_free(tmp); | |
2597 } | |
2598 | |
2599 /* Logged In */ | |
10567 | 2600 signon = gaim_presence_get_login_time(presence); |
10992
2bda44d66641
[gaim-migrate @ 12830]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10968
diff
changeset
|
2601 if (GAIM_BUDDY_IS_ONLINE(b) && signon > 0) |
10475 | 2602 { |
10567 | 2603 tmp = gaim_str_seconds_to_string(time(NULL) - signon); |
10475 | 2604 g_string_append_printf(str, _("\n<b>Logged In:</b> %s"), tmp); |
2605 g_free(tmp); | |
2606 } | |
2607 | |
2608 /* Idle */ | |
2609 idle = gaim_presence_is_idle(presence); | |
2610 if (idle) | |
2611 { | |
2612 idle_secs = gaim_presence_get_idle_time(presence); | |
2613 if (idle_secs > 0) | |
2614 { | |
2615 tmp = gaim_str_seconds_to_string(time(NULL) - idle_secs); | |
2616 g_string_append_printf(str, _("\n<b>Idle:</b> %s"), tmp); | |
2617 g_free(tmp); | |
2618 } | |
2619 } | |
2620 | |
2621 /* Last Seen */ | |
11910 | 2622 if (!GAIM_BUDDY_IS_ONLINE(b)) |
10475 | 2623 { |
11023 | 2624 struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode *)c)->ui_data; |
2625 GaimBlistNode *bnode; | |
2626 int lastseen = 0; | |
2627 | |
2628 if (!gtknode->contact_expanded || GAIM_BLIST_NODE_IS_CONTACT(node)) | |
2629 { | |
11437
1c20849fc716
[gaim-migrate @ 13674]
Richard Laager <rlaager@wiktel.com>
parents:
11436
diff
changeset
|
2630 /* We're either looking at a buddy for a collapsed contact or |
11438
5451fe2d89c0
[gaim-migrate @ 13675]
Richard Laager <rlaager@wiktel.com>
parents:
11437
diff
changeset
|
2631 * an expanded contact itself so we show the most recent |
11023 | 2632 * (largest) last_seen time for any of the buddies under |
2633 * the contact. */ | |
2634 for (bnode = ((GaimBlistNode *)c)->child ; bnode != NULL ; bnode = bnode->next) | |
2635 { | |
2636 int value = gaim_blist_node_get_int(bnode, "last_seen"); | |
2637 if (value > lastseen) | |
2638 lastseen = value; | |
2639 } | |
2640 } | |
2641 else | |
2642 { | |
2643 /* We're dealing with a buddy under an expanded contact, | |
2644 * so we show the last_seen time for the buddy. */ | |
2645 lastseen = gaim_blist_node_get_int(&b->node, "last_seen"); | |
2646 } | |
2647 | |
10475 | 2648 if (lastseen > 0) |
2649 { | |
2650 tmp = gaim_str_seconds_to_string(time(NULL) - lastseen); | |
2651 g_string_append_printf(str, _("\n<b>Last Seen:</b> %s ago"), tmp); | |
2652 g_free(tmp); | |
5234 | 2653 } |
2654 } | |
2655 | |
10475 | 2656 |
2657 /* Offline? */ | |
2658 if (!GAIM_BUDDY_IS_ONLINE(b)) { | |
2659 g_string_append_printf(str, _("\n<b>Status:</b> Offline")); | |
2660 } | |
10992
2bda44d66641
[gaim-migrate @ 12830]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10968
diff
changeset
|
2661 |
2bda44d66641
[gaim-migrate @ 12830]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10968
diff
changeset
|
2662 if (prpl_info && prpl_info->tooltip_text) |
10475 | 2663 { |
2664 /* Additional text from the PRPL */ | |
2665 const char *end; | |
2666 tmp = prpl_info->tooltip_text(b); | |
2667 | |
2668 if (tmp && !g_utf8_validate(tmp, -1, &end)) | |
2669 { | |
2670 char *new = g_strndup(tmp, g_utf8_pointer_to_offset(tmp, end)); | |
2671 g_free(tmp); | |
2672 tmp = new; | |
2673 } | |
2674 | |
11634 | 2675 if (tmp != NULL) |
2676 g_string_append(str, tmp); | |
10476 | 2677 g_free(tmp); |
10475 | 2678 } |
2679 | |
2680 /* These are Easter Eggs. Patches to remove them will be rejected. */ | |
2681 if (!g_ascii_strcasecmp(b->name, "robflynn")) | |
2682 g_string_append(str, _("\n<b>Description:</b> Spooky")); | |
2683 if (!g_ascii_strcasecmp(b->name, "seanegn")) | |
2684 g_string_append(str, _("\n<b>Status:</b> Awesome")); | |
2685 if (!g_ascii_strcasecmp(b->name, "chipx86")) | |
2686 g_string_append(str, _("\n<b>Status:</b> Rockin'")); | |
5234 | 2687 } |
10475 | 2688 |
8824 | 2689 gaim_signal_emit(gaim_gtk_blist_get_handle(), |
10477 | 2690 "drawing-tooltip", node, str); |
10475 | 2691 |
2692 return g_string_free(str, FALSE); | |
5228 | 2693 } |
2694 | |
7620 | 2695 struct _emblem_data { |
9954 | 2696 const char *filename; |
7620 | 2697 int x; |
2698 int y; | |
2699 }; | |
2700 | |
9944 | 2701 GdkPixbuf * |
2702 gaim_gtk_blist_get_status_icon(GaimBlistNode *node, GaimStatusIconSize size) | |
5228 | 2703 { |
7620 | 2704 GdkPixbuf *scale, *status = NULL; |
2705 int i, scalesize = 30; | |
2706 char *filename; | |
5228 | 2707 const char *protoname = NULL; |
7620 | 2708 struct _gaim_gtk_blist_node *gtknode = node->ui_data; |
11910 | 2709 struct _gaim_gtk_blist_node *gtkbuddynode = NULL; |
7620 | 2710 struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15}, |
2711 {NULL, 0, 0}, {NULL, 15, 0}}; | |
9944 | 2712 GaimPresence *presence = NULL; |
7620 | 2713 GaimBuddy *buddy = NULL; |
2714 GaimChat *chat = NULL; | |
2715 | |
2716 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
11910 | 2717 if(!gtknode->contact_expanded) { |
7620 | 2718 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); |
11910 | 2719 gtkbuddynode = ((GaimBlistNode*)buddy)->ui_data; |
2720 } | |
7620 | 2721 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
2722 buddy = (GaimBuddy*)node; | |
11910 | 2723 gtkbuddynode = node->ui_data; |
7620 | 2724 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { |
2725 chat = (GaimChat*)node; | |
2726 } else { | |
5228 | 2727 return NULL; |
5234 | 2728 } |
2729 | |
7620 | 2730 if(buddy || chat) { |
2731 GaimAccount *account; | |
2732 GaimPlugin *prpl; | |
2733 GaimPluginProtocolInfo *prpl_info; | |
2734 | |
2735 if(buddy) | |
2736 account = buddy->account; | |
2737 else | |
2738 account = chat->account; | |
2739 | |
7956 | 2740 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
7620 | 2741 if(!prpl) |
2742 return NULL; | |
2743 | |
2744 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
2745 | |
2746 if(prpl_info && prpl_info->list_icon) { | |
2747 protoname = prpl_info->list_icon(account, buddy); | |
2748 } | |
2749 if(prpl_info && prpl_info->list_emblems && buddy) { | |
11924 | 2750 if(gtknode && !gtknode->recent_signonoff) |
7620 | 2751 prpl_info->list_emblems(buddy, &emblems[0].filename, |
2752 &emblems[1].filename, &emblems[2].filename, | |
2753 &emblems[3].filename); | |
2754 } | |
5234 | 2755 } |
5228 | 2756 |
7620 | 2757 if(size == GAIM_STATUS_ICON_SMALL) { |
5228 | 2758 scalesize = 15; |
7620 | 2759 /* So that only the se icon will composite */ |
2760 emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL; | |
5228 | 2761 } |
2762 | |
11917 | 2763 if(buddy && GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { |
7620 | 2764 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); |
11917 | 2765 } else if(buddy && !GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { |
7620 | 2766 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL); |
2767 } else if(buddy || chat) { | |
5228 | 2768 char *image = g_strdup_printf("%s.png", protoname); |
2769 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
2770 g_free(image); | |
7620 | 2771 } else { |
2772 /* gaim dude */ | |
2773 filename = g_build_filename(DATADIR, "pixmaps", "gaim.png", NULL); | |
5228 | 2774 } |
7620 | 2775 |
2776 status = gdk_pixbuf_new_from_file(filename, NULL); | |
2777 g_free(filename); | |
2778 | |
2779 if(!status) | |
2780 return NULL; | |
2781 | |
2782 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, | |
2783 GDK_INTERP_BILINEAR); | |
2784 g_object_unref(status); | |
2785 | |
2786 for(i=0; i<4; i++) { | |
2787 if(emblems[i].filename) { | |
2788 GdkPixbuf *emblem; | |
2789 char *image = g_strdup_printf("%s.png", emblems[i].filename); | |
2790 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
2791 g_free(image); | |
2792 emblem = gdk_pixbuf_new_from_file(filename, NULL); | |
2793 g_free(filename); | |
2794 if(emblem) { | |
2795 if(i == 0 && size == GAIM_STATUS_ICON_SMALL) { | |
2796 gdk_pixbuf_composite(emblem, | |
2797 scale, 5, 5, | |
2798 10, 10, | |
2799 5, 5, | |
2800 .6, .6, | |
2801 GDK_INTERP_BILINEAR, | |
2802 255); | |
2803 } else { | |
2804 gdk_pixbuf_composite(emblem, | |
2805 scale, emblems[i].x, emblems[i].y, | |
2806 15, 15, | |
2807 emblems[i].x, emblems[i].y, | |
2808 1, 1, | |
2809 GDK_INTERP_BILINEAR, | |
2810 255); | |
2811 } | |
2812 g_object_unref(emblem); | |
2813 } | |
5228 | 2814 } |
2815 } | |
7620 | 2816 |
2817 if(buddy) { | |
9944 | 2818 presence = gaim_buddy_get_presence(buddy); |
2819 | |
2820 if (!GAIM_BUDDY_IS_ONLINE(buddy)) | |
7620 | 2821 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); |
10118 | 2822 else if (gaim_presence_is_idle(presence)) |
9944 | 2823 { |
7620 | 2824 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.25, FALSE); |
9944 | 2825 } |
11111
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2826 |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2827 if (!gaim_privacy_check(buddy->account, gaim_buddy_get_name(buddy))) |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2828 { |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2829 GdkPixbuf *emblem; |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2830 char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "blocked.png", NULL); |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2831 |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2832 emblem = gdk_pixbuf_new_from_file(filename, NULL); |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2833 g_free(filename); |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2834 |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2835 if (emblem) |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2836 { |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2837 gdk_pixbuf_composite(emblem, scale, |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2838 0, 0, scalesize, scalesize, |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2839 0, 0, |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2840 (double)scalesize / gdk_pixbuf_get_width(emblem), |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2841 (double)scalesize / gdk_pixbuf_get_height(emblem), |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2842 GDK_INTERP_BILINEAR, |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2843 224); |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2844 g_object_unref(emblem); |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2845 } |
f03dce7ea408
[gaim-migrate @ 13163]
Richard Laager <rlaager@wiktel.com>
parents:
11059
diff
changeset
|
2846 } |
5228 | 2847 } |
7620 | 2848 |
5228 | 2849 return scale; |
2850 } | |
2851 | |
7620 | 2852 static gchar *gaim_gtk_blist_get_name_markup(GaimBuddy *b, gboolean selected) |
5228 | 2853 { |
7620 | 2854 const char *name; |
2855 char *esc, *text = NULL; | |
5228 | 2856 GaimPlugin *prpl; |
2857 GaimPluginProtocolInfo *prpl_info = NULL; | |
7620 | 2858 GaimContact *contact; |
9944 | 2859 GaimPresence *presence; |
7620 | 2860 struct _gaim_gtk_blist_node *gtkcontactnode = NULL; |
11257 | 2861 char *idletime = NULL, *statustext = NULL; |
5228 | 2862 time_t t; |
7620 | 2863 /* XXX Clean up this crap */ |
2864 | |
2865 contact = (GaimContact*)((GaimBlistNode*)b)->parent; | |
2866 if(contact) | |
2867 gtkcontactnode = ((GaimBlistNode*)contact)->ui_data; | |
2868 | |
2869 if(gtkcontactnode && !gtkcontactnode->contact_expanded && contact->alias) | |
2870 name = contact->alias; | |
2871 else | |
9620 | 2872 name = gaim_buddy_get_alias(b); |
7620 | 2873 esc = g_markup_escape_text(name, strlen(name)); |
2874 | |
7956 | 2875 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
5228 | 2876 |
2877 if (prpl != NULL) | |
2878 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
2879 | |
9944 | 2880 presence = gaim_buddy_get_presence(b); |
2881 | |
7620 | 2882 if (!gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { |
9944 | 2883 |
10118 | 2884 if ((gaim_presence_is_idle(presence) || !GAIM_BUDDY_IS_ONLINE(b)) && !selected) |
9944 | 2885 { |
10118 | 2886 text = g_strdup_printf("<span color='%s'>%s</span>", |
2887 dim_grey(), esc); | |
5228 | 2888 g_free(esc); |
2889 return text; | |
7620 | 2890 } |
9944 | 2891 else |
5228 | 2892 return esc; |
2893 } | |
2894 | |
8122
36674144c510
[gaim-migrate @ 8826]
Christian Hammond <chipx86@chipx86.com>
parents:
8113
diff
changeset
|
2895 if (prpl_info && prpl_info->status_text && b->account->gc) { |
5228 | 2896 char *tmp = prpl_info->status_text(b); |
2897 const char *end; | |
2898 | |
2899 if(tmp && !g_utf8_validate(tmp, -1, &end)) { | |
2900 char *new = g_strndup(tmp, | |
2901 g_utf8_pointer_to_offset(tmp, end)); | |
2902 g_free(tmp); | |
2903 tmp = new; | |
2904 } | |
2905 | |
10288 | 2906 #if !GTK_CHECK_VERSION(2,6,0) |
5228 | 2907 if(tmp) { |
2908 char buf[32]; | |
2909 char *c = tmp; | |
2910 int length = 0, vis=0; | |
2911 gboolean inside = FALSE; | |
2912 g_strdelimit(tmp, "\n", ' '); | |
11920 | 2913 gaim_str_strip_char(tmp, '\r'); |
5228 | 2914 |
2915 while(*c && vis < 20) { | |
2916 if(*c == '&') | |
2917 inside = TRUE; | |
2918 else if(*c == ';') | |
2919 inside = FALSE; | |
2920 if(!inside) | |
2921 vis++; | |
7620 | 2922 c = g_utf8_next_char(c); /* this is fun */ |
5228 | 2923 } |
2924 | |
7620 | 2925 length = c - tmp; |
2926 | |
5228 | 2927 if(vis == 20) |
2928 g_snprintf(buf, sizeof(buf), "%%.%ds...", length); | |
2929 else | |
2930 g_snprintf(buf, sizeof(buf), "%%s "); | |
2931 | |
2932 statustext = g_strdup_printf(buf, tmp); | |
2933 | |
2934 g_free(tmp); | |
2935 } | |
10288 | 2936 #else |
2937 statustext = tmp; | |
2938 #endif | |
5228 | 2939 } |
2940 | |
10351 | 2941 if (gaim_presence_is_idle(presence)) { |
9944 | 2942 time_t idle_secs = gaim_presence_get_idle_time(presence); |
2943 | |
10351 | 2944 if (idle_secs > 0) { |
9944 | 2945 int ihrs, imin; |
2946 | |
2947 time(&t); | |
2948 ihrs = (t - idle_secs) / 3600; | |
2949 imin = ((t - idle_secs) / 60) % 60; | |
2950 | |
2951 if (ihrs) | |
11134
f78e7e982cf4
[gaim-migrate @ 13195]
Richard Laager <rlaager@wiktel.com>
parents:
11111
diff
changeset
|
2952 idletime = g_strdup_printf(_("Idle (%dh %02dm) "), ihrs, imin); |
9944 | 2953 else |
2954 idletime = g_strdup_printf(_("Idle (%dm) "), imin); | |
2955 } | |
5228 | 2956 else |
9944 | 2957 idletime = g_strdup(_("Idle ")); |
5228 | 2958 } |
2959 | |
2960 if(!GAIM_BUDDY_IS_ONLINE(b) && !statustext) | |
7620 | 2961 statustext = g_strdup(_("Offline ")); |
2962 | |
10118 | 2963 if (gaim_presence_is_idle(presence) && !selected) { |
2964 text = g_strdup_printf("<span color='%s'>%s</span>\n" | |
11257 | 2965 "<span color='%s' size='smaller'>%s%s%s</span>", |
10118 | 2966 dim_grey(), esc, dim_grey(), |
5228 | 2967 statustext != NULL ? statustext : "", |
11134
f78e7e982cf4
[gaim-migrate @ 13195]
Richard Laager <rlaager@wiktel.com>
parents:
11111
diff
changeset
|
2968 (idletime != NULL && statustext != NULL) ? " - " : "", |
11257 | 2969 idletime != NULL ? idletime : ""); |
2970 } else if (statustext == NULL && idletime == NULL && GAIM_BUDDY_IS_ONLINE(b)) { | |
5228 | 2971 text = g_strdup(esc); |
2972 } else { | |
10118 | 2973 if (selected) |
2974 text = g_strdup_printf("%s\n" | |
11257 | 2975 "<span size='smaller'>%s%s%s</span>", esc, |
10118 | 2976 statustext != NULL ? statustext : "", |
11134
f78e7e982cf4
[gaim-migrate @ 13195]
Richard Laager <rlaager@wiktel.com>
parents:
11111
diff
changeset
|
2977 (idletime != NULL && statustext != NULL) ? " - " : "", |
11257 | 2978 idletime != NULL ? idletime : ""); |
10118 | 2979 else |
2980 text = g_strdup_printf("%s\n" | |
11257 | 2981 "<span color='%s' size='smaller'>%s%s%s</span>", esc, |
10144 | 2982 dim_grey(), |
10118 | 2983 statustext != NULL ? statustext : "", |
11134
f78e7e982cf4
[gaim-migrate @ 13195]
Richard Laager <rlaager@wiktel.com>
parents:
11111
diff
changeset
|
2984 (idletime != NULL && statustext != NULL) ? " - " : "", |
11257 | 2985 idletime != NULL ? idletime : ""); |
5228 | 2986 } |
2987 if (idletime) | |
2988 g_free(idletime); | |
2989 if (statustext) | |
2990 g_free(statustext); | |
2991 if (esc) | |
2992 g_free(esc); | |
2993 | |
2994 return text; | |
2995 } | |
2996 | |
2997 static void gaim_gtk_blist_restore_position() | |
2998 { | |
7620 | 2999 int blist_x, blist_y, blist_width, blist_height; |
3000 | |
3001 blist_width = gaim_prefs_get_int("/gaim/gtk/blist/width"); | |
3002 | |
3003 /* if the window exists, is hidden, we're saving positions, and the | |
3004 * position is sane... */ | |
3005 if (gtkblist && gtkblist->window && | |
3006 !GTK_WIDGET_VISIBLE(gtkblist->window) && blist_width != 0) { | |
3007 | |
3008 blist_x = gaim_prefs_get_int("/gaim/gtk/blist/x"); | |
3009 blist_y = gaim_prefs_get_int("/gaim/gtk/blist/y"); | |
3010 blist_height = gaim_prefs_get_int("/gaim/gtk/blist/height"); | |
3011 | |
5228 | 3012 /* ...check position is on screen... */ |
7620 | 3013 if (blist_x >= gdk_screen_width()) |
3014 blist_x = gdk_screen_width() - 100; | |
3015 else if (blist_x + blist_width < 0) | |
3016 blist_x = 100; | |
3017 | |
3018 if (blist_y >= gdk_screen_height()) | |
3019 blist_y = gdk_screen_height() - 100; | |
3020 else if (blist_y + blist_height < 0) | |
3021 blist_y = 100; | |
3022 | |
5228 | 3023 /* ...and move it back. */ |
7620 | 3024 gtk_window_move(GTK_WINDOW(gtkblist->window), blist_x, blist_y); |
3025 gtk_window_resize(GTK_WINDOW(gtkblist->window), blist_width, blist_height); | |
5228 | 3026 } |
3027 } | |
3028 | |
7620 | 3029 static gboolean gaim_gtk_blist_refresh_timer(GaimBuddyList *list) |
5228 | 3030 { |
7620 | 3031 GaimBlistNode *gnode, *cnode; |
3032 | |
3033 for(gnode = list->root; gnode; gnode = gnode->next) { | |
3034 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
5234 | 3035 continue; |
7620 | 3036 for(cnode = gnode->child; cnode; cnode = cnode->next) { |
3037 if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { | |
9944 | 3038 GaimBuddy *buddy; |
3039 | |
3040 buddy = gaim_contact_get_priority_buddy((GaimContact*)cnode); | |
10012 | 3041 |
3042 if (buddy && | |
3043 gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) | |
9944 | 3044 gaim_gtk_blist_update(list, cnode); |
7620 | 3045 } |
5228 | 3046 } |
3047 } | |
3048 | |
3049 /* keep on going */ | |
3050 return TRUE; | |
3051 } | |
3052 | |
7620 | 3053 static void gaim_gtk_blist_hide_node(GaimBuddyList *list, GaimBlistNode *node) |
5260 | 3054 { |
3055 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
3056 GtkTreeIter iter; | |
3057 | |
3058 if (!gtknode || !gtknode->row || !gtkblist) | |
3059 return; | |
3060 | |
3061 if(gtkblist->selected_node == node) | |
3062 gtkblist->selected_node = NULL; | |
3063 | |
3064 if (get_iter_from_node(node, &iter)) { | |
3065 gtk_tree_store_remove(gtkblist->treemodel, &iter); | |
7620 | 3066 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node) |
3067 || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
5260 | 3068 gaim_gtk_blist_update(list, node->parent); |
3069 } | |
3070 } | |
3071 gtk_tree_row_reference_free(gtknode->row); | |
3072 gtknode->row = NULL; | |
3073 } | |
3074 | |
10352 | 3075 static const char *require_connection[] = |
7620 | 3076 { |
10352 | 3077 N_("/Buddies/New Instant Message..."), |
3078 N_("/Buddies/Join a Chat..."), | |
3079 N_("/Buddies/Get User Info..."), | |
3080 N_("/Buddies/Add Buddy..."), | |
3081 N_("/Buddies/Add Chat..."), | |
3082 N_("/Buddies/Add Group..."), | |
3083 }; | |
3084 | |
10357 | 3085 static const int require_connection_size = sizeof(require_connection) |
3086 / sizeof(*require_connection); | |
10352 | 3087 |
3088 /** | |
3089 * Rebuild dynamic menus and make menu items sensitive/insensitive | |
3090 * where appropriate. | |
3091 */ | |
3092 static void | |
3093 update_menu_bar(GaimGtkBuddyList *gtkblist) | |
3094 { | |
8937 | 3095 GtkWidget *widget; |
10352 | 3096 gboolean sensitive; |
3097 int i; | |
3098 | |
3099 g_return_if_fail(gtkblist != NULL); | |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3100 |
7620 | 3101 gaim_gtk_blist_update_protocol_actions(); |
8937 | 3102 |
10352 | 3103 sensitive = (gaim_connections_get_all() != NULL); |
3104 | |
10357 | 3105 for (i = 0; i < require_connection_size; i++) |
10352 | 3106 { |
3107 widget = gtk_item_factory_get_widget(gtkblist->ift, require_connection[i]); | |
3108 gtk_widget_set_sensitive(widget, sensitive); | |
3109 } | |
3110 | |
8940 | 3111 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Join a Chat...")); |
3112 gtk_widget_set_sensitive(widget, gaim_gtk_blist_joinchat_is_showable()); | |
3113 | |
11988 | 3114 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Add Chat...")); |
3115 gtk_widget_set_sensitive(widget, gaim_gtk_blist_joinchat_is_showable()); | |
3116 | |
12136
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
3117 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Buddy Pounces")); |
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
3118 gtk_widget_set_sensitive(widget, (gaim_connections_get_all() != NULL)); |
8938 | 3119 |
3120 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Privacy")); | |
3121 gtk_widget_set_sensitive(widget, gaim_gtk_privacy_is_showable()); | |
12136
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
3122 |
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
3123 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Room List")); |
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
3124 gtk_widget_set_sensitive(widget, gaim_gtk_roomlist_is_showable()); |
7620 | 3125 } |
3126 | |
10352 | 3127 static void |
3128 sign_on_off_cb(GaimConnection *gc, GaimBuddyList *blist) | |
3129 { | |
3130 GaimGtkBuddyList *gtkblist = GAIM_GTK_BLIST(blist); | |
3131 | |
3132 update_menu_bar(gtkblist); | |
3133 } | |
8986 | 3134 |
3135 static void | |
3136 plugin_changed_cb(GaimPlugin *p, gpointer *data) | |
3137 { | |
3138 gaim_gtk_blist_update_plugin_actions(); | |
3139 } | |
3140 | |
12133
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3141 static void |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3142 unseen_conv_menu() |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3143 { |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3144 static GtkWidget *menu = NULL; |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3145 |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3146 if (menu) |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3147 gtk_widget_destroy(menu); |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3148 |
12175
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3149 menu = gtk_menu_new(); |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3150 if (!gaim_gtk_conversations_fill_unseen_menu(menu, GAIM_CONV_TYPE_IM, GAIM_UNSEEN_TEXT)) { |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3151 /* no conversations added, don't show the menu */ |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3152 gtk_widget_destroy(menu); |
12133
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3153 return; |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3154 } |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3155 gtk_widget_show_all(menu); |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3156 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3157 gtk_get_current_event_time()); |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3158 } |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3159 |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3160 static gboolean |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3161 menutray_press_cb(GtkWidget *widget, GdkEventButton *event) |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3162 { |
12208 | 3163 GaimConversation *conv; |
3164 | |
12133
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3165 switch (event->button) { |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3166 case 1: |
12208 | 3167 conv = gaim_gtk_conversations_get_first_unseen(GAIM_CONV_TYPE_IM, GAIM_UNSEEN_TEXT); |
3168 if (conv != NULL) | |
3169 gaim_gtkconv_present_conversation(conv); | |
12133
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3170 break; |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3171 case 3: |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3172 unseen_conv_menu(); |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3173 break; |
8254bb99f929
[gaim-migrate @ 14433]
Richard Laager <rlaager@wiktel.com>
parents:
12124
diff
changeset
|
3174 } |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3175 return TRUE; |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3176 } |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3177 |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3178 static void |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3179 conversation_updated_cb(GaimConversation *conv, GaimConvUpdateType type, |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3180 GaimGtkBuddyList *gtkblist) |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3181 { |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3182 GtkWidget *img = NULL; |
12117 | 3183 GString *tooltip_text = NULL; |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3184 |
12175
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3185 if (type != GAIM_CONV_UPDATE_UNSEEN) |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3186 return; |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3187 |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3188 if (gtkblist->menutrayicon) { |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3189 gtk_widget_destroy(gtkblist->menutrayicon); |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3190 gtkblist->menutrayicon = NULL; |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3191 } |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3192 |
12175
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3193 if (gaim_gtk_conversations_get_first_unseen(GAIM_CONV_TYPE_IM, GAIM_UNSEEN_TEXT)) { |
12117 | 3194 GList *convs = gaim_get_ims(); |
3195 tooltip_text = g_string_new(""); | |
12175
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3196 while (convs) { |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3197 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION((GaimConversation *)convs->data); |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3198 |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3199 if (gtkconv->unseen_state >= GAIM_UNSEEN_TEXT) { |
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3200 g_string_append_printf(tooltip_text, |
12208 | 3201 ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count), |
3202 gtkconv->unseen_count, | |
12175
a655bdeb561d
[gaim-migrate @ 14477]
Richard Laager <rlaager@wiktel.com>
parents:
12163
diff
changeset
|
3203 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); |
12117 | 3204 } |
3205 convs = convs->next; | |
3206 } | |
3207 /* get rid of the last newline */ | |
3208 tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len -1); | |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3209 img = gtk_image_new_from_stock(GAIM_STOCK_PENDING, GTK_ICON_SIZE_MENU); |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3210 |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3211 gtkblist->menutrayicon = gtk_event_box_new(); |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3212 gtk_container_add(GTK_CONTAINER(gtkblist->menutrayicon), img); |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3213 gtk_widget_show(img); |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3214 gtk_widget_show(gtkblist->menutrayicon); |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3215 g_signal_connect(G_OBJECT(gtkblist->menutrayicon), "button-press-event", G_CALLBACK(menutray_press_cb), NULL); |
12117 | 3216 |
3217 gaim_gtk_menu_tray_append(GAIM_GTK_MENU_TRAY(gtkblist->menutray), gtkblist->menutrayicon, g_string_free(tooltip_text, FALSE)); | |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3218 } |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3219 } |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3220 |
12208 | 3221 static void |
3222 conversation_deleting_cb(GaimConversation *conv, GaimGtkBuddyList *gtkblist) | |
3223 { | |
3224 conversation_updated_cb(conv, GAIM_CONV_UPDATE_UNSEEN, gtkblist); | |
3225 } | |
3226 | |
5228 | 3227 /********************************************************************************** |
3228 * Public API Functions * | |
3229 **********************************************************************************/ | |
9774 | 3230 |
7620 | 3231 static void gaim_gtk_blist_new_list(GaimBuddyList *blist) |
5228 | 3232 { |
7620 | 3233 GaimGtkBuddyList *gtkblist; |
3234 | |
3235 gtkblist = g_new0(GaimGtkBuddyList, 1); | |
3236 blist->ui_data = gtkblist; | |
5228 | 3237 } |
3238 | |
5256 | 3239 static void gaim_gtk_blist_new_node(GaimBlistNode *node) |
3240 { | |
3241 node->ui_data = g_new0(struct _gaim_gtk_blist_node, 1); | |
3242 } | |
3243 | |
11018 | 3244 gboolean gaim_gtk_blist_node_is_contact_expanded(GaimBlistNode *node) |
3245 { | |
3246 if GAIM_BLIST_NODE_IS_BUDDY(node) | |
3247 node = node->parent; | |
3248 | |
3249 g_return_val_if_fail(GAIM_BLIST_NODE_IS_CONTACT(node), FALSE); | |
3250 | |
3251 return ((struct _gaim_gtk_blist_node *)node->ui_data)->contact_expanded; | |
3252 } | |
3253 | |
5228 | 3254 void gaim_gtk_blist_update_columns() |
3255 { | |
3256 if(!gtkblist) | |
3257 return; | |
3258 | |
7620 | 3259 if (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { |
5228 | 3260 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, TRUE); |
3261 gtk_tree_view_column_set_visible(gtkblist->idle_column, FALSE); | |
3262 } else { | |
10351 | 3263 gtk_tree_view_column_set_visible(gtkblist->idle_column, TRUE); |
5228 | 3264 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, FALSE); |
3265 } | |
3266 } | |
3267 | |
10433 | 3268 enum { |
3269 DRAG_BUDDY, | |
3270 DRAG_ROW, | |
3271 DRAG_VCARD, | |
3272 DRAG_TEXT, | |
3273 DRAG_URI, | |
3274 NUM_TARGETS | |
3275 }; | |
5228 | 3276 |
3277 static char * | |
3278 item_factory_translate_func (const char *path, gpointer func_data) | |
3279 { | |
7620 | 3280 return _((char *)path); |
5228 | 3281 } |
3282 | |
5422 | 3283 void gaim_gtk_blist_setup_sort_methods() |
3284 { | |
11798
01c3eec6ea3c
[gaim-migrate @ 14089]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11797
diff
changeset
|
3285 gaim_gtk_blist_sort_method_reg("none", _("Manually"), sort_method_none); |
7620 | 3286 #if GTK_CHECK_VERSION(2,2,1) |
11798
01c3eec6ea3c
[gaim-migrate @ 14089]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11797
diff
changeset
|
3287 gaim_gtk_blist_sort_method_reg("alphabetical", _("Alphabetically"), sort_method_alphabetical); |
7620 | 3288 gaim_gtk_blist_sort_method_reg("status", _("By status"), sort_method_status); |
3289 gaim_gtk_blist_sort_method_reg("log_size", _("By log size"), sort_method_log); | |
3290 #endif | |
3291 gaim_gtk_blist_sort_method_set(gaim_prefs_get_string("/gaim/gtk/blist/sort_type")); | |
3292 } | |
3293 | |
10433 | 3294 static void _prefs_change_redo_list() |
3295 { | |
7620 | 3296 redo_buddy_list(gaim_get_blist(), TRUE); |
3297 } | |
3298 | |
3299 static void _prefs_change_sort_method(const char *pref_name, GaimPrefType type, | |
10433 | 3300 gpointer val, gpointer data) |
3301 { | |
7620 | 3302 if(!strcmp(pref_name, "/gaim/gtk/blist/sort_type")) |
3303 gaim_gtk_blist_sort_method_set(val); | |
3304 } | |
3305 | |
10433 | 3306 /* |
3307 * "This is so dead sexy." | |
3308 * "Two thumbs up." | |
3309 * "Best movie of the year." | |
3310 * | |
3311 * This is the function that handles CTRL+F searching in the buddy list. | |
3312 * It finds the top-most buddy/group/chat/whatever containing the | |
3313 * entered string. | |
3314 * | |
3315 * It's somewhat ineffecient, because we strip all the HTML from the | |
3316 * "name" column of the buddy list (because the GtkTreeModel does not | |
3317 * contain the screen name in a non-markedup format). But the alternative | |
3318 * is to add an extra column to the GtkTreeModel. And this function is | |
3319 * used rarely, so it shouldn't matter TOO much. | |
3320 */ | |
3321 static gboolean | |
3322 _search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data) | |
3323 { | |
10435 | 3324 gboolean result; |
10433 | 3325 gchar *enteredstring; |
10439 | 3326 gchar *withmarkup; |
10433 | 3327 gchar *nomarkup; |
11490 | 3328 gchar *normalized; |
10435 | 3329 |
3330 gtk_tree_model_get(model, iter, column, &withmarkup, -1); | |
10433 | 3331 |
11490 | 3332 enteredstring = g_utf8_casefold(gaim_normalize(NULL, key), -1); |
10433 | 3333 nomarkup = gaim_markup_strip_html(withmarkup); |
11490 | 3334 normalized = g_utf8_casefold(gaim_normalize(NULL, nomarkup), -1); |
10433 | 3335 |
3336 result = (g_strstr_len(normalized, strlen(normalized), enteredstring) == NULL); | |
3337 | |
10439 | 3338 g_free(withmarkup); |
10433 | 3339 g_free(enteredstring); |
3340 g_free(nomarkup); | |
11490 | 3341 g_free(normalized); |
10433 | 3342 |
3343 return result; | |
3344 } | |
3345 | |
12070 | 3346 static void account_enabled(GaimAccount *account, GaimGtkBuddyList *gtkblist) |
3347 { | |
3348 GtkWidget *box; | |
3349 | |
3350 if (!gtkblist) | |
3351 return; | |
3352 | |
3353 box = gtk_gaim_status_box_new_with_account(account); | |
3354 gtkblist->statusboxes = g_list_append(gtkblist->statusboxes, box); | |
3355 gtk_box_pack_start(GTK_BOX(gtkblist->statusboxbox), box, FALSE, TRUE, 0); | |
3356 gtk_widget_show(box); | |
3357 } | |
3358 | |
3359 static void account_disabled(GaimAccount *account, GaimGtkBuddyList *gtkblist) | |
3360 { | |
3361 GList *iter; | |
3362 | |
3363 if (!gtkblist) | |
3364 return; | |
3365 | |
3366 for (iter = gtkblist->statusboxes; iter; iter = iter->next) | |
3367 { | |
3368 GtkWidget *box = iter->data; | |
3369 GaimAccount *ac = NULL; | |
3370 | |
3371 g_object_get(G_OBJECT(box), "account", &ac, NULL); | |
3372 if (ac == account) | |
3373 { | |
3374 gtkblist->statusboxes = g_list_remove_link(gtkblist->statusboxes, iter); | |
3375 gtk_widget_destroy(box); | |
3376 break; | |
3377 } | |
3378 } | |
3379 } | |
3380 | |
12124
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3381 static gboolean |
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3382 pane_position_cb(GtkPaned *paned, GParamSpec *param_spec, gpointer data) |
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3383 { |
12179
92ba143044e6
[gaim-migrate @ 14481]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12175
diff
changeset
|
3384 gaim_prefs_set_int("/gaim/gtk/blist/pane", |
92ba143044e6
[gaim-migrate @ 14481]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12175
diff
changeset
|
3385 gtk_paned_get_position(paned)); |
12124
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3386 |
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3387 return FALSE; |
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3388 } |
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3389 |
7620 | 3390 static void gaim_gtk_blist_show(GaimBuddyList *list) |
5228 | 3391 { |
10087 | 3392 void *handle; |
5228 | 3393 GtkCellRenderer *rend; |
3394 GtkTreeViewColumn *column; | |
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3395 GtkWidget *menu; |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
3396 GtkWidget *account_actions_menu; |
5228 | 3397 GtkWidget *sw; |
11983 | 3398 GtkWidget *vpane; |
5228 | 3399 GtkAccelGroup *accel_group; |
3400 GtkTreeSelection *selection; | |
9556 | 3401 GtkTargetEntry dte[] = {{"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW}, |
8089 | 3402 {"application/x-im-contact", 0, DRAG_BUDDY}, |
9495 | 3403 {"text/x-vcard", 0, DRAG_VCARD }, |
9525 | 3404 {"text/uri-list", 0, DRAG_URI}, |
3405 {"text/plain", 0, DRAG_TEXT}}; | |
9556 | 3406 GtkTargetEntry ste[] = {{"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW}, |
3407 {"application/x-im-contact", 0, DRAG_BUDDY}, | |
3408 {"text/x-vcard", 0, DRAG_VCARD }}; | |
5228 | 3409 if (gtkblist && gtkblist->window) { |
12119
312efb43c49a
[gaim-migrate @ 14419]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12117
diff
changeset
|
3410 gaim_blist_set_visible(gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")); |
5228 | 3411 return; |
3412 } | |
3413 | |
3414 gtkblist = GAIM_GTK_BLIST(list); | |
3415 | |
3416 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
3417 gtk_window_set_role(GTK_WINDOW(gtkblist->window), "buddy_list"); | |
9746 | 3418 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); |
5228 | 3419 |
3420 gtkblist->vbox = gtk_vbox_new(FALSE, 0); | |
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3421 gtk_widget_show(gtkblist->vbox); |
5228 | 3422 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); |
3423 | |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
3424 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); |
5228 | 3425 g_signal_connect(G_OBJECT(gtkblist->window), "configure_event", G_CALLBACK(gtk_blist_configure_cb), NULL); |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
3426 g_signal_connect(G_OBJECT(gtkblist->window), "visibility_notify_event", G_CALLBACK(gtk_blist_visibility_cb), NULL); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
3427 g_signal_connect(G_OBJECT(gtkblist->window), "window_state_event", G_CALLBACK(gtk_blist_window_state_cb), NULL); |
5228 | 3428 gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK); |
3429 | |
3430 /******************************* Menu bar *************************************/ | |
3431 accel_group = gtk_accel_group_new(); | |
3432 gtk_window_add_accel_group(GTK_WINDOW (gtkblist->window), accel_group); | |
3433 g_object_unref(accel_group); | |
5427 | 3434 gtkblist->ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", accel_group); |
9811 | 3435 gtk_item_factory_set_translate_func(gtkblist->ift, |
3436 item_factory_translate_func, | |
3437 NULL, NULL); | |
5427 | 3438 gtk_item_factory_create_items(gtkblist->ift, sizeof(blist_menu) / sizeof(*blist_menu), |
9811 | 3439 blist_menu, NULL); |
7620 | 3440 gaim_gtk_load_accels(); |
3441 g_signal_connect(G_OBJECT(accel_group), "accel-changed", | |
3442 G_CALLBACK(gaim_gtk_save_accels_cb), NULL); | |
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3443 menu = gtk_item_factory_get_widget(gtkblist->ift, "<GaimMain>"); |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3444 gtkblist->menutray = gaim_gtk_menu_tray_new(); |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3445 gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtkblist->menutray); |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3446 gtk_widget_show(gtkblist->menutray); |
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3447 gtk_widget_show(menu); |
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3448 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), menu, FALSE, FALSE, 0); |
5228 | 3449 |
12191
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
3450 protomenu = gtk_menu_new(); |
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
3451 account_actions_menu = gtk_item_factory_get_item(gtkblist->ift, N_("/Tools/Account Actions")); |
bc2b9f925979
[gaim-migrate @ 14493]
Richard Laager <rlaager@wiktel.com>
parents:
12179
diff
changeset
|
3452 gtk_menu_item_set_submenu(GTK_MENU_ITEM(account_actions_menu), protomenu); |
10352 | 3453 |
11983 | 3454 /****************************** GtkVPaned ************************************/ |
3455 vpane = gtk_vpaned_new(); | |
3456 gtk_widget_show(vpane); | |
3457 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), vpane, TRUE, TRUE, 0); | |
12124
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3458 gtk_paned_set_position(GTK_PANED(vpane), |
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3459 gaim_prefs_get_int("/gaim/gtk/blist/pane")); |
12179
92ba143044e6
[gaim-migrate @ 14481]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12175
diff
changeset
|
3460 g_signal_connect(G_OBJECT(vpane), "notify::position", |
12124
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
3461 G_CALLBACK(pane_position_cb), NULL); |
11983 | 3462 |
5228 | 3463 /****************************** GtkTreeView **********************************/ |
3464 sw = gtk_scrolled_window_new(NULL,NULL); | |
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3465 gtk_widget_show(sw); |
5228 | 3466 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); |
3467 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
3468 | |
7620 | 3469 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, |
11494 | 3470 GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, |
11257 | 3471 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); |
5228 | 3472 |
3473 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); | |
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3474 gtk_widget_show(gtkblist->treeview); |
9176 | 3475 gtk_widget_set_name(gtkblist->treeview, "gaim_gtkblist_treeview"); |
5228 | 3476 |
3477 /* Set up selection stuff */ | |
3478 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
3479 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(gaim_gtk_blist_selection_changed), NULL); | |
3480 | |
3481 /* Set up dnd */ | |
7650 | 3482 gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), |
9811 | 3483 GDK_BUTTON1_MASK, ste, 3, |
3484 GDK_ACTION_COPY); | |
7650 | 3485 gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), |
9811 | 3486 dte, 5, |
3487 GDK_ACTION_COPY | GDK_ACTION_MOVE); | |
7636 | 3488 |
10544 | 3489 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(gaim_gtk_blist_drag_data_rcv_cb), NULL); |
5228 | 3490 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(gaim_gtk_blist_drag_data_get_cb), NULL); |
11059
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
3491 #ifdef _WIN32 |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
3492 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-begin", G_CALLBACK(gaim_gtk_blist_drag_begin), NULL); |
c86d423df757
[gaim-migrate @ 13012]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11038
diff
changeset
|
3493 #endif |
10433 | 3494 |
10354 | 3495 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-motion", G_CALLBACK(gaim_gtk_blist_drag_motion_cb), NULL); |
5228 | 3496 |
3497 /* Tooltips */ | |
3498 g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(gaim_gtk_blist_motion_cb), NULL); | |
3499 g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(gaim_gtk_blist_leave_cb), NULL); | |
3500 | |
3501 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
3502 | |
11016 | 3503 gtkblist->text_column = column = gtk_tree_view_column_new (); |
5228 | 3504 |
3505 rend = gtk_cell_renderer_pixbuf_new(); | |
9811 | 3506 gtk_tree_view_column_pack_start(column, rend, FALSE); |
3507 gtk_tree_view_column_set_attributes(column, rend, | |
3508 "pixbuf", STATUS_ICON_COLUMN, | |
3509 "visible", STATUS_ICON_VISIBLE_COLUMN, | |
3510 NULL); | |
5228 | 3511 g_object_set(rend, "xalign", 0.0, "ypad", 0, NULL); |
3512 | |
11016 | 3513 gtkblist->text_rend = rend = gtk_cell_renderer_text_new(); |
5228 | 3514 gtk_tree_view_column_pack_start (column, rend, TRUE); |
9811 | 3515 gtk_tree_view_column_set_attributes(column, rend, |
3516 "markup", NAME_COLUMN, | |
3517 NULL); | |
11016 | 3518 g_signal_connect(G_OBJECT(rend), "edited", G_CALLBACK(gtk_blist_renderer_edited_cb), NULL); |
5228 | 3519 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); |
10285 | 3520 #if GTK_CHECK_VERSION(2,6,0) |
3521 gtk_tree_view_column_set_expand (column, TRUE); | |
10501 | 3522 g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
10285 | 3523 #endif |
5228 | 3524 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); |
3525 | |
3526 rend = gtk_cell_renderer_text_new(); | |
10351 | 3527 gtkblist->idle_column = gtk_tree_view_column_new_with_attributes("Idle", rend, "markup", IDLE_COLUMN, NULL); |
3528 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->idle_column); | |
5228 | 3529 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); |
3530 | |
3531 rend = gtk_cell_renderer_pixbuf_new(); | |
3532 gtkblist->buddy_icon_column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); | |
3533 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); | |
3534 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column); | |
3535 | |
3536 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); | |
3537 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-expanded", G_CALLBACK(gtk_blist_row_expanded_cb), NULL); | |
3538 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-collapsed", G_CALLBACK(gtk_blist_row_collapsed_cb), NULL); | |
3539 g_signal_connect(G_OBJECT(gtkblist->treeview), "button-press-event", G_CALLBACK(gtk_blist_button_press_cb), NULL); | |
7620 | 3540 g_signal_connect(G_OBJECT(gtkblist->treeview), "key-press-event", G_CALLBACK(gtk_blist_key_press_cb), NULL); |
8143 | 3541 g_signal_connect(G_OBJECT(gtkblist->treeview), "popup-menu", G_CALLBACK(gaim_gtk_blist_popup_menu_cb), NULL); |
5228 | 3542 |
5419 | 3543 /* Enable CTRL+F searching */ |
3544 gtk_tree_view_set_search_column(GTK_TREE_VIEW(gtkblist->treeview), NAME_COLUMN); | |
10433 | 3545 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(gtkblist->treeview), _search_func, NULL, NULL); |
5419 | 3546 |
11983 | 3547 gtk_paned_pack1(GTK_PANED(vpane), sw, TRUE, FALSE); |
5228 | 3548 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); |
3549 gaim_gtk_blist_update_columns(); | |
3550 | |
11732 | 3551 /* TODO: functionize this */ |
3552 { | |
3553 GList *accounts, *l; | |
11983 | 3554 GtkWidget *sw2 = gtk_scrolled_window_new(NULL, NULL); |
3555 | |
11732 | 3556 /* Set up some per account status boxes */ |
3557 gtkblist->statusboxbox = gtk_vbox_new(FALSE, 0); | |
3558 gtkblist->statusboxes = NULL; | |
11983 | 3559 |
11732 | 3560 for (l = accounts = gaim_accounts_get_all_active(); l; l = l->next) { |
3561 GtkWidget *statusbox = gtk_gaim_status_box_new_with_account(l->data); | |
3562 gtkblist->statusboxes = g_list_append(gtkblist->statusboxes, statusbox); | |
3563 gtk_box_pack_start(GTK_BOX(gtkblist->statusboxbox), statusbox, FALSE, TRUE, 0); | |
3564 gtk_widget_show(statusbox); | |
3565 } | |
3566 g_list_free(accounts); | |
11983 | 3567 |
11732 | 3568 gtk_widget_show(gtkblist->statusboxbox); |
11983 | 3569 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw2), gtkblist->statusboxbox); |
3570 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw2), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); | |
3571 gtk_widget_show(sw2); | |
3572 gtk_paned_pack2(GTK_PANED(vpane), sw2, FALSE, TRUE); | |
11732 | 3573 |
3574 gtkblist->statusbox = gtk_gaim_status_box_new(); | |
3575 | |
3576 gtk_widget_show(gtkblist->statusbox); | |
3577 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->statusbox, FALSE, TRUE, 0); | |
3578 | |
3579 } | |
10178
96a850ab30c8
[gaim-migrate @ 11293]
Christian Hammond <chipx86@chipx86.com>
parents:
10144
diff
changeset
|
3580 |
5228 | 3581 /* set the Show Offline Buddies option. must be done |
3582 * after the treeview or faceprint gets mad. -Robot101 | |
3583 */ | |
5427 | 3584 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show Offline Buddies"))), |
7620 | 3585 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")); |
5427 | 3586 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show Empty Groups"))), |
7620 | 3587 gaim_prefs_get_bool("/gaim/gtk/blist/show_empty_groups")); |
10074 | 3588 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))), |
3589 gaim_prefs_get_bool("/gaim/gtk/sound/mute")); | |
11796 | 3590 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show Buddy Details"))), |
11920 | 3591 gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")); |
10074 | 3592 if(!strcmp(gaim_prefs_get_string("/gaim/gtk/sound/method"), "none")) |
11494 | 3593 gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), FALSE); |
5228 | 3594 |
10353 | 3595 /* Update some dynamic things */ |
3596 update_menu_bar(gtkblist); | |
3597 gaim_gtk_blist_update_plugin_actions(); | |
11796 | 3598 gaim_gtk_blist_update_sort_methods(); |
10353 | 3599 |
5228 | 3600 /* OK... let's show this bad boy. */ |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
3601 gaim_gtk_blist_refresh(list); |
12119
312efb43c49a
[gaim-migrate @ 14419]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12117
diff
changeset
|
3602 gaim_gtk_blist_restore_position(); |
312efb43c49a
[gaim-migrate @ 14419]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12117
diff
changeset
|
3603 gtk_widget_show_all(GTK_WIDGET(gtkblist->window)); |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
3604 gaim_blist_set_visible(gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")); |
5228 | 3605 |
3606 /* start the refresh timer */ | |
10351 | 3607 gtkblist->refresh_timer = g_timeout_add(30000, (GSourceFunc)gaim_gtk_blist_refresh_timer, list); |
10353 | 3608 |
10087 | 3609 handle = gaim_gtk_blist_get_handle(); |
3610 | |
7620 | 3611 /* things that affect how buddies are displayed */ |
10087 | 3612 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_buddy_icons", |
3613 _prefs_change_redo_list, NULL); | |
3614 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_empty_groups", | |
3615 _prefs_change_redo_list, NULL); | |
3616 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_offline_buddies", | |
3617 _prefs_change_redo_list, NULL); | |
7620 | 3618 |
3619 /* sorting */ | |
10087 | 3620 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/sort_type", |
3621 _prefs_change_sort_method, NULL); | |
7620 | 3622 |
3623 /* things that affect what columns are displayed */ | |
10087 | 3624 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_buddy_icons", |
3625 gaim_gtk_blist_update_columns, NULL); | |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3626 |
10074 | 3627 /* menus */ |
10087 | 3628 gaim_prefs_connect_callback(handle, "/gaim/gtk/sound/mute", |
3629 gaim_gtk_blist_mute_pref_cb, NULL); | |
3630 gaim_prefs_connect_callback(handle, "/gaim/gtk/sound/method", | |
3631 gaim_gtk_blist_sound_method_pref_cb, NULL); | |
10074 | 3632 |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3633 /* Setup some gaim signal handlers. */ |
12070 | 3634 gaim_signal_connect(gaim_accounts_get_handle(), "account-disabled", |
3635 gtkblist, GAIM_CALLBACK(account_disabled), gtkblist); | |
12226 | 3636 gaim_signal_connect(gaim_accounts_get_handle(), "account-removed", |
3637 gtkblist, GAIM_CALLBACK(account_disabled), gtkblist); | |
12070 | 3638 gaim_signal_connect(gaim_accounts_get_handle(), "account-enabled", |
3639 gtkblist, GAIM_CALLBACK(account_enabled), gtkblist); | |
3640 | |
8937 | 3641 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", |
3642 gtkblist, GAIM_CALLBACK(sign_on_off_cb), list); | |
3643 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | |
3644 gtkblist, GAIM_CALLBACK(sign_on_off_cb), list); | |
8815 | 3645 |
8986 | 3646 gaim_signal_connect(gaim_plugins_get_handle(), "plugin-load", |
3647 gtkblist, GAIM_CALLBACK(plugin_changed_cb), NULL); | |
3648 gaim_signal_connect(gaim_plugins_get_handle(), "plugin-unload", | |
3649 gtkblist, GAIM_CALLBACK(plugin_changed_cb), NULL); | |
3650 | |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3651 gaim_signal_connect(gaim_conversations_get_handle(), "conversation-updated", |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3652 gtkblist, GAIM_CALLBACK(conversation_updated_cb), |
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3653 gtkblist); |
12208 | 3654 gaim_signal_connect(gaim_conversations_get_handle(), "deleting-conversation", |
3655 gtkblist, GAIM_CALLBACK(conversation_deleting_cb), | |
3656 gtkblist); | |
12116
e75ef7aa913e
[gaim-migrate @ 14416]
Luke Schierer <lschiere@pidgin.im>
parents:
12115
diff
changeset
|
3657 |
8815 | 3658 /* emit our created signal */ |
10087 | 3659 gaim_signal_emit(handle, "gtkblist-created", list); |
5228 | 3660 } |
3661 | |
7620 | 3662 static void redo_buddy_list(GaimBuddyList *list, gboolean remove) |
5228 | 3663 { |
12112 | 3664 GaimBlistNode *node = list->root; |
3665 | |
3666 while (node) | |
3667 { | |
3668 if (!GAIM_BLIST_NODE_IS_GROUP(node) && remove) | |
3669 gaim_gtk_blist_hide_node(list, node); | |
3670 | |
3671 gaim_gtk_blist_update(list, node); | |
3672 node = gaim_blist_node_next(node, FALSE); | |
5228 | 3673 } |
3674 } | |
3675 | |
7620 | 3676 void gaim_gtk_blist_refresh(GaimBuddyList *list) |
5422 | 3677 { |
3678 redo_buddy_list(list, FALSE); | |
3679 } | |
3680 | |
5297 | 3681 void |
3682 gaim_gtk_blist_update_refresh_timeout() | |
3683 { | |
7620 | 3684 GaimBuddyList *blist; |
3685 GaimGtkBuddyList *gtkblist; | |
5297 | 3686 |
3687 blist = gaim_get_blist(); | |
3688 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); | |
3689 | |
10351 | 3690 gtkblist->refresh_timer = g_timeout_add(30000,(GSourceFunc)gaim_gtk_blist_refresh_timer, blist); |
5297 | 3691 } |
3692 | |
5256 | 3693 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) { |
3694 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
3695 GtkTreePath *path; | |
5228 | 3696 |
5263 | 3697 if (!gtknode) { |
3698 return FALSE; | |
3699 } | |
3700 | |
3701 if (!gtkblist) { | |
10006 | 3702 gaim_debug_error("gtkblist", "get_iter_from_node was called, but we don't seem to have a blist\n"); |
5263 | 3703 return FALSE; |
3704 } | |
3705 | |
3706 if (!gtknode->row) | |
5228 | 3707 return FALSE; |
11494 | 3708 |
5228 | 3709 |
5256 | 3710 if ((path = gtk_tree_row_reference_get_path(gtknode->row)) == NULL) |
5228 | 3711 return FALSE; |
11016 | 3712 |
5256 | 3713 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), iter, path)) { |
3714 gtk_tree_path_free(path); | |
3715 return FALSE; | |
3716 } | |
3717 gtk_tree_path_free(path); | |
3718 return TRUE; | |
5228 | 3719 } |
3720 | |
7620 | 3721 static void gaim_gtk_blist_remove(GaimBuddyList *list, GaimBlistNode *node) |
5228 | 3722 { |
11910 | 3723 struct _gaim_gtk_blist_node *gtknode = node->ui_data; |
3724 | |
10222 | 3725 gaim_request_close_with_handle(node); |
3726 | |
5260 | 3727 gaim_gtk_blist_hide_node(list, node); |
5228 | 3728 |
7620 | 3729 if(node->parent) |
3730 gaim_gtk_blist_update(list, node->parent); | |
3731 | |
10504 | 3732 /* There's something I don't understand here - Ethan */ |
3733 /* Ethan said that back in 2003, but this g_free has been left commented | |
3734 * out ever since. I can't find any reason at all why this is bad and | |
3735 * valgrind found several reasons why it's good. If this causes problems | |
3736 * comment it out again. Stu */ | |
10510 | 3737 /* Of course it still causes problems - this breaks dragging buddies into |
10515 | 3738 * contacts, the dragged buddy mysteriously 'disappears'. Stu. */ |
3739 /* I think it's fixed now. Stu. */ | |
11910 | 3740 |
11915 | 3741 if(gtknode) { |
3742 if(gtknode->recent_signonoff_timer > 0) | |
3743 gaim_timeout_remove(gtknode->recent_signonoff_timer); | |
3744 | |
3745 g_free(node->ui_data); | |
3746 node->ui_data = NULL; | |
3747 } | |
5228 | 3748 } |
3749 | |
3750 static gboolean do_selection_changed(GaimBlistNode *new_selection) | |
3751 { | |
5254 | 3752 GaimBlistNode *old_selection = NULL; |
5228 | 3753 |
5254 | 3754 /* test for gtkblist because crazy timeout means we can be called after the blist is gone */ |
3755 if (gtkblist && new_selection != gtkblist->selected_node) { | |
3756 old_selection = gtkblist->selected_node; | |
5228 | 3757 gtkblist->selected_node = new_selection; |
3758 if(new_selection) | |
3759 gaim_gtk_blist_update(NULL, new_selection); | |
3760 if(old_selection) | |
3761 gaim_gtk_blist_update(NULL, old_selection); | |
3762 } | |
3763 | |
3764 return FALSE; | |
3765 } | |
3766 | |
3767 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data) | |
3768 { | |
3769 GaimBlistNode *new_selection = NULL; | |
3770 GtkTreeIter iter; | |
3771 | |
3772 if(gtk_tree_selection_get_selected(selection, NULL, &iter)){ | |
3773 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
3774 NODE_COLUMN, &new_selection, -1); | |
3775 } | |
5254 | 3776 |
5228 | 3777 /* we set this up as a timeout, otherwise the blist flickers */ |
3778 g_timeout_add(0, (GSourceFunc)do_selection_changed, new_selection); | |
3779 } | |
3780 | |
8252 | 3781 static gboolean insert_node(GaimBuddyList *list, GaimBlistNode *node, GtkTreeIter *iter) |
7620 | 3782 { |
3783 GtkTreeIter parent_iter, cur, *curptr = NULL; | |
3784 struct _gaim_gtk_blist_node *gtknode = node->ui_data; | |
5256 | 3785 GtkTreePath *newpath; |
7620 | 3786 |
10515 | 3787 if(!iter) |
8252 | 3788 return FALSE; |
7620 | 3789 |
3790 if(node->parent && !get_iter_from_node(node->parent, &parent_iter)) | |
8252 | 3791 return FALSE; |
7620 | 3792 |
3793 if(get_iter_from_node(node, &cur)) | |
3794 curptr = &cur; | |
3795 | |
3796 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
3797 *iter = current_sort_method->func(node, list, parent_iter, curptr); | |
3798 } else { | |
3799 *iter = sort_method_none(node, list, parent_iter, curptr); | |
5228 | 3800 } |
3801 | |
10515 | 3802 if(gtknode != NULL) { |
3803 gtk_tree_row_reference_free(gtknode->row); | |
3804 } else { | |
3805 gaim_gtk_blist_new_node(node); | |
3806 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
3807 } | |
3808 | |
7620 | 3809 newpath = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), |
3810 iter); | |
3811 gtknode->row = | |
3812 gtk_tree_row_reference_new(GTK_TREE_MODEL(gtkblist->treemodel), | |
3813 newpath); | |
11494 | 3814 |
5256 | 3815 gtk_tree_path_free(newpath); |
3816 | |
5228 | 3817 gtk_tree_store_set(gtkblist->treemodel, iter, |
3818 NODE_COLUMN, node, | |
3819 -1); | |
7620 | 3820 |
3821 if(node->parent) { | |
3822 GtkTreePath *expand = NULL; | |
3823 struct _gaim_gtk_blist_node *gtkparentnode = node->parent->ui_data; | |
3824 | |
3825 if(GAIM_BLIST_NODE_IS_GROUP(node->parent)) { | |
7693 | 3826 if(!gaim_blist_node_get_bool(node->parent, "collapsed")) |
7620 | 3827 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &parent_iter); |
3828 } else if(GAIM_BLIST_NODE_IS_CONTACT(node->parent) && | |
3829 gtkparentnode->contact_expanded) { | |
3830 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &parent_iter); | |
3831 } | |
3832 if(expand) { | |
7693 | 3833 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), expand, FALSE); |
7620 | 3834 gtk_tree_path_free(expand); |
3835 } | |
3836 } | |
3837 | |
8252 | 3838 return TRUE; |
5228 | 3839 } |
3840 | |
7620 | 3841 static void gaim_gtk_blist_update_group(GaimBuddyList *list, GaimBlistNode *node) |
3842 { | |
3843 GaimGroup *group; | |
8203 | 3844 int count; |
7620 | 3845 |
3846 g_return_if_fail(GAIM_BLIST_NODE_IS_GROUP(node)); | |
3847 | |
3848 group = (GaimGroup*)node; | |
3849 | |
8203 | 3850 if(gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) |
3851 count = gaim_blist_get_group_size(group, FALSE); | |
3852 else | |
3853 count = gaim_blist_get_group_online_count(group); | |
3854 if(gaim_prefs_get_bool("/gaim/gtk/blist/show_empty_groups") || count > 0) { | |
7620 | 3855 char *mark, *esc; |
3856 GtkTreeIter iter; | |
3857 | |
8252 | 3858 if(!insert_node(list, node, &iter)) |
3859 return; | |
7620 | 3860 |
3861 esc = g_markup_escape_text(group->name, -1); | |
8945 | 3862 mark = g_strdup_printf("<span weight='bold'>%s</span> (%d/%d)", |
3863 esc, gaim_blist_get_group_online_count(group), | |
3864 gaim_blist_get_group_size(group, FALSE)); | |
7620 | 3865 g_free(esc); |
3866 | |
3867 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
3868 STATUS_ICON_COLUMN, NULL, | |
3869 STATUS_ICON_VISIBLE_COLUMN, FALSE, | |
3870 NAME_COLUMN, mark, | |
3871 NODE_COLUMN, node, | |
3872 -1); | |
3873 g_free(mark); | |
3874 } else { | |
3875 gaim_gtk_blist_hide_node(list, node); | |
3876 } | |
3877 } | |
3878 | |
3879 static void buddy_node(GaimBuddy *buddy, GtkTreeIter *iter, GaimBlistNode *node) | |
5228 | 3880 { |
9944 | 3881 GaimPresence *presence; |
7620 | 3882 GdkPixbuf *status, *avatar; |
3883 char *mark; | |
11257 | 3884 char *idle = NULL; |
7620 | 3885 gboolean selected = (gtkblist->selected_node == node); |
3886 | |
9944 | 3887 presence = gaim_buddy_get_presence(buddy); |
3888 | |
7620 | 3889 status = gaim_gtk_blist_get_status_icon((GaimBlistNode*)buddy, |
3890 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") | |
3891 ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
3892 | |
10482 | 3893 avatar = gaim_gtk_blist_get_buddy_icon((GaimBlistNode *)buddy, TRUE, TRUE); |
7620 | 3894 mark = gaim_gtk_blist_get_name_markup(buddy, selected); |
3895 | |
9944 | 3896 if (gaim_presence_is_idle(presence)) |
3897 { | |
3898 time_t idle_secs = gaim_presence_get_idle_time(presence); | |
3899 | |
3900 if (idle_secs > 0) | |
3901 { | |
3902 time_t t; | |
3903 int ihrs, imin; | |
3904 time(&t); | |
3905 ihrs = (t - idle_secs) / 3600; | |
3906 imin = ((t - idle_secs) / 60) % 60; | |
3907 | |
3908 if (ihrs > 0) | |
3909 idle = g_strdup_printf("(%d:%02d)", ihrs, imin); | |
3910 else | |
3911 idle = g_strdup_printf("(%d)", imin); | |
3912 } | |
7620 | 3913 } |
3914 | |
10118 | 3915 if (gaim_presence_is_idle(presence)) |
9944 | 3916 { |
3917 if (idle && !selected) { | |
10118 | 3918 char *i2 = g_strdup_printf("<span color='%s'>%s</span>", |
3919 dim_grey(), idle); | |
7620 | 3920 g_free(idle); |
3921 idle = i2; | |
5228 | 3922 } |
7620 | 3923 } |
3924 | |
3925 gtk_tree_store_set(gtkblist->treemodel, iter, | |
3926 STATUS_ICON_COLUMN, status, | |
3927 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
3928 NAME_COLUMN, mark, | |
3929 IDLE_COLUMN, idle, | |
3930 BUDDY_ICON_COLUMN, avatar, | |
3931 -1); | |
3932 | |
3933 g_free(mark); | |
3934 if(idle) | |
3935 g_free(idle); | |
3936 if(status) | |
3937 g_object_unref(status); | |
3938 if(avatar) | |
3939 g_object_unref(avatar); | |
3940 } | |
3941 | |
11890 | 3942 |
7620 | 3943 static void gaim_gtk_blist_update_contact(GaimBuddyList *list, GaimBlistNode *node) |
3944 { | |
3945 GaimContact *contact; | |
3946 GaimBuddy *buddy; | |
3947 struct _gaim_gtk_blist_node *gtknode; | |
3948 | |
3949 g_return_if_fail(GAIM_BLIST_NODE_IS_CONTACT(node)); | |
3950 | |
3951 /* First things first, update the group */ | |
3952 gaim_gtk_blist_update_group(list, node->parent); | |
3953 | |
3954 contact = (GaimContact*)node; | |
3955 buddy = gaim_contact_get_priority_buddy(contact); | |
3956 | |
11890 | 3957 if (buddy_is_displayable(buddy)) |
10006 | 3958 { |
7620 | 3959 GtkTreeIter iter; |
3960 | |
8252 | 3961 if(!insert_node(list, node, &iter)) |
3962 return; | |
7620 | 3963 |
10515 | 3964 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; |
3965 | |
7620 | 3966 if(gtknode->contact_expanded) { |
3967 GdkPixbuf *status; | |
5228 | 3968 char *mark; |
3969 | |
7620 | 3970 status = gaim_gtk_blist_get_status_icon(node, |
3971 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") ? | |
3972 GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
3973 | |
3974 mark = g_markup_escape_text(gaim_contact_get_alias(contact), -1); | |
3975 | |
5228 | 3976 gtk_tree_store_set(gtkblist->treemodel, &iter, |
7620 | 3977 STATUS_ICON_COLUMN, status, |
3978 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
5228 | 3979 NAME_COLUMN, mark, |
7620 | 3980 IDLE_COLUMN, NULL, |
3981 BUDDY_ICON_COLUMN, NULL, | |
5228 | 3982 -1); |
3983 g_free(mark); | |
7620 | 3984 if(status) |
3985 g_object_unref(status); | |
3986 } else { | |
3987 buddy_node(buddy, &iter, node); | |
5228 | 3988 } |
7620 | 3989 } else { |
3990 gaim_gtk_blist_hide_node(list, node); | |
5228 | 3991 } |
7620 | 3992 } |
3993 | |
3994 static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node) | |
3995 { | |
3996 GaimContact *contact; | |
3997 GaimBuddy *buddy; | |
3998 struct _gaim_gtk_blist_node *gtkparentnode; | |
3999 | |
4000 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
4001 | |
4002 buddy = (GaimBuddy*)node; | |
4003 contact = (GaimContact*)node->parent; | |
4004 | |
11624 | 4005 if (contact == NULL) |
4006 return; | |
4007 | |
7620 | 4008 /* First things first, update the contact */ |
4009 gaim_gtk_blist_update_contact(list, node->parent); | |
4010 | |
10918 | 4011 gtkparentnode = (struct _gaim_gtk_blist_node *)node->parent->ui_data; |
4012 | |
10006 | 4013 if (gtkparentnode->contact_expanded && |
4014 (gaim_presence_is_online(buddy->presence) || | |
11910 | 4015 (0 /* XXX: if we just signed off, need to show logout.png */) || |
7620 | 4016 (gaim_account_is_connected(buddy->account) && |
10006 | 4017 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || |
4018 gaim_blist_node_get_bool(node->parent, "show_offline"))) | |
4019 { | |
7620 | 4020 GtkTreeIter iter; |
4021 | |
10006 | 4022 if (!insert_node(list, node, &iter)) |
8252 | 4023 return; |
4024 | |
7620 | 4025 buddy_node(buddy, &iter, node); |
4026 | |
4027 } else { | |
4028 gaim_gtk_blist_hide_node(list, node); | |
4029 } | |
4030 | |
4031 } | |
4032 | |
4033 static void gaim_gtk_blist_update_chat(GaimBuddyList *list, GaimBlistNode *node) | |
4034 { | |
4035 GaimChat *chat; | |
4036 | |
4037 g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); | |
4038 | |
4039 /* First things first, update the group */ | |
4040 gaim_gtk_blist_update_group(list, node->parent); | |
4041 | |
4042 chat = (GaimChat*)node; | |
4043 | |
4044 if(gaim_account_is_connected(chat->account)) { | |
4045 GtkTreeIter iter; | |
5234 | 4046 GdkPixbuf *status; |
7620 | 4047 char *mark; |
4048 | |
8252 | 4049 if(!insert_node(list, node, &iter)) |
4050 return; | |
5234 | 4051 |
4052 status = gaim_gtk_blist_get_status_icon(node, | |
7620 | 4053 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") ? |
4054 GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
4055 | |
4056 mark = g_markup_escape_text(gaim_chat_get_name(chat), -1); | |
5234 | 4057 |
4058 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
7620 | 4059 STATUS_ICON_COLUMN, status, |
4060 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
4061 NAME_COLUMN, mark, | |
4062 -1); | |
5228 | 4063 |
4064 g_free(mark); | |
7620 | 4065 if(status) |
5228 | 4066 g_object_unref(status); |
7620 | 4067 } else { |
5260 | 4068 gaim_gtk_blist_hide_node(list, node); |
5228 | 4069 } |
7620 | 4070 } |
4071 | |
4072 static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node) | |
4073 { | |
4074 if(!gtkblist) | |
4075 return; | |
4076 | |
4077 switch(node->type) { | |
4078 case GAIM_BLIST_GROUP_NODE: | |
4079 gaim_gtk_blist_update_group(list, node); | |
4080 break; | |
4081 case GAIM_BLIST_CONTACT_NODE: | |
4082 gaim_gtk_blist_update_contact(list, node); | |
4083 break; | |
4084 case GAIM_BLIST_BUDDY_NODE: | |
4085 gaim_gtk_blist_update_buddy(list, node); | |
4086 break; | |
4087 case GAIM_BLIST_CHAT_NODE: | |
4088 gaim_gtk_blist_update_chat(list, node); | |
4089 break; | |
4090 case GAIM_BLIST_OTHER_NODE: | |
4091 return; | |
4092 } | |
5234 | 4093 |
5228 | 4094 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); |
4095 } | |
4096 | |
7620 | 4097 |
4098 static void gaim_gtk_blist_destroy(GaimBuddyList *list) | |
5228 | 4099 { |
4100 if (!gtkblist) | |
4101 return; | |
4102 | |
8937 | 4103 gaim_signal_disconnect(gaim_connections_get_handle(), "signed-on", |
4104 gtkblist, GAIM_CALLBACK(sign_on_off_cb)); | |
4105 gaim_signal_disconnect(gaim_connections_get_handle(), "signed-off", | |
4106 gtkblist, GAIM_CALLBACK(sign_on_off_cb)); | |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
4107 |
5228 | 4108 gtk_widget_destroy(gtkblist->window); |
7620 | 4109 |
8254 | 4110 gaim_gtk_blist_tooltip_destroy(); |
7620 | 4111 |
5228 | 4112 if (gtkblist->refresh_timer) |
4113 g_source_remove(gtkblist->refresh_timer); | |
4114 if (gtkblist->timeout) | |
4115 g_source_remove(gtkblist->timeout); | |
10354 | 4116 if (gtkblist->drag_timeout) |
4117 g_source_remove(gtkblist->drag_timeout); | |
5228 | 4118 |
4119 gtkblist->refresh_timer = 0; | |
4120 gtkblist->timeout = 0; | |
10354 | 4121 gtkblist->drag_timeout = 0; |
5228 | 4122 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; |
4123 gtkblist->treemodel = NULL; | |
4124 gtkblist->idle_column = NULL; | |
11257 | 4125 gtkblist->buddy_icon_column = NULL; |
5427 | 4126 g_object_unref(G_OBJECT(gtkblist->ift)); |
5228 | 4127 protomenu = NULL; |
4128 gtkblist = NULL; | |
7620 | 4129 |
10087 | 4130 gaim_prefs_disconnect_by_handle(gaim_gtk_blist_get_handle()); |
5228 | 4131 } |
4132 | |
7620 | 4133 static void gaim_gtk_blist_set_visible(GaimBuddyList *list, gboolean show) |
5228 | 4134 { |
4135 if (!(gtkblist && gtkblist->window)) | |
4136 return; | |
10325 | 4137 |
5228 | 4138 if (show) { |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4139 if(!GAIM_WINDOW_ICONIFIED(gtkblist->window) && !GTK_WIDGET_VISIBLE(gtkblist->window)) |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4140 gaim_signal_emit(gaim_gtk_blist_get_handle(), "gtkblist-unhiding", gtkblist); |
5228 | 4141 gaim_gtk_blist_restore_position(); |
4142 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
4143 } else { | |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4144 if(visibility_manager_count) { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4145 gaim_signal_emit(gaim_gtk_blist_get_handle(), "gtkblist-hiding", gtkblist); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4146 gtk_widget_hide(gtkblist->window); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4147 } else { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4148 gtk_window_iconify(GTK_WINDOW(gtkblist->window)); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4149 } |
5228 | 4150 } |
4151 } | |
4152 | |
7620 | 4153 static GList * |
4154 groups_tree(void) | |
4155 { | |
4156 GList *tmp = NULL; | |
4157 char *tmp2; | |
4158 GaimGroup *g; | |
4159 GaimBlistNode *gnode; | |
4160 | |
4161 if (gaim_get_blist()->root == NULL) | |
4162 { | |
4163 tmp2 = g_strdup(_("Buddies")); | |
4164 tmp = g_list_append(tmp, tmp2); | |
4165 } | |
4166 else | |
4167 { | |
4168 for (gnode = gaim_get_blist()->root; | |
4169 gnode != NULL; | |
4170 gnode = gnode->next) | |
4171 { | |
4172 if (GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
4173 { | |
4174 g = (GaimGroup *)gnode; | |
4175 tmp2 = g->name; | |
4176 tmp = g_list_append(tmp, tmp2); | |
4177 } | |
4178 } | |
4179 } | |
4180 | |
4181 return tmp; | |
4182 } | |
4183 | |
4184 static void | |
4185 add_buddy_select_account_cb(GObject *w, GaimAccount *account, | |
4186 GaimGtkAddBuddyData *data) | |
4187 { | |
4188 /* Save our account */ | |
4189 data->account = account; | |
4190 } | |
4191 | |
4192 static void | |
4193 destroy_add_buddy_dialog_cb(GtkWidget *win, GaimGtkAddBuddyData *data) | |
4194 { | |
4195 g_free(data); | |
4196 } | |
4197 | |
4198 static void | |
4199 add_buddy_cb(GtkWidget *w, int resp, GaimGtkAddBuddyData *data) | |
4200 { | |
4201 const char *grp, *who, *whoalias; | |
4202 GaimConversation *c; | |
4203 GaimBuddy *b; | |
4204 GaimGroup *g; | |
4205 | |
4206 if (resp == GTK_RESPONSE_OK) | |
4207 { | |
4208 who = gtk_entry_get_text(GTK_ENTRY(data->entry)); | |
4209 grp = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(data->combo)->entry)); | |
4210 whoalias = gtk_entry_get_text(GTK_ENTRY(data->entry_for_alias)); | |
9658 | 4211 if (*whoalias == '\0') |
4212 whoalias = NULL; | |
7620 | 4213 |
4214 if ((g = gaim_find_group(grp)) == NULL) | |
4215 { | |
4216 g = gaim_group_new(grp); | |
4217 gaim_blist_add_group(g, NULL); | |
4218 } | |
4219 | |
4220 b = gaim_buddy_new(data->account, who, whoalias); | |
4221 gaim_blist_add_buddy(b, NULL, g, NULL); | |
11643 | 4222 gaim_account_add_buddy(data->account, b); |
7620 | 4223 |
7887 | 4224 /* |
9285 | 4225 * XXX |
11643 | 4226 * It really seems like it would be better if the call to |
4227 * gaim_account_add_buddy() and gaim_conversation_update() were done in | |
4228 * blist.c, possibly in the gaim_blist_add_buddy() function. Maybe | |
4229 * gaim_account_add_buddy() should be renamed to | |
4230 * gaim_blist_add_new_buddy() or something, and have it call | |
7887 | 4231 * gaim_blist_add_buddy() after it creates it. --Mark |
9285 | 4232 * |
4233 * No that's not good. blist.c should only deal with adding nodes to the | |
11643 | 4234 * local list. We need a new, non-gtk file that calls both |
4235 * gaim_account_add_buddy and gaim_blist_add_buddy(). | |
4236 * Or something. --Mark | |
7887 | 4237 */ |
4238 | |
11338 | 4239 c = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, who, data->account); |
7620 | 4240 if (c != NULL) { |
4241 gaim_buddy_icon_update(gaim_conv_im_get_icon(GAIM_CONV_IM(c))); | |
4242 gaim_conversation_update(c, GAIM_CONV_UPDATE_ADD); | |
4243 } | |
4244 } | |
4245 | |
4246 gtk_widget_destroy(data->window); | |
4247 } | |
4248 | |
4249 static void | |
4250 gaim_gtk_blist_request_add_buddy(GaimAccount *account, const char *username, | |
4251 const char *group, const char *alias) | |
4252 { | |
4253 GtkWidget *table; | |
4254 GtkWidget *label; | |
4255 GtkWidget *hbox; | |
4256 GtkWidget *vbox; | |
4257 GtkWidget *img; | |
4258 GaimGtkBuddyList *gtkblist; | |
4259 GaimGtkAddBuddyData *data = g_new0(GaimGtkAddBuddyData, 1); | |
4260 | |
4261 data->account = | |
4262 (account != NULL | |
4263 ? account | |
4264 : gaim_connection_get_account(gaim_connections_get_all()->data)); | |
4265 | |
4266 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
4267 GTK_ICON_SIZE_DIALOG); | |
4268 | |
4269 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); | |
4270 | |
4271 data->window = gtk_dialog_new_with_buttons(_("Add Buddy"), | |
8975 | 4272 NULL, GTK_DIALOG_NO_SEPARATOR, |
7620 | 4273 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
4274 GTK_STOCK_ADD, GTK_RESPONSE_OK, | |
4275 NULL); | |
4276 | |
4277 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); | |
11243 | 4278 gtk_container_set_border_width(GTK_CONTAINER(data->window), GAIM_HIG_BOX_SPACE); |
7620 | 4279 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); |
11243 | 4280 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BORDER); |
4281 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BOX_SPACE); | |
7620 | 4282 gtk_window_set_role(GTK_WINDOW(data->window), "add_buddy"); |
8975 | 4283 gtk_window_set_type_hint(GTK_WINDOW(data->window), |
9811 | 4284 GDK_WINDOW_TYPE_HINT_DIALOG); |
7620 | 4285 |
11243 | 4286 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
7620 | 4287 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); |
4288 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
4289 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
4290 | |
4291 vbox = gtk_vbox_new(FALSE, 0); | |
4292 gtk_container_add(GTK_CONTAINER(hbox), vbox); | |
4293 | |
4294 label = gtk_label_new( | |
4295 _("Please enter the screen name of the person you would like " | |
4296 "to add to your buddy list. You may optionally enter an alias, " | |
4297 "or nickname, for the buddy. The alias will be displayed in " | |
4298 "place of the screen name whenever possible.\n")); | |
4299 | |
4300 gtk_widget_set_size_request(GTK_WIDGET(label), 400, -1); | |
4301 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
4302 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
4303 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
4304 | |
11243 | 4305 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); |
7620 | 4306 gtk_container_add(GTK_CONTAINER(vbox), hbox); |
4307 | |
4308 g_signal_connect(G_OBJECT(data->window), "destroy", | |
4309 G_CALLBACK(destroy_add_buddy_dialog_cb), data); | |
4310 | |
4311 table = gtk_table_new(4, 2, FALSE); | |
4312 gtk_table_set_row_spacings(GTK_TABLE(table), 5); | |
4313 gtk_table_set_col_spacings(GTK_TABLE(table), 5); | |
4314 gtk_container_set_border_width(GTK_CONTAINER(table), 0); | |
4315 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); | |
4316 | |
4317 label = gtk_label_new(_("Screen Name:")); | |
4318 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4319 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); | |
4320 | |
4321 data->entry = gtk_entry_new(); | |
4322 gtk_table_attach_defaults(GTK_TABLE(table), data->entry, 1, 2, 0, 1); | |
4323 gtk_widget_grab_focus(data->entry); | |
4324 | |
4325 if (username != NULL) | |
4326 gtk_entry_set_text(GTK_ENTRY(data->entry), username); | |
4327 | |
4328 gtk_entry_set_activates_default (GTK_ENTRY(data->entry), TRUE); | |
8137 | 4329 gaim_set_accessible_label (data->entry, label); |
7620 | 4330 |
4331 label = gtk_label_new(_("Alias:")); | |
4332 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4333 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | |
4334 | |
4335 data->entry_for_alias = gtk_entry_new(); | |
4336 gtk_table_attach_defaults(GTK_TABLE(table), | |
4337 data->entry_for_alias, 1, 2, 1, 2); | |
4338 | |
4339 if (alias != NULL) | |
4340 gtk_entry_set_text(GTK_ENTRY(data->entry_for_alias), alias); | |
4341 | |
10734
8b2c81d9b271
[gaim-migrate @ 12336]
Luke Schierer <lschiere@pidgin.im>
parents:
10694
diff
changeset
|
4342 if (username != NULL) |
8b2c81d9b271
[gaim-migrate @ 12336]
Luke Schierer <lschiere@pidgin.im>
parents:
10694
diff
changeset
|
4343 gtk_widget_grab_focus(GTK_WIDGET(data->entry_for_alias)); |
8b2c81d9b271
[gaim-migrate @ 12336]
Luke Schierer <lschiere@pidgin.im>
parents:
10694
diff
changeset
|
4344 |
7620 | 4345 gtk_entry_set_activates_default (GTK_ENTRY(data->entry_for_alias), TRUE); |
8137 | 4346 gaim_set_accessible_label (data->entry_for_alias, label); |
7620 | 4347 |
4348 label = gtk_label_new(_("Group:")); | |
4349 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4350 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); | |
4351 | |
4352 data->combo = gtk_combo_new(); | |
4353 gtk_combo_set_popdown_strings(GTK_COMBO(data->combo), groups_tree()); | |
4354 gtk_table_attach_defaults(GTK_TABLE(table), data->combo, 1, 2, 2, 3); | |
8137 | 4355 gaim_set_accessible_label (data->combo, label); |
7620 | 4356 |
4357 /* Set up stuff for the account box */ | |
4358 label = gtk_label_new(_("Account:")); | |
4359 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4360 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); | |
4361 | |
4362 data->account_box = gaim_gtk_account_option_menu_new(account, FALSE, | |
4363 G_CALLBACK(add_buddy_select_account_cb), NULL, data); | |
4364 | |
4365 gtk_table_attach_defaults(GTK_TABLE(table), data->account_box, 1, 2, 3, 4); | |
8137 | 4366 gaim_set_accessible_label (data->account_box, label); |
7620 | 4367 /* End of account box */ |
4368 | |
4369 g_signal_connect(G_OBJECT(data->window), "response", | |
4370 G_CALLBACK(add_buddy_cb), data); | |
4371 | |
4372 gtk_widget_show_all(data->window); | |
4373 | |
4374 if (group != NULL) | |
4375 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(data->combo)->entry), group); | |
4376 } | |
4377 | |
4378 static void | |
4379 add_chat_cb(GtkWidget *w, GaimGtkAddChatData *data) | |
4380 { | |
4381 GHashTable *components; | |
4382 GList *tmp; | |
4383 GaimChat *chat; | |
4384 GaimGroup *group; | |
4385 const char *group_name; | |
9918 | 4386 char *chat_name = NULL; |
4387 GaimConversation *conv = NULL; | |
10475 | 4388 const char *value; |
7620 | 4389 |
4390 components = g_hash_table_new_full(g_str_hash, g_str_equal, | |
4391 g_free, g_free); | |
4392 | |
4393 for (tmp = data->entries; tmp; tmp = tmp->next) | |
4394 { | |
4395 if (g_object_get_data(tmp->data, "is_spin")) | |
4396 { | |
4397 g_hash_table_replace(components, | |
4398 g_strdup(g_object_get_data(tmp->data, "identifier")), | |
4399 g_strdup_printf("%d", | |
4400 gtk_spin_button_get_value_as_int(tmp->data))); | |
4401 } | |
4402 else | |
4403 { | |
10475 | 4404 value = gtk_entry_get_text(tmp->data); |
4405 if (*value != '\0') | |
4406 g_hash_table_replace(components, | |
4407 g_strdup(g_object_get_data(tmp->data, "identifier")), | |
4408 g_strdup(value)); | |
7620 | 4409 } |
4410 } | |
4411 | |
4412 chat = gaim_chat_new(data->account, | |
4413 gtk_entry_get_text(GTK_ENTRY(data->alias_entry)), | |
4414 components); | |
4415 | |
4416 group_name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(data->group_combo)->entry)); | |
4417 | |
4418 if ((group = gaim_find_group(group_name)) == NULL) | |
4419 { | |
4420 group = gaim_group_new(group_name); | |
4421 gaim_blist_add_group(group, NULL); | |
4422 } | |
4423 | |
4424 if (chat != NULL) | |
4425 { | |
4426 gaim_blist_add_chat(chat, group, NULL); | |
9918 | 4427 |
4428 if (GAIM_PLUGIN_PROTOCOL_INFO(data->account->gc->prpl)->get_chat_name != NULL) | |
4429 chat_name = GAIM_PLUGIN_PROTOCOL_INFO( | |
4430 data->account->gc->prpl)->get_chat_name(chat->components); | |
10246 | 4431 |
9918 | 4432 if (chat_name != NULL) { |
11338 | 4433 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
10246 | 4434 chat_name, |
4435 data->account); | |
9918 | 4436 g_free(chat_name); |
4437 } | |
4438 | |
4439 if (conv != NULL) | |
4440 gaim_conversation_update(conv, GAIM_CONV_UPDATE_ADD); | |
7620 | 4441 } |
4442 | |
4443 gtk_widget_destroy(data->window); | |
9812 | 4444 g_free(data->default_chat_name); |
7620 | 4445 g_list_free(data->entries); |
4446 g_free(data); | |
4447 } | |
4448 | |
4449 static void | |
4450 add_chat_resp_cb(GtkWidget *w, int resp, GaimGtkAddChatData *data) | |
4451 { | |
4452 if (resp == GTK_RESPONSE_OK) | |
4453 { | |
4454 add_chat_cb(NULL, data); | |
4455 } | |
4456 else | |
4457 { | |
4458 gtk_widget_destroy(data->window); | |
9812 | 4459 g_free(data->default_chat_name); |
7620 | 4460 g_list_free(data->entries); |
4461 g_free(data); | |
4462 } | |
4463 } | |
4464 | |
10475 | 4465 /* |
4466 * Check the values of all the text entry boxes. If any required input | |
4467 * strings are empty then don't allow the user to click on "OK." | |
4468 */ | |
4469 static void | |
4470 addchat_set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data) | |
4471 { | |
4472 GaimGtkAddChatData *data; | |
4473 GList *tmp; | |
4474 const char *text; | |
4475 gboolean required; | |
4476 gboolean sensitive = TRUE; | |
4477 | |
4478 data = user_data; | |
4479 | |
4480 for (tmp = data->entries; tmp != NULL; tmp = tmp->next) | |
4481 { | |
4482 if (!g_object_get_data(tmp->data, "is_spin")) | |
4483 { | |
4484 required = GPOINTER_TO_INT(g_object_get_data(tmp->data, "required")); | |
4485 text = gtk_entry_get_text(tmp->data); | |
4486 if (required && (*text == '\0')) | |
4487 sensitive = FALSE; | |
4488 } | |
4489 } | |
4490 | |
4491 gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_OK, sensitive); | |
4492 } | |
4493 | |
7620 | 4494 static void |
4495 rebuild_addchat_entries(GaimGtkAddChatData *data) | |
4496 { | |
4497 GaimConnection *gc; | |
9959 | 4498 GList *list = NULL, *tmp = NULL; |
9754 | 4499 GHashTable *defaults = NULL; |
7620 | 4500 struct proto_chat_entry *pce; |
4501 gboolean focus = TRUE; | |
4502 | |
10127 | 4503 g_return_if_fail(data->account != NULL); |
4504 | |
7620 | 4505 gc = gaim_account_get_connection(data->account); |
4506 | |
4507 while (GTK_BOX(data->entries_box)->children) | |
4508 { | |
4509 gtk_container_remove(GTK_CONTAINER(data->entries_box), | |
10475 | 4510 ((GtkBoxChild *)GTK_BOX(data->entries_box)->children->data)->widget); |
7620 | 4511 } |
4512 | |
4513 if (data->entries != NULL) | |
4514 g_list_free(data->entries); | |
4515 | |
4516 data->entries = NULL; | |
4517 | |
9959 | 4518 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) |
4519 list = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); | |
7620 | 4520 |
9754 | 4521 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) |
10475 | 4522 defaults = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, data->default_chat_name); |
9754 | 4523 |
7620 | 4524 for (tmp = list; tmp; tmp = tmp->next) |
4525 { | |
4526 GtkWidget *label; | |
4527 GtkWidget *rowbox; | |
10475 | 4528 GtkWidget *input; |
7620 | 4529 |
4530 pce = tmp->data; | |
4531 | |
4532 rowbox = gtk_hbox_new(FALSE, 5); | |
4533 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0); | |
4534 | |
7889 | 4535 label = gtk_label_new_with_mnemonic(pce->label); |
7620 | 4536 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
4537 gtk_size_group_add_widget(data->sg, label); | |
4538 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
4539 | |
4540 if (pce->is_int) | |
4541 { | |
4542 GtkObject *adjust; | |
4543 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, | |
4544 1, 10, 10); | |
10475 | 4545 input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); |
4546 gtk_widget_set_size_request(input, 50, -1); | |
4547 gtk_box_pack_end(GTK_BOX(rowbox), input, FALSE, FALSE, 0); | |
7620 | 4548 } |
4549 else | |
4550 { | |
9754 | 4551 char *value; |
10475 | 4552 input = gtk_entry_new(); |
4553 gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE); | |
9754 | 4554 value = g_hash_table_lookup(defaults, pce->identifier); |
4555 if (value != NULL) | |
10475 | 4556 gtk_entry_set_text(GTK_ENTRY(input), value); |
7620 | 4557 if (pce->secret) |
11986 | 4558 { |
10475 | 4559 gtk_entry_set_visibility(GTK_ENTRY(input), FALSE); |
11986 | 4560 gtk_entry_set_invisible_char(GTK_ENTRY(input), GAIM_INVISIBLE_CHAR); |
4561 } | |
10475 | 4562 gtk_box_pack_end(GTK_BOX(rowbox), input, TRUE, TRUE, 0); |
4563 g_signal_connect(G_OBJECT(input), "changed", | |
4564 G_CALLBACK(addchat_set_sensitive_if_input_cb), data); | |
7620 | 4565 } |
4566 | |
10475 | 4567 /* Do the following for any type of input widget */ |
4568 if (focus) | |
4569 { | |
4570 gtk_widget_grab_focus(input); | |
4571 focus = FALSE; | |
4572 } | |
4573 gtk_label_set_mnemonic_widget(GTK_LABEL(label), input); | |
4574 gaim_set_accessible_label(input, label); | |
4575 g_object_set_data(G_OBJECT(input), "identifier", pce->identifier); | |
4576 g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int)); | |
4577 g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required)); | |
4578 data->entries = g_list_append(data->entries, input); | |
4579 | |
7620 | 4580 g_free(pce); |
4581 } | |
4582 | |
4583 g_list_free(list); | |
9754 | 4584 g_hash_table_destroy(defaults); |
7620 | 4585 |
10475 | 4586 /* Set whether the "OK" button should be clickable initially */ |
4587 addchat_set_sensitive_if_input_cb(NULL, data); | |
4588 | |
7620 | 4589 gtk_widget_show_all(data->entries_box); |
4590 } | |
4591 | |
4592 static void | |
10475 | 4593 addchat_select_account_cb(GObject *w, GaimAccount *account, |
7620 | 4594 GaimGtkAddChatData *data) |
4595 { | |
9460 | 4596 if (strcmp(gaim_account_get_protocol_id(data->account), |
4597 gaim_account_get_protocol_id(account)) == 0) | |
7620 | 4598 { |
4599 data->account = account; | |
4600 } | |
4601 else | |
4602 { | |
4603 data->account = account; | |
4604 rebuild_addchat_entries(data); | |
4605 } | |
4606 } | |
4607 | |
4608 void | |
7859 | 4609 gaim_gtk_blist_request_add_chat(GaimAccount *account, GaimGroup *group, |
9754 | 4610 const char *alias, const char *name) |
7620 | 4611 { |
4612 GaimGtkAddChatData *data; | |
8975 | 4613 GaimGtkBuddyList *gtkblist; |
4614 GList *l; | |
4615 GaimConnection *gc; | |
7620 | 4616 GtkWidget *label; |
4617 GtkWidget *rowbox; | |
4618 GtkWidget *hbox; | |
4619 GtkWidget *vbox; | |
4620 GtkWidget *img; | |
4621 | |
9812 | 4622 if (account != NULL) { |
4623 gc = gaim_account_get_connection(account); | |
4624 | |
4625 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat == NULL) { | |
4626 gaim_notify_error(gc, NULL, _("This protocol does not support chat rooms."), NULL); | |
4627 return; | |
4628 } | |
4629 } else { | |
4630 /* Find an account with chat capabilities */ | |
4631 for (l = gaim_connections_get_all(); l != NULL; l = l->next) { | |
4632 gc = (GaimConnection *)l->data; | |
4633 | |
4634 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat != NULL) { | |
4635 account = gaim_connection_get_account(gc); | |
4636 break; | |
4637 } | |
4638 } | |
4639 | |
4640 if (account == NULL) { | |
4641 gaim_notify_error(NULL, NULL, | |
4642 _("You are not currently signed on with any " | |
4643 "protocols that have the ability to chat."), NULL); | |
4644 return; | |
4645 } | |
4646 } | |
4647 | |
7620 | 4648 data = g_new0(GaimGtkAddChatData, 1); |
9812 | 4649 data->account = account; |
4650 data->default_chat_name = g_strdup(name); | |
7620 | 4651 |
4652 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
4653 GTK_ICON_SIZE_DIALOG); | |
4654 | |
8975 | 4655 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); |
4656 | |
7620 | 4657 data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
4658 | |
8975 | 4659 data->window = gtk_dialog_new_with_buttons(_("Add Chat"), |
4660 NULL, GTK_DIALOG_NO_SEPARATOR, | |
4661 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
4662 GTK_STOCK_ADD, GTK_RESPONSE_OK, | |
4663 NULL); | |
4664 | |
4665 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); | |
11243 | 4666 gtk_container_set_border_width(GTK_CONTAINER(data->window), GAIM_HIG_BOX_SPACE); |
8975 | 4667 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); |
11243 | 4668 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BORDER); |
4669 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), GAIM_HIG_BOX_SPACE); | |
7620 | 4670 gtk_window_set_role(GTK_WINDOW(data->window), "add_chat"); |
8975 | 4671 gtk_window_set_type_hint(GTK_WINDOW(data->window), |
9811 | 4672 GDK_WINDOW_TYPE_HINT_DIALOG); |
7620 | 4673 |
11243 | 4674 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER); |
7620 | 4675 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); |
4676 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
4677 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
4678 | |
4679 vbox = gtk_vbox_new(FALSE, 5); | |
4680 gtk_container_add(GTK_CONTAINER(hbox), vbox); | |
4681 | |
4682 label = gtk_label_new( | |
4683 _("Please enter an alias, and the appropriate information " | |
4684 "about the chat you would like to add to your buddy list.\n")); | |
4685 gtk_widget_set_size_request(label, 400, -1); | |
4686 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
4687 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
4688 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
4689 | |
4690 rowbox = gtk_hbox_new(FALSE, 5); | |
4691 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
4692 | |
4693 label = gtk_label_new(_("Account:")); | |
4694 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4695 gtk_size_group_add_widget(data->sg, label); | |
4696 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
4697 | |
4698 data->account_menu = gaim_gtk_account_option_menu_new(account, FALSE, | |
10475 | 4699 G_CALLBACK(addchat_select_account_cb), |
9987 | 4700 chat_account_filter_func, data); |
7620 | 4701 gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0); |
8137 | 4702 gaim_set_accessible_label (data->account_menu, label); |
7620 | 4703 |
4704 data->entries_box = gtk_vbox_new(FALSE, 5); | |
9811 | 4705 gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0); |
7620 | 4706 gtk_box_pack_start(GTK_BOX(vbox), data->entries_box, TRUE, TRUE, 0); |
4707 | |
4708 rebuild_addchat_entries(data); | |
4709 | |
4710 rowbox = gtk_hbox_new(FALSE, 5); | |
4711 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
4712 | |
4713 label = gtk_label_new(_("Alias:")); | |
4714 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4715 gtk_size_group_add_widget(data->sg, label); | |
4716 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
4717 | |
4718 data->alias_entry = gtk_entry_new(); | |
7859 | 4719 if (alias != NULL) |
4720 gtk_entry_set_text(GTK_ENTRY(data->alias_entry), alias); | |
7620 | 4721 gtk_box_pack_end(GTK_BOX(rowbox), data->alias_entry, TRUE, TRUE, 0); |
10311 | 4722 gtk_entry_set_activates_default(GTK_ENTRY(data->alias_entry), TRUE); |
8137 | 4723 gaim_set_accessible_label (data->alias_entry, label); |
7620 | 4724 |
4725 rowbox = gtk_hbox_new(FALSE, 5); | |
4726 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
4727 | |
9811 | 4728 label = gtk_label_new(_("Group:")); |
7620 | 4729 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
4730 gtk_size_group_add_widget(data->sg, label); | |
4731 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
4732 | |
9811 | 4733 data->group_combo = gtk_combo_new(); |
4734 gtk_combo_set_popdown_strings(GTK_COMBO(data->group_combo), groups_tree()); | |
7620 | 4735 gtk_box_pack_end(GTK_BOX(rowbox), data->group_combo, TRUE, TRUE, 0); |
4736 | |
4737 if (group) | |
4738 { | |
4739 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(data->group_combo)->entry), | |
4740 group->name); | |
4741 } | |
8137 | 4742 gaim_set_accessible_label (data->group_combo, label); |
7620 | 4743 |
4744 g_signal_connect(G_OBJECT(data->window), "response", | |
4745 G_CALLBACK(add_chat_resp_cb), data); | |
4746 | |
4747 gtk_widget_show_all(data->window); | |
4748 } | |
4749 | |
4750 static void | |
4751 add_group_cb(GaimConnection *gc, const char *group_name) | |
4752 { | |
9285 | 4753 GaimGroup *group; |
4754 | |
4755 group = gaim_group_new(group_name); | |
4756 gaim_blist_add_group(group, NULL); | |
7620 | 4757 } |
4758 | |
4759 void | |
4760 gaim_gtk_blist_request_add_group(void) | |
4761 { | |
7853 | 4762 gaim_request_input(NULL, _("Add Group"), NULL, |
7620 | 4763 _("Please enter the name of the group to be added."), |
8697 | 4764 NULL, FALSE, FALSE, NULL, |
7620 | 4765 _("Add"), G_CALLBACK(add_group_cb), |
4766 _("Cancel"), NULL, NULL); | |
4767 } | |
4768 | |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4769 void |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4770 gaim_gtk_blist_toggle_visibility() |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4771 { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4772 if (gtkblist && gtkblist->window) { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4773 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4774 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gtk_blist_obscured); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4775 } else { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4776 gaim_blist_set_visible(TRUE); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4777 } |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4778 } |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4779 } |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4780 |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4781 void |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4782 gaim_gtk_blist_visibility_manager_add() |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4783 { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4784 visibility_manager_count++; |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4785 } |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4786 |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4787 void |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4788 gaim_gtk_blist_visibility_manager_remove() |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4789 { |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4790 if (visibility_manager_count) |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4791 visibility_manager_count--; |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4792 if (!visibility_manager_count) |
12115
e9790eb93216
[gaim-migrate @ 14415]
Luke Schierer <lschiere@pidgin.im>
parents:
12113
diff
changeset
|
4793 gaim_blist_set_visible(gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")); |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4794 } |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4795 |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4796 |
7620 | 4797 static GaimBlistUiOps blist_ui_ops = |
5228 | 4798 { |
4799 gaim_gtk_blist_new_list, | |
5256 | 4800 gaim_gtk_blist_new_node, |
5228 | 4801 gaim_gtk_blist_show, |
4802 gaim_gtk_blist_update, | |
4803 gaim_gtk_blist_remove, | |
4804 gaim_gtk_blist_destroy, | |
7620 | 4805 gaim_gtk_blist_set_visible, |
4806 gaim_gtk_blist_request_add_buddy, | |
4807 gaim_gtk_blist_request_add_chat, | |
10012 | 4808 gaim_gtk_blist_request_add_group |
5228 | 4809 }; |
4810 | |
4811 | |
7620 | 4812 GaimBlistUiOps * |
4813 gaim_gtk_blist_get_ui_ops(void) | |
5228 | 4814 { |
4815 return &blist_ui_ops; | |
4816 } | |
4817 | |
10643 | 4818 GaimGtkBuddyList *gaim_gtk_blist_get_default_gtk_blist() |
4819 { | |
4820 return gtkblist; | |
4821 } | |
4822 | |
7620 | 4823 static void account_signon_cb(GaimConnection *gc, gpointer z) |
4824 { | |
4825 GaimAccount *account = gaim_connection_get_account(gc); | |
4826 GaimBlistNode *gnode, *cnode; | |
4827 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) | |
4828 { | |
4829 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
4830 continue; | |
4831 for(cnode = gnode->child; cnode; cnode = cnode->next) | |
4832 { | |
4833 GaimChat *chat; | |
4834 | |
4835 if(!GAIM_BLIST_NODE_IS_CHAT(cnode)) | |
4836 continue; | |
4837 | |
4838 chat = (GaimChat *)cnode; | |
4839 | |
4840 if(chat->account != account) | |
4841 continue; | |
4842 | |
8197 | 4843 if(gaim_blist_node_get_bool((GaimBlistNode*)chat, "gtk-autojoin") || |
8198 | 4844 (gaim_blist_node_get_string((GaimBlistNode*)chat, |
4845 "gtk-autojoin") != NULL)) | |
7620 | 4846 serv_join_chat(gc, chat->components); |
4847 } | |
4848 } | |
4849 } | |
4850 | |
8815 | 4851 void * |
4852 gaim_gtk_blist_get_handle() { | |
4853 static int handle; | |
4854 | |
4855 return &handle; | |
4856 } | |
4857 | |
11910 | 4858 static gboolean buddy_signonoff_timeout_cb(GaimBuddy *buddy) |
4859 { | |
4860 struct _gaim_gtk_blist_node *gtknode = ((GaimBlistNode*)buddy)->ui_data; | |
4861 GaimConversation *conv; | |
4862 | |
4863 gtknode->recent_signonoff = FALSE; | |
4864 gtknode->recent_signonoff_timer = 0; | |
4865 | |
4866 gaim_gtk_blist_update(NULL, (GaimBlistNode*)buddy); | |
4867 | |
4868 if((conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, buddy->name, buddy->account))) { | |
4869 if(GAIM_BUDDY_IS_ONLINE(buddy)) { | |
4870 gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_ONLINE); | |
4871 } else { | |
4872 gaim_conversation_update(conv, GAIM_CONV_ACCOUNT_OFFLINE); | |
4873 } | |
4874 } | |
4875 | |
4876 return FALSE; | |
4877 } | |
4878 | |
4879 static void buddy_signonoff_cb(GaimBuddy *buddy) | |
4880 { | |
11915 | 4881 struct _gaim_gtk_blist_node *gtknode; |
4882 | |
4883 if(!((GaimBlistNode*)buddy)->ui_data) { | |
4884 gaim_gtk_blist_new_node((GaimBlistNode*)buddy); | |
4885 } | |
4886 | |
4887 gtknode = ((GaimBlistNode*)buddy)->ui_data; | |
11910 | 4888 |
4889 gtknode->recent_signonoff = TRUE; | |
4890 | |
4891 if(gtknode->recent_signonoff_timer > 0) | |
4892 gaim_timeout_remove(gtknode->recent_signonoff_timer); | |
4893 gtknode->recent_signonoff_timer = gaim_timeout_add(10000, | |
4894 (GSourceFunc)buddy_signonoff_timeout_cb, buddy); | |
4895 } | |
4896 | |
7620 | 4897 void gaim_gtk_blist_init(void) |
4898 { | |
8815 | 4899 void *gtk_blist_handle = gaim_gtk_blist_get_handle(); |
7620 | 4900 |
4901 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | |
8815 | 4902 gtk_blist_handle, GAIM_CALLBACK(account_signon_cb), |
7620 | 4903 NULL); |
7731 | 4904 |
4905 /* Initialize prefs */ | |
8819 | 4906 gaim_prefs_add_none("/gaim/gtk/blist"); |
4907 gaim_prefs_add_bool("/gaim/gtk/blist/show_buddy_icons", TRUE); | |
4908 gaim_prefs_add_bool("/gaim/gtk/blist/show_empty_groups", FALSE); | |
4909 gaim_prefs_add_bool("/gaim/gtk/blist/show_offline_buddies", FALSE); | |
10282 | 4910 gaim_prefs_add_bool("/gaim/gtk/blist/list_visible", TRUE); |
9711 | 4911 gaim_prefs_add_string("/gaim/gtk/blist/sort_type", "alphabetical"); |
8819 | 4912 gaim_prefs_add_int("/gaim/gtk/blist/x", 0); |
4913 gaim_prefs_add_int("/gaim/gtk/blist/y", 0); | |
9778 | 4914 gaim_prefs_add_int("/gaim/gtk/blist/width", 309); /* Golden ratio, baby */ |
4915 gaim_prefs_add_int("/gaim/gtk/blist/height", 500); /* Golden ratio, baby */ | |
12124
9c123e27e2f6
[gaim-migrate @ 14424]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12119
diff
changeset
|
4916 gaim_prefs_add_int("/gaim/gtk/blist/pane", 300); |
8819 | 4917 gaim_prefs_add_int("/gaim/gtk/blist/tooltip_delay", 500); |
7731 | 4918 |
8815 | 4919 /* Register our signals */ |
12016
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4920 gaim_signal_register(gtk_blist_handle, "gtkblist-hiding", |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4921 gaim_marshal_VOID__POINTER, NULL, 1, |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4922 gaim_value_new(GAIM_TYPE_POINTER)); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4923 |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4924 gaim_signal_register(gtk_blist_handle, "gtkblist-unhiding", |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4925 gaim_marshal_VOID__POINTER, NULL, 1, |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4926 gaim_value_new(GAIM_TYPE_SUBTYPE)); |
24c7fb94d3a3
[gaim-migrate @ 14309]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11988
diff
changeset
|
4927 |
8815 | 4928 gaim_signal_register(gtk_blist_handle, "gtkblist-created", |
9811 | 4929 gaim_marshal_VOID__POINTER, NULL, 1, |
4930 gaim_value_new(GAIM_TYPE_SUBTYPE, | |
4931 GAIM_SUBTYPE_BLIST)); | |
8819 | 4932 |
4933 gaim_signal_register(gtk_blist_handle, "drawing-tooltip", | |
9811 | 4934 gaim_marshal_VOID__POINTER_POINTER, NULL, 2, |
4935 gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_BLIST_NODE), | |
10477 | 4936 gaim_value_new_outgoing(GAIM_TYPE_BOXED, "GString *")); |
11910 | 4937 |
4938 | |
4939 gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", gtk_blist_handle, GAIM_CALLBACK(buddy_signonoff_cb), NULL); | |
4940 gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-off", gtk_blist_handle, GAIM_CALLBACK(buddy_signonoff_cb), NULL); | |
7620 | 4941 } |
4942 | |
8815 | 4943 void |
4944 gaim_gtk_blist_uninit(void) { | |
4945 gaim_signals_unregister_by_instance(gaim_gtk_blist_get_handle()); | |
4946 } | |
5228 | 4947 |
4948 /********************************************************************* | |
9811 | 4949 * Buddy List sorting functions * |
5422 | 4950 *********************************************************************/ |
4951 | |
11796 | 4952 GList *gaim_gtk_blist_get_sort_methods() |
4953 { | |
4954 return gaim_gtk_blist_sort_methods; | |
4955 } | |
4956 | |
7620 | 4957 void gaim_gtk_blist_sort_method_reg(const char *id, const char *name, gaim_gtk_blist_sort_function func) |
5422 | 4958 { |
4959 struct gaim_gtk_blist_sort_method *method = g_new0(struct gaim_gtk_blist_sort_method, 1); | |
7620 | 4960 method->id = g_strdup(id); |
5422 | 4961 method->name = g_strdup(name); |
9775 | 4962 method->func = func; |
11796 | 4963 gaim_gtk_blist_sort_methods = g_list_append(gaim_gtk_blist_sort_methods, method); |
4964 gaim_gtk_blist_update_sort_methods(); | |
5422 | 4965 } |
4966 | |
7620 | 4967 void gaim_gtk_blist_sort_method_unreg(const char *id){ |
11796 | 4968 GList *l = gaim_gtk_blist_sort_methods; |
7620 | 4969 |
4970 while(l) { | |
4971 struct gaim_gtk_blist_sort_method *method = l->data; | |
4972 if(!strcmp(method->id, id)) { | |
11796 | 4973 gaim_gtk_blist_sort_methods = g_list_delete_link(gaim_gtk_blist_sort_methods, l); |
7620 | 4974 g_free(method->id); |
4975 g_free(method->name); | |
4976 g_free(method); | |
4977 break; | |
4978 } | |
4979 } | |
11796 | 4980 gaim_gtk_blist_update_sort_methods(); |
5422 | 4981 } |
4982 | |
7620 | 4983 void gaim_gtk_blist_sort_method_set(const char *id){ |
11796 | 4984 GList *l = gaim_gtk_blist_sort_methods; |
7620 | 4985 |
4986 if(!id) | |
4987 id = "none"; | |
4988 | |
4989 while (l && strcmp(((struct gaim_gtk_blist_sort_method*)l->data)->id, id)) | |
5422 | 4990 l = l->next; |
7620 | 4991 |
5422 | 4992 if (l) { |
4993 current_sort_method = l->data; | |
4994 } else if (!current_sort_method) { | |
7620 | 4995 gaim_gtk_blist_sort_method_set("none"); |
5422 | 4996 return; |
4997 } | |
4998 redo_buddy_list(gaim_get_blist(), TRUE); | |
4999 | |
5000 } | |
5001 | |
5002 /****************************************** | |
5003 ** Sort Methods | |
5004 ******************************************/ | |
5005 | |
7620 | 5006 static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter parent_iter, GtkTreeIter *cur) |
5422 | 5007 { |
7620 | 5008 GtkTreeIter iter; |
5009 GaimBlistNode *sibling = node->prev; | |
5010 GtkTreeIter sibling_iter; | |
5011 | |
5012 if(cur) | |
5422 | 5013 return *cur; |
7620 | 5014 |
5015 while (sibling && !get_iter_from_node(sibling, &sibling_iter)) { | |
5016 sibling = sibling->prev; | |
5422 | 5017 } |
7620 | 5018 |
5019 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, | |
5020 node->parent ? &parent_iter : NULL, | |
5021 sibling ? &sibling_iter : NULL); | |
5022 | |
5422 | 5023 return iter; |
5024 } | |
5025 | |
7620 | 5026 #if GTK_CHECK_VERSION(2,2,1) |
5027 | |
5028 static GtkTreeIter sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) | |
5422 | 5029 { |
5030 GtkTreeIter more_z, iter; | |
5031 GaimBlistNode *n; | |
5032 GValue val = {0,}; | |
7620 | 5033 |
5034 const char *my_name; | |
5035 | |
5036 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
5037 my_name = gaim_contact_get_alias((GaimContact*)node); | |
5038 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
5039 my_name = gaim_chat_get_name((GaimChat*)node); | |
5040 } else { | |
5041 return sort_method_none(node, blist, groupiter, cur); | |
5042 } | |
5043 | |
5422 | 5044 |
5045 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { | |
5046 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
7620 | 5047 return iter; |
5048 } | |
5049 | |
5050 do { | |
5051 const char *this_name; | |
5052 int cmp; | |
5053 | |
5054 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); | |
5055 n = g_value_get_pointer(&val); | |
5056 | |
5057 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
5058 this_name = gaim_contact_get_alias((GaimContact*)n); | |
5059 } else if(GAIM_BLIST_NODE_IS_CHAT(n)) { | |
5060 this_name = gaim_chat_get_name((GaimChat*)n); | |
5061 } else { | |
5062 this_name = NULL; | |
5063 } | |
5064 | |
5065 cmp = gaim_utf8_strcasecmp(my_name, this_name); | |
5066 | |
5067 if(this_name && (cmp < 0 || (cmp == 0 && node < n))) { | |
5068 if(cur) { | |
5069 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); | |
5070 return *cur; | |
5071 } else { | |
5072 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, | |
5073 &groupiter, &more_z); | |
5074 return iter; | |
5075 } | |
5076 } | |
5077 g_value_unset(&val); | |
5078 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z)); | |
5079 | |
5080 if(cur) { | |
5081 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
5082 return *cur; | |
5083 } else { | |
5084 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
5085 return iter; | |
5086 } | |
5087 } | |
5088 | |
5089 static GtkTreeIter sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) | |
5090 { | |
5091 GtkTreeIter more_z, iter; | |
5092 GaimBlistNode *n; | |
5093 GValue val = {0,}; | |
5094 | |
5095 GaimBuddy *my_buddy, *this_buddy; | |
5096 | |
5097 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
5098 my_buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
5099 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
5100 if(cur) | |
5101 return *cur; | |
5102 | |
5103 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
5104 return iter; | |
5105 } else { | |
5106 return sort_method_none(node, blist, groupiter, cur); | |
5107 } | |
5108 | |
5109 | |
5110 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { | |
5111 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
5422 | 5112 return iter; |
5113 } | |
5114 | |
5115 do { | |
9944 | 5116 gint name_cmp; |
5117 gint presence_cmp; | |
7620 | 5118 |
5422 | 5119 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); |
5120 n = g_value_get_pointer(&val); | |
7620 | 5121 |
5122 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
5123 this_buddy = gaim_contact_get_priority_buddy((GaimContact*)n); | |
5124 } else { | |
5125 this_buddy = NULL; | |
5126 } | |
5127 | |
9944 | 5128 name_cmp = gaim_utf8_strcasecmp( |
5129 (my_buddy | |
5130 ? gaim_contact_get_alias(gaim_buddy_get_contact(my_buddy)) | |
5131 : NULL), | |
5132 (this_buddy | |
5133 ? gaim_contact_get_alias(gaim_buddy_get_contact(this_buddy)) | |
5134 : NULL)); | |
5135 | |
5136 presence_cmp = gaim_presence_compare( | |
5137 gaim_buddy_get_presence(my_buddy), | |
5138 gaim_buddy_get_presence(this_buddy)); | |
5139 | |
5140 if (this_buddy == NULL || | |
10860 | 5141 (presence_cmp < 0 || |
9944 | 5142 (presence_cmp == 0 && |
5143 (name_cmp < 0 || (name_cmp == 0 && node < n))))) | |
5144 { | |
5145 if (cur != NULL) | |
5146 { | |
7620 | 5147 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); |
5148 return *cur; | |
9944 | 5149 } |
5150 else | |
5151 { | |
7620 | 5152 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, |
9944 | 5153 &groupiter, &more_z); |
7620 | 5154 return iter; |
5155 } | |
5422 | 5156 } |
9944 | 5157 |
5422 | 5158 g_value_unset(&val); |
9944 | 5159 } |
5160 while (gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), | |
5161 &more_z)); | |
7620 | 5162 |
5163 if(cur) { | |
5164 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
5165 return *cur; | |
5166 } else { | |
5167 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
5168 return iter; | |
5169 } | |
5422 | 5170 } |
5171 | |
7620 | 5172 static GtkTreeIter sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) |
5422 | 5173 { |
5174 GtkTreeIter more_z, iter; | |
7620 | 5175 GaimBlistNode *n = NULL, *n2; |
5422 | 5176 GValue val = {0,}; |
7620 | 5177 |
5178 int log_size = 0, this_log_size = 0; | |
5179 const char *buddy_name, *this_buddy_name; | |
5180 | |
5181 if(cur && (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter) == 1)) | |
5182 return *cur; | |
5183 | |
5184 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
5185 for (n = node->child; n; n = n->next) | |
8898 | 5186 log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy*)(n))->name, ((GaimBuddy*)(n))->account); |
7620 | 5187 buddy_name = gaim_contact_get_alias((GaimContact*)node); |
5188 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
5189 /* we don't have a reliable way of getting the log filename | |
5190 * from the chat info in the blist, yet */ | |
5191 if(cur) | |
5192 return *cur; | |
5193 | |
5194 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
5195 return iter; | |
5196 } else { | |
5197 return sort_method_none(node, blist, groupiter, cur); | |
5198 } | |
5199 | |
5200 | |
5422 | 5201 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { |
5202 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
5203 return iter; | |
5204 } | |
5205 | |
5206 do { | |
7620 | 5207 int cmp; |
5208 | |
5422 | 5209 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); |
5210 n = g_value_get_pointer(&val); | |
7620 | 5211 this_log_size = 0; |
5212 | |
5213 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
5214 for (n2 = n->child; n2; n2 = n2->next) | |
8898 | 5215 this_log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy*)(n2))->name, ((GaimBuddy*)(n2))->account); |
7620 | 5216 this_buddy_name = gaim_contact_get_alias((GaimContact*)n); |
5217 } else { | |
5218 this_buddy_name = NULL; | |
5422 | 5219 } |
7620 | 5220 |
5221 cmp = gaim_utf8_strcasecmp(buddy_name, this_buddy_name); | |
5222 | |
5223 if (!GAIM_BLIST_NODE_IS_CONTACT(n) || log_size > this_log_size || | |
5224 ((log_size == this_log_size) && | |
5225 (cmp < 0 || (cmp == 0 && node < n)))) { | |
5226 if(cur) { | |
5227 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); | |
5228 return *cur; | |
5229 } else { | |
5230 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, | |
5231 &groupiter, &more_z); | |
5232 return iter; | |
5233 } | |
5422 | 5234 } |
5235 g_value_unset(&val); | |
5236 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z)); | |
7620 | 5237 |
5238 if(cur) { | |
5239 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
5240 return *cur; | |
5241 } else { | |
5242 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
5243 return iter; | |
5244 } | |
5245 } | |
5246 | |
5247 #endif | |
5248 | |
5249 static void | |
9015 | 5250 plugin_act(GtkObject *obk, GaimPluginAction *pam) |
7620 | 5251 { |
10352 | 5252 if (pam->callback) |
5253 pam->callback(pam); | |
5422 | 5254 } |
7620 | 5255 |
11742 | 5256 static GList *plugin_menu_items = NULL; |
12136
370f9d7868f9
[gaim-migrate @ 14436]
Richard Laager <rlaager@wiktel.com>
parents:
12133
diff
changeset
|
5257 static int plugin_menu_index = 10; |
11742 | 5258 |
8986 | 5259 static void |
9015 | 5260 build_plugin_actions(GtkWidget *menu, GaimPlugin *plugin, gpointer context) |
8986 | 5261 { |
9015 | 5262 GtkWidget *menuitem = NULL; |
5263 GaimPluginAction *action = NULL; | |
5264 GList *l, *ll; | |
5265 | |
5266 for (l = ll = GAIM_PLUGIN_ACTIONS(plugin, context); l; l = l->next) { | |
5267 if (l->data) { | |
5268 action = (GaimPluginAction *) l->data; | |
5269 action->plugin = plugin; | |
5270 action->context = context; | |
5271 | |
5272 menuitem = gtk_menu_item_new_with_label(action->label); | |
11745 | 5273 if (context) { |
5274 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
5275 } else { | |
5276 plugin_menu_items = g_list_append(plugin_menu_items, menuitem); | |
5277 plugin_menu_index++; | |
5278 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menuitem, plugin_menu_index); | |
5279 } | |
9015 | 5280 g_signal_connect(G_OBJECT(menuitem), "activate", |
5281 G_CALLBACK(plugin_act), action); | |
5282 g_object_set_data(G_OBJECT(menuitem), "plugin_action", action); | |
5283 gtk_widget_show(menuitem); | |
5284 } | |
5285 else | |
5286 gaim_separator(menu); | |
5287 } | |
5288 | |
5289 g_list_free(ll); | |
8986 | 5290 } |
5291 | |
5292 | |
7620 | 5293 void |
5294 gaim_gtk_blist_update_protocol_actions(void) | |
5295 { | |
9015 | 5296 GtkWidget *menuitem, *submenu; |
7620 | 5297 GList *l; |
5298 GaimConnection *gc = NULL; | |
9015 | 5299 GaimPlugin *plugin = NULL; |
7620 | 5300 int count = 0; |
9015 | 5301 |
9019 | 5302 if (protomenu == NULL) |
7620 | 5303 return; |
5304 | |
9019 | 5305 /* Clear the old Account Actions menu */ |
9015 | 5306 for (l = gtk_container_get_children(GTK_CONTAINER(protomenu)); l; l = l->next) { |
5307 GaimPluginAction *action; | |
9987 | 5308 |
7620 | 5309 menuitem = l->data; |
9015 | 5310 action = (GaimPluginAction *) g_object_get_data(G_OBJECT(menuitem), |
5311 "plugin_action"); | |
5312 g_free(action); | |
7620 | 5313 |
5314 gtk_container_remove(GTK_CONTAINER(protomenu), GTK_WIDGET(menuitem)); | |
5315 } | |
5316 | |
9019 | 5317 /* Count the number of accounts with actions */ |
9015 | 5318 for (l = gaim_connections_get_all(); l; l = l->next) { |
5319 gc = l->data; | |
5320 plugin = gc->prpl; | |
5321 | |
9019 | 5322 if (GAIM_CONNECTION_IS_CONNECTED(gc) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
5323 count++; | |
5324 | |
9015 | 5325 /* no need to count past 2, so don't */ |
9019 | 5326 if (count > 1) |
9015 | 5327 break; |
7620 | 5328 } |
5329 | |
9015 | 5330 if (count == 0) { |
5331 menuitem = gtk_menu_item_new_with_label(_("No actions available")); | |
7620 | 5332 gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem); |
9015 | 5333 gtk_widget_set_sensitive(menuitem, FALSE); |
7620 | 5334 gtk_widget_show(menuitem); |
5335 } | |
9019 | 5336 |
5337 else if (count == 1) { | |
5338 /* Find the one account that has actions */ | |
5339 for (l = gaim_connections_get_all(); l; l = l->next) { | |
5340 gc = l->data; | |
5341 plugin = gc->prpl; | |
5342 | |
5343 if (GAIM_CONNECTION_IS_CONNECTED(gc) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) | |
5344 break; | |
5345 } | |
5346 | |
9015 | 5347 build_plugin_actions(protomenu, plugin, gc); |
7620 | 5348 } |
9019 | 5349 |
7620 | 5350 else { |
9015 | 5351 for (l = gaim_connections_get_all(); l; l = l->next) { |
7620 | 5352 GaimAccount *account; |
5353 GdkPixbuf *pixbuf, *scale; | |
5354 GtkWidget *image; | |
9015 | 5355 char *buf; |
5356 | |
5357 gc = l->data; | |
5358 plugin = gc->prpl; | |
5359 | |
9019 | 5360 if (!GAIM_CONNECTION_IS_CONNECTED(gc) || !GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
7620 | 5361 continue; |
5362 | |
5363 account = gaim_connection_get_account(gc); | |
9015 | 5364 buf = g_strconcat(gaim_account_get_username(account), " (", |
5365 plugin->info->name, ")", NULL); | |
7620 | 5366 menuitem = gtk_image_menu_item_new_with_label(buf); |
9015 | 5367 g_free(buf); |
5368 | |
10884 | 5369 pixbuf = gaim_gtk_create_prpl_icon(account); |
9019 | 5370 if (pixbuf) { |
7620 | 5371 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, |
5372 GDK_INTERP_BILINEAR); | |
5373 image = gtk_image_new_from_pixbuf(scale); | |
5374 g_object_unref(G_OBJECT(pixbuf)); | |
5375 g_object_unref(G_OBJECT(scale)); | |
5376 gtk_widget_show(image); | |
9015 | 5377 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); |
7620 | 5378 } |
5379 | |
5380 gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem); | |
5381 gtk_widget_show(menuitem); | |
5382 | |
5383 submenu = gtk_menu_new(); | |
5384 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
5385 gtk_widget_show(submenu); | |
5386 | |
9015 | 5387 build_plugin_actions(submenu, plugin, gc); |
7620 | 5388 } |
5389 } | |
5390 } | |
8986 | 5391 |
5392 void | |
5393 gaim_gtk_blist_update_plugin_actions(void) | |
5394 { | |
11742 | 5395 GtkWidget *menuitem; |
9015 | 5396 GaimPlugin *plugin = NULL; |
8986 | 5397 GList *l; |
5398 int count = 0; | |
5399 | |
11742 | 5400 GtkWidget *pluginmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools")); |
5401 | |
9019 | 5402 if (pluginmenu == NULL) |
8986 | 5403 return; |
5404 | |
9019 | 5405 /* Clear the old Account Actions menu */ |
11742 | 5406 for (l = plugin_menu_items; l; l = l->next) { |
9015 | 5407 GaimPluginAction *action; |
11742 | 5408 plugin_menu_index--; |
8986 | 5409 menuitem = l->data; |
9015 | 5410 action = g_object_get_data(G_OBJECT(menuitem), "plugin_action"); |
5411 g_free(action); | |
8986 | 5412 |
5413 gtk_container_remove(GTK_CONTAINER(pluginmenu), GTK_WIDGET(menuitem)); | |
5414 } | |
11742 | 5415 g_list_free(plugin_menu_items); |
5416 plugin_menu_items = NULL; | |
8986 | 5417 |
9019 | 5418 /* Count the number of plugins with actions */ |
9015 | 5419 for (l = gaim_plugins_get_loaded(); l; l = l->next) { |
5420 plugin = (GaimPlugin *) l->data; | |
5421 | |
9019 | 5422 if (!GAIM_IS_PROTOCOL_PLUGIN(plugin) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
5423 count++; | |
5424 | |
5425 /* no need to count past 2, so don't */ | |
5426 if (count > 1) | |
9015 | 5427 break; |
8986 | 5428 } |
5429 | |
11742 | 5430 for (l = gaim_plugins_get_loaded(); l; l = l->next) { |
11923 | 5431 |
11742 | 5432 plugin = (GaimPlugin *) l->data; |
11923 | 5433 |
11742 | 5434 if (GAIM_IS_PROTOCOL_PLUGIN(plugin)) |
5435 continue; | |
5436 | |
5437 if (!GAIM_PLUGIN_HAS_ACTIONS(plugin)) | |
5438 continue; | |
9019 | 5439 |
9015 | 5440 build_plugin_actions(pluginmenu, plugin, NULL); |
8986 | 5441 } |
5442 } | |
11796 | 5443 |
5444 void sortmethod_act(GtkCheckMenuItem *checkmenuitem, char *id) | |
5445 { | |
5446 if (gtk_check_menu_item_get_active(checkmenuitem)) | |
11923 | 5447 { |
11796 | 5448 gaim_gtk_blist_sort_method_set(id); |
11923 | 5449 gaim_prefs_set_string("/gaim/gtk/blist/sort_type", id); |
5450 } | |
11796 | 5451 } |
5452 | |
5453 void | |
5454 gaim_gtk_blist_update_sort_methods(void) | |
5455 { | |
5456 GtkWidget *menuitem = NULL, *activeitem = NULL; | |
5457 GaimGtkBlistSortMethod *method = NULL; | |
5458 GList *l; | |
5459 GSList *sl = NULL; | |
5460 GtkWidget *sortmenu; | |
11797 | 5461 const char *m = gaim_prefs_get_string("/gaim/gtk/blist/sort_type"); |
11796 | 5462 |
5463 if (gtkblist == NULL) | |
5464 return; | |
5465 | |
11798
01c3eec6ea3c
[gaim-migrate @ 14089]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11797
diff
changeset
|
5466 sortmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Sort Buddies")); |
11796 | 5467 |
5468 if (sortmenu == NULL) | |
5469 return; | |
5470 | |
5471 /* Clear the old menu */ | |
5472 for (l = gtk_container_get_children(GTK_CONTAINER(sortmenu)); l; l = l->next) { | |
5473 menuitem = l->data; | |
5474 gtk_widget_destroy(GTK_WIDGET(menuitem)); | |
5475 } | |
11923 | 5476 |
11796 | 5477 for (l = gaim_gtk_blist_sort_methods; l; l = l->next) { |
5478 method = (GaimGtkBlistSortMethod *) l->data; | |
5479 menuitem = gtk_radio_menu_item_new_with_label(sl, _(method->name)); | |
5480 if (!strcmp(m, method->id)) | |
5481 activeitem = menuitem; | |
5482 sl = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem)); | |
5483 gtk_menu_shell_append(GTK_MENU_SHELL(sortmenu), menuitem); | |
5484 g_signal_connect(G_OBJECT(menuitem), "toggled", | |
5485 G_CALLBACK(sortmethod_act), method->id); | |
11923 | 5486 gtk_widget_show(menuitem); |
11796 | 5487 } |
5488 if (activeitem) | |
5489 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(activeitem), TRUE); | |
5490 | |
5491 } |