Mercurial > pidgin
annotate src/buddy.c @ 5226:a2199ef77cbc
[gaim-migrate @ 5596]
Javier Fern?ndez-Sanguino Pe?a writes:
"Please find adjointed a revised spanish translation for the gaim version
available at CVS. I have made a lot of effort in order to make it
homogeneus in the translation (the same term was translated in different
ways) and added missing translations (or updated fuzzy ones).
Please add this to CVS. Thanks
Javi
PS: I'm cc:ing the last translator too since gaim's po files are not in the
GNU's translation project.
PPS: I'm sending a diff instead of the file since it's quite big, but feel
free to ask for the whole file if needed."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sat, 26 Apr 2003 15:42:36 +0000 |
parents | 1cf4eb75e3ee |
children |
rev | line source |
---|---|
1 | 1 /* |
2 * gaim | |
3 * | |
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 | |
349
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
342
diff
changeset
|
22 #ifdef HAVE_CONFIG_H |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2048
diff
changeset
|
23 #include <config.h> |
349
b402a23f35df
[gaim-migrate @ 359]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
342
diff
changeset
|
24 #endif |
391
be408b41c172
[gaim-migrate @ 401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
350
diff
changeset
|
25 #ifdef GAIM_PLUGINS |
3630 | 26 #ifndef _WIN32 |
391
be408b41c172
[gaim-migrate @ 401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
350
diff
changeset
|
27 #include <dlfcn.h> |
3630 | 28 #endif |
391
be408b41c172
[gaim-migrate @ 401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
350
diff
changeset
|
29 #endif /* GAIM_PLUGINS */ |
1 | 30 #include <string.h> |
31 #include <stdio.h> | |
32 #include <stdlib.h> | |
3159 | 33 #include <ctype.h> |
1 | 34 #include <math.h> |
35 #include <time.h> | |
3630 | 36 #include <ctype.h> |
37 | |
38 #ifdef _WIN32 | |
39 #include <gdk/gdkwin32.h> | |
40 #else | |
1233
728a90516211
[gaim-migrate @ 1243]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1230
diff
changeset
|
41 #include <unistd.h> |
3630 | 42 #include <gdk/gdkx.h> |
43 #endif | |
1 | 44 |
1634
d029dc28a61e
[gaim-migrate @ 1644]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1625
diff
changeset
|
45 #include <gdk/gdkkeysyms.h> |
1 | 46 #include <gtk/gtk.h> |
1030
38452403563b
[gaim-migrate @ 1040]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1002
diff
changeset
|
47 #include "prpl.h" |
4561 | 48 #include "sound.h" |
1 | 49 #include "gaim.h" |
4687 | 50 #include "gtklist.h" |
5054 | 51 #include "gtkpounce.h" |
4687 | 52 #include "gtkft.h" |
3630 | 53 |
54 #ifdef _WIN32 | |
55 #include "win32dep.h" | |
56 #endif | |
57 | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
58 static struct gaim_gtk_buddy_list *gtkblist = NULL; |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
59 |
4840 | 60 /* part of the best damn Docklet code this side of Tahiti */ |
4698 | 61 static gboolean gaim_gtk_blist_obscured = FALSE; |
62 | |
4810 | 63 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); |
4687 | 64 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node); |
4724 | 65 static char *gaim_get_tooltip_text(struct buddy *b); |
4834 | 66 static char *item_factory_translate_func (const char *path, gpointer func_data); |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
67 |
4687 | 68 /*************************************************** |
69 * Callbacks * | |
70 ***************************************************/ | |
3869 | 71 |
4840 | 72 static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) |
4698 | 73 { |
74 if (docklet_count) | |
75 gaim_blist_set_visible(FALSE); | |
76 else | |
77 do_quit(); | |
4840 | 78 |
79 /* we handle everything, event should not propogate further */ | |
80 return TRUE; | |
81 } | |
82 | |
83 static gboolean gtk_blist_save_prefs_cb(gpointer data) | |
84 { | |
85 save_prefs(); | |
86 | |
87 /* only run once */ | |
88 return FALSE; | |
89 } | |
90 | |
91 static gboolean gtk_blist_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) | |
92 { | |
93 /* unfortunately GdkEventConfigure ignores the window gravity, but * | |
94 * the only way we have of setting the position doesn't. we have to * | |
95 * call get_position and get_size because they do pay attention to * | |
96 * the gravity. this is inefficient and I agree it sucks, but it's * | |
97 * more likely to work correctly. - Robot101 */ | |
98 gint x, y; | |
99 | |
100 /* check for visibility because when we aren't visible, this will * | |
101 * give us bogus (0,0) coordinates. - xOr */ | |
102 if (GTK_WIDGET_VISIBLE(w)) { | |
103 gtk_window_get_position(GTK_WINDOW(w), &x, &y); | |
104 | |
105 if (x != blist_pos.x || | |
106 y != blist_pos.y || | |
107 event->width != blist_pos.width || | |
108 event->height != blist_pos.height) { | |
109 blist_pos.x = x; | |
110 blist_pos.y = y; | |
111 blist_pos.width = event->width; | |
112 blist_pos.height = event->height; | |
113 | |
114 if (!g_main_context_find_source_by_user_data(NULL, >k_blist_save_prefs_cb)) { | |
115 g_timeout_add(5000, gtk_blist_save_prefs_cb, >k_blist_save_prefs_cb); | |
116 } | |
117 } | |
118 } | |
119 | |
120 /* continue to handle event normally */ | |
121 return FALSE; | |
122 } | |
123 | |
124 static gboolean gtk_blist_visibility_cb(GtkWidget *w, GdkEventVisibility *event, gpointer data) | |
125 { | |
126 if (event->state == GDK_VISIBILITY_FULLY_OBSCURED) | |
127 gaim_gtk_blist_obscured = TRUE; | |
128 else | |
129 gaim_gtk_blist_obscured = FALSE; | |
130 | |
131 /* continue to handle event normally */ | |
132 return FALSE; | |
4698 | 133 } |
134 | |
4732 | 135 static void gtk_blist_menu_info_cb(GtkWidget *w, struct buddy *b) |
136 { | |
137 serv_get_info(b->account->gc, b->name); | |
138 } | |
139 | |
4697 | 140 static void gtk_blist_menu_im_cb(GtkWidget *w, struct buddy *b) |
141 { | |
142 gaim_conversation_new(GAIM_CONV_IM, b->account, b->name); | |
143 } | |
144 | |
145 static void gtk_blist_menu_alias_cb(GtkWidget *w, struct buddy *b) | |
146 { | |
147 alias_dialog_bud(b); | |
148 } | |
149 | |
150 static void gtk_blist_menu_bp_cb(GtkWidget *w, struct buddy *b) | |
151 { | |
5032
cb700c07ee07
[gaim-migrate @ 5375]
Christian Hammond <chipx86@chipx86.com>
parents:
5024
diff
changeset
|
152 gaim_gtkpounce_dialog_show(b, NULL); |
4697 | 153 } |
154 | |
155 static void gtk_blist_menu_showlog_cb(GtkWidget *w, struct buddy *b) | |
156 { | |
157 show_log(b->name); | |
158 } | |
159 | |
160 static void gtk_blist_show_systemlog_cb() | |
161 { | |
162 show_log(NULL); | |
163 } | |
164 | |
4776 | 165 static void gtk_blist_show_onlinehelp_cb() |
166 { | |
4916 | 167 open_url(NULL, WEBSITE "documentation.php"); |
4776 | 168 } |
169 | |
4692 | 170 static void gtk_blist_button_im_cb(GtkWidget *w, GtkTreeView *tv) |
171 { | |
172 GtkTreeIter iter; | |
173 GtkTreeModel *model = gtk_tree_view_get_model(tv); | |
174 GtkTreeSelection *sel = gtk_tree_view_get_selection(tv); | |
175 | |
176 if(gtk_tree_selection_get_selected(sel, &model, &iter)){ | |
177 GaimBlistNode *node; | |
178 | |
179 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
4999 | 180 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
4692 | 181 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name); |
4999 | 182 return; |
183 } | |
4692 | 184 } |
4999 | 185 show_im_dialog(); |
4694 | 186 } |
4692 | 187 |
4694 | 188 static void gtk_blist_button_info_cb(GtkWidget *w, GtkTreeView *tv) |
189 { | |
190 GtkTreeIter iter; | |
191 GtkTreeModel *model = gtk_tree_view_get_model(tv); | |
192 GtkTreeSelection *sel = gtk_tree_view_get_selection(tv); | |
4692 | 193 |
4694 | 194 if(gtk_tree_selection_get_selected(sel, &model, &iter)){ |
195 GaimBlistNode *node; | |
196 | |
197 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
198 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
199 serv_get_info(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name); | |
200 return; | |
201 } | |
202 } | |
203 show_info_dialog(); | |
204 } | |
205 | |
206 static void gtk_blist_button_chat_cb(GtkWidget *w, gpointer data) | |
207 { | |
208 /* FIXME: someday, we can check to see if we've selected a chat node */ | |
209 join_chat(); | |
210 } | |
211 | |
212 static void gtk_blist_button_away_cb(GtkWidget *w, gpointer data) | |
213 { | |
214 gtk_menu_popup(GTK_MENU(awaymenu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME); | |
4692 | 215 } |
216 | |
5142 | 217 static void gtk_blist_row_expanded_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { |
218 GaimBlistNode *node; | |
219 GValue val = {0,}; | |
220 | |
221 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val); | |
222 | |
223 node = g_value_get_pointer(&val); | |
224 | |
225 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
226 gaim_group_set_setting((struct group *)node, "collapsed", NULL); | |
227 gaim_blist_save(); | |
228 } | |
229 } | |
230 | |
231 static void gtk_blist_row_collapsed_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { | |
232 GaimBlistNode *node; | |
233 GValue val = {0,}; | |
234 | |
235 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val); | |
236 | |
237 node = g_value_get_pointer(&val); | |
238 | |
239 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
240 gaim_group_set_setting((struct group *)node, "collapsed", "true"); | |
241 gaim_blist_save(); | |
242 } | |
243 } | |
244 | |
4687 | 245 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) { |
246 GaimBlistNode *node; | |
247 GtkTreeIter iter; | |
248 GValue val = { 0, }; | |
4936 | 249 |
4687 | 250 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); |
4936 | 251 |
4687 | 252 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); |
253 node = g_value_get_pointer(&val); | |
4936 | 254 |
4687 | 255 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
4911 | 256 struct gaim_conversation *conv = |
257 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name); | |
258 if(conv) { | |
259 gaim_window_raise(gaim_conversation_get_window(conv)); | |
260 gaim_window_switch_conversation( | |
261 gaim_conversation_get_window(conv), | |
262 gaim_conversation_get_index(conv)); | |
263 } | |
4697 | 264 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
265 if (gtk_tree_view_row_expanded(tv, path)) | |
266 gtk_tree_view_collapse_row(tv, path); | |
267 else | |
268 gtk_tree_view_expand_row(tv,path,FALSE); | |
1 | 269 } |
270 } | |
271 | |
4916 | 272 static void gaim_gtk_blist_add_buddy_cb() |
273 { | |
274 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
275 GtkTreeIter iter; | |
276 GaimBlistNode *node; | |
277 | |
278 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ | |
279 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
280 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
281 show_add_buddy(NULL, NULL, ((struct group*)node->parent)->name, NULL); | |
282 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
283 show_add_buddy(NULL, NULL, ((struct group*)node)->name, NULL); | |
284 } | |
285 else { | |
286 show_add_buddy(NULL, NULL, NULL, NULL); | |
287 } | |
288 } | |
5018 | 289 |
4921 | 290 static void |
4916 | 291 gaim_gtk_blist_remove_cb (GtkWidget *w, GaimBlistNode *node) |
292 { | |
293 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
294 struct buddy *b = (struct buddy*)node; | |
295 show_confirm_del(b->account->gc, b->name); | |
296 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
297 struct group *g = (struct group*)node; | |
298 show_confirm_del_group(g); | |
299 } | |
300 } | |
301 | |
4687 | 302 static void gaim_proto_menu_cb(GtkMenuItem *item, struct buddy *b) |
1 | 303 { |
4687 | 304 struct proto_buddy_menu *pbm = g_object_get_data(G_OBJECT(item), "gaimcallback"); |
305 if (pbm->callback) | |
306 pbm->callback(pbm->gc, b->name); | |
1396
df7c3cacac92
[gaim-migrate @ 1406]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1392
diff
changeset
|
307 } |
1 | 308 |
4687 | 309 static gboolean gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer null) |
1391
d606da211acb
[gaim-migrate @ 1401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1376
diff
changeset
|
310 { |
4687 | 311 GtkTreePath *path; |
312 GaimBlistNode *node; | |
313 GValue val = { 0, }; | |
314 GtkTreeIter iter; | |
315 GtkWidget *menu, *menuitem; | |
4702 | 316 GtkTreeSelection *sel; |
4687 | 317 GList *list; |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
318 GaimPlugin *prpl = NULL; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
319 GaimPluginProtocolInfo *prpl_info = NULL; |
1391
d606da211acb
[gaim-migrate @ 1401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1376
diff
changeset
|
320 |
4687 | 321 if (event->button != 3) |
322 return FALSE; | |
4718 | 323 |
4687 | 324 /* Here we figure out which node was clicked */ |
325 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL)) | |
326 return FALSE; | |
327 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
328 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
329 node = g_value_get_pointer(&val); | |
330 menu = gtk_menu_new(); | |
3251 | 331 |
4916 | 332 if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
5156 | 333 gaim_new_item_from_stock(menu, _("_Add a Buddy"), GTK_STOCK_ADD, G_CALLBACK(gaim_gtk_blist_add_buddy_cb), node, 0, 0, NULL); |
334 gaim_new_item_from_stock(menu, _("_Delete Group"), GTK_STOCK_REMOVE, G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
335 gaim_new_item_from_stock(menu, _("_Rename"), NULL, G_CALLBACK(show_rename_group), node, 0, 0, NULL); | |
4916 | 336 } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
337 /* Protocol specific options */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
338 prpl = gaim_find_prpl(((struct buddy*)node)->account->protocol); |
4916 | 339 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
340 if (prpl != NULL) |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
341 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
342 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
343 if (prpl && prpl_info->get_info) |
5156 | 344 gaim_new_item_from_stock(menu, _("_Get Info"), GAIM_STOCK_INFO, G_CALLBACK(gtk_blist_menu_info_cb), node, 0, 0, NULL); |
4732 | 345 |
5156 | 346 gaim_new_item_from_stock(menu, _("_IM"), GAIM_STOCK_IM, G_CALLBACK(gtk_blist_menu_im_cb), node, 0, 0, NULL); |
347 gaim_new_item_from_stock(menu, _("Add Buddy _Pounce"), NULL, G_CALLBACK(gtk_blist_menu_bp_cb), node, 0, 0, NULL); | |
348 gaim_new_item_from_stock(menu, _("View _Log"), NULL, G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL); | |
4916 | 349 |
350 if (prpl) { | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
351 list = prpl_info->buddy_menu(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name); |
4916 | 352 while (list) { |
353 struct proto_buddy_menu *pbm = list->data; | |
354 menuitem = gtk_menu_item_new_with_mnemonic(pbm->label); | |
355 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pbm); | |
356 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_proto_menu_cb), node); | |
357 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
358 list = list->next; | |
359 } | |
360 } | |
5017 | 361 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
362 gaim_event_broadcast (event_draw_menu, menu, ((struct buddy *) node)->name); |
5156 | 363 |
4916 | 364 gaim_separator(menu); |
5156 | 365 gaim_new_item_from_stock(menu, _("_Alias"), GAIM_STOCK_EDIT, G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
366 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
4732 | 367 } |
4916 | 368 |
4687 | 369 gtk_widget_show_all(menu); |
370 | |
371 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time); | |
1 | 372 |
4702 | 373 #if (1) /* This code only exists because GTK doesn't work. If we return FALSE here, as would be normal |
374 * the event propoagates down and somehow gets interpreted as the start of a drag event. */ | |
375 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
376 gtk_tree_selection_select_path(sel, path); | |
4721 | 377 gtk_tree_path_free(path); |
4702 | 378 return TRUE; |
379 #endif | |
1 | 380 } |
381 | |
5000 | 382 static void gaim_gtk_blist_show_empty_groups_cb(gpointer data, guint action, GtkWidget *item) |
383 { | |
384 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item))) | |
385 blist_options &= ~OPT_BLIST_NO_MT_GRP; | |
386 else | |
387 blist_options |= OPT_BLIST_NO_MT_GRP; | |
388 save_prefs(); | |
389 gaim_gtk_blist_refresh(gaim_get_blist()); | |
390 } | |
391 | |
4944 | 392 static void gaim_gtk_blist_edit_mode_cb(gpointer callback_data, guint callback_action, |
4936 | 393 GtkWidget *checkitem) { |
5135 | 394 if(gtkblist->window->window) { |
395 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); | |
396 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
397 while (gtk_events_pending()) | |
398 gtk_main_iteration(); | |
399 gdk_cursor_unref(cursor); | |
400 } | |
401 | |
4936 | 402 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem))) |
403 blist_options |= OPT_BLIST_SHOW_OFFLINE; | |
404 else | |
405 blist_options &= ~OPT_BLIST_SHOW_OFFLINE; | |
4929 | 406 save_prefs(); |
5135 | 407 |
408 if(gtkblist->window->window) { | |
409 GdkCursor *cursor = gdk_cursor_new(GDK_LEFT_PTR); | |
410 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
411 gdk_cursor_unref(cursor); | |
412 } | |
413 | |
4916 | 414 gaim_gtk_blist_refresh(gaim_get_blist()); |
415 } | |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4349
diff
changeset
|
416 |
4702 | 417 static void gaim_gtk_blist_drag_data_get_cb (GtkWidget *widget, |
418 GdkDragContext *dc, | |
419 GtkSelectionData *data, | |
420 guint info, | |
421 guint time, | |
422 gpointer *null) | |
423 { | |
4781 | 424 if (data->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE)) { |
4702 | 425 GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); |
426 GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref); | |
427 GtkTreeIter iter; | |
428 GaimBlistNode *node = NULL; | |
429 GValue val = {0}; | |
430 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, sourcerow); | |
431 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
432 node = g_value_get_pointer(&val); | |
4781 | 433 gtk_selection_data_set (data, |
434 gdk_atom_intern ("GAIM_BLIST_NODE", FALSE), | |
435 8, /* bits */ | |
436 (void*)&node, | |
437 sizeof (node)); | |
438 | |
4721 | 439 gtk_tree_path_free(sourcerow); |
4702 | 440 } |
4781 | 441 |
4702 | 442 } |
443 | |
444 static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | |
445 GtkSelectionData *sd, guint info, guint t) | |
446 { | |
4781 | 447 if (sd->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE) && sd->data) { |
448 GaimBlistNode *n = NULL; | |
4702 | 449 GtkTreePath *path = NULL; |
4704 | 450 GtkTreeViewDropPosition position; |
4781 | 451 memcpy(&n, sd->data, sizeof(n)); |
4704 | 452 if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) { |
453 /* if we're here, I think it means the drop is ok */ | |
4770 | 454 GtkTreeIter iter; |
455 GaimBlistNode *node; | |
456 GValue val = {0}; | |
457 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
458 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
459 node = g_value_get_pointer(&val); | |
4781 | 460 |
461 if (GAIM_BLIST_NODE_IS_BUDDY(n)) { | |
462 struct buddy *b = (struct buddy*)n; | |
463 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
4795 | 464 switch(position) { |
465 case GTK_TREE_VIEW_DROP_AFTER: | |
466 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
467 gaim_blist_add_buddy(b, (struct group*)node->parent, node); | |
468 break; | |
469 case GTK_TREE_VIEW_DROP_BEFORE: | |
470 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
471 gaim_blist_add_buddy(b, (struct group*)node->parent, node->prev); | |
472 break; | |
4781 | 473 } |
474 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
475 gaim_blist_add_buddy(b, (struct group*)node, NULL); | |
4795 | 476 } |
4781 | 477 } else if (GAIM_BLIST_NODE_IS_GROUP(n)) { |
478 struct group *g = (struct group*)n; | |
479 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
480 switch (position) { | |
481 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
482 case GTK_TREE_VIEW_DROP_AFTER: | |
483 gaim_blist_add_group(g, node); | |
484 break; | |
485 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
486 case GTK_TREE_VIEW_DROP_BEFORE: | |
487 gaim_blist_add_group(g, node->prev); | |
488 break; | |
489 } | |
490 | |
5055 | 491 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
492 gaim_blist_add_group(g, node->parent); | |
4770 | 493 } |
4781 | 494 |
4777 | 495 } |
4781 | 496 |
4721 | 497 gtk_tree_path_free(path); |
4970 | 498 gaim_blist_save(); |
4704 | 499 } |
4702 | 500 } |
501 } | |
502 | |
4724 | 503 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, struct buddy *b) |
504 { | |
505 GtkStyle *style; | |
506 GdkPixbuf *pixbuf = gaim_gtk_blist_get_status_icon(b, GAIM_STATUS_ICON_LARGE); | |
507 PangoLayout *layout; | |
508 char *tooltiptext = gaim_get_tooltip_text(b); | |
509 | |
510 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); | |
511 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); | |
4732 | 512 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); |
4733 | 513 pango_layout_set_width(layout, 300000); |
4724 | 514 style = gtkblist->tipwindow->style; |
4732 | 515 |
4724 | 516 gtk_paint_flat_box (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, |
517 NULL, gtkblist->tipwindow, "tooltip", 0, 0, -1, -1); | |
4729 | 518 |
519 #if GTK_CHECK_VERSION(2,2,0) | |
4724 | 520 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, pixbuf, |
521 0, 0, 4, 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); | |
4729 | 522 #else |
4758 | 523 gdk_pixbuf_render_to_drawable(pixbuf, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 4, 4, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); |
4729 | 524 #endif |
4724 | 525 |
526 gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, TRUE, | |
527 NULL, gtkblist->tipwindow, "tooltip", 38, 4, layout); | |
528 | |
529 g_object_unref (pixbuf); | |
530 g_object_unref (layout); | |
531 g_free(tooltiptext); | |
532 return; | |
533 } | |
534 | |
535 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv) | |
536 { | |
537 GtkTreePath *path; | |
538 GtkTreeIter iter; | |
539 GaimBlistNode *node; | |
540 GValue val = {0}; | |
541 | |
542 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->rect.x, gtkblist->rect.y, &path, NULL, NULL, NULL)) | |
543 return FALSE; | |
544 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
545 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
546 node = g_value_get_pointer(&val); | |
547 | |
548 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
549 int scr_w,scr_h, w, h, x, y; | |
550 PangoLayout *layout; | |
551 struct buddy *buddy = (struct buddy*)node; | |
552 char *tooltiptext = gaim_get_tooltip_text(buddy); | |
553 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP); | |
4907
68e2b07ef8d7
[gaim-migrate @ 5241]
Christian Hammond <chipx86@chipx86.com>
parents:
4883
diff
changeset
|
554 gtkblist->tipwindow->parent = tv; |
4724 | 555 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); |
4729 | 556 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); |
4724 | 557 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); |
558 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", | |
559 G_CALLBACK(gaim_gtk_blist_paint_tip), buddy); | |
560 gtk_widget_ensure_style (gtkblist->tipwindow); | |
561 | |
562 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); | |
4733 | 563 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); |
564 pango_layout_set_width(layout, 300000); | |
4724 | 565 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); |
566 scr_w = gdk_screen_width(); | |
567 scr_h = gdk_screen_height(); | |
568 pango_layout_get_size (layout, &w, &h); | |
569 w = PANGO_PIXELS(w) + 8; | |
570 h = PANGO_PIXELS(h) + 8; | |
571 | |
572 /* 38 is the size of a large status icon plus 4 pixels padding on each side. | |
573 I should #define this or something */ | |
574 w = w + 38; | |
575 h = MAX(h, 38); | |
576 | |
577 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
578 if (GTK_WIDGET_NO_WINDOW(gtkblist->window)) | |
579 y+=gtkblist->window->allocation.y; | |
580 | |
581 x -= ((w >> 1) + 4); | |
582 | |
583 if ((x + w) > scr_w) | |
584 x -= (x + w) - scr_w; | |
585 else if (x < 0) | |
586 x = 0; | |
587 | |
588 if ((y + h + 4) > scr_h) | |
589 y = y - h; | |
590 else | |
591 y = y + 6; | |
592 g_object_unref (layout); | |
593 g_free(tooltiptext); | |
594 gtk_widget_set_size_request(gtkblist->tipwindow, w, h); | |
4729 | 595 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y); |
4724 | 596 gtk_widget_show(gtkblist->tipwindow); |
597 } | |
4729 | 598 |
4724 | 599 gtk_tree_path_free(path); |
600 return FALSE; | |
601 } | |
602 | |
4730 | 603 static gboolean gaim_gtk_blist_motion_cb (GtkWidget *tv, GdkEventMotion *event, gpointer null) |
4724 | 604 { |
605 GtkTreePath *path; | |
606 if (gtkblist->timeout) { | |
607 if ((event->y > gtkblist->rect.y) && ((event->y - gtkblist->rect.height) < gtkblist->rect.y)) | |
4732 | 608 return FALSE; |
4724 | 609 /* We've left the cell. Remove the timeout and create a new one below */ |
610 if (gtkblist->tipwindow) { | |
611 gtk_widget_destroy(gtkblist->tipwindow); | |
612 gtkblist->tipwindow = NULL; | |
613 } | |
614 | |
615 g_source_remove(gtkblist->timeout); | |
616 } | |
617 | |
618 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL); | |
619 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->rect); | |
620 if (path) | |
621 gtk_tree_path_free(path); | |
622 gtkblist->timeout = g_timeout_add(500, (GSourceFunc)gaim_gtk_blist_tooltip_timeout, tv); | |
4730 | 623 return FALSE; |
4724 | 624 } |
625 | |
626 static void gaim_gtk_blist_leave_cb (GtkWidget *w, GdkEventCrossing *e, gpointer n) | |
627 { | |
4978 | 628 if (gtkblist->timeout) { |
629 g_source_remove(gtkblist->timeout); | |
630 gtkblist->timeout = 0; | |
631 } | |
4724 | 632 if (gtkblist->tipwindow) { |
633 gtk_widget_destroy(gtkblist->tipwindow); | |
634 gtkblist->tipwindow = NULL; | |
635 } | |
4978 | 636 } |
4724 | 637 |
5211
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
638 static void |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
639 toggle_debug(void) |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
640 { |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
641 misc_options ^= OPT_MISC_DEBUG; |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
642 |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
643 if ((misc_options & OPT_MISC_DEBUG)) |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
644 gaim_gtk_debug_window_show(); |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
645 else |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
646 gaim_gtk_debug_window_hide(); |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
647 |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
648 save_prefs(); |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
649 } |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
650 |
0241d6b6702d
[gaim-migrate @ 5581]
Christian Hammond <chipx86@chipx86.com>
parents:
5205
diff
changeset
|
651 |
4687 | 652 /*************************************************** |
653 * Crap * | |
654 ***************************************************/ | |
655 static GtkItemFactoryEntry blist_menu[] = | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
656 { |
4687 | 657 /* Buddies menu */ |
658 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, | |
5024 | 659 { N_("/Buddies/New _Instant Message..."), "<CTL>I", show_im_dialog, 0, "<StockItem>", GAIM_STOCK_IM }, |
660 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0, "<StockItem>", GAIM_STOCK_CHAT }, | |
5145 | 661 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0, "<StockItem>", GAIM_STOCK_INFO }, |
4834 | 662 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" }, |
4983 | 663 { N_("/Buddies/_Show Offline Buddies"), NULL, gaim_gtk_blist_edit_mode_cb, 1, "<CheckItem>"}, |
5000 | 664 { N_("/Buddies/Show _Empty Groups"), NULL, gaim_gtk_blist_show_empty_groups_cb, 1, "<CheckItem>"}, |
4983 | 665 { N_("/Buddies/_Add a Buddy..."), NULL, gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD }, |
666 { N_("/Buddies/Add a _Group..."), NULL, show_add_group, 0, NULL}, | |
5024 | 667 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" }, |
668 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, "<StockItem>", GAIM_STOCK_SIGN_OFF }, | |
669 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, "<StockItem>", GTK_STOCK_QUIT }, | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
670 |
4687 | 671 /* Tools */ |
672 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, | |
673 { N_("/Tools/_Away"), NULL, NULL, 0, "<Branch>" }, | |
674 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" }, | |
5024 | 675 { N_("/Tools/P_rotocol Actions"), NULL, NULL, 0, "<Branch>" }, |
676 { "/Tools/sep1", NULL, NULL, 0, "<Separator>" }, | |
5053 | 677 { N_("/Tools/A_ccounts..."), "<CTL>A", account_editor, 0, "<StockItem>", GAIM_STOCK_ACCOUNTS }, |
5024 | 678 { N_("/Tools/_File Transfers..."), NULL, gaim_show_xfer_dialog, 0, "<StockItem>", GAIM_STOCK_FILE_TRANSFER }, |
679 { N_("/Tools/Preferences..."), "<CTL>P", show_prefs, 0, "<StockItem>", GTK_STOCK_PREFERENCES }, | |
680 { N_("/Tools/Pr_ivacy..."), NULL, show_privacy_options, 0, "<StockItem>", GAIM_STOCK_PRIVACY }, | |
4834 | 681 { "/Tools/sep2", NULL, NULL, 0, "<Separator>" }, |
5024 | 682 { N_("/Tools/View System _Log..."), NULL, gtk_blist_show_systemlog_cb, 0, NULL }, |
3251 | 683 |
4687 | 684 /* Help */ |
685 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, | |
5024 | 686 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP }, |
687 { N_("/Help/_Debug Window..."), NULL, toggle_debug, 0, NULL }, | |
688 { N_("/Help/_About..."), NULL, show_about, 0, "<StockItem>", GAIM_STOCK_ABOUT }, | |
4687 | 689 }; |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
690 |
4687 | 691 /********************************************************* |
692 * Private Utility functions * | |
693 *********************************************************/ | |
694 | |
4724 | 695 static char *gaim_get_tooltip_text(struct buddy *b) |
696 { | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
697 GaimPlugin *prpl; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
698 GaimPluginProtocolInfo *prpl_info = NULL; |
4724 | 699 char *text = NULL; |
700 char *statustext = NULL; | |
4867 | 701 char *aliastext = NULL, *nicktext = NULL; |
4724 | 702 char *warning = NULL, *idletime = NULL; |
703 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
704 prpl = gaim_find_prpl(b->account->protocol); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
705 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
706 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
707 if (prpl_info->tooltip_text) { |
4815 | 708 const char *end; |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
709 statustext = prpl_info->tooltip_text(b); |
4815 | 710 |
711 if(statustext && !g_utf8_validate(statustext, -1, &end)) { | |
712 char *new = g_strndup(statustext, | |
713 g_utf8_pointer_to_offset(statustext, end)); | |
714 g_free(statustext); | |
715 statustext = new; | |
716 } | |
4724 | 717 } |
4732 | 718 |
5131 | 719 if (!statustext && !GAIM_BUDDY_IS_ONLINE(b)) |
720 statustext = g_strdup(_("<b>Status:</b> Offline")); | |
721 | |
5002 | 722 if (b->idle > 0) { |
4724 | 723 int ihrs, imin; |
724 time_t t; | |
725 time(&t); | |
726 ihrs = (t - b->idle) / 3600; | |
727 imin = ((t - b->idle) / 60) % 60; | |
728 if (ihrs) | |
4744 | 729 idletime = g_strdup_printf(_("%dh%02dm"), ihrs, imin); |
4724 | 730 else |
4744 | 731 idletime = g_strdup_printf(_("%dm"), imin); |
4724 | 732 } |
4732 | 733 |
4945 | 734 if(b->alias && b->alias[0]) |
4867 | 735 aliastext = g_markup_escape_text(b->alias, -1); |
736 | |
737 if(b->server_alias) | |
738 nicktext = g_markup_escape_text(b->server_alias, -1); | |
739 | |
4724 | 740 if (b->evil > 0) |
4744 | 741 warning = g_strdup_printf(_("%d%%"), b->evil); |
4732 | 742 |
4724 | 743 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>" |
4744 | 744 "%s %s" /* Alias */ |
745 "%s %s" /* Nickname */ | |
746 "%s %s" /* Idle */ | |
747 "%s %s" /* Warning */ | |
4968 | 748 "%s%s" /* Status */ |
749 "%s", | |
4724 | 750 b->name, |
4867 | 751 aliastext ? _("\n<b>Alias:</b>") : "", aliastext ? aliastext : "", |
752 nicktext ? _("\n<b>Nickname:</b>") : "", nicktext ? nicktext : "", | |
5002 | 753 idletime ? _("\n<b>Idle:</b>") : "", idletime ? idletime : "", |
4744 | 754 b->evil ? _("\n<b>Warned:</b>") : "", b->evil ? warning : "", |
4968 | 755 statustext ? "\n" : "", statustext ? statustext : "", |
5116 | 756 !g_ascii_strcasecmp(b->name, "robflynn") ? _("\n<b>Description:</b> Spooky") : ""); |
4968 | 757 |
4737 | 758 if(warning) |
759 g_free(warning); | |
760 if(idletime) | |
761 g_free(idletime); | |
762 if(statustext) | |
763 g_free(statustext); | |
4867 | 764 if(nicktext) |
765 g_free(nicktext); | |
766 if(aliastext) | |
767 g_free(aliastext); | |
4737 | 768 |
4724 | 769 return text; |
770 | |
771 } | |
772 | |
5168 | 773 GdkPixbuf *gaim_gtk_blist_get_status_icon(struct buddy *b, GaimStatusIconSize size) |
4687 | 774 { |
775 GdkPixbuf *status = NULL; | |
776 GdkPixbuf *scale = NULL; | |
777 GdkPixbuf *emblem = NULL; | |
4737 | 778 gchar *filename = NULL; |
4687 | 779 const char *protoname = NULL; |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
780 |
4691 | 781 char *se = NULL, *sw = NULL ,*nw = NULL ,*ne = NULL; |
4737 | 782 |
4687 | 783 int scalesize = 30; |
784 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
785 GaimPlugin *prpl; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
786 GaimPluginProtocolInfo *prpl_info = NULL; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
787 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
788 prpl = gaim_find_prpl(b->account->protocol); |
4916 | 789 |
790 if (!prpl) | |
791 return NULL; | |
792 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
793 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
794 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
795 if (prpl_info->list_icon) |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
796 protoname = prpl_info->list_icon(b->account, b); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
797 if (b->present != GAIM_BUDDY_SIGNING_OFF && prpl_info->list_emblems) |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
798 prpl_info->list_emblems(b, &se, &sw, &nw, &ne); |
5068 | 799 |
4724 | 800 if (size == GAIM_STATUS_ICON_SMALL) { |
4687 | 801 scalesize = 15; |
802 sw = nw = ne = NULL; /* So that only the se icon will composite */ | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
803 } |
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
804 |
4701 | 805 |
5068 | 806 if (b->present == GAIM_BUDDY_SIGNING_ON) { |
4687 | 807 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); |
808 status = gdk_pixbuf_new_from_file(filename,NULL); | |
809 g_free(filename); | |
5068 | 810 } else if (b->present == GAIM_BUDDY_SIGNING_OFF) { |
811 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL); | |
812 status = gdk_pixbuf_new_from_file(filename,NULL); | |
813 g_free(filename); | |
4701 | 814 |
4737 | 815 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and |
4687 | 816 then it will look up protoname from the theme */ |
817 } else { | |
818 char *image = g_strdup_printf("%s.png", protoname); | |
819 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
820 status = gdk_pixbuf_new_from_file(filename,NULL); | |
821 g_free(image); | |
822 g_free(filename); | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
823 |
4687 | 824 } |
4737 | 825 |
4687 | 826 if (!status) |
827 return NULL; | |
4737 | 828 |
4687 | 829 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, GDK_INTERP_BILINEAR); |
4737 | 830 |
831 g_object_unref(G_OBJECT(status)); | |
832 | |
4687 | 833 /* Emblems */ |
4737 | 834 |
4687 | 835 /* Each protocol can specify up to four "emblems" to composite over the base icon. "away", "busy", "mobile user" |
836 * are all examples of states represented by emblems. I'm not even really sure I like this yet. */ | |
4737 | 837 |
4687 | 838 /* XXX Clean this crap up, yo. */ |
839 if (se) { | |
840 char *image = g_strdup_printf("%s.png", se); | |
841 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
842 g_free(image); | |
843 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
844 g_free(filename); | |
845 if (emblem) { | |
4724 | 846 if (size == GAIM_STATUS_ICON_LARGE) |
4687 | 847 gdk_pixbuf_composite (emblem, |
848 scale, 15, 15, | |
849 15, 15, | |
850 15, 15, | |
851 1, 1, | |
852 GDK_INTERP_BILINEAR, | |
853 255); | |
854 else | |
855 gdk_pixbuf_composite (emblem, | |
5017 | 856 scale, 5, 5, |
857 10, 10, | |
858 5, 5, | |
859 .6, .6, | |
4687 | 860 GDK_INTERP_BILINEAR, |
861 255); | |
4737 | 862 g_object_unref(G_OBJECT(emblem)); |
4687 | 863 } |
864 } | |
865 if (sw) { | |
866 char *image = g_strdup_printf("%s.png", sw); | |
867 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
868 g_free(image); | |
869 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
870 g_free(filename); | |
871 if (emblem) { | |
4737 | 872 gdk_pixbuf_composite (emblem, |
873 scale, 0, 15, | |
874 15, 15, | |
875 0, 15, | |
876 1, 1, | |
877 GDK_INTERP_BILINEAR, | |
878 255); | |
879 g_object_unref(G_OBJECT(emblem)); | |
4687 | 880 } |
881 } | |
882 if (nw) { | |
883 char *image = g_strdup_printf("%s.png", nw); | |
884 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
885 g_free(image); | |
886 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
887 g_free(filename); | |
888 if (emblem) { | |
889 gdk_pixbuf_composite (emblem, | |
890 scale, 0, 0, | |
891 15, 15, | |
892 0, 0, | |
893 1, 1, | |
894 GDK_INTERP_BILINEAR, | |
895 255); | |
4737 | 896 g_object_unref(G_OBJECT(emblem)); |
4687 | 897 } |
898 } | |
899 if (ne) { | |
900 char *image = g_strdup_printf("%s.png", ne); | |
901 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
902 g_free(image); | |
903 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
904 g_free(filename); | |
905 if (emblem) { | |
906 gdk_pixbuf_composite (emblem, | |
907 scale, 15, 0, | |
908 15, 15, | |
909 15, 0, | |
910 1, 1, | |
911 GDK_INTERP_BILINEAR, | |
912 255); | |
4954 | 913 g_object_unref(G_OBJECT(emblem)); |
4687 | 914 } |
4737 | 915 } |
4687 | 916 |
4737 | 917 |
4718 | 918 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */ |
5068 | 919 if (b->present == GAIM_BUDDY_OFFLINE) |
4928 | 920 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); |
921 else if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) | |
922 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.25, FALSE); | |
4687 | 923 return scale; |
1 | 924 } |
925 | |
4737 | 926 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) |
1 | 927 { |
4687 | 928 /* This just opens a file from ~/.gaim/icons/screenname. This needs to change to be more gooder. */ |
4737 | 929 char *file; |
930 GdkPixbuf *buf, *ret; | |
931 | |
4687 | 932 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) |
933 return NULL; | |
4737 | 934 |
4757 | 935 if ((file = gaim_buddy_get_setting(b, "buddy_icon")) == NULL) |
936 return NULL; | |
937 | |
4737 | 938 buf = gdk_pixbuf_new_from_file(file, NULL); |
939 g_free(file); | |
940 | |
941 | |
4687 | 942 if (buf) { |
5068 | 943 if (!GAIM_BUDDY_IS_ONLINE(b)) |
4928 | 944 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE); |
945 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) | |
946 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE); | |
947 | |
4737 | 948 ret = gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); |
949 g_object_unref(G_OBJECT(buf)); | |
950 return ret; | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
951 } |
4687 | 952 return NULL; |
2986 | 953 } |
954 | |
4810 | 955 static gchar *gaim_gtk_blist_get_name_markup(struct buddy *b, gboolean selected) |
1 | 956 { |
4687 | 957 char *name = gaim_get_buddy_alias(b); |
958 char *esc = g_markup_escape_text(name, strlen(name)), *text = NULL; | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
959 GaimPlugin *prpl; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
960 GaimPluginProtocolInfo *prpl_info = NULL; |
4687 | 961 /* XXX Clean up this crap */ |
4699 | 962 |
4687 | 963 int ihrs, imin; |
4724 | 964 char *idletime = NULL, *warning = NULL, *statustext = NULL; |
4732 | 965 time_t t; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
966 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
967 prpl = gaim_find_prpl(b->account->protocol); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
968 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
969 if (prpl != NULL) |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
970 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
971 |
4687 | 972 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { |
5068 | 973 if ((b->idle && blist_options & OPT_BLIST_GREY_IDLERS && !selected) || !GAIM_BUDDY_IS_ONLINE(b)) { |
4718 | 974 text = g_strdup_printf("<span color='dim grey'>%s</span>", |
4699 | 975 esc); |
4687 | 976 g_free(esc); |
977 return text; | |
978 } else { | |
979 return esc; | |
980 } | |
1 | 981 } |
982 | |
4687 | 983 time(&t); |
984 ihrs = (t - b->idle) / 3600; | |
985 imin = ((t - b->idle) / 60) % 60; | |
4699 | 986 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
987 if (prpl && prpl_info->status_text) { |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
988 char *tmp = prpl_info->status_text(b); |
4815 | 989 const char *end; |
990 | |
991 if(tmp && !g_utf8_validate(tmp, -1, &end)) { | |
992 char *new = g_strndup(tmp, | |
993 g_utf8_pointer_to_offset(tmp, end)); | |
994 g_free(tmp); | |
995 tmp = new; | |
996 } | |
4732 | 997 |
998 if(tmp) { | |
4855 | 999 char buf[32]; |
1000 char *c = tmp; | |
1001 int length = 0, vis=0; | |
1002 gboolean inside = FALSE; | |
4806 | 1003 g_strdelimit(tmp, "\n", ' '); |
4852
d1c17e81055e
[gaim-migrate @ 5179]
Christian Hammond <chipx86@chipx86.com>
parents:
4847
diff
changeset
|
1004 |
4855 | 1005 while(*c && vis < 20) { |
1006 if(*c == '&') | |
1007 inside = TRUE; | |
4856 | 1008 else if(*c == ';') |
1009 inside = FALSE; | |
4855 | 1010 if(!inside) |
1011 vis++; | |
1012 length++; | |
1013 c++; /* this is fun */ | |
1014 } | |
4852
d1c17e81055e
[gaim-migrate @ 5179]
Christian Hammond <chipx86@chipx86.com>
parents:
4847
diff
changeset
|
1015 |
4855 | 1016 if(vis == 20) |
1017 g_snprintf(buf, sizeof(buf), "%%.%ds...", length); | |
1018 else | |
1019 g_snprintf(buf, sizeof(buf), "%%s "); | |
4852
d1c17e81055e
[gaim-migrate @ 5179]
Christian Hammond <chipx86@chipx86.com>
parents:
4847
diff
changeset
|
1020 |
4855 | 1021 statustext = g_strdup_printf(buf, tmp); |
4852
d1c17e81055e
[gaim-migrate @ 5179]
Christian Hammond <chipx86@chipx86.com>
parents:
4847
diff
changeset
|
1022 |
4732 | 1023 g_free(tmp); |
1024 } | |
4722 | 1025 } |
4732 | 1026 |
5002 | 1027 if (b->idle > 0) { |
4687 | 1028 if (ihrs) |
4757 | 1029 idletime = g_strdup_printf(_("Idle (%dh%02dm) "), ihrs, imin); |
4687 | 1030 else |
4757 | 1031 idletime = g_strdup_printf(_("Idle (%dm) "), imin); |
4687 | 1032 } |
4757 | 1033 |
4687 | 1034 if (b->evil > 0) |
4757 | 1035 warning = g_strdup_printf(_("Warned (%d%%) "), b->evil); |
1036 | |
5135 | 1037 if(!GAIM_BUDDY_IS_ONLINE(b) && !statustext) |
1038 statustext = g_strdup("Offline "); | |
1039 | |
4810 | 1040 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS && !selected) { |
4916 | 1041 text = g_strdup_printf("<span color='dim grey'>%s</span>\n" |
5135 | 1042 "<span color='dim grey' size='smaller'>%s%s%s</span>", |
4687 | 1043 esc, |
4722 | 1044 statustext != NULL ? statustext : "", |
5135 | 1045 idletime != NULL ? idletime : "", |
1046 warning != NULL ? warning : ""); | |
5068 | 1047 } else if (statustext == NULL && idletime == NULL && warning == NULL && GAIM_BUDDY_IS_ONLINE(b)) { |
4916 | 1048 text = g_strdup(esc); |
4797 | 1049 } else { |
4916 | 1050 text = g_strdup_printf("%s\n" |
5135 | 1051 "<span %s size='smaller'>%s%s%s</span>", esc, |
4916 | 1052 selected ? "" : "color='dim grey'", |
1053 statustext != NULL ? statustext : "", | |
1054 idletime != NULL ? idletime : "", | |
5135 | 1055 warning != NULL ? warning : ""); |
4797 | 1056 } |
4722 | 1057 if (idletime) |
4687 | 1058 g_free(idletime); |
4722 | 1059 if (warning) |
4687 | 1060 g_free(warning); |
4722 | 1061 if (statustext) |
1062 g_free(statustext); | |
4737 | 1063 if (esc) |
1064 g_free(esc); | |
4699 | 1065 |
4687 | 1066 return text; |
1067 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1068 |
4840 | 1069 static void gaim_gtk_blist_restore_position() |
1070 { | |
1071 /* if the window exists, is hidden, we're saving positions, and the position is sane... */ | |
1072 if(gtkblist && gtkblist->window && | |
1073 !GTK_WIDGET_VISIBLE(gtkblist->window) && | |
1074 blist_pos.width != 0) { | |
1075 /* ...check position is on screen... */ | |
1076 if (blist_pos.x >= gdk_screen_width()) | |
1077 blist_pos.x = gdk_screen_width() - 100; | |
1078 else if (blist_pos.x < 0) | |
1079 blist_pos.x = 100; | |
1080 | |
1081 if (blist_pos.y >= gdk_screen_height()) | |
1082 blist_pos.y = gdk_screen_height() - 100; | |
1083 else if (blist_pos.y < 0) | |
1084 blist_pos.y = 100; | |
1085 | |
1086 /* ...and move it back. */ | |
1087 gtk_window_move(GTK_WINDOW(gtkblist->window), blist_pos.x, blist_pos.y); | |
1088 gtk_window_resize(GTK_WINDOW(gtkblist->window), blist_pos.width, blist_pos.height); | |
1089 } | |
1090 } | |
1091 | |
4944 | 1092 static gboolean gaim_gtk_blist_refresh_timer(struct gaim_buddy_list *list) |
1093 { | |
1094 GaimBlistNode *group = list->root; | |
1095 GaimBlistNode *buddy; | |
1096 | |
1097 while (group) { | |
1098 buddy = group->child; | |
1099 while (buddy) { | |
1100 if (((struct buddy *)buddy)->idle) | |
1101 gaim_gtk_blist_update(list, buddy); | |
1102 buddy = buddy->next; | |
1103 } | |
1104 group = group->next; | |
1105 } | |
1106 | |
1107 /* keep on going */ | |
1108 return TRUE; | |
1109 } | |
4840 | 1110 |
4687 | 1111 /********************************************************************************** |
1112 * Public API Functions * | |
1113 **********************************************************************************/ | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1114 static void gaim_gtk_blist_new_list(struct gaim_buddy_list *blist) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1115 { |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1116 blist->ui_data = g_new0(struct gaim_gtk_buddy_list, 1); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1117 } |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1118 |
4729 | 1119 void gaim_gtk_blist_update_columns() |
1120 { | |
5187 | 1121 if(!gtkblist) |
1122 return; | |
1123 | |
4729 | 1124 if (blist_options & OPT_BLIST_SHOW_ICONS) { |
1125 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, TRUE); | |
1126 gtk_tree_view_column_set_visible(gtkblist->idle_column, FALSE); | |
1127 gtk_tree_view_column_set_visible(gtkblist->warning_column, FALSE); | |
1128 } else { | |
1129 gtk_tree_view_column_set_visible(gtkblist->idle_column, blist_options & OPT_BLIST_SHOW_IDLETIME); | |
1130 gtk_tree_view_column_set_visible(gtkblist->warning_column, blist_options & OPT_BLIST_SHOW_WARN); | |
1131 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, FALSE); | |
1132 } | |
1133 } | |
1134 | |
4702 | 1135 enum {DRAG_BUDDY, DRAG_ROW}; |
1136 | |
4834 | 1137 static char * |
1138 item_factory_translate_func (const char *path, gpointer func_data) | |
1139 { | |
1140 return _(path); | |
1141 } | |
1142 | |
4687 | 1143 static void gaim_gtk_blist_show(struct gaim_buddy_list *list) |
1144 { | |
1145 GtkItemFactory *ift; | |
1146 GtkCellRenderer *rend; | |
1147 GtkTreeViewColumn *column; | |
1148 GtkWidget *sw; | |
1149 GtkWidget *button; | |
4694 | 1150 GtkSizeGroup *sg; |
5089 | 1151 GtkAccelGroup *accel_group; |
4810 | 1152 GtkTreeSelection *selection; |
4781 | 1153 GtkTargetEntry gte[] = {{"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW}, |
4702 | 1154 {"application/x-im-contact", 0, DRAG_BUDDY}}; |
4690 | 1155 |
4745 | 1156 if (gtkblist && gtkblist->window) { |
4687 | 1157 gtk_widget_show(gtkblist->window); |
1158 return; | |
1159 } | |
4690 | 1160 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1161 gtkblist = GAIM_GTK_BLIST(list); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1162 |
4687 | 1163 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
4840 | 1164 gtk_window_set_role(GTK_WINDOW(gtkblist->window), "buddy_list"); |
4964 | 1165 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); |
4690 | 1166 |
5168 | 1167 GTK_WINDOW(gtkblist->window)->allow_shrink = TRUE; |
1168 | |
4925 | 1169 gtkblist->vbox = gtk_vbox_new(FALSE, 0); |
4687 | 1170 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); |
1 | 1171 |
4840 | 1172 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); |
1173 g_signal_connect(G_OBJECT(gtkblist->window), "configure_event", G_CALLBACK(gtk_blist_configure_cb), NULL); | |
1174 g_signal_connect(G_OBJECT(gtkblist->window), "visibility_notify_event", G_CALLBACK(gtk_blist_visibility_cb), NULL); | |
1175 gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK); | |
4698 | 1176 |
4687 | 1177 /******************************* Menu bar *************************************/ |
5089 | 1178 accel_group = gtk_accel_group_new(); |
1179 gtk_window_add_accel_group(GTK_WINDOW (gtkblist->window), accel_group); | |
1180 g_object_unref(accel_group); | |
1181 ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", accel_group); | |
4834 | 1182 gtk_item_factory_set_translate_func (ift, |
1183 item_factory_translate_func, | |
1184 NULL, NULL); | |
4687 | 1185 gtk_item_factory_create_items(ift, sizeof(blist_menu) / sizeof(*blist_menu), |
1186 blist_menu, NULL); | |
1187 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtk_item_factory_get_widget(ift, "<GaimMain>"), FALSE, FALSE, 0); | |
1 | 1188 |
4834 | 1189 awaymenu = gtk_item_factory_get_widget(ift, N_("/Tools/Away")); |
4694 | 1190 do_away_menu(); |
1191 | |
5032
cb700c07ee07
[gaim-migrate @ 5375]
Christian Hammond <chipx86@chipx86.com>
parents:
5024
diff
changeset
|
1192 gtkblist->bpmenu = gtk_item_factory_get_widget(ift, N_("/Tools/Buddy Pounce")); |
cb700c07ee07
[gaim-migrate @ 5375]
Christian Hammond <chipx86@chipx86.com>
parents:
5024
diff
changeset
|
1193 gaim_gtkpounce_menu_build(gtkblist->bpmenu); |
4696 | 1194 |
4834 | 1195 protomenu = gtk_item_factory_get_widget(ift, N_("/Tools/Protocol Actions")); |
4696 | 1196 do_proto_menu(); |
1197 | |
4687 | 1198 /****************************** GtkTreeView **********************************/ |
1199 sw = gtk_scrolled_window_new(NULL,NULL); | |
1200 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); | |
1201 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
1202 | |
5060 | 1203 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, G_TYPE_STRING, |
4687 | 1204 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); |
4702 | 1205 |
4687 | 1206 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); |
4943 | 1207 gtk_widget_set_size_request(gtkblist->treeview, -1, 200); |
4704 | 1208 |
4810 | 1209 /* Set up selection stuff */ |
1210 | |
1211 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
1212 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(gaim_gtk_blist_selection_changed), NULL); | |
1213 | |
1214 | |
4702 | 1215 /* Set up dnd */ |
1216 gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), GDK_BUTTON1_MASK, gte, | |
1217 2, GDK_ACTION_COPY); | |
4704 | 1218 gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), gte, 2, |
4702 | 1219 GDK_ACTION_COPY | GDK_ACTION_MOVE); |
4704 | 1220 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(gaim_gtk_blist_drag_data_rcv_cb), NULL); |
1221 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(gaim_gtk_blist_drag_data_get_cb), NULL); | |
1222 | |
4724 | 1223 /* Tooltips */ |
1224 g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(gaim_gtk_blist_motion_cb), NULL); | |
1225 g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(gaim_gtk_blist_leave_cb), NULL); | |
4687 | 1226 |
1227 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
1 | 1228 |
5060 | 1229 column = gtk_tree_view_column_new (); |
1230 | |
4687 | 1231 rend = gtk_cell_renderer_pixbuf_new(); |
5060 | 1232 gtk_tree_view_column_pack_start (column, rend, FALSE); |
1233 gtk_tree_view_column_set_attributes (column, rend, | |
1234 "pixbuf", STATUS_ICON_COLUMN, | |
1235 "visible", STATUS_ICON_VISIBLE_COLUMN, | |
1236 NULL); | |
4933 | 1237 g_object_set(rend, "xalign", 0.0, "ypad", 0, NULL); |
4706 | 1238 |
4687 | 1239 rend = gtk_cell_renderer_text_new(); |
5060 | 1240 gtk_tree_view_column_pack_start (column, rend, TRUE); |
1241 gtk_tree_view_column_set_attributes (column, rend, | |
1242 "markup", NAME_COLUMN, | |
1243 NULL); | |
1244 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); | |
1245 | |
4687 | 1246 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); |
4706 | 1247 |
4687 | 1248 rend = gtk_cell_renderer_text_new(); |
4725 | 1249 gtkblist->warning_column = gtk_tree_view_column_new_with_attributes("Warning", rend, "markup", WARNING_COLUMN, NULL); |
1250 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->warning_column); | |
4796 | 1251 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); |
4687 | 1252 |
1253 rend = gtk_cell_renderer_text_new(); | |
4725 | 1254 gtkblist->idle_column = gtk_tree_view_column_new_with_attributes("Idle", rend, "markup", IDLE_COLUMN, NULL); |
1255 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->idle_column); | |
4796 | 1256 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); |
1 | 1257 |
4687 | 1258 rend = gtk_cell_renderer_pixbuf_new(); |
4725 | 1259 gtkblist->buddy_icon_column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); |
4796 | 1260 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); |
4725 | 1261 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column); |
4718 | 1262 |
4687 | 1263 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); |
5142 | 1264 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-expanded", G_CALLBACK(gtk_blist_row_expanded_cb), NULL); |
1265 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-collapsed", G_CALLBACK(gtk_blist_row_collapsed_cb), NULL); | |
4687 | 1266 g_signal_connect(G_OBJECT(gtkblist->treeview), "button-press-event", G_CALLBACK(gtk_blist_button_press_cb), NULL); |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1267 |
4687 | 1268 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); |
1269 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); | |
4725 | 1270 gaim_gtk_blist_update_columns(); |
4934 | 1271 |
4956 | 1272 /* set the Show Offline Buddies option. must be done |
1273 * after the treeview or faceprint gets mad. -Robot101 | |
1274 */ | |
5000 | 1275 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (ift, N_("/Buddies/Show Offline Buddies"))), |
4956 | 1276 blist_options & OPT_BLIST_SHOW_OFFLINE); |
5000 | 1277 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (ift, N_("/Buddies/Show Empty Groups"))), |
1278 !(blist_options & OPT_BLIST_NO_MT_GRP)); | |
4956 | 1279 |
1280 /* OK... let's show this bad boy. */ | |
1281 gaim_gtk_blist_refresh(list); | |
1282 gaim_gtk_blist_restore_position(); | |
1283 gtk_widget_show_all(gtkblist->window); | |
1284 | |
4687 | 1285 /**************************** Button Box **************************************/ |
4956 | 1286 /* add this afterwards so it doesn't force up the width of the window */ |
4694 | 1287 |
5018 | 1288 gtkblist->tooltips = gtk_tooltips_new(); |
4973 | 1289 |
4694 | 1290 sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); |
4687 | 1291 gtkblist->bbox = gtk_hbox_new(TRUE, 0); |
1292 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->bbox, FALSE, FALSE, 0); | |
4956 | 1293 gtk_widget_show(gtkblist->bbox); |
1294 | |
4687 | 1295 button = gaim_pixbuf_button_from_stock(_("IM"), GAIM_STOCK_IM, GAIM_BUTTON_VERTICAL); |
1296 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
1297 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 1298 gtk_size_group_add_widget(sg, button); |
4692 | 1299 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_im_cb), |
4697 | 1300 gtkblist->treeview); |
5018 | 1301 gtk_tooltips_set_tip(GTK_TOOLTIPS(gtkblist->tooltips), button, _("Send a message to the selected buddy"), NULL); |
4956 | 1302 gtk_widget_show(button); |
1303 | |
4687 | 1304 button = gaim_pixbuf_button_from_stock(_("Get Info"), GAIM_STOCK_INFO, GAIM_BUTTON_VERTICAL); |
1305 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
1306 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 1307 gtk_size_group_add_widget(sg, button); |
1308 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_info_cb), | |
4697 | 1309 gtkblist->treeview); |
5018 | 1310 gtk_tooltips_set_tip(GTK_TOOLTIPS(gtkblist->tooltips), button, _("Get information on the selected buddy"), NULL); |
4956 | 1311 gtk_widget_show(button); |
4729 | 1312 |
4687 | 1313 button = gaim_pixbuf_button_from_stock(_("Chat"), GAIM_STOCK_CHAT, GAIM_BUTTON_VERTICAL); |
1314 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
1315 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 1316 gtk_size_group_add_widget(sg, button); |
1317 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_chat_cb), NULL); | |
5018 | 1318 gtk_tooltips_set_tip(GTK_TOOLTIPS(gtkblist->tooltips), button, _("Join a chat room"), NULL); |
4956 | 1319 gtk_widget_show(button); |
4694 | 1320 |
5024 | 1321 button = gaim_pixbuf_button_from_stock(_("Away"), GAIM_STOCK_ICON_AWAY, GAIM_BUTTON_VERTICAL); |
4687 | 1322 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); |
1323 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 1324 gtk_size_group_add_widget(sg, button); |
1325 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL); | |
5018 | 1326 gtk_tooltips_set_tip(GTK_TOOLTIPS(gtkblist->tooltips), button, _("Set an away message"), NULL); |
4956 | 1327 gtk_widget_show(button); |
4687 | 1328 |
4956 | 1329 /* this will show the right image/label widgets for us */ |
4944 | 1330 gaim_gtk_blist_update_toolbar(); |
1331 | |
4956 | 1332 /* start the refresh timer */ |
4944 | 1333 gtkblist->refresh_timer = g_timeout_add(30000, (GSourceFunc)gaim_gtk_blist_refresh_timer, list); |
4687 | 1334 } |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1335 |
4687 | 1336 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list) |
1337 { | |
1338 GaimBlistNode *group = list->root; | |
1339 GaimBlistNode *buddy; | |
4690 | 1340 |
4687 | 1341 while (group) { |
4916 | 1342 buddy = group->child; |
4687 | 1343 gaim_gtk_blist_update(list, group); |
1344 while (buddy) { | |
4699 | 1345 gaim_gtk_blist_update(list, buddy); |
4687 | 1346 buddy = buddy->next; |
1347 } | |
1348 group = group->next; | |
1349 } | |
1350 } | |
1 | 1351 |
4699 | 1352 static gboolean get_iter_from_node_helper(GaimBlistNode *node, GtkTreeIter *iter, GtkTreeIter *root) { |
4867 | 1353 |
4699 | 1354 do { |
1355 GaimBlistNode *n; | |
1356 GtkTreeIter child; | |
1357 | |
1358 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), root, NODE_COLUMN, &n, -1); | |
1359 if(n == node) { | |
1360 *iter = *root; | |
1361 return TRUE; | |
1362 } | |
1363 | |
1364 if(gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &child, root)) { | |
1365 if(get_iter_from_node_helper(node,iter,&child)) | |
1366 return TRUE; | |
1367 } | |
1368 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), root)); | |
1369 | |
1370 return FALSE; | |
1371 } | |
1372 | |
1373 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) { | |
1374 GtkTreeIter root; | |
1375 | |
1376 if (!gtkblist) | |
1377 return FALSE; | |
1378 | |
1379 if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(gtkblist->treemodel), &root)) | |
1380 return FALSE; | |
1381 | |
1382 return get_iter_from_node_helper(node, iter, &root); | |
1383 } | |
1384 | |
4944 | 1385 /* |
1386 * These state assignments suck. I'm sorry. They're for historical reasons. | |
1387 * Roll on new prefs. -Robot101 | |
1388 * | |
1389 * NO_BUTTON_TEXT && SHOW_BUTTON_XPM - image | |
1390 * !NO_BUTTON_TEXT && !SHOW_BUTTON_XPM - text | |
1391 * !NO_BUTTON_TEXT && SHOW_BUTTON_XPM - text & images | |
1392 * NO_BUTTON_TEXT && !SHOW_BUTTON_XPM - none | |
1393 */ | |
1394 | |
1395 static void gaim_gtk_blist_update_toolbar_icons (GtkWidget *widget, gpointer data) { | |
1396 if (GTK_IS_IMAGE(widget)) { | |
1397 if (blist_options & OPT_BLIST_SHOW_BUTTON_XPM) | |
1398 gtk_widget_show(widget); | |
1399 else | |
1400 gtk_widget_hide(widget); | |
1401 } else if (GTK_IS_LABEL(widget)) { | |
1402 if (blist_options & OPT_BLIST_NO_BUTTON_TEXT) | |
1403 gtk_widget_hide(widget); | |
1404 else | |
1405 gtk_widget_show(widget); | |
1406 } else if (GTK_IS_CONTAINER(widget)) { | |
1407 gtk_container_foreach(GTK_CONTAINER(widget), gaim_gtk_blist_update_toolbar_icons, NULL); | |
1408 } | |
1409 } | |
1410 | |
4697 | 1411 void gaim_gtk_blist_update_toolbar() { |
1412 if (!gtkblist) | |
1413 return; | |
4699 | 1414 |
4944 | 1415 if (blist_options & OPT_BLIST_NO_BUTTON_TEXT && !(blist_options & OPT_BLIST_SHOW_BUTTON_XPM)) |
4697 | 1416 gtk_widget_hide(gtkblist->bbox); |
4944 | 1417 else { |
1418 gtk_container_foreach(GTK_CONTAINER(gtkblist->bbox), gaim_gtk_blist_update_toolbar_icons, NULL); | |
4956 | 1419 gtk_widget_show(gtkblist->bbox); |
4944 | 1420 } |
4697 | 1421 } |
1422 | |
4701 | 1423 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node) |
1424 { | |
1425 GtkTreeIter iter; | |
1426 | |
4912 | 1427 /* For some reason, we're called before we have a buddy list sometimes */ |
1428 if(!gtkblist) | |
1429 return; | |
1430 | |
4831 | 1431 if(gtkblist->selected_node == node) |
1432 gtkblist->selected_node = NULL; | |
1433 | |
4701 | 1434 if (get_iter_from_node(node, &iter)) { |
1435 gtk_tree_store_remove(gtkblist->treemodel, &iter); | |
5041 | 1436 if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
1437 gaim_gtk_blist_update(list, node->parent); | |
4701 | 1438 } |
1439 } | |
1440 } | |
1441 | |
4810 | 1442 static gboolean do_selection_changed(GaimBlistNode *new_selection) |
1443 { | |
1444 GaimBlistNode *old_selection = gtkblist->selected_node; | |
1445 | |
1446 if(new_selection != gtkblist->selected_node) { | |
1447 gtkblist->selected_node = new_selection; | |
1448 if(new_selection) | |
1449 gaim_gtk_blist_update(NULL, new_selection); | |
1450 if(old_selection) | |
1451 gaim_gtk_blist_update(NULL, old_selection); | |
1452 } | |
1453 | |
1454 return FALSE; | |
1455 } | |
1456 | |
1457 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data) | |
1458 { | |
1459 GaimBlistNode *new_selection = NULL; | |
1460 GtkTreeIter iter; | |
1461 | |
1462 if(gtk_tree_selection_get_selected(selection, NULL, &iter)){ | |
1463 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
1464 NODE_COLUMN, &new_selection, -1); | |
1465 } | |
1466 /* we set this up as a timeout, otherwise the blist flickers */ | |
1467 g_timeout_add(0, (GSourceFunc)do_selection_changed, new_selection); | |
1468 } | |
1469 | |
4936 | 1470 static void make_a_group(GaimBlistNode *node, GtkTreeIter *iter) { |
1471 GaimBlistNode *sibling; | |
1472 GtkTreeIter siblingiter; | |
4980 | 1473 struct group *group = (struct group *)node; |
1474 char *esc = g_markup_escape_text(group->name, -1); | |
1475 char *mark; | |
1476 | |
1477 if(blist_options & OPT_BLIST_SHOW_GRPNUM) | |
1478 mark = g_strdup_printf("<span weight='bold'>%s</span> (%d/%d)", esc, gaim_blist_get_group_online_count(group), gaim_blist_get_group_size(group, FALSE)); | |
1479 else | |
1480 mark = g_strdup_printf("<span weight='bold'>%s</span>", esc); | |
1481 | |
4936 | 1482 g_free(esc); |
4980 | 1483 |
4936 | 1484 sibling = node->prev; |
1485 while (sibling && !get_iter_from_node(sibling, &siblingiter)) { | |
1486 sibling = sibling->prev; | |
1487 } | |
1488 | |
1489 gtk_tree_store_insert_after(gtkblist->treemodel, iter, NULL, | |
1490 sibling ? &siblingiter : NULL); | |
1491 gtk_tree_store_set(gtkblist->treemodel, iter, | |
5060 | 1492 STATUS_ICON_COLUMN, NULL, |
1493 STATUS_ICON_VISIBLE_COLUMN, FALSE, | |
4936 | 1494 NAME_COLUMN, mark, |
1495 NODE_COLUMN, node, | |
1496 -1); | |
1497 g_free(mark); | |
1498 } | |
1499 | |
4701 | 1500 |
4687 | 1501 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) |
1502 { | |
4699 | 1503 GtkTreeIter iter; |
4936 | 1504 GtkTreePath *expand = NULL; |
4699 | 1505 gboolean new_entry = FALSE; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1506 |
4687 | 1507 if (!gtkblist) |
1508 return; | |
4699 | 1509 |
1510 if (!get_iter_from_node(node, &iter)) { /* This is a newly added node */ | |
1511 new_entry = TRUE; | |
4687 | 1512 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
5068 | 1513 if (((struct buddy*)node)->present != GAIM_BUDDY_OFFLINE || ((blist_options & OPT_BLIST_SHOW_OFFLINE) && ((struct buddy*)node)->account->gc)) { |
4699 | 1514 GtkTreeIter groupiter; |
1515 GaimBlistNode *oldersibling; | |
1516 GtkTreeIter oldersiblingiter; | |
5142 | 1517 char *collapsed = gaim_group_get_setting((struct group *)node->parent, "collapsed"); |
4690 | 1518 |
4936 | 1519 if(node->parent && |
1520 !get_iter_from_node(node->parent, &groupiter)) { | |
1521 /* This buddy's group has not yet been added. | |
1522 * We do that here */ | |
1523 make_a_group(node->parent, &groupiter); | |
5000 | 1524 } |
5142 | 1525 if(!collapsed) |
4936 | 1526 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter); |
5142 | 1527 else |
1528 g_free(collapsed); | |
4810 | 1529 |
4699 | 1530 oldersibling = node->prev; |
4867 | 1531 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) { |
4699 | 1532 oldersibling = oldersibling->prev; |
4867 | 1533 } |
4699 | 1534 |
1535 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL); | |
4810 | 1536 |
5200 | 1537 if (blist_options & OPT_BLIST_POPUP) { |
1538 gtk_widget_show(gtkblist->window); | |
1539 gtk_window_deiconify(GTK_WINDOW(gtkblist->window)); | |
1540 gdk_window_raise(gtkblist->window->window); | |
1541 } | |
4699 | 1542 |
1543 } | |
1544 } | |
5000 | 1545 else if (GAIM_BLIST_NODE_IS_GROUP(node) && |
1546 ((blist_options & OPT_BLIST_SHOW_OFFLINE) || | |
1547 !(blist_options & OPT_BLIST_NO_MT_GRP))) { | |
4936 | 1548 make_a_group(node, &iter); |
1549 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); | |
4916 | 1550 } |
1551 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
5000 | 1552 if((blist_options & OPT_BLIST_NO_MT_GRP) && !(blist_options & OPT_BLIST_SHOW_OFFLINE) && !gaim_blist_get_group_online_count((struct group *)node)) { |
4916 | 1553 gtk_tree_store_remove(gtkblist->treemodel, &iter); |
4936 | 1554 } else { |
4980 | 1555 struct group *group = (struct group *)node; |
1556 char *esc = g_markup_escape_text(group->name, -1); | |
1557 char *mark; | |
1558 | |
1559 if(blist_options & OPT_BLIST_SHOW_GRPNUM) | |
1560 mark = g_strdup_printf("<span weight='bold'>%s</span> (%d/%d)", esc, gaim_blist_get_group_online_count(group), gaim_blist_get_group_size(group, FALSE)); | |
1561 else | |
1562 mark = g_strdup_printf("<span weight='bold'>%s</span>", esc); | |
1563 | |
4916 | 1564 g_free(esc); |
1565 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
4936 | 1566 NAME_COLUMN, mark, |
1567 -1); | |
4916 | 1568 g_free(mark); |
1569 } | |
4699 | 1570 } |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1571 |
5068 | 1572 if (GAIM_BLIST_NODE_IS_BUDDY(node) && (((struct buddy*)node)->present != GAIM_BUDDY_OFFLINE || ((blist_options & OPT_BLIST_SHOW_OFFLINE) && ((struct buddy*)node)->account->gc))) { |
4687 | 1573 GdkPixbuf *status, *avatar; |
1574 char *mark; | |
4697 | 1575 char *warning = NULL, *idle = NULL; |
1576 | |
4810 | 1577 gboolean selected = (gtkblist->selected_node == node); |
1578 | |
1579 status = gaim_gtk_blist_get_status_icon((struct buddy*)node, | |
4724 | 1580 blist_options & OPT_BLIST_SHOW_ICONS ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL); |
4687 | 1581 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node); |
4810 | 1582 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node, selected); |
4697 | 1583 |
4725 | 1584 if (((struct buddy*)node)->idle > 0) { |
4697 | 1585 time_t t; |
1586 int ihrs, imin; | |
1587 time(&t); | |
1588 ihrs = (t - ((struct buddy *)node)->idle) / 3600; | |
1589 imin = ((t - ((struct buddy*)node)->idle) / 60) % 60; | |
4718 | 1590 if(ihrs > 0) |
1591 idle = g_strdup_printf("(%d:%02d)", ihrs, imin); | |
1592 else | |
1593 idle = g_strdup_printf("(%d)", imin); | |
4697 | 1594 } |
1595 | |
4725 | 1596 if (((struct buddy*)node)->evil > 0) |
4699 | 1597 warning = g_strdup_printf("%d%%", ((struct buddy*)node)->evil); |
4810 | 1598 |
4697 | 1599 |
4718 | 1600 if((blist_options & OPT_BLIST_GREY_IDLERS) |
1601 && ((struct buddy *)node)->idle) { | |
4810 | 1602 if(warning && !selected) { |
4718 | 1603 char *w2 = g_strdup_printf("<span color='dim grey'>%s</span>", |
1604 warning); | |
1605 g_free(warning); | |
1606 warning = w2; | |
1607 } | |
1608 | |
4810 | 1609 if(idle && !selected) { |
4718 | 1610 char *i2 = g_strdup_printf("<span color='dim grey'>%s</span>", |
1611 idle); | |
1612 g_free(idle); | |
1613 idle = i2; | |
1614 } | |
1615 } | |
1616 | |
4699 | 1617 gtk_tree_store_set(gtkblist->treemodel, &iter, |
4687 | 1618 STATUS_ICON_COLUMN, status, |
5060 | 1619 STATUS_ICON_VISIBLE_COLUMN, TRUE, |
4687 | 1620 NAME_COLUMN, mark, |
4697 | 1621 WARNING_COLUMN, warning, |
1622 IDLE_COLUMN, idle, | |
4699 | 1623 BUDDY_ICON_COLUMN, avatar, |
4687 | 1624 NODE_COLUMN, node, |
1625 -1); | |
4699 | 1626 |
5189 | 1627 if (blist_options & OPT_BLIST_POPUP && |
5200 | 1628 ((struct buddy *)node)->present == GAIM_BUDDY_SIGNING_OFF) { |
1629 gtk_widget_show(gtkblist->window); | |
1630 gtk_window_deiconify(GTK_WINDOW(gtkblist->window)); | |
1631 gdk_window_raise(gtkblist->window->window); | |
1632 } | |
5189 | 1633 |
4687 | 1634 g_free(mark); |
4697 | 1635 if (idle) |
1636 g_free(idle); | |
1637 if (warning) | |
1638 g_free(warning); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1639 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1640 if (status != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1641 g_object_unref(status); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1642 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1643 if (avatar != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1644 g_object_unref(avatar); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1645 |
4701 | 1646 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && !new_entry) { |
1647 gaim_gtk_blist_remove(list, node); | |
4687 | 1648 } |
4980 | 1649 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); |
4936 | 1650 |
4974 | 1651 |
4936 | 1652 if(expand) { |
1653 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), expand, TRUE); | |
1654 gtk_tree_path_free(expand); | |
1655 } | |
4980 | 1656 |
1657 if(GAIM_BLIST_NODE_IS_BUDDY(node)) | |
1658 gaim_gtk_blist_update(list, node->parent); | |
4687 | 1659 } |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1660 |
4687 | 1661 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) |
1662 { | |
4770 | 1663 if (!gtkblist) |
1664 return; | |
4944 | 1665 |
4687 | 1666 gtk_widget_destroy(gtkblist->window); |
5018 | 1667 gtk_object_sink(GTK_OBJECT(gtkblist->tooltips)); |
4745 | 1668 |
4944 | 1669 if (gtkblist->refresh_timer) |
1670 g_source_remove(gtkblist->refresh_timer); | |
1671 if (gtkblist->timeout) | |
1672 g_source_remove(gtkblist->timeout); | |
1673 | |
1674 gtkblist->refresh_timer = 0; | |
1675 gtkblist->timeout = 0; | |
4745 | 1676 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; |
1677 gtkblist->treemodel = NULL; | |
1678 gtkblist->idle_column = NULL; | |
1679 gtkblist->warning_column = gtkblist->buddy_icon_column = NULL; | |
1680 gtkblist->bbox = gtkblist->tipwindow = NULL; | |
1681 protomenu = NULL; | |
1682 awaymenu = NULL; | |
5187 | 1683 gtkblist = NULL; |
4687 | 1684 } |
1 | 1685 |
4687 | 1686 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) |
1687 { | |
4840 | 1688 if (!(gtkblist && gtkblist->window)) |
1689 return; | |
1690 | |
4698 | 1691 if (show) { |
4840 | 1692 gaim_gtk_blist_restore_position(); |
4699 | 1693 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
4698 | 1694 } else { |
1695 if (!connections || docklet_count) { | |
1696 #ifdef _WIN32 | |
4711
0c1f3e651d3e
[gaim-migrate @ 5022]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4706
diff
changeset
|
1697 wgaim_systray_minimize(gtkblist->window); |
4698 | 1698 #endif |
1699 gtk_widget_hide(gtkblist->window); | |
1700 } else { | |
1701 gtk_window_iconify(GTK_WINDOW(gtkblist->window)); | |
1702 } | |
1703 } | |
1704 } | |
1705 | |
1706 void gaim_gtk_blist_docklet_toggle() { | |
1707 /* Useful for the docklet plugin and also for the win32 tray icon*/ | |
1708 /* This is called when one of those is clicked--it will show/hide the | |
1709 buddy list/login window--depending on which is active */ | |
4840 | 1710 if (connections) { |
1711 if (gtkblist && gtkblist->window) { | |
1712 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { | |
1713 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gaim_gtk_blist_obscured); | |
1714 } else { | |
4698 | 1715 #if _WIN32 |
4840 | 1716 wgaim_systray_maximize(gtkblist->window); |
4698 | 1717 #endif |
4840 | 1718 gaim_blist_set_visible(TRUE); |
1719 } | |
1720 } else { | |
1721 /* we're logging in or something... do nothing */ | |
1722 /* or should I make the blist? */ | |
5213
1cf4eb75e3ee
[gaim-migrate @ 5583]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
1723 gaim_debug(GAIM_DEBUG_WARNING, "blist", |
1cf4eb75e3ee
[gaim-migrate @ 5583]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
1724 "docklet_toggle called with connections " |
1cf4eb75e3ee
[gaim-migrate @ 5583]
Christian Hammond <chipx86@chipx86.com>
parents:
5211
diff
changeset
|
1725 "but no blist!\n"); |
4698 | 1726 } |
4840 | 1727 } else if (mainwindow) { |
1728 if (GTK_WIDGET_VISIBLE(mainwindow)) { | |
4698 | 1729 if (GAIM_WINDOW_ICONIFIED(mainwindow)) { |
1730 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1731 } else { | |
1732 #if _WIN32 | |
1733 wgaim_systray_minimize(mainwindow); | |
1734 #endif | |
1735 gtk_widget_hide(mainwindow); | |
1736 } | |
1737 } else { | |
1738 #if _WIN32 | |
1739 wgaim_systray_maximize(mainwindow); | |
1740 #endif | |
4833 | 1741 show_login(); |
4698 | 1742 } |
4840 | 1743 } else { |
1744 show_login(); | |
4698 | 1745 } |
1746 } | |
1747 | |
1748 void gaim_gtk_blist_docklet_add() | |
1749 { | |
1750 docklet_count++; | |
1751 } | |
1752 | |
1753 void gaim_gtk_blist_docklet_remove() | |
1754 { | |
1755 docklet_count--; | |
1756 if (!docklet_count) { | |
4944 | 1757 if (connections) |
4698 | 1758 gaim_blist_set_visible(TRUE); |
4944 | 1759 else if (mainwindow) |
4840 | 1760 gtk_window_present(GTK_WINDOW(mainwindow)); |
4944 | 1761 else |
4840 | 1762 show_login(); |
4698 | 1763 } |
4687 | 1764 } |
1 | 1765 |
4687 | 1766 static struct gaim_blist_ui_ops blist_ui_ops = |
1767 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1768 gaim_gtk_blist_new_list, |
5068 | 1769 NULL, |
4687 | 1770 gaim_gtk_blist_show, |
1771 gaim_gtk_blist_update, | |
1772 gaim_gtk_blist_remove, | |
1773 gaim_gtk_blist_destroy, | |
1774 gaim_gtk_blist_set_visible | |
1775 }; | |
1 | 1776 |
1777 | |
4687 | 1778 struct gaim_blist_ui_ops *gaim_get_gtk_blist_ui_ops() |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1779 { |
4687 | 1780 return &blist_ui_ops; |
1037
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1781 } |
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1782 |
3131 | 1783 |
1784 | |
4687 | 1785 /********************************************************************* |
1786 * Public utility functions * | |
1787 *********************************************************************/ | |
1058
4927ce25d8cc
[gaim-migrate @ 1068]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
1788 |
4687 | 1789 GdkPixbuf * |
1790 create_prpl_icon(struct gaim_account *account) | |
4553
d03fcb3f4be2
[gaim-migrate @ 4833]
Christian Hammond <chipx86@chipx86.com>
parents:
4525
diff
changeset
|
1791 { |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1792 GaimPlugin *prpl; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1793 GaimPluginProtocolInfo *prpl_info = NULL; |
4687 | 1794 GdkPixbuf *status = NULL; |
1795 char *filename = NULL; | |
5151 | 1796 const char *protoname = NULL; |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1797 char buf[256]; |
5151 | 1798 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1799 prpl = gaim_find_prpl(account->protocol); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1800 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1801 if (prpl != NULL) { |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1802 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1803 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1804 if (prpl_info->list_icon != NULL) |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1805 protoname = prpl_info->list_icon(account, NULL); |
5151 | 1806 } |
1807 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1808 if (protoname == NULL) |
5201 | 1809 return NULL; |
1810 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1811 /* |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1812 * Status icons will be themeable too, and then it will look up |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1813 * protoname from the theme |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1814 */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1815 g_snprintf(buf, sizeof(buf), "%s.png", protoname); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1816 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1817 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1818 "default", buf, NULL); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1819 status = gdk_pixbuf_new_from_file(filename, NULL); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1820 g_free(filename); |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5201
diff
changeset
|
1821 |
4687 | 1822 return status; |
1 | 1823 } |
4699 | 1824 |